39 lines
1.8 KiB
TypeScript
39 lines
1.8 KiB
TypeScript
import { useState } from 'react';
|
|
import { useNavigate } from '@tanstack/react-router';
|
|
import { useRecommendations } from '../api/hooks';
|
|
import { DataTable, type Column } from '../components/DataTable';
|
|
import { StatusBadge, ConfidenceBar, LoadingSpinner, TickerFilter } from '../components/ui';
|
|
import type { Recommendation } from '../api/hooks';
|
|
|
|
export function RecommendationsPage() {
|
|
const navigate = useNavigate();
|
|
const [ticker, setTicker] = useState('');
|
|
const { data, isLoading } = useRecommendations({ ticker: ticker || undefined, limit: 100 });
|
|
|
|
const columns: Column<Recommendation>[] = [
|
|
{ key: 'ticker', header: 'Ticker', className: 'font-mono font-semibold text-brand-300' },
|
|
{ key: 'action', header: 'Action', render: (r) => <StatusBadge status={r.action} /> },
|
|
{ key: 'mode', header: 'Mode', render: (r) => <StatusBadge status={r.mode} /> },
|
|
{ key: 'confidence', header: 'Confidence', render: (r) => <ConfidenceBar value={r.confidence} /> },
|
|
{ key: 'thesis', header: 'Thesis', render: (r) => <span className="line-clamp-1 max-w-xs text-xs text-gray-400">{r.thesis ?? '—'}</span> },
|
|
{ key: 'generated_at', header: 'Generated', render: (r) => <span className="text-xs">{new Date(r.generated_at).toLocaleString()}</span> },
|
|
];
|
|
|
|
if (isLoading) return <LoadingSpinner />;
|
|
|
|
return (
|
|
<div>
|
|
<div className="mb-4 flex items-center justify-between">
|
|
<h1 className="text-xl font-semibold text-gray-100">Recommendations</h1>
|
|
<TickerFilter value={ticker} onChange={setTicker} />
|
|
</div>
|
|
<DataTable<Recommendation>
|
|
data={data ?? []}
|
|
columns={columns}
|
|
keyField="id"
|
|
onRowClick={(row) => navigate({ to: '/recommendations/$id', params: { id: row.id } })}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|