6 Commits

Author SHA1 Message Date
sean ce05593127 Merge branch 'it-works' into develop 2025-12-07 16:54:37 -05:00
dstrawsb be03424e26 fixed the name change from gunbuilder to builder and added the TM for trademark 2025-12-05 23:32:23 -05:00
dstrawsb fa710d35a1 fixed conflict 2025-12-05 22:28:40 -05:00
dstrawsb 6863b3618c fixed merge config 2025-12-05 21:01:10 -05:00
dstrawsb b4177883f8 deleteing .next 2025-12-04 10:12:03 -05:00
dstrawsb 48e677bcfb deleting .next 2025-12-04 10:10:22 -05:00
16 changed files with 64 additions and 128 deletions
+8
View File
@@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
+6
View File
@@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
</component>
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/shadow-gunbuilder-ai-proto.iml" filepath="$PROJECT_DIR$/.idea/shadow-gunbuilder-ai-proto.iml" />
</modules>
</component>
</project>
+9
View File
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="SqlDialectMappings">
<file url="file://$PROJECT_DIR$/schema-example.sql" dialect="PostgreSQL" />
</component>
</project>
Generated
+1 -1
View File
@@ -3,4 +3,4 @@
<component name="VcsDirectoryMappings"> <component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" /> <mapping directory="$PROJECT_DIR$" vcs="Git" />
</component> </component>
</project> </project>
-93
View File
@@ -1,93 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="261566a2-3672-4898-b754-916bbdb2063b" name="Changes" comment="">
<change beforePath="$PROJECT_DIR$/next-env.d.ts" beforeDir="false" afterPath="$PROJECT_DIR$/next-env.d.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/tsconfig.json" beforeDir="false" afterPath="$PROJECT_DIR$/tsconfig.json" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="ProjectColorInfo">{
&quot;associatedIndex&quot;: 1
}</component>
<component name="ProjectId" id="361l08WqyxLtDro87xvcOWn3FhH" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent">{
&quot;keyToString&quot;: {
&quot;ModuleVcsDetector.initialDetectionPerformed&quot;: &quot;true&quot;,
&quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
&quot;RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252&quot;: &quot;true&quot;,
&quot;RunOnceActivity.git.unshallow&quot;: &quot;true&quot;,
&quot;git-widget-placeholder&quot;: &quot;main&quot;,
&quot;ignore.virus.scanning.warn.message&quot;: &quot;true&quot;,
&quot;js.debugger.nextJs.config.created.client&quot;: &quot;true&quot;,
&quot;js.debugger.nextJs.config.created.server&quot;: &quot;true&quot;,
&quot;kotlin-language-version-configured&quot;: &quot;true&quot;,
&quot;last_opened_file_path&quot;: &quot;//wsl.localhost/Arch/home/don/code/shadow-gunbuilder-ai-proto&quot;,
&quot;node.js.detected.package.eslint&quot;: &quot;true&quot;,
&quot;node.js.detected.package.tslint&quot;: &quot;true&quot;,
&quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;,
&quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;,
&quot;nodejs_package_manager_path&quot;: &quot;npm&quot;,
&quot;vue.rearranger.settings.migration&quot;: &quot;true&quot;
}
}</component>
<component name="RunManager" selected="npm.Next.js: server-side">
<configuration name="Next.js: debug client-side" type="JavascriptDebugType" uri="http://localhost:3000/">
<method v="2" />
</configuration>
<configuration name="Next.js: server-side" type="js.build_tools.npm">
<package-json value="$PROJECT_DIR$/package.json" />
<command value="run" />
<scripts>
<script value="dev" />
</scripts>
<node-interpreter value="project" />
<envs />
<method v="2" />
</configuration>
</component>
<component name="SharedIndexes">
<attachedChunks>
<set>
<option value="bundled-jdk-9823dce3aa75-bf35d07a577b-intellij.indexing.shared.core-IU-252.27397.103" />
<option value="bundled-js-predefined-d6986cc7102b-3aa1da707db6-JavaScript-IU-252.27397.103" />
</set>
</attachedChunks>
</component>
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="261566a2-3672-4898-b754-916bbdb2063b" name="Changes" comment="" />
<created>1764181733358</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1764181733358</updated>
<workItem from="1764181734592" duration="78000" />
<workItem from="1764181824336" duration="9367000" />
</task>
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
<component name="github-copilot-workspace">
<instructionFileLocations>
<option value=".github/instructions" />
</instructionFileLocations>
<promptFileLocations>
<option value=".github/prompts" />
</promptFileLocations>
</component>
</project>
+6 -6
View File
@@ -11,7 +11,7 @@ This is an internal tool built for speed, clarity, and capability.
# 🚀 What This Admin UI Does # 🚀 What This Admin UI Does
## Merchant Feeds ## Merchant Feeds
Path: `/gunbuilder/admin/merchants` Path: `//admin/merchants`
A clean dashboard for all merchants feeding the system. A clean dashboard for all merchants feeding the system.
@@ -26,7 +26,7 @@ Purpose: keep the catalog alive, current, and trustworthy.
--- ---
## Category Mapping ## Category Mapping
Path: `/gunbuilder/admin/category-mapping` Path: `/builder/admin/category-mapping`
This is where raw merchant chaos gets cleaned up. This is where raw merchant chaos gets cleaned up.
@@ -42,7 +42,7 @@ Once mapped, future imports classify parts automatically.
## Builder Integration ## Builder Integration
The admin UI powers the consumer-facing Builder at `/gunbuilder`. The admin UI powers the consumer-facing Builder at `/builder`.
Today: Today:
- Load compatible parts - Load compatible parts
@@ -80,13 +80,13 @@ pnpm install
Create `.env.local`: Create `.env.local`:
NEXT_PUBLIC_API_BASE_URL=http://localhost:8080 NEXT_PUBLIC_API_BASE_URL=http://localhost:8080
NEXT_PUBLIC_ADMIN_BASE_PATH=/gunbuilder/admin NEXT_PUBLIC_ADMIN_BASE_PATH=/builder/admin
## Start Dev Server ## Start Dev Server
npm run dev npm run dev
Then visit: Then visit:
http://localhost:3000/gunbuilder/admin http://localhost:3000/builder/admin
--- ---
@@ -103,7 +103,7 @@ If CORS fails, the admin cannot communicate with the API.
# 🧭 Project Structure # 🧭 Project Structure
app/ app/
gunbuilder/ builder/
admin/ admin/
merchants/ merchants/
category-mapping/ category-mapping/
+1 -1
View File
@@ -1,4 +1,4 @@
// app/gunbuilder/[categoryId]/[partId]/data.ts // app/builder/[categoryId]/[partId]/data.ts
// Simulated data functions - Replace these with API calls when ready // Simulated data functions - Replace these with API calls when ready
// Example: export async function getPricingHistory(partId: string) { ... } // Example: export async function getPricingHistory(partId: string) { ... }
+7 -7
View File
@@ -131,10 +131,10 @@ export default function PartDetailPage() {
<div className="mx-auto max-w-6xl px-4 py-6 lg:py-10"> <div className="mx-auto max-w-6xl px-4 py-6 lg:py-10">
<h1 className="text-2xl font-semibold mb-4">Category Not Found</h1> <h1 className="text-2xl font-semibold mb-4">Category Not Found</h1>
<Link <Link
href="/gunbuilder" href="/builder"
className="text-amber-300 hover:text-amber-200 underline" className="text-amber-300 hover:text-amber-200 underline"
> >
Return to Gunbuilder Return to Builder
</Link> </Link>
</div> </div>
</main> </main>
@@ -147,14 +147,14 @@ export default function PartDetailPage() {
{/* Breadcrumbs */} {/* Breadcrumbs */}
<nav className="mb-4 text-xs text-zinc-500"> <nav className="mb-4 text-xs text-zinc-500">
<Link <Link
href="/gunbuilder" href="/builder"
className="hover:text-zinc-300 transition-colors" className="hover:text-zinc-300 transition-colors"
> >
Gunbuilder Builder
</Link> </Link>
<span className="mx-1">/</span> <span className="mx-1">/</span>
<Link <Link
href={`/gunbuilder/${categoryId}`} href={`/builder/${categoryId}`}
className="hover:text-zinc-300 transition-colors" className="hover:text-zinc-300 transition-colors"
> >
{category.name} {category.name}
@@ -176,7 +176,7 @@ export default function PartDetailPage() {
{error ?? "We couldnt find this product."} {error ?? "We couldnt find this product."}
</p> </p>
<Link <Link
href={`/gunbuilder/${categoryId}`} href={`/builder/${categoryId}`}
className="text-amber-300 hover:text-amber-200 underline text-sm" className="text-amber-300 hover:text-amber-200 underline text-sm"
> >
Back to {category.name} parts Back to {category.name} parts
@@ -352,7 +352,7 @@ export default function PartDetailPage() {
<div className="space-y-2"> <div className="space-y-2">
<Link <Link
href={`/gunbuilder?select=${categoryId}:${product.id}`} href={`/builder?select=${categoryId}:${product.id}`}
className="block w-full rounded-md bg-amber-400 text-black text-sm font-semibold text-center py-2.5 hover:bg-amber-300 transition-colors" className="block w-full rounded-md bg-amber-400 text-black text-sm font-semibold text-center py-2.5 hover:bg-amber-300 transition-colors"
> >
Add to Build Add to Build
+1 -1
View File
@@ -305,7 +305,7 @@ export default function CategoryPage() {
href="/builder" href="/builder"
className="text-amber-300 hover:text-amber-200 underline" className="text-amber-300 hover:text-amber-200 underline"
> >
Return to Gunbuilder Return to Builder
</Link> </Link>
</div> </div>
</div> </div>
+7 -7
View File
@@ -150,7 +150,7 @@ export default function BuildDetailsPage() {
useEffect(() => { useEffect(() => {
if (typeof window !== "undefined" && Object.keys(build).length > 0) { if (typeof window !== "undefined" && Object.keys(build).length > 0) {
const encoded = encodeBuildState(build); const encoded = encodeBuildState(build);
const url = `${window.location.origin}/gunbuilder/build?build=${encoded}`; const url = `${window.location.origin}/builder/build?build=${encoded}`;
setShareUrl(url); setShareUrl(url);
} }
}, [build]); }, [build]);
@@ -212,10 +212,10 @@ export default function BuildDetailsPage() {
You need to select at least one part to view your build. You need to select at least one part to view your build.
</p> </p>
<Link <Link
href="/gunbuilder" href="/builder"
className="inline-block rounded-md border border-amber-400/60 bg-amber-400/10 px-4 py-2 text-sm font-medium text-amber-200 hover:bg-amber-400/15 transition-colors" className="inline-block rounded-md border border-amber-400/60 bg-amber-400/10 px-4 py-2 text-sm font-medium text-amber-200 hover:bg-amber-400/15 transition-colors"
> >
Go to Gunbuilder Go to Builder
</Link> </Link>
</div> </div>
</div> </div>
@@ -229,7 +229,7 @@ export default function BuildDetailsPage() {
{/* Header */} {/* Header */}
<header className="mb-6"> <header className="mb-6">
<Link <Link
href="/gunbuilder" href="/builder"
className="text-xs text-zinc-400 hover:text-zinc-300 mb-4 inline-block" className="text-xs text-zinc-400 hover:text-zinc-300 mb-4 inline-block"
> >
Back to The Armory Back to The Armory
@@ -368,7 +368,7 @@ export default function BuildDetailsPage() {
</a> </a>
)} )}
<Link <Link
href={`/gunbuilder/${category.id}/${part.id}`} href={`/builder/${category.id}/${part.id}`}
className="inline-flex items-center rounded-md border border-zinc-700 bg-zinc-900/50 px-4 py-2 text-sm font-medium text-zinc-300 hover:bg-zinc-800 hover:border-zinc-600 transition-colors" className="inline-flex items-center rounded-md border border-zinc-700 bg-zinc-900/50 px-4 py-2 text-sm font-medium text-zinc-300 hover:bg-zinc-800 hover:border-zinc-600 transition-colors"
> >
View Details View Details
@@ -398,7 +398,7 @@ export default function BuildDetailsPage() {
{/* Actions */} {/* Actions */}
<div className="mt-6 flex flex-col gap-3 sm:flex-row sm:justify-between"> <div className="mt-6 flex flex-col gap-3 sm:flex-row sm:justify-between">
<Link <Link
href="/gunbuilder" href="/builder"
className="rounded-md border border-zinc-700 bg-zinc-900/50 px-6 py-3 text-sm font-medium text-zinc-300 hover:bg-zinc-800 hover:border-zinc-600 transition-colors text-center" className="rounded-md border border-zinc-700 bg-zinc-900/50 px-6 py-3 text-sm font-medium text-zinc-300 hover:bg-zinc-800 hover:border-zinc-600 transition-colors text-center"
> >
Edit Build Edit Build
@@ -408,7 +408,7 @@ export default function BuildDetailsPage() {
type="button" type="button"
onClick={() => { onClick={() => {
localStorage.removeItem(STORAGE_KEY); localStorage.removeItem(STORAGE_KEY);
router.push("/gunbuilder"); router.push("/builder");
}} }}
className="rounded-md border border-zinc-700 bg-zinc-900/50 px-6 py-3 text-sm font-medium text-zinc-300 hover:bg-zinc-800 hover:border-zinc-600 transition-colors" className="rounded-md border border-zinc-700 bg-zinc-900/50 px-6 py-3 text-sm font-medium text-zinc-300 hover:bg-zinc-800 hover:border-zinc-600 transition-colors"
> >
+1 -1
View File
@@ -15,7 +15,7 @@ export default function LoginPage() {
const [password, setPassword] = useState(""); const [password, setPassword] = useState("");
const [error, setError] = useState<string | null>(null); const [error, setError] = useState<string | null>(null);
const next = searchParams.get("next") || "/gunbuilder"; const next = searchParams.get("next") || "/builder";
async function handleSubmit(e: FormEvent) { async function handleSubmit(e: FormEvent) {
e.preventDefault(); e.preventDefault();
+2 -2
View File
@@ -12,10 +12,10 @@ export default function HomePage() {
bg-gradient-to-r from-amber-400 via-amber-200 to-amber-400 bg-gradient-to-r from-amber-400 via-amber-200 to-amber-400
text-transparent uppercase bg-clip-text drop-shadow-[0_2px_6px_rgba(255,193,7,0.25)]" text-transparent uppercase bg-clip-text drop-shadow-[0_2px_6px_rgba(255,193,7,0.25)]"
> >
Battl Builder Battl Builder&trade;
</h1> </h1>
<p className="mt-3 text-sm md:text-base text-zinc-400"> <p className="mt-3 text-sm md:text-base text-zinc-400">
Battl Builder is your command center for rifle builds. We surface live Battl Builder&trade; is your command center for rifle builds. We surface live
parts and hard-use brands, giving you a mission-ready workbench to parts and hard-use brands, giving you a mission-ready workbench to
design smarter, track cost, swap components, and save setups. No design smarter, track cost, swap components, and save setups. No
fluff. Just clean, trustworthy data. fluff. Just clean, trustworthy data.
+1 -1
View File
@@ -16,7 +16,7 @@ export default function RegisterPage() {
const [password, setPassword] = useState(""); const [password, setPassword] = useState("");
const [error, setError] = useState<string | null>(null); const [error, setError] = useState<string | null>(null);
const next = searchParams.get("next") || "/gunbuilder"; const next = searchParams.get("next") || "/builder";
async function handleSubmit(e: FormEvent) { async function handleSubmit(e: FormEvent) {
e.preventDefault(); e.preventDefault();
-8
View File
@@ -994,7 +994,6 @@
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"bin": { "bin": {
"acorn": "bin/acorn" "acorn": "bin/acorn"
}, },
@@ -1435,7 +1434,6 @@
} }
], ],
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"baseline-browser-mapping": "^2.8.25", "baseline-browser-mapping": "^2.8.25",
"caniuse-lite": "^1.0.30001754", "caniuse-lite": "^1.0.30001754",
@@ -2098,7 +2096,6 @@
"deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.6.1", "@eslint-community/regexpp": "^4.6.1",
@@ -4429,7 +4426,6 @@
} }
], ],
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"nanoid": "^3.3.7", "nanoid": "^3.3.7",
"picocolors": "^1.0.0", "picocolors": "^1.0.0",
@@ -4588,7 +4584,6 @@
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
"integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"loose-envify": "^1.1.0" "loose-envify": "^1.1.0"
}, },
@@ -4601,7 +4596,6 @@
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
"integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"loose-envify": "^1.1.0", "loose-envify": "^1.1.0",
"scheduler": "^0.23.2" "scheduler": "^0.23.2"
@@ -5548,7 +5542,6 @@
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"engines": { "engines": {
"node": ">=12" "node": ">=12"
}, },
@@ -5718,7 +5711,6 @@
"integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"peer": true,
"bin": { "bin": {
"tsc": "bin/tsc", "tsc": "bin/tsc",
"tsserver": "bin/tsserver" "tsserver": "bin/tsserver"