import { useState, useMemo } from "react"; import { useAuth } from "@/_core/hooks/useAuth"; import { trpc } from "@/lib/trpc"; import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Skeleton } from "@/components/ui/skeleton"; import { toast } from "sonner"; import { Target, Loader2, CheckCircle2, Circle, Clock, Dumbbell, RefreshCw, Footprints, Hand, ArrowRight, Sparkles } from "lucide-react"; const categoryIcons: Record = { "影子挥拍": , "脚步移动": , "体能训练": , "墙壁练习": , }; const categoryColors: Record = { "影子挥拍": "bg-blue-50 text-blue-700 border-blue-200", "脚步移动": "bg-green-50 text-green-700 border-green-200", "体能训练": "bg-orange-50 text-orange-700 border-orange-200", "墙壁练习": "bg-purple-50 text-purple-700 border-purple-200", }; type Exercise = { day: number; name: string; category: string; duration: number; description: string; tips: string; sets: number; reps: number; }; export default function Training() { const { user } = useAuth(); const [skillLevel, setSkillLevel] = useState<"beginner" | "intermediate" | "advanced">("beginner"); const [durationDays, setDurationDays] = useState(7); const [selectedDay, setSelectedDay] = useState(1); const utils = trpc.useUtils(); const { data: activePlan, isLoading: planLoading } = trpc.plan.active.useQuery(); const generateMutation = trpc.plan.generate.useMutation({ onSuccess: () => { toast.success("训练计划已生成!"); utils.plan.active.invalidate(); utils.plan.list.invalidate(); }, onError: (err) => toast.error("生成失败: " + err.message), }); const adjustMutation = trpc.plan.adjust.useMutation({ onSuccess: (data) => { toast.success("训练计划已调整!"); utils.plan.active.invalidate(); if (data.adjustmentNotes) toast.info("调整说明: " + data.adjustmentNotes); }, onError: (err) => toast.error("调整失败: " + err.message), }); const recordMutation = trpc.record.create.useMutation({ onSuccess: () => toast.success("训练记录已创建"), }); const completeMutation = trpc.record.complete.useMutation({ onSuccess: () => { toast.success("训练已完成!"); utils.profile.stats.invalidate(); }, }); const exercises = useMemo(() => { if (!activePlan?.exercises) return []; return (activePlan.exercises as Exercise[]).filter(e => e.day === selectedDay); }, [activePlan, selectedDay]); const totalDays = activePlan?.durationDays || 7; if (planLoading) { return (
); } return (

训练计划

按水平和周期生成训练安排

{!activePlan ? ( /* Generate new plan */ 生成训练计划 根据水平和目标生成训练安排
) : ( /* Active plan display */ <>
{activePlan.title} {activePlan.skillLevel === "beginner" ? "初级" : activePlan.skillLevel === "intermediate" ? "中级" : "高级"} {activePlan.durationDays}天计划 {activePlan.version > 1 && ( v{activePlan.version} 已调整 )}
{activePlan.adjustmentNotes && (
调整说明:{activePlan.adjustmentNotes}
)}
{/* Day selector */}
{Array.from({ length: totalDays }, (_, i) => i + 1).map(day => ( ))}

第 {selectedDay} 天训练

{exercises.length > 0 ? (
{exercises.map((ex, idx) => (
{categoryIcons[ex.category] || }

{ex.name}

{ex.description}

{ex.duration}分钟 {ex.sets}组 × {ex.reps}次
{ex.tips && (

💡 {ex.tips}

)}
))}
) : (

该天暂无训练安排

)}
)}
); }