import { useQueryClient } from '@tanstack/react-query';
import { usePipelineReadiness } from '../../hooks/useAdmin';
import { useFetchSymbolData } from '../../hooks/useFetchSymbolData';
import { formatDateTime } from '../../lib/format';
import { SkeletonTable } from '../ui/Skeleton';
function scoreBadge(score: number | null) {
if (score === null) return —;
const cls = score >= 60 ? 'text-emerald-400' : score >= 40 ? 'text-amber-400' : 'text-red-400';
return {score.toFixed(0)};
}
export function PipelineReadinessPanel() {
const queryClient = useQueryClient();
const { data, isLoading, isError, error, isFetching } = usePipelineReadiness();
const fetchMutation = useFetchSymbolData({
includeSymbolPrefix: true,
invalidatePipelineReadiness: true,
});
if (isLoading) return
{(error as Error)?.message || 'Failed to load pipeline readiness'}
; const rows = data ?? []; return (Shows why tickers may be missing in scanner/rankings and what is incomplete.
No tickers available.
) : (| Symbol | OHLCV | Dims | S/R | Scanner | Missing Reasons | Action |
|---|---|---|---|---|---|---|
| {row.symbol} |
{row.ohlcv_bars} bars
{row.ohlcv_last_date ? formatDateTime(row.ohlcv_last_date) : '—'}
|
{scoreBadge(row.dimensions.technical)}
{scoreBadge(row.dimensions.sr_quality)}
{scoreBadge(row.dimensions.sentiment)}
{scoreBadge(row.dimensions.fundamental)}
{scoreBadge(row.dimensions.momentum)}
T SR S F M
|
{row.sr_level_count} |
{row.ready_for_scanner ? 'Ready' : 'Blocked'}
setups: {row.trade_setup_count}
|
{row.missing_reasons.length ? row.missing_reasons.join(', ') : none} |