feat: initialize project structure with core components and pages
CI / Lint, typecheck, test, build (push) Canceled after 0s
CI / End-to-end tests (push) Canceled after 0s

- Added shared styles for UI components in `src/components/styles.ts`.
- Created configuration constants in `src/lib/config.ts`.
- Implemented date formatting and greeting functions in `src/lib/dates.ts` and corresponding tests in `src/lib/dates.test.ts`.
- Developed incident management functions in `src/lib/incidents.ts` with tests in `src/lib/incidents.test.ts`.
- Established navigation structure in `src/lib/navigation.ts`.
- Seeded demo data for incidents and users in `src/lib/seed.ts`.
- Defined tone classes for UI elements in `src/lib/tones.ts`.
- Created type definitions for incidents and related entities in `src/lib/types.ts`.
- Set up main application entry point in `src/main.tsx`.
- Developed various pages including About, Analytics, Incidents, Locations, Overview, and Report Incident.
- Configured testing setup in `src/test/setup.ts` and TypeScript configurations.
- Integrated Vite for development and testing with appropriate plugins.
This commit is contained in:
jayjennings committed 2026-10-06 10:07:57 -07:00
1 parent 732d4d8931
commit a382fa904a
53 files changed
+3523 -31

No files matched your search

+62
View File
@@ -0,0 +1,62 @@
import { FileText, Filter, Plus, Search } from 'lucide-react'
import { useState } from 'react'
import { NavLink } from 'react-router-dom'
import { IncidentTable } from '../components/IncidentTable'
import { Page } from '../components/Page'
import { PageIntro } from '../components/PageIntro'
import { filterBox, panel, primaryButton, secondaryButton } from '../components/styles'
import { ALL_TYPES, filterIncidents, type TypeFilter } from '../lib/incidents'
import { incidentTypes, type Incident } from '../lib/types'
export function Incidents({ incidents }: { incidents: Incident[] }) {
const [query, setQuery] = useState('')
const [type, setType] = useState<TypeFilter>(ALL_TYPES)
const filtered = filterIncidents(incidents, query, type)
return (
<Page>
<PageIntro
eyebrow="Safety register"
title="Incidents"
copy="A complete record of reported events, hazards, and learnings."
action={
<NavLink className={primaryButton} to="/report">
<Plus size={17} /> Report incident
</NavLink>
}
/>
<section className={`${panel} overflow-hidden`}>
<div className="flex flex-wrap items-center gap-2.5 border-b border-line px-[17px] py-3.5 sm:flex-nowrap sm:px-6 sm:py-[18px]">
<div className={`${filterBox} basis-full sm:max-w-[350px] sm:flex-1 sm:basis-auto`}>
<Search size={17} />
<input
className="w-full bg-transparent text-xs text-ink outline-none"
value={query}
onChange={(event) => setQuery(event.target.value)}
placeholder="Search incidents"
aria-label="Search incidents"
/>
</div>
<div className={`${filterBox} sm:ml-auto`}>
<Filter size={16} />
<select
className="bg-transparent text-xs text-ink outline-none"
value={type}
onChange={(event) => setType(event.target.value as TypeFilter)}
aria-label="Filter by type"
>
<option>{ALL_TYPES}</option>
{incidentTypes.map((option) => (
<option key={option}>{option}</option>
))}
</select>
</div>
<button type="button" className={secondaryButton}>
<FileText size={16} /> Export
</button>
</div>
<IncidentTable incidents={filtered} wide />
</section>
</Page>
)
}