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

95 lines
2.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// app/api/options/lens/route.ts
import { NextResponse } from "next/server";
import { directusFetch } from "@/lib/directus";
/**
* Lens options:
* - Fiber / UV / CO2 Galvo -> laser_scan_lens (field_size, focal_length)
* - CO2 Gantry -> laser_focus_lens (focal_length)
* Returns [{ id, label }] using submission_id if present, otherwise 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: [] });
// Important: don't request fields that don't exist.
const fields =
coll === "laser_scan_lens"
? "submission_id,id,field_size,focal_length"
: "submission_id,id,focal_length";
const url = `/items/${coll}?fields=${encodeURIComponent(
fields
)}&limit=${limit}`;
const { data } = await directusFetch<{ data: any[] }>(url);
const list = Array.isArray(data) ? data : [];
const items = list.map((x) => {
const id = String(x?.submission_id ?? x?.id);
const fieldSize =
x?.field_size !== null && x?.field_size !== undefined
? String(x.field_size).trim()
: "";
const fnum = Number(x?.focal_length);
const focalTxt = Number.isFinite(fnum) ? `F${fnum} mm` : "";
// Label: field_size first, then focal length (requested order).
let label = [fieldSize, focalTxt].filter(Boolean).join(" — ");
if (!label) label = id;
// Sort numerically by focal length when available, else alpha by label.
const sortKey: number | string = Number.isFinite(fnum)
? fnum
: label.toLowerCase();
return {
id,
label,
sortKey,
_search: `${id} ${label} ${fieldSize} ${x?.focal_length ?? ""}`.toLowerCase(),
};
});
const filtered = q ? items.filter((m) => m._search.includes(q)) : items;
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 so the UI doesnt hang
return NextResponse.json({ data: [] });
}
}