import { useState, useEffect } from 'react'
import { getAccuracy } from '../api'
import { IconRefresh } from '../icons'
function Accuracy() {
const [data, setData] = useState({ stats: {}, recent_predictions: [] })
const [loading, setLoading] = useState(true)
const fetchData = async () => {
setLoading(true)
try {
const result = await getAccuracy()
setData(result)
} catch (err) {
console.error('Failed to load accuracy:', err)
} finally {
setLoading(false)
}
}
useEffect(() => {
fetchData()
// Auto-refresh every 60 seconds
const interval = setInterval(fetchData, 60000)
return () => clearInterval(interval)
}, [])
if (loading) {
return (
Loading accuracy stats...
)
}
const { stats, recent_predictions } = data
const overallAccuracy = stats.overall_accuracy || 0
const byConfidence = stats.by_confidence || {}
return (
Model Accuracy
Track prediction performance and model reliability
{/* Primary Stats Grid */}
Total Predictions
{stats.total_predictions || 0}
Completed Games
{stats.completed_games || 0}
Correct Predictions
{stats.correct_predictions || 0}
Overall Accuracy
{(overallAccuracy * 100).toFixed(1)}%
{/* Detailed Metrics */}
{/* Performance Metrics */}
Performance Metrics
Current Streak
{stats.current_streak || 0}{stats.streak_type || ''}
Last 10 Games
{stats.last_10_record || '0-0'}
({((stats.last_10_accuracy || 0) * 100).toFixed(0)}%)
Pending Predictions
{stats.pending_predictions || 0}
Avg Probability
{((stats.avg_probability_correct || 0) * 100).toFixed(1)}%
{/* Home vs Away */}
Home vs Away Picks
Home Team Picks
{((stats.home_pick_accuracy || 0) * 100).toFixed(1)}%
{stats.home_picks_total || 0} picks
Away Team Picks
{((stats.away_pick_accuracy || 0) * 100).toFixed(1)}%
{stats.away_picks_total || 0} picks
{/* Visual bar */}
stats.away_pick_accuracy ? 1 : 0.5
}}>
stats.home_pick_accuracy ? 1 : 0.5
}}>
{/* Accuracy by Confidence */}
{Object.keys(byConfidence).length > 0 && (
Accuracy by Confidence Level
{['high', 'medium', 'low'].map((conf) => {
const confData = byConfidence[conf] || { accuracy: 0, correct: 0, total: 0 }
const accuracyPercent = (confData.accuracy * 100).toFixed(1)
return (
{conf.toUpperCase()}
{accuracyPercent}%
{confData.correct}/{confData.total} correct
{/* Progress ring visual */}
)
})}
)}
{/* Accuracy by Team */}
{stats.by_team && Object.keys(stats.by_team).length > 0 && (
Accuracy by Team Predicted
| Team |
Correct |
Total |
Accuracy |
{Object.entries(stats.by_team)
.sort((a, b) => b[1].accuracy - a[1].accuracy)
.map(([team, data]) => (
| {team} |
{data.correct} |
{data.total} |
{(data.accuracy * 100).toFixed(1)}%
|
))
}
)}
{/* Recent Predictions */}
Recent Predictions
{recent_predictions.length === 0 ? (
No Predictions Yet
Visit the Live Games page to start tracking predictions.
) : (
| Date |
Matchup |
Prediction |
Confidence |
Result |
{recent_predictions.map((pred, idx) => {
const isPending = pred.is_correct === -1
const isCorrect = pred.is_correct === 1
return (
|
{pred.game_date || 'N/A'}
|
{pred.away_team || 'N/A'}
@
{pred.home_team || 'N/A'}
|
{pred.predicted_winner || 'N/A'}
({((pred.home_win_prob > 0.5 ? pred.home_win_prob : pred.away_win_prob) * 100 || 50).toFixed(0)}%)
|
{(pred.confidence || 'medium').toUpperCase()}
|
{isPending ? (
PENDING
) : isCorrect ? (
CORRECT
) : (
WRONG
)}
|
)
})}
)}
)
}
export default Accuracy