104 lines
3.3 KiB
TypeScript
104 lines
3.3 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_software?: { id: number; name?: string };
|
|
};
|
|
|
|
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_software?.name ? (
|
|
<>Software: {r.laser_software.name}. </>
|
|
) : null}
|
|
</div>
|
|
{r.notes ? <div className="text-sm mt-2">{r.notes}</div> : null}
|
|
</div>
|
|
))}
|
|
</div>
|
|
);
|
|
}
|