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

+80
View File
@@ -0,0 +1,80 @@
import { AlertTriangle, MapPin } from 'lucide-react'
import { formatDate } from '../lib/dates'
import { severityDotClass, statusClass, typeTone } from '../lib/incidents'
import { toneClasses } from '../lib/tones'
import type { Incident } from '../lib/types'
import { iconButton } from './styles'
const th = 'border-b border-line px-2.5 py-3 font-mono text-3xs font-medium tracking-[0.06em] text-faint uppercase first:pl-6 last:pr-[18px]'
const td = 'border-b border-line-soft px-2.5 py-3.5 text-2xs whitespace-nowrap text-body first:pl-6 last:pr-[18px]'
interface IncidentTableProps {
incidents: Incident[]
limit?: number
wide?: boolean
}
export function IncidentTable({ incidents, limit, wide = false }: IncidentTableProps) {
const rows = limit ? incidents.slice(0, limit) : incidents
return (
<div className="overflow-auto">
<table className={`w-full border-collapse text-left ${wide ? 'min-w-[900px]' : 'min-w-[720px]'}`}>
<thead>
<tr>
<th className={th}>Incident</th>
<th className={th}>Type</th>
<th className={th}>Severity</th>
<th className={th}>Location</th>
<th className={th}>Status</th>
<th className={th}>Date</th>
<th className={th}>
<span className="sr-only">Actions</span>
</th>
</tr>
</thead>
<tbody>
{rows.map((incident) => (
<tr key={incident.id} className="[&:last-child>td]:border-b-0">
<td className={td}>
<div className="flex min-w-[250px] items-center gap-2.5">
<span className={`grid size-7 place-items-center rounded-[7px] ${toneClasses[typeTone[incident.type]]}`}>
<AlertTriangle size={14} />
</span>
<div>
<strong className="block text-xs font-semibold text-ink">{incident.title}</strong>
<small className="mt-1 block text-3xs text-faint">
{incident.id} · {incident.reporter}
</small>
</div>
</div>
</td>
<td className={td}>{incident.type}</td>
<td className={td}>
<span className="inline-flex items-center gap-[5px]">
<i className={`size-1.5 rounded-full ${severityDotClass[incident.severity]}`} />
{incident.severity}
</span>
</td>
<td className={td}>
<div className="flex max-w-[120px] flex-wrap items-center gap-1">
<MapPin size={14} />
{incident.location}
<small className="mt-1 ml-[18px] block w-full text-3xs text-faint">{incident.building}</small>
</div>
</td>
<td className={td}>
<span className={`rounded px-2 py-[5px] text-3xs ${statusClass(incident.status)}`}>{incident.status}</span>
</td>
<td className={`${td} text-[#87938f]`}>{formatDate(incident.date)}</td>
<td className={td}>
<button type="button" className={iconButton} aria-label={`More actions for ${incident.id}`}>
<span className="tracking-[2px] text-[#91aaa0]">•••</span>
</button>
</td>
</tr>
))}
</tbody>
</table>
</div>
)
}