HRV baseline band from Garmin + dashboard HRV colours + route name on recent activities + sync-now race fix
This commit is contained in:
@@ -11,6 +11,7 @@ import { startOfWeek, format, subWeeks, eachWeekOfInterval, subDays, addDays } f
|
||||
import api from '../utils/api'
|
||||
import { useIsMobile } from '../hooks/useMediaQuery'
|
||||
import StatCard from '../components/ui/StatCard'
|
||||
import HrvBadge from '../components/ui/HrvBadge'
|
||||
import ActivityMap from '../components/activity/ActivityMap'
|
||||
import {
|
||||
formatDuration, formatDistance, formatHeartRate, formatElevation,
|
||||
@@ -23,20 +24,13 @@ const Grid = WidthProvider(GridLayout)
|
||||
const MEDALS = { 1: '🥇', 2: '🥈', 3: '🥉' }
|
||||
const tooltipStyle = { background: '#111827', border: '1px solid #374151', borderRadius: 8, fontSize: 12, color: '#fff' }
|
||||
|
||||
const HRV_PALETTE = {
|
||||
balanced: 'text-green-400 bg-green-400/10 border-green-400/30',
|
||||
unbalanced: 'text-orange-400 bg-orange-400/10 border-orange-400/30',
|
||||
low: 'text-red-400 bg-red-400/10 border-red-400/30',
|
||||
poor: 'text-red-400 bg-red-400/10 border-red-400/30',
|
||||
}
|
||||
|
||||
// Compact single-stat widgets. val(health, ytdStats) → display string.
|
||||
const STAT_DEFS = {
|
||||
stat_steps: { label: 'Steps today', accent: 'green', sub: 'goal 10,000', val: h => h.steps != null ? h.steps.toLocaleString() : '--' },
|
||||
stat_resting_hr: { label: 'Resting HR', accent: 'red', val: h => formatHeartRate(h.resting_hr) },
|
||||
stat_sleep: { label: 'Sleep', accent: 'default', val: h => formatSleep(h.sleep_duration_s) },
|
||||
stat_vo2max: { label: 'VO₂ max', accent: 'blue', val: h => h.vo2max != null ? h.vo2max.toFixed(1) : '--', sub: h => h.fitness_age != null ? `fitness age ${h.fitness_age}` : undefined },
|
||||
stat_hrv: { label: 'HRV status', accent: 'purple', val: h => h.hrv_nightly_avg != null ? `${Math.round(h.hrv_nightly_avg)} ms` : '--', sub: h => h.hrv_status || undefined },
|
||||
stat_hrv: { label: 'HRV status', accent: 'purple', val: h => h.hrv_nightly_avg != null ? `${Math.round(h.hrv_nightly_avg)} ms` : '--', sub: h => h.hrv_status ? <HrvBadge status={h.hrv_status} /> : undefined },
|
||||
stat_running: { label: 'Running this year', accent: 'blue', val: (h, y) => y ? `${y.running_km.toFixed(0)} km` : '--' },
|
||||
stat_cycling: { label: 'Cycling this year', accent: 'orange', val: (h, y) => y ? `${y.cycling_km.toFixed(0)} km` : '--' },
|
||||
stat_stress: { label: 'Stress', accent: 'purple', val: h => h.avg_stress != null ? Math.round(h.avg_stress) : '--' },
|
||||
@@ -410,6 +404,9 @@ function RecentActivities({ activities }) {
|
||||
<span className="text-lg">{sportIcon(activity.sport_type)}</span>
|
||||
<div className="flex-1 min-w-0">
|
||||
<p className="text-sm font-medium text-white truncate">{activity.name}</p>
|
||||
{activity.named_route_name && (
|
||||
<p className="text-xs text-blue-400 truncate">📍 {activity.named_route_name}</p>
|
||||
)}
|
||||
<p className="text-xs text-gray-500">{formatDate(activity.start_time)}</p>
|
||||
</div>
|
||||
<div className="text-right text-sm">
|
||||
|
||||
Reference in New Issue
Block a user