/* global React, Button, Input, Ic, VS, LoadingState, ErrorState */ // ============================================================ // NORM PICKER — modal z listą norm + podglądem opisu // ============================================================ function NormPicker({ currentId, onPick, onClose }) { const [list, setList] = React.useState(null); const [err, setErr] = React.useState(''); const [q, setQ] = React.useState(''); const [previewId, setPreviewId] = React.useState(currentId || null); React.useEffect(() => { VS.norms() .then((r) => setList(r || [])) .catch((e) => setErr(e.message)); }, []); React.useEffect(() => { function onKey(e) { if (e.key === 'Escape') onClose && onClose(); } document.addEventListener('keydown', onKey); return () => document.removeEventListener('keydown', onKey); }, [onClose]); const filtered = React.useMemo(() => { if (!list) return []; const qq = (q || '').trim().toLowerCase(); if (!qq) return list; return list.filter((it) => (it.numer || '').toLowerCase().includes(qq) || (it.wartosci || '').toLowerCase().includes(qq) || (it.opis || '').toLowerCase().includes(qq) ); }, [list, q]); const preview = React.useMemo( () => (list || []).find((n) => n.id === previewId) || null, [list, previewId] ); function confirm() { const item = (list || []).find((n) => n.id === previewId); if (!item) return; if (onPick) onPick(item.id, item.numer || item.wartosci || ''); if (onClose) onClose(); } return (
e.stopPropagation()} style={{ width: 'min(1100px, 100%)', maxHeight: 'calc(100vh - 48px)', background: 'var(--bg)', border: '1px solid var(--border)', borderRadius: 'var(--r-md)', boxShadow: '0 20px 60px rgba(0,0,0,0.35)', display: 'flex', flexDirection: 'column', overflow: 'hidden', }} > {/* Header */}
Biblioteka norm
Wybierz normę dla protokołu
{/* Toolbar */}
} placeholder="Szukaj normy…" value={q} onChange={(e) => setQ(e.target.value)} />
{/* Body: lista (lewo) + podgląd (prawo) */}
{/* Lista */}
{err &&
} {!err && !list &&
} {!err && list && list.length === 0 && (
Brak norm w bazie.
)} {!err && filtered.length === 0 && list && list.length > 0 && (
Brak wyników.
)} {!err && filtered.map((it) => ( setPreviewId(it.id)} onDoubleClick={() => { if (onPick) onPick(it.id, it.numer || ''); if (onClose) onClose(); }} /> ))}
{/* Podgląd */}
{!preview && (
Wybierz normę z listy aby zobaczyć pełny opis.
)} {preview && (
Nazwa
{preview.numer || '—'}
Numer normy
{preview.wartosci || '—'}
Opis
{preview.opis || '—'}
)}
{/* Footer */}
{list ? `${filtered.length} / ${list.length} norm` : ''}
); } function NormRow({ norm, selected, current, onClick, onDoubleClick }) { const [hover, setHover] = React.useState(false); const bg = selected ? 'var(--bg-sunken)' : hover ? 'var(--surface)' : 'transparent'; return (
setHover(true)} onMouseLeave={() => setHover(false)} style={{ padding: '10px 14px', borderBottom: '1px solid var(--hairline)', cursor: 'pointer', background: bg, display: 'flex', flexDirection: 'column', gap: 3, }} >
{norm.numer || '—'}
{current && ( aktualna )}
{norm.wartosci || '—'}
); } Object.assign(window, { NormPicker });