import React, { useState, useEffect } from 'react'; import { Plus, Trash2, PlayCircle, Dumbbell, Save, X, ChevronRight, List, ArrowUp, ArrowDown, Scale, Edit2, User, Flame, Timer as TimerIcon, Ruler, Footprints, Activity, Percent, CheckCircle, GripVertical } from 'lucide-react'; import { WorkoutPlan, ExerciseDef, PlannedSet, Language, ExerciseType } from '../types'; import { getPlans, savePlan, deletePlan, getExercises, saveExercise } from '../services/storage'; import { t } from '../services/i18n'; interface PlansProps { userId: string; onStartPlan: (plan: WorkoutPlan) => void; lang: Language; } const FilledInput = ({ label, value, onChange, type = "number", icon, autoFocus, step }: any) => (
); const Plans: React.FC = ({ userId, onStartPlan, lang }) => { const [plans, setPlans] = useState([]); const [isEditing, setIsEditing] = useState(false); const [editId, setEditId] = useState(null); const [name, setName] = useState(''); const [description, setDescription] = useState(''); const [steps, setSteps] = useState([]); const [availableExercises, setAvailableExercises] = useState([]); const [showExerciseSelector, setShowExerciseSelector] = useState(false); // Drag and Drop Refs const dragItem = React.useRef(null); const [draggingIndex, setDraggingIndex] = useState(null); // Create Exercise State const [isCreatingExercise, setIsCreatingExercise] = useState(false); const [newExName, setNewExName] = useState(''); const [newExType, setNewExType] = useState(ExerciseType.STRENGTH); const [newExBwPercentage, setNewExBwPercentage] = useState('100'); useEffect(() => { const loadData = async () => { const fetchedPlans = await getPlans(userId); setPlans(fetchedPlans); const fetchedExercises = await getExercises(userId); // Filter out archived exercises if (Array.isArray(fetchedExercises)) { setAvailableExercises(fetchedExercises.filter(e => !e.isArchived)); } else { setAvailableExercises([]); } }; loadData(); }, [userId]); const handleCreateNew = () => { setEditId(crypto.randomUUID()); setName(''); setDescription(''); setSteps([]); setIsEditing(true); }; const handleEdit = (plan: WorkoutPlan) => { setEditId(plan.id); setName(plan.name); setDescription(plan.description || ''); setSteps(plan.steps); setIsEditing(true); }; const handleSave = async () => { if (!name.trim() || !editId) return; const newPlan: WorkoutPlan = { id: editId, name, description, steps }; await savePlan(userId, newPlan); const updated = await getPlans(userId); setPlans(updated); setIsEditing(false); }; const handleDelete = async (id: string, e: React.MouseEvent) => { e.stopPropagation(); if (confirm(t('delete_confirm', lang))) { await deletePlan(userId, id); const updated = await getPlans(userId); setPlans(updated); } }; const addStep = (ex: ExerciseDef) => { const newStep: PlannedSet = { id: crypto.randomUUID(), exerciseId: ex.id, exerciseName: ex.name, exerciseType: ex.type, isWeighted: false }; setSteps([...steps, newStep]); setShowExerciseSelector(false); }; const handleCreateExercise = async () => { if (!newExName.trim()) return; const newEx: ExerciseDef = { id: crypto.randomUUID(), name: newExName.trim(), type: newExType, ...(newExType === ExerciseType.BODYWEIGHT && { bodyWeightPercentage: parseFloat(newExBwPercentage) || 100 }) }; await saveExercise(userId, newEx); const exList = await getExercises(userId); setAvailableExercises(exList.filter(e => !e.isArchived)); // Automatically add the new exercise to the plan addStep(newEx); setNewExName(''); setNewExType(ExerciseType.STRENGTH); setNewExBwPercentage('100'); setIsCreatingExercise(false); }; const exerciseTypeLabels: Record = { [ExerciseType.STRENGTH]: t('type_strength', lang), [ExerciseType.BODYWEIGHT]: t('type_bodyweight', lang), [ExerciseType.CARDIO]: t('type_cardio', lang), [ExerciseType.STATIC]: t('type_static', lang), [ExerciseType.HIGH_JUMP]: t('type_height', lang), [ExerciseType.LONG_JUMP]: t('type_dist', lang), [ExerciseType.PLYOMETRIC]: t('type_jump', lang), }; const toggleWeighted = (stepId: string) => { setSteps(steps.map(s => s.id === stepId ? { ...s, isWeighted: !s.isWeighted } : s)); }; const removeStep = (stepId: string) => { setSteps(steps.filter(s => s.id !== stepId)); }; const onDragStart = (index: number) => { dragItem.current = index; setDraggingIndex(index); }; const onDragEnter = (index: number) => { if (dragItem.current === null) return; if (dragItem.current === index) return; const newSteps = [...steps]; const draggedItemContent = newSteps.splice(dragItem.current, 1)[0]; newSteps.splice(index, 0, draggedItemContent); setSteps(newSteps); dragItem.current = index; setDraggingIndex(index); }; const onDragEnd = () => { dragItem.current = null; setDraggingIndex(null); }; if (isEditing) { return (

{t('plan_editor', lang)}

setName(e.target.value)} />