phase 16: React dashboard with full platform control and analytics

This commit is contained in:
Celes Renata
2026-04-11 16:19:46 -07:00
parent 25e0e386b7
commit faccb0b8db
53 changed files with 7924 additions and 13 deletions
+49
View File
@@ -0,0 +1,49 @@
import { useNavigate } from '@tanstack/react-router';
import { useCompanies } from '../api/hooks';
import { DataTable, type Column } from '../components/DataTable';
import { StatusBadge, LoadingSpinner } from '../components/ui';
import type { Company } from '../api/hooks';
const columns: Column<Company>[] = [
{ key: 'ticker', header: 'Ticker', className: 'font-mono font-semibold text-brand-300' },
{ key: 'legal_name', header: 'Name' },
{ key: 'sector', header: 'Sector' },
{
key: 'active',
header: 'Status',
render: (r) => <StatusBadge status={r.active ? 'active' : 'disabled'} />,
},
{
key: 'active_source_count',
header: 'Sources',
render: (r) => <span>{r.active_source_count ?? '—'}</span>,
},
];
export function CompaniesPage() {
const navigate = useNavigate();
const { data, isLoading, error } = useCompanies();
if (isLoading) return <LoadingSpinner />;
if (error) return <div className="text-red-400">Failed to load companies</div>;
return (
<div>
<h1 className="mb-4 text-xl font-semibold text-gray-100">Companies</h1>
<DataTable<Company>
data={data ?? []}
columns={columns}
keyField="id"
onRowClick={(row) => navigate({ to: '/companies/$id', params: { id: row.id } })}
filterFn={(row, q) => {
const lq = q.toLowerCase();
return (
row.ticker.toLowerCase().includes(lq) ||
(row.legal_name ?? '').toLowerCase().includes(lq) ||
(row.sector ?? '').toLowerCase().includes(lq)
);
}}
/>
</div>
);
}