'lasers' build fix

This commit is contained in:
makearmy 2025-09-27 17:01:53 -04:00
parent 7b5f66e946
commit a4520c420d

View file

@ -14,7 +14,9 @@ type LaserRow = {
kHz?: string;
ns?: string;
v?: string;
op?: { name?: string } | string | null;
// Directus returns `op` as a string for an “options” field.
// We also defensively support an object with {label|name} in case of custom responses.
op?: { label?: string; name?: string } | string | null;
};
export default function LaserSourcesPage() {
@ -34,11 +36,12 @@ export default function LaserSourcesPage() {
}, [query]);
useEffect(() => {
fetch(
`${process.env.NEXT_PUBLIC_API_BASE_URL}/items/laser_source?limit=-1&fields=*,op.name`
)
// Request everything; `op` will come back as a simple string for an “options” field.
fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}/items/laser_source?limit=-1&fields=*`, {
cache: 'no-store',
})
.then((res) => res.json())
.then((data) => setSources(data.data || []));
.then((data) => setSources(data?.data || []));
}, []);
const highlightMatch = (text?: string, q?: string) => {
@ -51,6 +54,15 @@ export default function LaserSourcesPage() {
);
};
// Render OP as a string safely (supports string or {label|name})
const opText = (row: LaserRow) => {
const v = row.op as any;
if (v && typeof v === 'object') {
return String(v.label ?? v.name ?? '—');
}
return v == null || v === '' ? '—' : String(v);
};
const filtered = useMemo(() => {
const q = debouncedQuery.toLowerCase();
return sources.filter((src) => {
@ -84,11 +96,7 @@ export default function LaserSourcesPage() {
};
const getSortableValue = (row: LaserRow, key: keyof LaserRow | 'op' | 'model') => {
const val =
key === 'op'
? (typeof row.op === 'object' && row.op ? row.op.name : row.op)
: (row as any)[key];
const val = key === 'op' ? opText(row) : (row as any)[key];
if (val == null) return '';
const k = String(key).toLowerCase();
@ -111,8 +119,8 @@ export default function LaserSourcesPage() {
nmCounts[nm] = (nmCounts[nm] || 0) + 1;
}
}
const mostCommonNm = Object.entries(nmCounts)
.sort((a, b) => (Number(b[1]) || 0) - (Number(a[1]) || 0))[0]?.[0] || '—';
const mostCommonNm =
Object.entries(nmCounts).sort((a, b) => (Number(b[1]) || 0) - (Number(a[1]) || 0))[0]?.[0] || '—';
return {
total: sources.length,
uniqueMakes: makes.size,
@ -153,7 +161,9 @@ export default function LaserSourcesPage() {
<div className="card p-4">
<h2 className="text-lg font-semibold mb-2">Feedback</h2>
<p className="text-sm mb-2">See something wrong or want to suggest an improvement?</p>
<Link href="#" className="btn-primary inline-block">Submit Feedback</Link>
<Link href="#" className="btn-primary inline-block">
Submit Feedback
</Link>
</div>
</div>
@ -204,9 +214,7 @@ export default function LaserSourcesPage() {
toggleFilter(make, w);
}}
className={`px-2 py-1 text-xs rounded-md border ${
wavelengthFilters[make] === w
? 'bg-accent text-white'
: 'bg-muted text-muted-foreground'
wavelengthFilters[make] === w ? 'bg-accent text-white' : 'bg-muted text-muted-foreground'
}`}
>
{w}
@ -220,7 +228,9 @@ export default function LaserSourcesPage() {
<tr>
<th className="px-2 py-2 text-left">Make</th>
<th className="px-2 py-2 text-left w-64">
<button onClick={() => toggleSort('model')}>Model{sortArrow('model')}</button>
<button onClick={() => toggleSort('model')}>
Model{sortArrow('model')}
</button>
</th>
<th className="px-2 py-2 text-left">
<button onClick={() => toggleSort('w')}>W{sortArrow('w')}</button>
@ -258,9 +268,7 @@ export default function LaserSourcesPage() {
</td>
<td className="px-2 py-2 whitespace-nowrap">{src.w || '—'}</td>
<td className="px-2 py-2 whitespace-nowrap">{src.mj || '—'}</td>
<td className="px-2 py-2 whitespace-nowrap">
{typeof src.op === 'object' && src.op ? src.op.name || '—' : src.op || '—'}
</td>
<td className="px-2 py-2 whitespace-nowrap">{opText(src)}</td>
<td className="px-2 py-2 whitespace-nowrap">{src.nm || '—'}</td>
<td className="px-2 py-2 whitespace-nowrap">{src.kHz || '—'}</td>
<td className="px-2 py-2 whitespace-nowrap">{src.ns || '—'}</td>