lens formatting improvements

This commit is contained in:
makearmy 2025-09-22 15:09:05 -04:00
parent 7b27005f67
commit fba31918c6

View file

@ -2,22 +2,42 @@
import { NextResponse } from "next/server"; import { NextResponse } from "next/server";
import { directusFetch } from "@/lib/directus"; import { directusFetch } from "@/lib/directus";
/** Map target to the correct lens collection */ type Target =
function collectionForTarget( | "settings_fiber"
target?: string | "settings_uv"
): "laser_scan_lens" | "laser_focus_lens" | null { | "settings_co2gal"
switch (target) { | "settings_co2gan";
/** Map target -> Directus collection */
function collectionForTarget(t?: string) {
switch ((t ?? "") as Target) {
case "settings_fiber": case "settings_fiber":
case "settings_uv": case "settings_uv":
case "settings_co2gal": case "settings_co2gal":
return "laser_scan_lens"; return "laser_scan_lens" as const; // has field_size + focal_length
case "settings_co2gan": case "settings_co2gan":
return "laser_focus_lens"; return "laser_focus_lens" as const; // has name (no focal_length)
default: default:
return null; return null;
} }
} }
/** Parse "110x110", "110×110", "110 x 110", or single "110" => {w,h} */
function parseFieldSize(raw: unknown): { w: number; h: number } | null {
if (raw == null) return null;
const s = String(raw).trim();
const m = s.match(/(\d+(?:\.\d+)?)(?:\s*[x×]\s*(\d+(?:\.\d+)?))?/i);
if (!m) return null;
const w = Number(m[1]);
const h = m[2] ? Number(m[2]) : w;
if (!Number.isFinite(w) || !Number.isFinite(h)) return null;
return { w, h };
}
const fmtNum = (n: number) =>
Number.isInteger(n) ? String(n) : String(n).replace(/\.0+$/, "");
const dimsText = (d: { w: number; h: number }) => `${fmtNum(d.w)}x${fmtNum(d.h)}`;
export async function GET(req: Request) { export async function GET(req: Request) {
try { try {
const { searchParams } = new URL(req.url); const { searchParams } = new URL(req.url);
@ -28,65 +48,70 @@ export async function GET(req: Request) {
const coll = collectionForTarget(target); const coll = collectionForTarget(target);
if (!coll) return NextResponse.json({ data: [] }); if (!coll) return NextResponse.json({ data: [] });
// IMPORTANT: only request fields that exist on each collection. if (coll === "laser_scan_lens") {
const fields = // fiber / uv / co2gal → scan lenses have field_size + focal_length
coll === "laser_scan_lens" const { data } = await directusFetch<{ data: any[] }>(
? "id,field_size,focal_length" `/items/${coll}?fields=id,field_size,focal_length&limit=${encodeURIComponent(
: "id,focal_length"; String(limit)
)}`
);
const url = `/items/${coll}?fields=${encodeURIComponent( const rows = (data ?? []).map((r) => {
fields const dim = parseFieldSize(r.field_size);
)}&limit=${limit}`; const fnumRaw = r.focal_length;
const label =
dim && fnumRaw != null && fnumRaw !== ""
? `${dimsText(dim)} (F${fmtNum(Number(fnumRaw))})`
: dim
? dimsText(dim)
: String(r.field_size ?? r.id);
const { data } = await directusFetch<{ data: any[] }>(url); const area =
const list = Array.isArray(data) ? data : []; dim && Number.isFinite(dim.w) && Number.isFinite(dim.h)
? dim.w * dim.h
: Number.POSITIVE_INFINITY;
const items = list.map((x) => { return {
const id = String(x?.id); id: String(r.id),
label,
_sort: { area, w: dim?.w ?? Number.POSITIVE_INFINITY, h: dim?.h ?? Number.POSITIVE_INFINITY },
_search: `${r.field_size ?? ""} ${r.focal_length ?? ""} ${label}`.toLowerCase(),
};
});
const fieldSize = const filtered = q ? rows.filter((r) => r._search.includes(q)) : rows;
x?.field_size !== null && x?.field_size !== undefined
? String(x.field_size).trim()
: "";
const fnum = Number(x?.focal_length); filtered.sort((a, b) => {
const focalTxt = Number.isFinite(fnum) ? `F${fnum} mm` : ""; if (a._sort.area !== b._sort.area) return a._sort.area - b._sort.area;
if (a._sort.w !== b._sort.w) return a._sort.w - b._sort.w;
if (a._sort.h !== b._sort.h) return a._sort.h - b._sort.h;
return a.label.localeCompare(b.label);
});
// Requested order: field_size first, then focal length return NextResponse.json({
let label = data: filtered.map(({ id, label }) => ({ id, label })),
coll === "laser_scan_lens" });
? [fieldSize, focalTxt].filter(Boolean).join(" — ") }
: focalTxt || id;
if (!label) label = id; // CO2 Gantry → focus lenses only have "name"
const { data } = await directusFetch<{ data: any[] }>(
`/items/${coll}?fields=id,name&limit=${encodeURIComponent(String(limit))}`
);
const sortKey: number | string = Number.isFinite(fnum) const rows = (data ?? []).map((r) => ({
? fnum id: String(r.id),
: label.toLowerCase(); label: String(r.name ?? r.id),
_search: String(r.name ?? r.id).toLowerCase(),
}));
return { const filtered = q ? rows.filter((r) => r._search.includes(q)) : rows;
id, filtered.sort((a, b) => a.label.localeCompare(b.label));
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({ return NextResponse.json({
data: filtered.map(({ id, label }) => ({ id, label })), data: filtered.map(({ id, label }) => ({ id, label })),
}); });
} catch (e: any) { } catch (err: any) {
console.error("[options/lens] error:", e?.message || e); console.error("[options/lens] error:", err?.message || err);
// Fail-soft so the UI doesnt hang return NextResponse.json({ data: [] }, { status: 200 });
return NextResponse.json({ data: [] });
} }
} }