import React from 'react'; import { MoreVertical, X, CheckSquare, ChevronUp, ChevronDown, Scale, Dumbbell, Plus, Activity, Timer as TimerIcon, ArrowRight, ArrowUp, CheckCircle, Edit, Trash2 } from 'lucide-react'; import { ExerciseType, Language, WorkoutSet } from '../../types'; import { t } from '../../services/i18n'; import FilledInput from '../FilledInput'; import ExerciseModal from '../ExerciseModal'; import { useTracker } from './useTracker'; import SetLogger from './SetLogger'; import { formatSetMetrics } from '../../utils/setFormatting'; import { useAuth } from '../../context/AuthContext'; import { api } from '../../services/api'; import RestTimerFAB from '../ui/RestTimerFAB'; import EditSetModal from '../EditSetModal'; interface ActiveSessionViewProps { tracker: ReturnType; activeSession: any; // Using any to avoid strict type issues with the complex session object for now, but ideally should be WorkoutSession lang: Language; onSessionEnd: () => void; onSessionQuit: () => void; onRemoveSet: (setId: string) => void; } const ActiveSessionView: React.FC = ({ tracker, activeSession, lang, onSessionEnd, onSessionQuit, onRemoveSet }) => { const { elapsedTime, showFinishConfirm, setShowFinishConfirm, showQuitConfirm, setShowQuitConfirm, showMenu, setShowMenu, activePlan, // This comes from useTracker props but we might need to pass it explicitly if not in hook return currentStepIndex, showPlanList, setShowPlanList, jumpToStep, searchQuery, setSearchQuery, setShowSuggestions, showSuggestions, filteredExercises, setSelectedExercise, selectedExercise, weight, setWeight, reps, setReps, duration, setDuration, distance, setDistance, height, setHeight, handleAddSet, editingSetId, editWeight, setEditWeight, editReps, setEditReps, editDuration, setEditDuration, editDistance, setEditDistance, editHeight, setEditHeight, editSide, setEditSide, handleCancelEdit, handleSaveEdit, handleEditSet, isCreating, setIsCreating, handleCreateExercise, exercises } = tracker; const { currentUser, updateUser } = useAuth(); // Timer Logic is now managed in useTracker to persist across re-renders/step changes const { timer } = tracker; const [editingSet, setEditingSet] = React.useState(null); const handleSaveSetFromModal = async (updatedSet: WorkoutSet) => { if (tracker.updateSet) { tracker.updateSet(updatedSet); } setEditingSet(null); }; const handleLogSet = async () => { await handleAddSet(); // Determine next rest time let nextTime = currentUser?.profile?.restTimerDefault || 120; if (activePlan) { // Logic: activePlan set just added. We are moving to next step? // Tracker's handleAddSet calls addSet -> which calls ActiveWorkoutContext's addSet -> which increments currentStepIndex (logic inside context) // But state update might be async or we might need to look at current index before update? // Usually we want the rest time AFTER the set we just did. // The user just configured the set for the *current* step index. // So we look at activePlan.steps[currentStepIndex].restTime. // BUT, if the user just finished step 0, and step 0 says "Rest 60s", then we rest 60s. // If fallback, use default. // Note: currentStepIndex might update immediately or after render. // In a real app, we might get the next set's target time? No, rest is usually associated with the fatigue of the set just done. // Requirement: "rest time after this set". // So we use currentStepIndex (which likely points to the set we just logged, assuming UI hasn't advanced yet? // Actually, handleAddSet likely appends set. Context might auto-advance. // Let's assume we use the restTime of the step that matches the set just logged. const currentStep = activePlan.steps[currentStepIndex]; if (currentStep && currentStep.restTimeSeconds) { nextTime = currentStep.restTimeSeconds; } } if (timer.status !== 'RUNNING') { timer.reset(nextTime); // timer.start(); // Removed per user request: disable auto-start } }; const handleDurationChange = async (newVal: number) => { // Update user profile try { await api.patch('/auth/profile', { restTimerDefault: newVal }); if (currentUser) { updateUser({ ...currentUser, profile: { ...currentUser.profile, restTimerDefault: newVal } }); } } catch (e) { console.error("Failed to update default timer", e); } }; const isPlanFinished = activePlan && currentStepIndex >= activePlan.steps.length; return (

{activePlan ? activePlan.name : t('free_workout', lang)}

{elapsedTime} {activeSession.userBodyWeight ? ` • ${activeSession.userBodyWeight}kg` : ''}
{showMenu && ( <>
setShowMenu(false)} />
)}
{activePlan && (
{showPlanList && (
{activePlan.steps.map((step, idx) => ( ))}
)}
)}
{activeSession.sets.length > 0 && (

{t('history_section', lang)}

{[...activeSession.sets].reverse().map((set: WorkoutSet, idx: number) => { const setNumber = activeSession.sets.length - idx; return (
{setNumber}
{set.exerciseName}{set.side && {t(set.side.toLowerCase() as any, lang)}}
{formatSetMetrics(set, lang)}
); })}
)}
{isCreating && ( setIsCreating(false)} onSave={handleCreateExercise} lang={lang} existingExercises={exercises} initialName={tracker.searchQuery} /> )} {/* Finish Confirmation Dialog */} {showFinishConfirm && (

{t('finish_confirm_title', lang)}

{t('finish_confirm_msg', lang)}

)} {/* Quit Without Saving Confirmation Dialog */} {showQuitConfirm && (

{t('quit_confirm_title', lang)}

{t('quit_confirm_msg', lang)}

)} {/* Edit Set Modal */} {editingSet && ( setEditingSet(null)} set={editingSet} exerciseDef={tracker.exercises.find(e => e.id === editingSet.exerciseId) || tracker.exercises.find(e => e.name === editingSet.exerciseName)} onSave={handleSaveSetFromModal} lang={lang} /> )}
); }; export default ActiveSessionView;