Files
dh-inspeccion-v2/web-v2/src/components/OperationalContextBar.tsx
T

92 lines
4.0 KiB
TypeScript

import { SearchableSelect } from './SearchableSelect';
import { useEffect, useMemo, useState } from 'react';
import type { FormEvent } from 'react';
import { Link, useNavigate } from 'react-router';
import { useAuth } from '../auth/AuthContext';
import { useOperationalContext } from '../context/OperationalContext';
import { listCompaniesForArea, listOperationalAreas } from '../lib/api';
import type { OperationalAssetSummary } from '../lib/api';
import { Icon } from './Icon';
export function OperationalContextBar() {
const navigate = useNavigate();
const { hasPermission } = useAuth();
const { areaId, companyId, setAreaId, setCompanyId, clearContext } = useOperationalContext();
const [areas, setAreas] = useState<OperationalAssetSummary[]>([]);
const [companies, setCompanies] = useState<OperationalAssetSummary[]>([]);
const [search, setSearch] = useState('');
const canReadInventory = hasPermission('assets.read');
const canReadInspections = hasPermission('inspections.read');
useEffect(() => {
if (!canReadInventory && !canReadInspections) return;
listOperationalAreas().then(setAreas).catch(() => setAreas([]));
}, [canReadInventory, canReadInspections]);
useEffect(() => {
if (!areaId) {
setCompanies([]);
if (companyId) setCompanyId('');
return;
}
listCompaniesForArea(areaId)
.then((rows) => {
setCompanies(rows);
if (companyId && !rows.some((item) => item.id === companyId)) setCompanyId('');
})
.catch(() => setCompanies([]));
}, [areaId, companyId, setCompanyId]);
const selectedArea = useMemo(() => areas.find((item) => item.id === areaId) ?? null, [areas, areaId]);
const selectedCompany = useMemo(() => companies.find((item) => item.id === companyId) ?? null, [companies, companyId]);
const submitSearch = (event: FormEvent) => {
event.preventDefault();
const term = search.trim();
if (!term || !canReadInventory) return;
navigate(`/inventarios?view=list&search=${encodeURIComponent(term)}`);
};
if (!canReadInventory && !canReadInspections) return null;
return <section className="operational-context-bar" aria-label="Contexto de trabajo">
<div className="operational-context-summary">
<span className="operational-context-icon"><Icon name="layers" size={17} /></span>
<div>
<small>CONTEXTO DE TRABAJO</small>
<strong>{selectedArea ? selectedArea.name : 'Todas las Áreas'}{selectedCompany ? ` · ${selectedCompany.name}` : ''}</strong>
</div>
</div>
<div className="operational-context-selectors">
<label>
<span>Área</span>
<SearchableSelect value={areaId} onChange={(event) => setAreaId(event.target.value)}>
<option value="">Todas las Áreas</option>
{areas.map((area) => <option key={area.id} value={area.id}>{area.name}</option>)}
</SearchableSelect>
</label>
<label>
<span>Operadora</span>
<SearchableSelect value={companyId} disabled={!areaId} onChange={(event) => setCompanyId(event.target.value)}>
<option value="">{areaId ? 'Todas las Operadoras' : 'Primero elegí un Área'}</option>
{companies.map((company) => <option key={company.id} value={company.id}>{company.name}</option>)}
</SearchableSelect>
</label>
</div>
{canReadInventory && <form className="operational-context-search" onSubmit={submitSearch}>
<Icon name="search" size={16} />
<input value={search} onChange={(event) => setSearch(event.target.value)} placeholder="Buscar en el Inventario…" />
<button type="submit">Buscar</button>
</form>}
<div className="operational-context-actions">
{canReadInventory && <Link className="button secondary compact" to="/inventarios">Inventario</Link>}
{canReadInspections && <Link className="button secondary compact" to="/inspecciones">Inspecciones</Link>}
{(areaId || companyId) && <button type="button" className="button text compact" onClick={clearContext}>Ver todo</button>}
</div>
</section>;
}