From d0106c0f18c903d1f046d31ab943b583ab4514bb Mon Sep 17 00:00:00 2001 From: makearmy Date: Mon, 29 Sep 2025 18:51:35 -0400 Subject: [PATCH] added server component to rig builder --- app/rigs/RigBuilderClient.tsx | 136 +++++++++++++++++++++++++++------- app/rigs/RigBuilderServer.tsx | 32 ++++++++ app/rigs/RigsListClient.tsx | 59 ++++++++++++--- app/rigs/page.tsx | 28 ++++++- makearmy-app1806.zip | Bin 0 -> 213909 bytes 5 files changed, 215 insertions(+), 40 deletions(-) create mode 100644 app/rigs/RigBuilderServer.tsx create mode 100644 makearmy-app1806.zip diff --git a/app/rigs/RigBuilderClient.tsx b/app/rigs/RigBuilderClient.tsx index b9f0a7e2..28a04ae7 100644 --- a/app/rigs/RigBuilderClient.tsx +++ b/app/rigs/RigBuilderClient.tsx @@ -7,7 +7,14 @@ type Opt = { id: string | number; label: string }; const API = (process.env.NEXT_PUBLIC_API_BASE_URL || "").replace(/\/$/, ""); -function useOptions(kind: "user_rig_type" | "laser_software" | "laser_source" | "lens", targetKey?: string) { +/** + * Note: we are ONLY using this hook for kinds OTHER THAN "user_rig_type". + * Rig types now arrive from the server via props. + */ +function useOptions( + kind: "laser_software" | "laser_source" | "lens", + targetKey?: string +) { const [opts, setOpts] = useState([]); const [loading, setLoading] = useState(false); @@ -17,10 +24,15 @@ function useOptions(kind: "user_rig_type" | "laser_software" | "laser_source" | (async () => { let url = ""; - let normalize = (rows: any[]): Opt[] => rows.map(r => ({ id: String(r.id ?? r.submission_id), label: String(r.name ?? r.label ?? r.title ?? r.model ?? r.id) })); - if (kind === "user_rig_type") { - url = `${API}/items/user_rig_type?fields=id,name&sort=sort`; - } else if (kind === "laser_software") { + let normalize = (rows: any[]): Opt[] => + rows.map((r) => ({ + id: String(r.id ?? r.submission_id), + label: String( + r.name ?? r.label ?? r.title ?? r.model ?? r.id + ), + })); + + if (kind === "laser_software") { url = `${API}/items/laser_software?fields=id,name&limit=1000&sort=name`; } else if (kind === "laser_source") { // fetch all sources; client filter by nm band from targetKey @@ -35,8 +47,10 @@ function useOptions(kind: "user_rig_type" | "laser_software" | "laser_source" | const s = t.toLowerCase(); if (s.includes("fiber")) return [1000, 9000]; if (s.includes("uv")) return [300, 400]; - if (s.includes("gantry") || s.includes("co2 gantry") || s.includes("co₂ gantry")) return [10000, 11000]; - if (s.includes("galvo") || s.includes("co2 galvo") || s.includes("co₂ galvo")) return [10000, 11000]; + if (s.includes("gantry") || s.includes("co2 gantry") || s.includes("co₂ gantry")) + return [10000, 11000]; + if (s.includes("galvo") || s.includes("co2 galvo") || s.includes("co₂ galvo")) + return [10000, 11000]; return null; }; const range = nmRange(targetKey); @@ -49,7 +63,9 @@ function useOptions(kind: "user_rig_type" | "laser_software" | "laser_source" | : rows; return filtered.map((r: any) => ({ id: String(r.submission_id), - label: [r.make, r.model].filter(Boolean).join(" ") || String(r.submission_id), + label: + [r.make, r.model].filter(Boolean).join(" ") || + String(r.submission_id), })); }; } else if (kind === "lens") { @@ -63,16 +79,27 @@ function useOptions(kind: "user_rig_type" | "laser_software" | "laser_source" | return m ? parseFloat(m[0]) : Number.POSITIVE_INFINITY; }; return [...rows] - .sort((a, b) => toNum(a.focal_length) - toNum(b.focal_length)) + .sort( + (a, b) => toNum(a.focal_length) - toNum(b.focal_length) + ) .map((r) => ({ id: String(r.id), - label: [r.field_size && `${r.field_size} mm`, r.focal_length && `${r.focal_length} mm`].filter(Boolean).join(" — ") || String(r.id), + label: + [ + r.field_size && `${r.field_size} mm`, + r.focal_length && `${r.focal_length} mm`, + ] + .filter(Boolean) + .join(" — ") || String(r.id), })); }; } } - const res = await fetch(url, { credentials: "include", cache: "no-store" }); + const res = await fetch(url, { + credentials: "include", + cache: "no-store", + }); const json = await res.json(); const rows = json?.data ?? []; const mapped = normalize(rows); @@ -89,7 +116,7 @@ function useOptions(kind: "user_rig_type" | "laser_software" | "laser_source" | return { opts, loading }; } -export default function RigBuilderClient() { +export default function RigBuilderClient({ rigTypes }: { rigTypes: Opt[] }) { const router = useRouter(); const [name, setName] = useState(""); const [notes, setNotes] = useState(""); @@ -99,11 +126,12 @@ export default function RigBuilderClient() { const [focusLens, setFocusLens] = useState(""); const [software, setSoftware] = useState(""); - const rigTypes = useOptions("user_rig_type"); + // rigTypes now come from the SERVER, authenticated, as props. const targetKey = useMemo(() => { - const rt = rigTypes.opts.find(o => String(o.id) === String(rigType))?.label || ""; + const rt = + rigTypes.find((o) => String(o.id) === String(rigType))?.label || ""; return rt; - }, [rigTypes.opts, rigType]); + }, [rigTypes, rigType]); const sources = useOptions("laser_source", targetKey); const lens = useOptions("lens", targetKey); @@ -150,7 +178,12 @@ export default function RigBuilderClient() { - setName(e.target.value)} required /> + setName(e.target.value)} + required + />
@@ -158,9 +191,18 @@ export default function RigBuilderClient() { - setRigType(e.target.value)} + required + > + + {rigTypes.map((o) => ( + + ))}
@@ -168,9 +210,18 @@ export default function RigBuilderClient() { - setLaserSource(e.target.value)} + required + > - {sources.opts.map(o => )} + {sources.opts.map((o) => ( + + ))} @@ -179,32 +230,61 @@ export default function RigBuilderClient() { {isGantry ? (
- setFocusLens(e.target.value)} + > - {lens.opts.map(o => )} + {lens.opts.map((o) => ( + + ))}
) : (
- setScanLens(e.target.value)} + > - {lens.opts.map(o => )} + {lens.opts.map((o) => ( + + ))}
)}
- setSoftware(e.target.value)} + > - {softwares.opts.map(o => )} + {softwares.opts.map((o) => ( + + ))}
-