import { useEffect, useState } from 'react'; import { Link } from 'framework7-react'; import { apiClient, errorMessage, HealthDay } from '../services/api'; import Screen from '../components/Screen'; import Ring from '../components/charts/Ring'; import MetricCard from '../components/charts/MetricCard'; import MetricStrip from '../components/charts/MetricStrip'; import Skeleton from '../components/Skeleton'; import { useCountUp } from '../lib/motion'; import './Today.css'; const DAYS = 30; function StepHero({ today, history }: { today: HealthDay; history: HealthDay[] }) { const goal = today.stepGoal ?? null; const steps = today.steps ?? null; const progress = steps != null && goal ? steps / goal : null; const animated = useCountUp(steps); const week = history.slice(-7).map((d) => d.steps).filter((v): v is number => v != null); const weekAvg = week.length ? Math.round(week.reduce((a, b) => a + b, 0) / week.length) : null; const remaining = steps != null && goal ? goal - steps : null; return (
{steps == null ? '—' : Math.round(animated ?? steps).toLocaleString()}
{progress == null ? '今日暂无步数记录' : progress >= 1 ? '今日目标已完成' : `距目标还差 ${remaining!.toLocaleString()} 步`}
目标
{goal ? goal.toLocaleString() : '—'}
近 7 日均
{weekAvg ? weekAvg.toLocaleString() : '—'}
完成度
{progress != null ? `${Math.round(progress * 100)}%` : '—'}
); } function TodayPage() { const [days, setDays] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(''); useEffect(() => { const load = async () => { try { const end = new Date(); const start = new Date(end.getTime() - (DAYS - 1) * 86400000); setDays(await apiClient.getHealthSummary( start.toISOString().slice(0, 10), end.toISOString().slice(0, 10) )); } catch (err: any) { setError(errorMessage(err, '加载数据失败')); } finally { setLoading(false); } }; load(); }, []); const today = days[days.length - 1]; return ( {loading && ( <>