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
+43
View File
@@ -0,0 +1,43 @@
import { useState } from 'react';
import { useNavigate } from '@tanstack/react-router';
import { useDocuments } from '../api/hooks';
import { DataTable, type Column } from '../components/DataTable';
import { StatusBadge, LoadingSpinner, TickerFilter } from '../components/ui';
import type { Document } from '../api/hooks';
export function DocumentsPage() {
const navigate = useNavigate();
const [ticker, setTicker] = useState('');
const { data, isLoading, error } = useDocuments({ ticker: ticker || undefined, limit: 100 });
const columns: Column<Document>[] = [
{ key: 'title', header: 'Title', render: (r) => <span className="line-clamp-1 max-w-xs">{r.title ?? '—'}</span> },
{ key: 'document_type', header: 'Type' },
{ key: 'source_type', header: 'Source' },
{ key: 'published_at', header: 'Published', render: (r) => <span className="text-xs">{r.published_at ? new Date(r.published_at).toLocaleDateString() : '—'}</span> },
{ key: 'parse_confidence', header: 'Parse Quality', render: (r) => <StatusBadge status={r.parse_confidence ?? 'unknown'} /> },
{ key: 'status', header: 'Status', render: (r) => <StatusBadge status={r.status} /> },
];
if (isLoading) return <LoadingSpinner />;
if (error) return <div className="text-red-400">Failed to load documents</div>;
return (
<div>
<div className="mb-4 flex items-center justify-between">
<h1 className="text-xl font-semibold text-gray-100">Documents</h1>
<TickerFilter value={ticker} onChange={setTicker} />
</div>
<DataTable<Document>
data={data ?? []}
columns={columns}
keyField="id"
onRowClick={(row) => navigate({ to: '/documents/$id', params: { id: row.id } })}
filterFn={(row, q) => {
const lq = q.toLowerCase();
return (row.title ?? '').toLowerCase().includes(lq) || row.document_type.toLowerCase().includes(lq);
}}
/>
</div>
);
}