59 lines
1.8 KiB
TypeScript
59 lines
1.8 KiB
TypeScript
// app/lasers/[id]/LaserDetailsClient.tsx
|
|
"use client";
|
|
|
|
import Link from "next/link";
|
|
|
|
type Group = { title: string; fields: Record<string, string> };
|
|
type Laser = Record<string, any>;
|
|
|
|
const CHOICE_LABELS: Record<string, Record<string, string>> = {
|
|
op: { pm: "MOPA", pq: "Q-Switch" },
|
|
cooling: { aa: "Air, Active", ap: "Air, Passive", w: "Water" },
|
|
};
|
|
|
|
function resolveLabel(field: string, value: any) {
|
|
if (value == null || value === "") return "—";
|
|
const map = CHOICE_LABELS[field];
|
|
if (map && typeof value === "string" && map[value]) return map[value];
|
|
if (typeof value === "boolean") return value ? "Yes" : "No";
|
|
if (typeof value === "number") return Number.isFinite(value) ? String(value) : "—";
|
|
return String(value);
|
|
}
|
|
|
|
export default function LaserDetailsClient({
|
|
laser,
|
|
fieldGroups,
|
|
}: {
|
|
laser: Laser;
|
|
fieldGroups: Group[];
|
|
}) {
|
|
return (
|
|
<div className="p-6 max-w-4xl mx-auto">
|
|
<h1 className="text-3xl font-bold mb-4">
|
|
{(laser.make as string) || "—"} {laser.model || ""}
|
|
</h1>
|
|
|
|
<div className="space-y-6">
|
|
{fieldGroups.map(({ title, fields }) => (
|
|
<section key={title} className="bg-card border border-border rounded-xl p-4">
|
|
<h2 className="text-xl font-semibold mb-2">{title}</h2>
|
|
<dl className="grid grid-cols-1 sm:grid-cols-2 gap-x-6 gap-y-4">
|
|
{Object.entries(fields).map(([key, label]) => (
|
|
<div key={key}>
|
|
<dt className="font-medium text-muted-foreground">{label}</dt>
|
|
<dd className="text-base break-words">{resolveLabel(key, laser[key])}</dd>
|
|
</div>
|
|
))}
|
|
</dl>
|
|
</section>
|
|
))}
|
|
</div>
|
|
|
|
<div className="mt-8">
|
|
<Link href="/lasers" className="text-blue-600 underline">
|
|
← Back to Laser Sources
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|