makearmy-app/components/portal/SettingsSwitcher.tsx
2025-10-02 22:15:06 -04:00

128 lines
4.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// components/portal/SettingsSwitcher.tsx
"use client";
import { useRouter, useSearchParams } from "next/navigation";
import dynamic from "next/dynamic";
import { cn } from "@/lib/utils";
// Existing canonical pages
const FiberPanel = dynamic(() => import("@/app/settings/fiber/page"), { ssr: false });
const UVPanel = dynamic(() => import("@/app/settings/uv/page"), { ssr: false });
const CO2GalvoPanel = dynamic(() => import("@/app/settings/co2-galvo/page"), { ssr: false });
const CO2GantryPanel = dynamic(() => import("@/app/settings/co2-gantry/page"), { ssr: false });
// NEW: embed the submission form in the "Add" tab
const SettingsSubmit = dynamic(
() => import("@/components/forms/SettingsSubmit"),
{ ssr: false }
);
type DataTab = "fiber" | "uv" | "co2-gantry" | "co2-galvo";
type Tab = DataTab | "add" | "my";
const TABS: { key: Tab; label: string }[] = [
{ key: "fiber", label: "Fiber" },
{ key: "uv", label: "UV" },
{ key: "co2-gantry", label: "CO₂ Gantry" },
{ key: "co2-galvo", label: "CO₂ Galvo" },
{ key: "my", label: "My Settings" }, // ← NEW
{ key: "add", label: "Add Setting" },
];
const isDataTab = (k: string): k is DataTab =>
k === "fiber" || k === "uv" || k === "co2-ganry" || k === "co2-gantry" || k === "co2-galvo"
// keep typo guard for "co2-ganry" if you want; remove if unnecessary
? true
: (k === "fiber" || k === "uv" || k === "co2-gantry" || k === "co2-galvo");
const tabToTarget: Record<DataTab,
"settings_fiber" | "settings_uv" | "settings_co2gan" | "settings_co2gal"
> = {
fiber: "settings_fiber",
uv: "settings_uv",
"co2-gantry": "settings_co2gan",
"co2-galvo": "settings_co2gal",
};
function Panel({ tab, lastDataTab }: { tab: Tab; lastDataTab: DataTab }) {
switch (tab) {
case "fiber": return <FiberPanel />;
case "uv": return <UVPanel />;
case "co2-galvo": return <CO2GalvoPanel />;
case "co2-gantry": return <CO2GantryPanel />;
case "add":
return (
<div className="rounded-md border p-4 space-y-3">
<h3 className="font-semibold">Add Setting</h3>
<SettingsSubmit initialTarget={tabToTarget[lastDataTab]} />
</div>
);
case "my":
// We navigate away for "My Settings", so this branch is not normally rendered.
// Fallback content (just in case someone forces ?t=my on this page):
return (
<div className="rounded-md border p-4">
<p className="text-sm">
Opening <span className="font-medium">My Settings</span>
</p>
</div>
);
default:
return <FiberPanel />;
}
}
export default function SettingsSwitcher() {
const router = useRouter();
const sp = useSearchParams();
const activeRaw = (sp.get("t") || "fiber").toLowerCase();
const active: Tab = (TABS.some(t => t.key === activeRaw) ? activeRaw : "fiber") as Tab;
// last data tab is taken from ?last=… (or fallback to current active if its a data tab)
const lastParam = (sp.get("last") || (isDataTab(active) ? active : "fiber")).toLowerCase();
const lastDataTab: DataTab = isDataTab(lastParam) ? (lastParam as DataTab) : "fiber";
function setTab(nextKey: Tab) {
// NEW: "My Settings" navigates to its own page
if (nextKey === "my") {
router.push("/portal/my-settings");
return;
}
const q = new URLSearchParams(sp.toString());
q.set("t", nextKey);
// keep track of last data tab so the Add tab knows which target to preselect
if (nextKey === "add") {
q.set("last", isDataTab(active) ? (active as DataTab) : lastDataTab);
} else if (isDataTab(nextKey)) {
q.set("last", nextKey);
}
router.replace(`/portal/laser-settings?${q.toString()}`, { scroll: false });
}
return (
<div>
<div className="mb-4 flex flex-wrap items-center gap-2">
{TABS.map(({ key, label }) => (
<button
key={key}
onClick={() => setTab(key)}
className={cn(
"rounded-md border px-3 py-1.5 text-sm transition",
active === key ? "bg-primary text-primary-foreground" : "hover:bg-muted"
)}
>
{label}
</button>
))}
</div>
<div className="rounded-md border p-4">
<Panel tab={active} lastDataTab={lastDataTab} />
</div>
</div>
);
}