Files
geniusrun/frontend/src/pages/Analysis.tsx

87 lines
2.7 KiB
TypeScript
Raw Normal View History

import { useEffect, useState } from "react";
import { api } from "../api/client";
import { ProgressionChart } from "../components/charts/ProgressionChart";
import type { ProgressionMetric, ProgressionPoint, WorkoutKind } from "../types/api";
const METRICS: { key: ProgressionMetric; label: string }[] = [
{ key: "pace", label: "Pace" },
{ key: "hr", label: "Heart Rate" },
{ key: "vo2max", label: "VO2max" },
{ key: "aerobic_te", label: "Aerobic Training Effect" },
{ key: "anaerobic_te", label: "Anaerobic Training Effect" },
{ key: "efficiency_factor", label: "Efficiency Factor" },
];
2026-07-26 10:00:24 +02:00
export function Analysis() {
const [kinds, setKinds] = useState<WorkoutKind[]>([]);
const [selectedKindId, setSelectedKindId] = useState<number | null>(null);
const [metric, setMetric] = useState<ProgressionMetric>("pace");
const [points, setPoints] = useState<ProgressionPoint[]>([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
api
.listWorkoutKinds()
.then((k) => {
setKinds(k);
if (k.length > 0) setSelectedKindId(k[0].ID);
})
.catch((e) => setError(String(e)));
}, []);
useEffect(() => {
if (selectedKindId == null) return;
setLoading(true);
setError(null);
api
.progression(selectedKindId, metric)
.then(setPoints)
.catch((e) => setError(String(e)))
.finally(() => setLoading(false));
}, [selectedKindId, metric]);
return (
<div className="page">
{kinds.length === 0 ? (
<p className="empty-state">
No training types defined yet. See the Training types card on the Profile page to start seeing progression
here.
</p>
) : (
<>
<div className="controls">
<label>
Training types
<select
value={selectedKindId ?? ""}
onChange={(e) => setSelectedKindId(Number(e.target.value))}
>
{kinds.map((k) => (
<option key={k.ID} value={k.ID}>
{k.Name}
</option>
))}
</select>
</label>
<label>
Metric
<select value={metric} onChange={(e) => setMetric(e.target.value as ProgressionMetric)}>
{METRICS.map((m) => (
<option key={m.key} value={m.key}>
{m.label}
</option>
))}
</select>
</label>
</div>
{error && <p className="error">{error}</p>}
{loading ? <p>Loading...</p> : <ProgressionChart points={points} metric={metric} />}
</>
)}
</div>
);
}