Katalog, lernendes Mapping ohne KI, optionale Items und Import-Policy. Playwright-Smoke und Issue-Audit um Ernährung/Zuordnen/API ergänzt. Co-authored-by: Cursor <cursoragent@cursor.com>
58 lines
2.0 KiB
JavaScript
58 lines
2.0 KiB
JavaScript
import { useState } from 'react'
|
|
import { api } from '../utils/api'
|
|
|
|
export default function AdminBlsFoodsPage() {
|
|
const [q, setQ] = useState('')
|
|
const [rows, setRows] = useState([])
|
|
const [detail, setDetail] = useState(null)
|
|
const [error, setError] = useState(null)
|
|
|
|
const search = async () => {
|
|
try {
|
|
setRows(await api.adminBlsFoods(q))
|
|
} catch (e) {
|
|
setError(e.message)
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div className="card">
|
|
<h1 className="page-title">Lebensmittelkatalog</h1>
|
|
{error && <p style={{ color: 'var(--danger)' }}>{error}</p>}
|
|
<div className="form-row">
|
|
<input className="form-input" value={q} onChange={(e) => setQ(e.target.value)} placeholder="Name oder BLS-Code" />
|
|
<button type="button" className="btn btn-primary" onClick={search}>Suchen</button>
|
|
</div>
|
|
{rows.map((r) => (
|
|
<button
|
|
key={r.id}
|
|
type="button"
|
|
className="btn btn-secondary btn-full"
|
|
style={{ marginTop: 6, textAlign: 'left' }}
|
|
onClick={() => api.adminBlsFoodDetail(r.id).then(setDetail).catch((e) => setError(e.message))}
|
|
>
|
|
{r.bls_code ? `${r.bls_code} · ` : ''}{r.name_de}
|
|
{r.catalog_kind !== 'official_bls' ? ' · manuell' : ''}
|
|
</button>
|
|
))}
|
|
{detail && (
|
|
<div style={{ marginTop: 16 }}>
|
|
<h3>{detail.bls_code} {detail.name_de}</h3>
|
|
<p style={{ fontSize: 12, color: 'var(--text3)' }}>{detail.catalog_kind} · {detail.bls_version || '—'}</p>
|
|
<table style={{ width: '100%', fontSize: 12 }}>
|
|
<tbody>
|
|
{(detail.attributes || []).filter((a) => a.value_num != null || a.is_trace).slice(0, 40).map((a) => (
|
|
<tr key={a.attr_key}>
|
|
<td>{a.attr_key}</td>
|
|
<td>{a.name_de}</td>
|
|
<td>{a.is_trace ? 'Spuren' : a.value_num} {a.unit || ''}</td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|