makearmy-app/app/rigs/RigsListClient.tsx

89 lines
3.4 KiB
TypeScript

"use client";
import { useEffect, useState } from "react";
type Rig = {
id: string | number;
name: string;
notes?: string;
rig_type?: { id: number; name: string };
laser_source?: { submission_id: number; make?: string; model?: string };
laser_scan_lens?: { id: number; field_size?: string; focal_length?: string };
laser_focus_lens?: { id: number; name?: string };
laser_scan_lens_apt?: { id: number; name?: string };
laser_scan_lens_exp?: { id: number; name?: string };
laser_software?: { id: number; name?: string };
};
function fmtX(v?: string) {
if (!v) return "";
const s = String(v).trim();
if (/x$/i.test(s)) return s;
if (/^\d+(\.\d+)?$/.test(s)) {
if (/^\d$/.test(s)) return `0${s}x`;
return `${s}x`;
}
const m = s.match(/(\d+(?:\.\d+)?)/);
if (m) {
const n = m[1];
if (/^\d$/.test(n)) return `0${n}x`;
return `${n}x`;
}
return `${s}x`;
}
export default function RigsListClient() {
const [rows, setRows] = useState<Rig[]>([]);
const [loading, setLoading] = useState(false);
async function load() {
setLoading(true);
try {
const res = await fetch("/api/rigs", { credentials: "include", cache: "no-store" });
const data = await res.json();
setRows(Array.isArray(data) ? data : data?.data ?? []);
} finally {
setLoading(false);
}
}
useEffect(() => { load(); }, []);
async function remove(id: string | number) {
if (!confirm("Delete this rig?")) return;
const res = await fetch(`/api/rigs?id=${encodeURIComponent(String(id))}`, {
method: "DELETE",
credentials: "include",
});
if (res.ok) load();
else alert("Failed to delete");
}
if (loading) return <div className="text-sm opacity-70">Loading</div>;
if (!rows.length) return <div className="text-sm opacity-70">No rigs yet.</div>;
return (
<div className="space-y-3">
{rows.map((r) => (
<div key={r.id} className="rounded border p-3">
<div className="flex items-center justify-between gap-3">
<div className="font-medium">{r.name}</div>
<button onClick={() => remove(r.id)} className="text-sm px-2 py-1 border rounded hover:bg-muted">
Delete
</button>
</div>
<div className="text-sm text-muted-foreground mt-1">
{r.rig_type?.name ? <>Type: {r.rig_type.name}. </> : null}
{r.laser_source ? <>Source: {[r.laser_source.make, r.laser_source.model].filter(Boolean).join(" ") || r.laser_source.submission_id}. </> : null}
{r.laser_focus_lens?.name ? <>Focus Lens: {r.laser_focus_lens.name}. </> : null}
{r.laser_scan_lens ? <>Scan Lens: {[r.laser_scan_lens.field_size && `${r.laser_scan_lens.field_size}mm`, r.laser_scan_lens.focal_length && `${r.laser_scan_lens.focal_length}mm`].filter(Boolean).join(" / ")}. </> : null}
{r.laser_scan_lens_apt?.name ? <>Scan Lens Apt: {r.laser_scan_lens_apt.name}. </> : null}
{r.laser_scan_lens_exp?.name ? <>Scan Lens Exp: {fmtX(r.laser_scan_lens_exp.name)}. </> : null}
{r.laser_software?.name ? <>Software: {r.laser_software.name}. </> : null}
</div>
{r.notes ? <div className="text-sm mt-2">{r.notes}</div> : null}
</div>
))}
</div>
);
}