running-dashboard / src /components /WeeklySummary.js
lewtun's picture
lewtun HF Staff
Add week navigation to weekly summary section
7b6976e
import './WeeklySummary.css';
function WeeklySummary({ summary, recommendation, weekKey, isCurrentWeek, weeksOfData, longestRun, hasPrevWeek, hasNextWeek, onPrevWeek, onNextWeek }) {
const hasRuns = summary.run_count > 0;
return (
<div className="weekly-summary card">
<div className="week-nav">
<button className="week-nav-btn" disabled={!hasPrevWeek} onClick={onPrevWeek} aria-label="Previous week">&lsaquo;</button>
<h2>{isCurrentWeek ? 'This Week' : 'Week'} <span className="week-label">{weekKey}</span></h2>
<button className="week-nav-btn" disabled={!hasNextWeek} onClick={onNextWeek} aria-label="Next week">&rsaquo;</button>
</div>
{hasRuns ? (
<>
<div className="stats-grid">
<div className="stat-card">
<span className="stat-value">{summary.total_distance_km.toFixed(1)}</span>
<span className="stat-label">km total</span>
</div>
<div className="stat-card">
<span className="stat-value">{summary.total_training_load.toFixed(0)}</span>
<span className="stat-label">training load</span>
</div>
<div className="stat-card">
<span className="stat-value">{summary.run_count}</span>
<span className="stat-label">runs</span>
</div>
<div className="stat-card">
<span className="stat-value">{summary.avg_pace.toFixed(1)}</span>
<span className="stat-label">min/km avg</span>
</div>
</div>
{longestRun && (
<div className="longest-run">
<h3>
Single Run Cap <span className="rec-method">(BJSM 30-day)</span>
<span className="info-tip-wrapper">
<span className="info-icon">β“˜</span>
<span className="info-tooltip">
Overuse injury risk increases when a single session exceeds 10% of the longest run in the past 30 days.
<a href="https://bjsm.bmj.com/content/59/17/1203" target="_blank" rel="noopener noreferrer">
Read the paper&nbsp;β†’
</a>
</span>
</span>
</h3>
<div className="rec-row">
<span className="rec-label">Longest run (30d)</span>
<span className="rec-value">{longestRun.longest_km} km</span>
</div>
<div className="rec-row">
<span className="rec-label">Max next run (+10%)</span>
<span className="rec-value threshold-value">{longestRun.threshold_km} km</span>
</div>
</div>
)}
<div className="recommendation">
<h3>
Next Week Target <span className="rec-method">(ACWR, {weeksOfData || 1}w avg)</span>
<span className="info-tip-wrapper">
<span className="info-icon">β“˜</span>
<span className="info-tooltip">
The Acute:Chronic Workload Ratio compares your recent training to your rolling average over the last {weeksOfData || 1} week{(weeksOfData || 1) > 1 ? 's' : ''} (up to 4). A safe range is 0.8–1.3Γ— chronic load.
<a href="https://bjsm.bmj.com/content/50/5/273" target="_blank" rel="noopener noreferrer">
Read the paper&nbsp;β†’
</a>
</span>
</span>
</h3>
<div className="rec-row">
<span className="rec-label">Distance</span>
<span className="rec-value">
{recommendation.min_distance} – {recommendation.max_distance} km
</span>
</div>
<div className="rec-row">
<span className="rec-label">Training Load</span>
<span className="rec-value">
{recommendation.min_load} – {recommendation.max_load}
</span>
</div>
</div>
</>
) : (
<p className="empty-message">No runs logged this week yet. Add your first run to see stats and recommendations.</p>
)}
</div>
);
}
export default WeeklySummary;