fixed platform selector and part selector
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -87,7 +87,16 @@ export default function GunbuilderPage() {
|
|||||||
const [parts, setParts] = useState<Part[]>([]);
|
const [parts, setParts] = useState<Part[]>([]);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
const [platform, setPlatform] = useState<(typeof PLATFORMS)[number]>("AR-15");
|
const isValidPlatform = (
|
||||||
|
value: string | null
|
||||||
|
): value is (typeof PLATFORMS)[number] =>
|
||||||
|
!!value && (PLATFORMS as readonly string[]).includes(value);
|
||||||
|
|
||||||
|
const [platform, setPlatform] = useState<(typeof PLATFORMS)[number]>(() => {
|
||||||
|
if (typeof window === "undefined") return "AR-15";
|
||||||
|
const initial = new URLSearchParams(window.location.search).get("platform");
|
||||||
|
return isValidPlatform(initial) ? initial : "AR-15";
|
||||||
|
});
|
||||||
const [build, setBuild] = useState<BuildState>(() => {
|
const [build, setBuild] = useState<BuildState>(() => {
|
||||||
if (typeof window !== "undefined") {
|
if (typeof window !== "undefined") {
|
||||||
const stored = localStorage.getItem(STORAGE_KEY);
|
const stored = localStorage.getItem(STORAGE_KEY);
|
||||||
@@ -189,11 +198,26 @@ export default function GunbuilderPage() {
|
|||||||
return updated;
|
return updated;
|
||||||
});
|
});
|
||||||
|
|
||||||
router.replace("/builder", { scroll: false });
|
const qp = searchParams.get("platform");
|
||||||
|
const nextPlatform = isValidPlatform(qp) ? qp : platform;
|
||||||
|
|
||||||
|
router.replace(
|
||||||
|
`/builder?platform=${encodeURIComponent(nextPlatform)}`,
|
||||||
|
{
|
||||||
|
scroll: false,
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [searchParams, router]);
|
}, [searchParams, router]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const qp = searchParams.get("platform");
|
||||||
|
if (isValidPlatform(qp) && qp !== platform) {
|
||||||
|
setPlatform(qp);
|
||||||
|
}
|
||||||
|
}, [searchParams, platform]);
|
||||||
|
|
||||||
// Persist build state to localStorage whenever it changes
|
// Persist build state to localStorage whenever it changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (typeof window !== "undefined") {
|
if (typeof window !== "undefined") {
|
||||||
@@ -695,10 +719,24 @@ export default function GunbuilderPage() {
|
|||||||
<Link
|
<Link
|
||||||
href={{
|
href={{
|
||||||
pathname: `/builder/${category.id}`,
|
pathname: `/builder/${category.id}`,
|
||||||
query: { platform },
|
query: platform ? { platform } : {},
|
||||||
}}
|
}}
|
||||||
|
className="inline-flex items-center gap-1.5 whitespace-nowrap rounded-md border border-zinc-700 bg-zinc-900/70 px-3 py-1.5 text-xs font-medium text-zinc-300 hover:bg-zinc-800 hover:border-zinc-600 transition-colors"
|
||||||
>
|
>
|
||||||
Choose a Part
|
<svg
|
||||||
|
className="w-3.5 h-3.5"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
strokeWidth={2}
|
||||||
|
d="M12 4v16m8-8H4"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
<span>Choose a Part</span>
|
||||||
</Link>
|
</Link>
|
||||||
) : (
|
) : (
|
||||||
<span className="text-[0.7rem] text-zinc-600">
|
<span className="text-[0.7rem] text-zinc-600">
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ interface CategoryColumnProps {
|
|||||||
parts: Part[];
|
parts: Part[];
|
||||||
selectedPartId?: string;
|
selectedPartId?: string;
|
||||||
onSelectPart: (partId: string) => void;
|
onSelectPart: (partId: string) => void;
|
||||||
|
platform?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function CategoryColumn({
|
export function CategoryColumn({
|
||||||
@@ -16,6 +17,7 @@ export function CategoryColumn({
|
|||||||
parts,
|
parts,
|
||||||
selectedPartId,
|
selectedPartId,
|
||||||
onSelectPart,
|
onSelectPart,
|
||||||
|
platform,
|
||||||
}: CategoryColumnProps) {
|
}: CategoryColumnProps) {
|
||||||
// Show selected part if available, otherwise show placeholder
|
// Show selected part if available, otherwise show placeholder
|
||||||
const displayedPart = selectedPartId
|
const displayedPart = selectedPartId
|
||||||
@@ -37,8 +39,11 @@ export function CategoryColumn({
|
|||||||
<div className="w-full border border-zinc-700 rounded-md p-3 mb-2 flex items-center justify-between gap-3">
|
<div className="w-full border border-zinc-700 rounded-md p-3 mb-2 flex items-center justify-between gap-3">
|
||||||
<p className="text-sm text-zinc-500">No part selected</p>
|
<p className="text-sm text-zinc-500">No part selected</p>
|
||||||
<Link
|
<Link
|
||||||
href={`/builder/${category.id}`}
|
href={{
|
||||||
className="inline-flex items-center gap-2 rounded-md border border-zinc-700 bg-zinc-900/60 px-3 py-1.5 text-xs font-medium text-zinc-200 hover:bg-zinc-800 hover:border-zinc-500 transition-colors"
|
pathname: `/builder/${category.id}`,
|
||||||
|
query: platform ? { platform } : {},
|
||||||
|
}}
|
||||||
|
className="inline-flex w-full items-center justify-center rounded-md border border-zinc-700 bg-zinc-900 px-4 py-2 text-xs font-semibold text-zinc-100 hover:bg-zinc-800 hover:border-zinc-600 transition-colors"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
className="w-4 h-4"
|
className="w-4 h-4"
|
||||||
@@ -68,7 +73,10 @@ export function CategoryColumn({
|
|||||||
</div>
|
</div>
|
||||||
{parts.length >= 1 && (
|
{parts.length >= 1 && (
|
||||||
<Link
|
<Link
|
||||||
href={`/builder/${category.id}`}
|
href={{
|
||||||
|
pathname: `/builder/${category.id}`,
|
||||||
|
query: platform ? { platform } : {},
|
||||||
|
}}
|
||||||
className="mt-2 w-full rounded-md border border-zinc-700 bg-zinc-900/50 px-3 py-2 text-xs font-medium text-zinc-300 hover:bg-zinc-800 hover:border-zinc-600 transition-colors text-center"
|
className="mt-2 w-full rounded-md border border-zinc-700 bg-zinc-900/50 px-3 py-2 text-xs font-medium text-zinc-300 hover:bg-zinc-800 hover:border-zinc-600 transition-colors text-center"
|
||||||
>
|
>
|
||||||
View All ({parts.length})
|
View All ({parts.length})
|
||||||
|
|||||||
Reference in New Issue
Block a user