'use client'; import { useEffect, useMemo, useState } from 'react'; import { useParlay, type ParlayLeg } from '@/contexts/ParlayContext'; import { GradePill } from './GradeCard'; import { trackParlayBuilt } from '@/lib/analytics'; interface ParlayGradeResponse { parlay_grade: string; parlay_confidence: number; correlation_flags: { type: string; legs: number[]; detail: string; impact: string }[]; decimal_odds?: number; } export default function ParlayTray() { const { legs, isOpen, close, removeLeg, clear } = useParlay(); const [grading, setGrading] = useState(false); const [parlayResult, setParlayResult] = useState(null); // Reset the parlay grade whenever the leg set changes useEffect(() => { setParlayResult(null); }, [legs]); const sports = useMemo(() => Array.from(new Set(legs.map((l) => l.sport))), [legs]); const gradeParlay = async () => { if (legs.length < 2) return; setGrading(true); try { const token = typeof window !== 'undefined' ? localStorage.getItem('sb-token') : null; const res = await fetch('/api/parlay/grade', { method: 'POST', headers: { 'Content-Type': 'application/json', ...(token ? { Authorization: `Bearer ${token}` } : {}), }, body: JSON.stringify({ legs: legs.map((l) => ({ sport: l.sport, player: l.player, stat_type: l.stat, line: l.line, direction: l.direction, })), }), }); const data = (await res.json()) as ParlayGradeResponse; if (res.ok) { setParlayResult(data); trackParlayBuilt({ legs: legs.length, sports, grade: data.parlay_grade }); } } finally { setGrading(false); } }; if (!isOpen) return null; return (
{legs.length === 0 ? ( ) : (
    {legs.map((l) => ( removeLeg(l.id)} /> ))}
)} {parlayResult && (

PARLAY GRADE

{parlayResult.correlation_flags.length > 0 && (

CORRELATION WARNINGS

{parlayResult.correlation_flags.map((f, i) => (

{f.detail}

))}
)}
)} {legs.length > 0 && (
)}
); } function EmptyTrayCopy() { return (

NO LEGS YET

Read a prop, hit Add to Parlay, and we'll build the slip here. We grade overall correlation and surface the legs that secretly fight each other.

); } function LegRow({ leg, onRemove }: { leg: ParlayLeg; onRemove: () => void }) { return (
  • {leg.player}
    {leg.sport} · {leg.direction} {leg.line} {leg.stat.replace(/_/g, ' ')}
  • ); }