Skip to content

Marathon Training Dashboard

基于 React + CSS 的马拉松训练仪表盘,运行在 VitePress 中(通过 @docs-islands/vitepress 岛屿架构)。Strava 风格设计,支持亮/暗色主题。

根目录: daily/long-term-goals/components/

架构概览

Dashboard 采用两层布局:主面板仅展示 ProgressTracker(4 个统计卡片)+ TrainingCalendar(热力图日历),所有详细信息通过点击卡片弹窗展示。

MarathonDashboard
├── ProgressTracker (4 stat cards)
│   ├── 本周里程 ring   → click → WeeklyDistributionModal (柱状图)
│   │                              └── click bar → WorkoutModal (训练详情)
│   ├── 计划进度 ring   → click → CycleOverviewModal (周期时间线)
│   ├── 累计公里        (static)
│   └── 完成训练        → click → PersonalRecords (个人纪录)
└── TrainingCalendar (热力图)
    └── click day → TrainingDayModal (日详情)
                     └── click workout → WorkoutModal

快速入口

需求文件路径
修改训练计划数据training-config.ts
添加/同步训练记录pnpm strava:sync 或编辑 data/workouts.json
修改训练类型颜色/图标core/theme.ts + core/theme.css
修改日历弹窗样式composites/TrainingDayModal.tsx + .css
修改训练详情弹窗composites/WorkoutModal.tsx + .css
修改进度卡片/周里程弹窗composites/ProgressTracker.tsx + .css
修改周期概览弹窗composites/CycleOverview.tsx + .css
修改个人纪录弹窗composites/PersonalRecords.tsx + .css
修改日历样式composites/TrainingCalendar.tsx + .css
统计计算逻辑utils/compute-stats.ts
添加新组件参考 primitives/composites/ 目录

文件结构

bash
components/
├── core/
   ├── types.ts          # 所有 TypeScript 接口定义
   ├── theme.ts          # 训练类型 → {color, icon, label} 映射
   └── theme.css         # CSS 变量 (颜色/字体/间距/暗色模式)
├── primitives/
   ├── Badge.tsx         # 训练类型标签 <Badge type="tempo" />
   ├── Card.tsx          # 卡片容器 (支持 onClick)
   ├── HeartRateBar.tsx  # 心率5区可视化条
   ├── ProgressRing.tsx  # SVG 环形进度条
   └── Tabs.tsx          # 标签页切换
├── composites/
   ├── TrainingCalendar.tsx   # 热力图日历 + TrainingDayModal 入口
   ├── TrainingDayModal.tsx   # 点击日期后的详情弹窗
   ├── ProgressTracker.tsx    # 进度卡片 + WeeklyDistributionModal (内联)
   ├── CycleOverview.tsx      # CycleOverviewModal 弹窗
   ├── PersonalRecords.tsx    # PersonalRecords 弹窗
   ├── WorkoutModal.tsx       # 训练详情弹窗 (z-index: 1010)
   ├── HeartRateZones.tsx     # 心率区间 (在 TrainingDayModal 中使用)
   ├── TrainingTable.tsx      # 训练计划表格
   └── WeeklyDistribution.tsx # 独立周分布组件
├── utils/
   └── compute-stats.ts  # 动态统计计算 (周目标/每日目标/配速)
├── training-config.ts    # 训练计划配置 + 数据聚合入口
├── MarathonDashboard.tsx # 主组件,组合 ProgressTracker + Calendar
└── index.ts              # 导出入口

数据流

workouts.json (Strava 同步)

training-config.ts (聚合)
    ├── workoutRecords    ← workouts.json.workouts
    ├── personalRecords   ← workouts.json.personalRecords
    ├── progressStats     ← computeProgressStats(workoutRecords, config)
    ├── trainingPlan      ← 静态配置 (weeklyPlan, cycles, lsdDistanceByWeek)
    └── calendarConfig    ← { startDate: '2026-01-19' }

MarathonDashboard.tsx
    ├── ProgressTracker(stats, workoutRecords, cycles, personalRecords)
    └── TrainingCalendar(plan, startDate, workoutRecords)

核心类型

typescript
type TrainingType =
  | 'rest'
  | 'recovery'
  | 'easy'
  | 'tempo'
  | 'interval'
  | 'lsd'
  | 'strength';
接口用途关键字段
WorkoutRecordStrava 实际训练记录date, distance, avgPace, avgHeartRate, zoneDistribution
TrainingSession计划训练type, details, targetHR, weekParity, tips
ProgressStats进度统计weeklyDistance, weeklyTarget, dailyDistances, dailyTargets
TrainingCycle训练周期name, weeks, phase (base/build/peak/taper)
HeartRateZone心率区间定义zone(1-5), name, min, max, color
TrainingPlan完整训练计划weeklyPlan, cycles, heartRateZones, lsdDistanceByWeek
PersonalRecord个人纪录distance, time, date, dateDisplay

弹窗层级 (z-index)

弹窗z-index说明
基础弹窗 (Weekly/Cycle/PR)1000一级弹窗,从主面板打开
WorkoutModal1010二级弹窗,可从一级弹窗内打开

CSS 命名前缀

前缀组件
tr-ProgressTracker / 通用
wd-WeeklyDistributionModal
co-CycleOverviewModal
pr-PersonalRecords
tdm-TrainingDayModal

格式约定

数据格式示例
日期YYYY-MM-DD"2026-02-03"
配速分'秒"/km"5'00\"/km"
时长H:MM:SSMM:SS"0:40:07"
单双周weekParity'odd' = 1,3,5 周; 'even' = 2,4,6 周
心率区间Z1-Z5基于 Strava 个人设置,最大心率 185

Strava 同步

bash
pnpm strava:sync          # 同步最近 7 天
pnpm strava:sync --days 14 # 同步最近 14 天
pnpm strava:sync --all     # 同步所有数据 (从训练开始日期)
pnpm strava:sync --dry-run # 预览不写入
pnpm strava:auth           # 首次 OAuth 授权

脚本目录: scripts/strava/ (auth, client, config, sync, transform)

详细参考

主题说明参考
设计令牌CSS 变量、类型定义、暗色模式design-tokens
修改指南常用修改模板、组件 Props、弹窗流程modification-guide

Contributors

Changelog

Discuss

Released under the CC BY-SA 4.0 License. (134a8ec)