111 lines
4.1 KiB
TypeScript
111 lines
4.1 KiB
TypeScript
// app/api/options/[collection]/route.ts
|
|
import { NextRequest, NextResponse } from "next/server";
|
|
import { directusFetch } from "@/lib/directus";
|
|
|
|
const NM_FIELD = "nm"; // wavelength field in laser_source
|
|
|
|
// Parse wavelength that might be stored as "1064", "1064nm", "1,064", etc.
|
|
function parseNm(v: any): number | null {
|
|
const s = String(v ?? "").replace(/[^0-9.]/g, "");
|
|
if (!s) return null;
|
|
const n = Number(s);
|
|
return Number.isFinite(n) ? n : null;
|
|
}
|
|
|
|
// Target → wavelength range (nm)
|
|
function nmRangeForTarget(t?: string): [number, number] | null {
|
|
switch (t) {
|
|
case "settings_fiber": return [1000, 1100];
|
|
case "settings_uv": return [300, 400];
|
|
case "settings_co2gan":
|
|
case "settings_co2gal": return [10000, 11000];
|
|
default: return null;
|
|
}
|
|
}
|
|
|
|
// Generic lookups (request only fields we know exist)
|
|
const GENERIC: Record<
|
|
string,
|
|
{ path: string; fields: string[]; label: (x: any) => string }
|
|
> = {
|
|
material: { path: "/items/material", fields: ["id", "name"], label: (x) => x.name ?? String(x.id) },
|
|
material_coating: { path: "/items/material_coating", fields: ["id", "name"], label: (x) => x.name ?? String(x.id) },
|
|
material_color: { path: "/items/material_color", fields: ["id", "name"], label: (x) => x.name ?? String(x.id) },
|
|
material_opacity: { path: "/items/material_opacity", fields: ["id", "opacity"], label: (x) => String(x.opacity ?? x.id) },
|
|
laser_software: { path: "/items/laser_software", fields: ["id", "name"], label: (x) => x.name ?? String(x.id) },
|
|
};
|
|
|
|
async function fetchDirectus<T>(pathname: string, params: URLSearchParams) {
|
|
return directusFetch<T>(`${pathname}?${params.toString()}`);
|
|
}
|
|
|
|
export async function GET(req: NextRequest) {
|
|
try {
|
|
const url = new URL(req.url);
|
|
const collection = url.pathname.split("/").pop() || "";
|
|
const q = url.searchParams.get("q")?.trim() || "";
|
|
const limit = Number(url.searchParams.get("limit") || "400");
|
|
const target = url.searchParams.get("target") || undefined;
|
|
|
|
// ----- generic tables -----
|
|
const gen = GENERIC[collection];
|
|
if (gen) {
|
|
const params = new URLSearchParams();
|
|
params.set("fields", gen.fields.join(","));
|
|
params.set("limit", String(limit));
|
|
if (q) params.set("search", q);
|
|
|
|
const { data } = await fetchDirectus<{ data: any[] }>(gen.path, params);
|
|
const out = (data ?? [])
|
|
.map((x) => ({ id: String(x.id), label: gen.label(x) }))
|
|
.sort((a, b) => a.label.localeCompare(b.label));
|
|
return NextResponse.json({ data: out });
|
|
}
|
|
|
|
// ----- laser_source (uses submission_id as the key) -----
|
|
if (collection === "laser_source") {
|
|
const range = nmRangeForTarget(target);
|
|
if (!range) {
|
|
return NextResponse.json(
|
|
{ error: "missing/invalid target for laser_source" },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
const params = new URLSearchParams();
|
|
// IMPORTANT: request submission_id instead of id
|
|
params.set("fields", ["submission_id", "make", "model", NM_FIELD].join(","));
|
|
params.set("limit", String(limit));
|
|
if (q) params.set("search", q);
|
|
|
|
const { data } = await fetchDirectus<{ data: any[] }>("/items/laser_source", params);
|
|
const rows = data ?? [];
|
|
|
|
const [lo, hi] = range;
|
|
const filtered = rows.filter((x) => {
|
|
const nm = parseNm(x[NM_FIELD]);
|
|
return nm !== null && nm >= lo && nm <= hi;
|
|
});
|
|
|
|
const out = filtered
|
|
.map((x) => ({
|
|
id: String(x.submission_id), // <- use submission_id
|
|
label: [x.make, x.model].filter(Boolean).join(" ").trim() || String(x.submission_id),
|
|
sortKey: [(x.make ?? "").toLowerCase(), (x.model ?? "").toLowerCase()].join(" "),
|
|
}))
|
|
.filter((o) => o.id)
|
|
.sort((a, b) => a.sortKey.localeCompare(b.sortKey))
|
|
.map(({ id, label }) => ({ id, label }));
|
|
|
|
return NextResponse.json({ data: out });
|
|
}
|
|
|
|
return NextResponse.json({ error: "unsupported collection" }, { status: 400 });
|
|
} catch (err: any) {
|
|
return NextResponse.json(
|
|
{ error: err?.message || "Unknown error" },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|
|
|