// app/my/rigs/RigBuilderClient.tsx "use client"; import { useEffect, useMemo, useState } from "react"; import { z } from "zod"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { useToast } from "@/hooks/use-toast"; import { Input } from "@/components/ui/input"; import { Button } from "@/components/ui/button"; import { Select, SelectTrigger, SelectContent, SelectItem, SelectValue, } from "@/components/ui/select"; import { Textarea } from "@/components/ui/textarea"; import { Badge } from "@/components/ui/badge"; type RigType = { id: number | string; name: string }; export default function RigBuilderClient({ rigTypes }: { rigTypes: RigType[] }) { const { toast } = useToast(); const FormSchema = z.object({ name: z.string().min(2, "Please enter a name"), rig_type: z.string().min(1, "Choose a rig type"), laser_source: z.string().optional().nullable(), laser_focus_lens: z.string().optional().nullable(), laser_scan_lens: z.string().optional().nullable(), laser_scan_lens_apt: z.string().optional().nullable(), laser_scan_lens_exp: z.string().optional().nullable(), laser_software: z.string().optional().nullable(), notes: z.string().optional().nullable(), }); type FormValues = z.infer; const form = useForm({ resolver: zodResolver(FormSchema), defaultValues: { name: "", rig_type: "", notes: "", }, }); const selectedTypeName = useMemo(() => { const v = form.watch("rig_type"); return rigTypes.find((r) => String(r.id) === String(v))?.name ?? ""; }, [form, rigTypes]); // Option lists (pulled from your existing endpoints) const [laserSources, setLaserSources] = useState<{ id: string; label: string }[]>([]); const [scanLenses, setScanLenses] = useState<{ id: string; label: string }[]>([]); const [focusLenses, setFocusLenses] = useState<{ id: string; label: string }[]>([]); const [softwares, setSoftwares] = useState<{ id: string; label: string }[]>([]); useEffect(() => { (async () => { try { const ls = await fetch("/api/options/laser_source").then((r) => r.json()); setLaserSources(ls?.data ?? []); } catch {} try { const sl = await fetch("/api/options/lens?target=settings_fiber").then((r) => r.json()); setScanLenses(sl?.data ?? []); } catch {} try { const fl = await fetch("/api/options/repeater-choices?key=laser_focus_lens").then((r) => r.json() ); setFocusLenses(fl?.data ?? []); } catch {} try { const sw = await fetch("/api/options/repeater-choices?key=laser_software").then((r) => r.json() ); setSoftwares(sw?.data ?? []); } catch {} })(); }, []); const coerceId = (v: unknown) => { if (typeof v === "number") return v; if (typeof v === "string" && v !== "") { const n = Number(v); return Number.isFinite(n) ? n : v; } return v ?? null; }; async function onSubmit(values: FormValues) { try { const payload = { name: values.name, rig_type: coerceId(values.rig_type), // IMPORTANT: send ID laser_source: values.laser_source ? coerceId(values.laser_source) : null, laser_focus_lens: selectedTypeName === "co2_gantry" && values.laser_focus_lens ? coerceId(values.laser_focus_lens) : null, laser_scan_lens: selectedTypeName !== "co2_gantry" && values.laser_scan_lens ? coerceId(values.laser_scan_lens) : null, laser_scan_lens_apt: selectedTypeName !== "co2_gantry" && values.laser_scan_lens_apt ? values.laser_scan_lens_apt : null, laser_scan_lens_exp: selectedTypeName !== "co2_gantry" && values.laser_scan_lens_exp ? values.laser_scan_lens_exp : null, laser_software: values.laser_software ? coerceId(values.laser_software) : null, notes: values.notes ?? null, }; const res = await fetch("/api/my/rigs", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(payload), }); const json = await res.json().catch(() => ({})); if (!res.ok) { throw new Error(json?.error || json?.errors?.[0]?.message || res.statusText); } toast({ title: "Saved!", description: `Rig created (id: ${json?.data?.id ?? "?"}).` }); form.reset({ name: "", rig_type: "", notes: "" }); document.dispatchEvent(new CustomEvent("rigs:refresh")); } catch (err: any) { toast({ title: "Failed to save rig", description: String(err?.message || err), variant: "destructive", }); } } return ( <>

New Rig

{selectedTypeName ? {selectedTypeName} : null}
{/* Name */}
{form.formState.errors.name ? (

{form.formState.errors.name.message}

) : null}
{/* Rig Type (ID values) */}
{form.formState.errors.rig_type ? (

{form.formState.errors.rig_type.message}

) : null}
{/* Source */}
{/* Software */}
{/* Focus lens – only for co2_gantry */} {selectedTypeName === "co2_gantry" && (
)} {/* Scan lens fields – for fiber/uv/co2_galvo */} {selectedTypeName && selectedTypeName !== "co2_gantry" && ( <>
)}