import { FileDown, Filter, Plus, Search } from 'lucide-react' import { useEffect, useState } from 'react' import { NavLink, useSearchParams } from 'react-router-dom' import { incidentStatuses, incidentTypes, severities } from '../../shared/enums.ts' import { IncidentTable } from '../components/IncidentTable' import { Page } from '../components/Page' import { PageIntro } from '../components/PageIntro' import { Pagination } from '../components/Pagination' import { SavedViews } from '../components/SavedViews' import { Empty, ErrorMessage, Loading } from '../components/QueryState' import { filterBox, panel, primaryButton, secondaryButton } from '../components/styles' import { incidentTypeLabel, severityLabel, statusLabel } from '../lib/labels' import { filtersToQuery, useIncidents, useSites, type IncidentFilters } from '../lib/queries' const PAGE_SIZE = 25 const select = 'bg-transparent text-xs text-ink outline-none' export function Incidents() { const [params, setParams] = useSearchParams() const sites = useSites() const filters: IncidentFilters = { q: params.get('q') ?? undefined, type: params.get('type') ?? undefined, severity: params.get('severity') ?? undefined, status: params.get('status') ?? undefined, siteId: params.get('siteId') ?? undefined, } const page = Number(params.get('page') ?? 1) const incidents = useIncidents({ ...filters, page, pageSize: PAGE_SIZE }) // Search box updates the URL after a short pause const [query, setQuery] = useState(filters.q ?? '') useEffect(() => setQuery(params.get('q') ?? ''), [params]) useEffect(() => { const handle = setTimeout(() => { if ((params.get('q') ?? '') !== query.trim()) setFilter('q', query.trim()) }, 300) return () => clearTimeout(handle) // eslint-disable-next-line react-hooks/exhaustive-deps }, [query]) function setFilter(key: string, value: string) { const next = new URLSearchParams(params) if (value) next.set(key, value) else next.delete(key) next.delete('page') setParams(next, { replace: true }) } const setPage = (value: number) => { const next = new URLSearchParams(params) next.set('page', String(value)) setParams(next) } return ( Report incident } />
setQuery(event.target.value)} placeholder="Search title, location or INC number" aria-label="Search incidents" />
{(sites.data?.length ?? 0) > 1 && (
)}
Export CSV
{incidents.isPending ? ( ) : incidents.data?.items.length ? ( <> ) : ( {Object.values(filters).some(Boolean) ? 'No incidents match these filters.' : 'No incidents reported yet.'} )}
) }