diff --git a/dashboard/src/pages/meetKevin/StockDetail.tsx b/dashboard/src/pages/meetKevin/StockDetail.tsx new file mode 100644 index 0000000..c624183 --- /dev/null +++ b/dashboard/src/pages/meetKevin/StockDetail.tsx @@ -0,0 +1,179 @@ +import { useParams, Link } from 'react-router-dom'; +import { useQuery } from '@tanstack/react-query'; +import meetKevinApi from '../../api/meetKevin'; +import { ActionChip, ConvictionBar } from '../../components/meetKevin'; +import { + LineChart, + Line, + XAxis, + YAxis, + Tooltip, + ResponsiveContainer, +} from 'recharts'; +import type { StockMention } from '../../types/meetKevin'; + +interface TimelineBucket { + bucket_start: string; + net_action_score: number; +} + +interface TimelineResponse { + buckets?: TimelineBucket[]; +} + +export default function MeetKevinStockDetail() { + const { symbol = '' } = useParams<{ symbol: string }>(); + const sym = symbol.toUpperCase(); + + const { data: stock, isLoading } = useQuery({ + queryKey: ['meet-kevin', 'stock', sym], + queryFn: () => meetKevinApi.getStock(sym), + }); + + const { data: timeline } = useQuery({ + queryKey: ['meet-kevin', 'stock', sym, 'timeline'], + queryFn: () => meetKevinApi.getStockTimeline(sym, 'day'), + }); + + if (isLoading || !stock) { + return ( +
+ {mentions.length} mention{mentions.length !== 1 ? 's' : ''} +
++ "{m.rationale_quote}" +
+ )} +| + Symbol + | ++ Mentions + | ++ Last seen + | ++ Latest + | ++ Avg conviction + | +
|---|---|---|---|---|
| + + ${s.symbol} + + | ++ {s.mention_count} + | ++ {new Date(s.last_seen_at).toLocaleDateString()} + | +
+
+
+ |
+
+
+
+
+
+
+ {(s.avg_conviction * 100).toFixed(0)}%
+
+ |
+