import { useState } from 'react'; import { useTradingDecisions } from '../../api/tradingHooks'; import type { TradingDecision } from '../../api/tradingHooks'; import { Card, LoadingSpinner } from '../../components/ui'; import { DataTable, type Column } from '../../components/DataTable'; function fmtUsd(v: number | null | undefined) { if (v == null) return '—'; return `$${v.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`; } function pnlColor(v: number | null | undefined) { if (v == null) return 'text-gray-400'; return v >= 0 ? 'text-green-400' : 'text-red-400'; } const PAGE_SIZE = 25; const columns: Column[] = [ { key: 'ticker', header: 'Ticker', className: 'font-mono font-semibold text-brand-300', }, { key: 'decision', header: 'Decision', render: (r) => {r.decision}, }, { key: 'computed_share_quantity', header: 'Shares', render: (r) => {r.computed_share_quantity ?? '—'}, }, { key: 'computed_position_size', header: 'Position Size', render: (r) => {fmtUsd(r.computed_position_size)}, }, { key: 'risk_tier_at_decision', header: 'Risk Tier', render: (r) => {r.risk_tier_at_decision}, }, { key: 'portfolio_heat_at_decision', header: 'Heat', render: (r) => ( {r.portfolio_heat_at_decision != null ? `${(r.portfolio_heat_at_decision * 100).toFixed(1)}%` : '—'} ), }, { key: 'is_micro_trade', header: 'Micro', render: (r) => {r.is_micro_trade ? 'Yes' : 'No'}, }, { key: 'created_at', header: 'Date', render: (r) => {new Date(r.created_at).toLocaleString()}, }, ]; export function TradeHistory() { const [tickerFilter, setTickerFilter] = useState(''); const [page, setPage] = useState(0); const { data, isLoading } = useTradingDecisions({ ticker: tickerFilter || undefined, limit: PAGE_SIZE, offset: page * PAGE_SIZE, }); if (isLoading) return ; return (

Trade History

{ setTickerFilter(e.target.value.toUpperCase()); setPage(0); }} className="w-32 rounded-md border border-surface-700 bg-surface-950 px-2 py-1 text-xs text-gray-200 placeholder-gray-500 focus:border-brand-500 focus:outline-none" aria-label="Filter by ticker" />
data={data ?? []} columns={columns} keyField="id" pageSize={PAGE_SIZE} emptyMessage="No trading decisions found" /> {/* Server-side pagination controls */}
Page {page + 1}
); }