// app/api/options/lens/route.ts import { NextResponse } from "next/server"; import { directusFetch } from "@/lib/directus"; /** * Lenses endpoint * - Fiber/UV/CO2 Galvo -> laser_scan_lens (has field_size, focal_length) * - CO2 Gantry -> laser_focus_lens (usually focal_length only) * Returns [{ id, label }] using submission_id || id. */ function collectionForTarget( target?: string ): "laser_scan_lens" | "laser_focus_lens" | null { switch (target) { case "settings_fiber": case "settings_uv": case "settings_co2gal": return "laser_scan_lens"; case "settings_co2gan": return "laser_focus_lens"; default: return null; } } export async function GET(req: Request) { try { const { searchParams } = new URL(req.url); const target = searchParams.get("target") || undefined; const q = (searchParams.get("q") || "").toLowerCase().trim(); const limit = Number(searchParams.get("limit") || "500"); const coll = collectionForTarget(target); if (!coll) return NextResponse.json({ data: [] }); // Ask only for fields that exist on each collection const fields = coll === "laser_scan_lens" ? "submission_id,id,name,field_size,focal_length" : "submission_id,id,name,focal_length"; const url = `/items/${coll}?fields=${encodeURIComponent( fields )}&limit=${limit}`; const res = await directusFetch<{ data: any[] }>(url); const list = Array.isArray(res?.data) ? res.data : []; const mapped = list.map((x) => { const id = String(x?.submission_id ?? x?.id); const fieldSizeRaw = x?.field_size; const fieldSize = fieldSizeRaw !== null && fieldSizeRaw !== undefined ? String(fieldSizeRaw).trim() : ""; const fnum = Number(x?.focal_length); const focalTxt = Number.isFinite(fnum) ? `F${fnum} mm` : ""; // Label: field_size THEN focal_length (requested order). // Fall back to name, then id. let label = [fieldSize, focalTxt].filter(Boolean).join(" — "); if (!label) label = (x?.name ? String(x.name) : "").trim(); if (!label) label = id; // Sort by focal length if available; else by label const sortKey: number | string = Number.isFinite(fnum) ? fnum : label.toLowerCase(); return { id, label, sortKey, _search: `${id} ${label} ${fieldSize} ${x?.name ?? ""} ${ x?.focal_length ?? "" }`.toLowerCase(), }; }); const filtered = q ? mapped.filter((m) => m._search.includes(q)) : mapped; filtered.sort((a, b) => { if (typeof a.sortKey === "number" && typeof b.sortKey === "number") return a.sortKey - b.sortKey; return String(a.sortKey).localeCompare(String(b.sortKey)); }); return NextResponse.json({ data: filtered.map(({ id, label }) => ({ id, label })), }); } catch (e: any) { console.error("[options/lens] error:", e?.message || e); // Fail soft to keep UI responsive return NextResponse.json({ data: [] }); } }