added user rigs and updated collection route

This commit is contained in:
makearmy 2025-09-25 23:06:50 -04:00
parent 0ba2f9622e
commit faa7372887
2 changed files with 465 additions and 31 deletions

View file

@ -1,45 +1,61 @@
// app/app/api/options/[collection]/route.ts
import { NextResponse } from "next/server";
// app/api/options/[collection]/route.ts
import { NextRequest, NextResponse } from "next/server";
import { directusFetch } from "@/lib/directus";
type MapEntry = { path: string; fields: string; label: (x: any) => string };
// Expandable label-field preferences per collection.
// Well try each key in order until we find a value.
const MAP: Record<
string,
{ coll: string; labelFields: string[] }
> = {
material: { coll: "material", labelFields: ["name", "label", "title"] },
material_coating: { coll: "material_coating", labelFields: ["name", "label", "title"] },
material_color: { coll: "material_color", labelFields: ["name", "label", "title"] },
material_opacity: { coll: "material_opacity", labelFields: ["name", "label", "title", "value"] },
laser_software: { coll: "laser_software", labelFields: ["name", "label", "title"] },
const MAP: Record<string, MapEntry> = {
material: { path: "/items/material", fields: "id,name", label: (x) => String(x.name ?? x.id) },
material_coating: { path: "/items/material_coating", fields: "id,name", label: (x) => String(x.name ?? x.id) },
material_color: { path: "/items/material_color", fields: "id,name", label: (x) => String(x.name ?? 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) => String(x.name ?? x.id) },
// laser_source and lens have dedicated routes
// NEW: Galvo scan head aperture list
laser_scan_lens_apt: { coll: "laser_scan_lens_apt", labelFields: ["name", "label", "title", "aperture_mm", "size_mm", "value"] },
// NEW: Beam expander multiplier list
laser_scan_lens_exp: { coll: "laser_scan_lens_exp", labelFields: ["name", "label", "title", "multiplier", "value"] },
};
export async function GET(req: Request, ctx: any) {
function pickLabel(it: any, candidates: string[]) {
for (const k of candidates) if (it?.[k] != null && it[k] !== "") return String(it[k]);
// fallback: try some common numeric-ish fields if present
if (it?.value != null) return String(it.value);
return String(it?.name ?? it?.label ?? it?.title ?? it?.id ?? "");
}
export async function GET(req: NextRequest, ctx: any) {
try {
const { searchParams } = new URL(req.url);
const key = ctx?.params?.collection as string;
const q = (searchParams.get("q") || "").trim().toLowerCase();
const limit = Number(searchParams.get("limit") || "500");
const key = String(ctx?.params?.collection || "");
const cfg = MAP[key];
if (!cfg) {
return NextResponse.json({ error: "unsupported collection" }, { status: 400 });
}
if (!cfg) return NextResponse.json({ data: [] });
const url = `${cfg.path}?fields=${encodeURIComponent(cfg.fields)}&limit=${limit}`;
const { data } = await directusFetch<{ data: any[] }>(url);
const list = Array.isArray(data) ? data : [];
const { searchParams } = new URL(req.url);
const q = (searchParams.get("q") || "").toLowerCase();
const mapped = list.map((x) => ({
id: String(x.id),
label: cfg.label(x),
_s: Object.values(x).join(" ").toLowerCase(),
}));
// Keep fields=* so we can build a friendly label from whatever exists
const url = `/items/${cfg.coll}?fields=*&limit=500`;
const res = await directusFetch<{ data: any[] }>(url);
const items = res?.data ?? [];
const filtered = q ? mapped.filter((m) => m._s.includes(q)) : mapped;
const mapped = items.map((it) => ({
id: String(it.id ?? it.submission_id ?? ""),
label: pickLabel(it, cfg.labelFields),
_search: `${Object.values(it).join(" ")}`.toLowerCase(),
})).filter((m) => !!m.id);
const filtered = q ? mapped.filter((m) => m._search.includes(q)) : mapped;
filtered.sort((a, b) => a.label.localeCompare(b.label));
return NextResponse.json({ data: filtered.map(({ id, label }) => ({ id, label })) });
} catch (e: any) {
return NextResponse.json({ error: e?.message || "Failed to load options" }, { status: 500 });
return NextResponse.json({ data: filtered.map(({ _search, ...r }) => r) });
} catch (err: any) {
return NextResponse.json(
{ error: err?.message || "options error" },
{ status: 500 }
);
}
}