Initial commit

This commit is contained in:
makearmy 2025-09-22 10:37:53 -04:00
commit 78f8d225ee
21173 changed files with 2907774 additions and 0 deletions

View file

@ -0,0 +1,111 @@
// 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 }
);
}
}

View file

@ -0,0 +1,40 @@
// app/api/options/lens/route.ts
import { NextResponse } from "next/server";
import { directusFetch } from "@/lib/directus";
/** pick a decent label from whatever fields are readable */
function pickLabel(it: any) {
const mm = [it?.make, it?.model].filter(Boolean).join(" ").trim();
if (mm) return mm;
if (it?.name) return String(it.name);
const f = it?.focal_length ?? it?.f ?? it?.fl;
if (f != null) return `${mm ? mm + " " : ""}${f} mm`.trim();
return String(it?.label ?? it?.title ?? it?.id ?? "");
}
export async function GET(req: Request) {
const { searchParams } = new URL(req.url);
const target = searchParams.get("target") || ""; // required
const q = (searchParams.get("q") || "").toLowerCase();
const limit = Number(searchParams.get("limit") || "500");
// Fiber / CO2 Galvo / UV -> scan lens ; CO2 Gantry -> focus lens
const isGantry = target === "settings_co2gan";
const coll = isGantry ? "laser_focus_lens" : "laser_scan_lens";
// Avoid explicit fields -> prevents 403 on disallowed fields
const res = await directusFetch<{ data: any[] }>(`/items/${coll}?limit=${limit}`);
let items = res?.data ?? [];
let rows = items.map((it) => {
const label = pickLabel(it);
const search = Object.values(it ?? {}).join(" ").toLowerCase();
return { id: String(it?.id ?? ""), label, _search: search };
}).filter((r) => r.id);
if (q) rows = rows.filter((r) => r._search.includes(q));
rows.sort((a, b) => a.label.localeCompare(b.label));
return NextResponse.json({ data: rows.map(({ _search, ...r }) => r) });
}

View file

@ -0,0 +1,26 @@
import { NextRequest, NextResponse } from "next/server";
import { directusFetch } from "@/lib/directus";
export async function GET(req: NextRequest) {
const { searchParams } = new URL(req.url);
const target = searchParams.get("target") || "";
const group = searchParams.get("group") || "";
const field = searchParams.get("field") || "type";
if (!target || !group) return NextResponse.json({ error: "missing target/group" }, { status: 400 });
const meta = await directusFetch<any>(`/fields/${target}/${group}?fields=meta`);
const fields = meta?.data?.meta?.options?.fields ?? [];
const nested = fields.find((f: any) => (f?.field ?? f?.key) === field);
const choices = nested?.options?.choices ?? nested?.meta?.options?.choices ?? [];
const out = (choices as any[])
.map((c) => ({
id: String(c.value ?? c.text ?? c.label ?? ""),
label: String(c.text ?? c.label ?? c.value ?? ""),
}))
.filter((o) => o.id)
.sort((a, b) => a.label.localeCompare(b.label));
return NextResponse.json({ data: out });
}