fixing platform switcher bugs
This commit is contained in:
@@ -1,52 +1,75 @@
|
||||
"use client";
|
||||
|
||||
import { useMemo } from "react";
|
||||
import { usePathname, useRouter, useSearchParams } from "next/navigation";
|
||||
import Link from "next/link";
|
||||
import { usePathname, useSearchParams } from "next/navigation";
|
||||
|
||||
const PLATFORMS = ["AR-15", "AR-10", "AR-9"] as const;
|
||||
|
||||
type Platform = (typeof PLATFORMS)[number];
|
||||
|
||||
export default function PlatformSwitcher(props: {
|
||||
currentPlatform: string;
|
||||
partRole: string;
|
||||
preserveQuery?: boolean; // keep sort/page/etc (but NOT platform)
|
||||
/**
|
||||
* If true, preserve *all* existing query params (except platform will be overwritten).
|
||||
* Useful when you want to keep things like ?from=builder or future filters.
|
||||
*/
|
||||
preserveQuery?: boolean;
|
||||
/**
|
||||
* Force route behavior.
|
||||
* - "browse": /parts/[role]?platform=...
|
||||
* - "detail": /parts/p/[platform]/[role]
|
||||
* Default: auto based on current pathname
|
||||
*/
|
||||
mode?: "browse" | "detail";
|
||||
}) {
|
||||
const { currentPlatform, partRole, preserveQuery = true } = props;
|
||||
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
const searchParams = useSearchParams();
|
||||
|
||||
const queryString = useMemo(() => {
|
||||
if (!preserveQuery) return "";
|
||||
const inferredMode: "browse" | "detail" = pathname.startsWith("/parts/p/")
|
||||
? "detail"
|
||||
: "browse";
|
||||
|
||||
// Copy params and DROP legacy platform param so it can’t conflict with the path
|
||||
const sp = new URLSearchParams(searchParams?.toString());
|
||||
sp.delete("platform");
|
||||
const mode = props.mode ?? inferredMode;
|
||||
|
||||
const q = sp.toString();
|
||||
return q ? `?${q}` : "";
|
||||
}, [searchParams, preserveQuery]);
|
||||
const buildHref = (nextPlatform: Platform) => {
|
||||
if (mode === "detail") {
|
||||
return `/parts/p/${encodeURIComponent(nextPlatform)}/${encodeURIComponent(
|
||||
props.partRole
|
||||
)}`;
|
||||
}
|
||||
|
||||
function go(platform: string) {
|
||||
router.replace(
|
||||
`/parts/p/${encodeURIComponent(platform)}/${encodeURIComponent(partRole)}${queryString}`
|
||||
);
|
||||
}
|
||||
// browse mode => keep on /parts/[role] and just change the query param
|
||||
const qp = props.preserveQuery
|
||||
? new URLSearchParams(searchParams.toString())
|
||||
: new URLSearchParams();
|
||||
|
||||
qp.set("platform", nextPlatform);
|
||||
|
||||
return {
|
||||
pathname: `/parts/${encodeURIComponent(props.partRole)}`,
|
||||
query: Object.fromEntries(qp.entries()),
|
||||
} as const;
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-xs uppercase tracking-[0.14em] text-zinc-500">Platform</span>
|
||||
<select
|
||||
value={currentPlatform}
|
||||
onChange={(e) => go(e.target.value)}
|
||||
className="rounded-md border border-zinc-700 bg-zinc-950/80 px-2 py-1 text-xs text-zinc-100 outline-none focus:border-amber-400"
|
||||
>
|
||||
<option value="AR-15">AR-15</option>
|
||||
<option value="AR-10">AR-10</option>
|
||||
<option value="AR-9">AR-9</option>
|
||||
<option value="AK-47">AK-47</option>
|
||||
</select>
|
||||
|
||||
{/* debug only */}
|
||||
<span className="ml-2 text-[0.7rem] text-zinc-500">{pathname}</span>
|
||||
<div className="inline-flex items-center gap-1 rounded-md border border-zinc-800 bg-zinc-950/60 p-1">
|
||||
{PLATFORMS.map((p) => {
|
||||
const active = p === props.currentPlatform;
|
||||
return (
|
||||
<Link
|
||||
key={p}
|
||||
href={buildHref(p)}
|
||||
className={`px-3 py-1.5 text-xs font-medium rounded transition-colors ${
|
||||
active
|
||||
? "bg-zinc-800 text-zinc-50"
|
||||
: "text-zinc-400 hover:text-zinc-200 hover:bg-zinc-900/60"
|
||||
}`}
|
||||
>
|
||||
{p}
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user