chore: import DH V2 D5.6.4 production baseline
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Link } from 'react-router';
|
||||
import { useAuth } from '../../auth/AuthContext';
|
||||
import { Alert, EmptyState, LoadingBlock, errorMessage } from '../../components/Feedback';
|
||||
import { Icon } from '../../components/Icon';
|
||||
import { listInspectionActs } from '../../lib/api';
|
||||
import type { InspectionActListItem, InspectionVisit } from '../../lib/api';
|
||||
import { formatDate } from '../../lib/format';
|
||||
import { inspectionActStatusClass, inspectionActStatusLabel } from './inspectionActPresentation';
|
||||
|
||||
export function InspectionActsPanel({ visit }: { visit: InspectionVisit }) {
|
||||
const { hasPermission } = useAuth();
|
||||
const canRead = hasPermission('inspection_acts.read');
|
||||
const [acts, setActs] = useState<InspectionActListItem[]>([]);
|
||||
const [loading, setLoading] = useState(canRead);
|
||||
const [error, setError] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
if (!canRead) return;
|
||||
setLoading(true);
|
||||
setError('');
|
||||
listInspectionActs(visit.id, { pageSize: 100 })
|
||||
.then((response) => setActs(response.data))
|
||||
.catch((requestError) => setError(errorMessage(requestError)))
|
||||
.finally(() => setLoading(false));
|
||||
}, [canRead, visit.id]);
|
||||
|
||||
if (!canRead) return null;
|
||||
|
||||
return <section className="inspection-acts-panel">
|
||||
<div className="panel-heading">
|
||||
<div><span className="eyebrow">ACTA DE LA VISITA</span><h2>Acta única</h2><p className="section-copy">Cada visita genera una única acta, con numeración anual oficial y versiones inmutables.</p></div>
|
||||
<span className="status-badge pending">Sólo lectura</span>
|
||||
</div>
|
||||
<div className="temporal-notice"><Icon name="clipboard" /><p><strong>El acta se crea en la APK.</strong> El dashboard permite consultar el acta, sus hallazgos, firmas e informe después de la sincronización.</p></div>
|
||||
{error && <Alert>{error}</Alert>}
|
||||
{loading ? <LoadingBlock label="Cargando actas…" /> : acts.length === 0
|
||||
? <EmptyState title="Sin acta sincronizada" text={visit.status === 'IN_PROGRESS' ? 'El inspector debe crearla desde la APK.' : 'Aparecerá aquí cuando el inspector la genere desde la APK.'} />
|
||||
: <div className="table-panel inspection-acts-table"><div className="table-summary"><strong>Acta de inspección</strong><span>Numeración oficial global por año</span></div><div className="table-scroll"><table><thead><tr><th>Acta</th><th>Estado</th><th>Fecha</th><th>Registros</th><th>Hallazgos</th><th>Versión</th><th /></tr></thead><tbody>{acts.map((act) => <tr key={act.id}><td><div className="asset-cell"><span className="asset-symbol"><Icon name="clipboard" size={17} /></span><div><strong>{act.title}</strong><small>{act.code}</small></div></div></td><td><span className={`status-badge ${inspectionActStatusClass(act.status)}`}>{inspectionActStatusLabel(act.status)}</span></td><td>{formatDate(act.occurredAt)}</td><td>{act.assetCount}</td><td>{act.findingCount}</td><td>v{act.currentVersion}</td><td className="action-cell"><Link className="icon-button" to={`/inspecciones/actas/${act.id}`} aria-label={`Abrir ${act.code}`}><Icon name="chevron" /></Link></td></tr>)}</tbody></table></div></div>}
|
||||
</section>;
|
||||
}
|
||||
Reference in New Issue
Block a user