import { useState } from 'react'; import { useQuery } from '@tanstack/react-query'; import { Link } from 'react-router-dom'; import meetKevinApi from '../../api/meetKevin'; import type { MarketOutlook, TickerAction, VideoStatus } from '../../types/meetKevin'; const STATUS_OPTIONS: { value: VideoStatus | ''; label: string }[] = [ { value: '', label: 'All' }, { value: 'analyzed', label: 'Analyzed' }, { value: 'captioned', label: 'Captioned' }, { value: 'discovered', label: 'Discovered' }, { value: 'failed', label: 'Failed' }, { value: 'skipped', label: 'Skipped' }, ]; function statusColor(status: VideoStatus): string { if (status === 'analyzed') return 'text-green-400'; if (status === 'failed') return 'text-red-400'; return 'text-yellow-300'; } const ACTION_CHIP: Record = { buy: 'bg-green-600/30 text-green-300 border-green-500/40', sell: 'bg-red-600/30 text-red-300 border-red-500/40', hold: 'bg-slate-600/30 text-slate-300 border-slate-500/40', watch: 'bg-yellow-600/30 text-yellow-200 border-yellow-500/40', avoid: 'bg-rose-600/40 text-rose-200 border-rose-500/40', }; const OUTLOOK_PILL: Record = { bullish: 'bg-green-600/20 text-green-300 border-green-500/40', bearish: 'bg-red-600/20 text-red-300 border-red-500/40', neutral: 'bg-slate-600/20 text-slate-300 border-slate-500/40', mixed: 'bg-purple-600/20 text-purple-300 border-purple-500/40', }; export default function MeetKevinVideos() { const [status, setStatus] = useState(''); const [q, setQ] = useState(''); const [page, setPage] = useState(1); const per_page = 20; const { data, isLoading } = useQuery({ queryKey: ['meet-kevin', 'videos', status, q, page], queryFn: () => meetKevinApi.listVideos({ status: status || undefined, q: q || undefined, page, per_page, }), }); const totalPages = data ? Math.ceil(data.total / per_page) : 0; return (

Meet Kevin — Videos

{data?.total ?? 0} videos
{/* Filters */}
{ setQ(e.target.value); setPage(1); }} placeholder="e.g. Fed, rate cut…" className="w-full px-3 py-2 bg-slate-700 border border-slate-600 rounded-lg text-white text-sm placeholder-slate-400 focus:outline-none focus:ring-1 focus:ring-blue-500" />
{(status || q) && ( )}
{/* Cards */} {isLoading ? (
) : data && data.videos.length > 0 ? (
{data.videos.map((video) => ( {/* Thumbnail */} {video.thumbnail_url ? ( ) : (
No image
)} {/* Details */}

{video.title}

{new Date(video.published_at).toLocaleDateString()} {video.status}
{video.failure_reason && (

{video.failure_reason}

)} {video.outlook && (
{video.outlook}
)} {video.top_tickers.length > 0 && (
{video.top_tickers.map((t) => ( {t.symbol} {Math.round(t.conviction * 100)} ))}
)} {video.one_line_summary && (

{video.one_line_summary}

)}
))}
) : (
No videos found
)} {/* Pagination */} {totalPages > 1 && (
Page {page} of {totalPages}
)}
); }