makearmy-app/app/api/options/lens/route.ts
2025-09-22 14:18:08 -04:00

98 lines
3 KiB
TypeScript

// 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: [] });
}
}