import React, { useState } from 'react'; import { Calendar, Clock, TrendingUp, Gauge, Pencil, Trash2, X, Save, ArrowRight, ArrowUp, Timer, Activity, Dumbbell, Percent } from 'lucide-react'; import { WorkoutSession, ExerciseType, WorkoutSet, Language, SporadicSet } from '../types'; import { t } from '../services/i18n'; interface HistoryProps { sessions: WorkoutSession[]; sporadicSets?: SporadicSet[]; onUpdateSession?: (session: WorkoutSession) => void; onDeleteSession?: (sessionId: string) => void; onUpdateSporadicSet?: (set: SporadicSet) => void; onDeleteSporadicSet?: (setId: string) => void; lang: Language; } const History: React.FC = ({ sessions, sporadicSets, onUpdateSession, onDeleteSession, onUpdateSporadicSet, onDeleteSporadicSet, lang }) => { const [editingSession, setEditingSession] = useState(null); const [deletingId, setDeletingId] = useState(null); const [editingSporadicSet, setEditingSporadicSet] = useState(null); const [deletingSporadicId, setDeletingSporadicId] = useState(null); const calculateSessionWork = (session: WorkoutSession) => { const bw = session.userBodyWeight || 70; return session.sets.reduce((acc, set) => { let w = 0; if (set.type === ExerciseType.STRENGTH) { w = (set.weight || 0) * (set.reps || 0); } if (set.type === ExerciseType.BODYWEIGHT) { const percent = set.bodyWeightPercentage || 100; const effectiveBw = bw * (percent / 100); w = (effectiveBw + (set.weight || 0)) * (set.reps || 0); } return acc + Math.max(0, w); }, 0); }; const formatDateForInput = (timestamp: number) => { const d = new Date(timestamp); const pad = (n: number) => n < 10 ? '0' + n : n; return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`; }; const parseDateFromInput = (value: string) => { return new Date(value).getTime(); }; const formatDuration = (startTime: number, endTime?: number) => { if (!endTime || isNaN(endTime) || isNaN(startTime)) return ''; const durationMs = endTime - startTime; if (durationMs < 0 || isNaN(durationMs)) return ''; const hours = Math.floor(durationMs / 3600000); const minutes = Math.floor((durationMs % 3600000) / 60000); if (hours > 0) { return `${hours}h ${minutes}m`; } if (minutes < 1) { return '<1m'; } return `${minutes}m`; }; const handleSaveEdit = () => { if (editingSession && onUpdateSession) { onUpdateSession(editingSession); setEditingSession(null); } }; const handleUpdateSet = (setId: string, field: keyof WorkoutSet, value: number) => { if (!editingSession) return; const updatedSets = editingSession.sets.map(s => s.id === setId ? { ...s, [field]: value } : s ); setEditingSession({ ...editingSession, sets: updatedSets }); }; const handleDeleteSet = (setId: string) => { if (!editingSession) return; setEditingSession({ ...editingSession, sets: editingSession.sets.filter(s => s.id !== setId) }); }; const handleConfirmDelete = () => { if (deletingId && onDeleteSession) { onDeleteSession(deletingId); setDeletingId(null); } } const handleSaveSporadicEdit = () => { if (editingSporadicSet && onUpdateSporadicSet) { onUpdateSporadicSet(editingSporadicSet); setEditingSporadicSet(null); } }; const handleUpdateSporadicField = (field: keyof SporadicSet, value: number) => { if (!editingSporadicSet) return; setEditingSporadicSet({ ...editingSporadicSet, [field]: value }); }; const handleConfirmDeleteSporadic = () => { if (deletingSporadicId && onDeleteSporadicSet) { onDeleteSporadicSet(deletingSporadicId); setDeletingSporadicId(null); } }; if (sessions.length === 0 && (!sporadicSets || sporadicSets.length === 0)) { return (

{t('history_empty', lang)}

); } return (

{t('tab_history', lang)}

{sessions.map((session) => { const totalWork = calculateSessionWork(session); return (
setEditingSession(JSON.parse(JSON.stringify(session)))} >
{new Date(session.startTime).toISOString().split('T')[0]} {new Date(session.startTime).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })} {session.endTime && ( {formatDuration(session.startTime, session.endTime)} )} {session.planName || t('no_plan', lang)} {session.userBodyWeight && ( {session.userBodyWeight}kg )}
{t('sets_count', lang)}: {session.sets.length} {totalWork > 0 && ( {(totalWork / 1000).toFixed(1)}t )}
) })} {/* Sporadic Sets Section */} {sporadicSets && sporadicSets.length > 0 && (

{t('sporadic_sets_title', lang)}

{Object.entries( sporadicSets.reduce((groups: Record, set) => { const date = new Date(set.timestamp).toISOString().split('T')[0]; if (!groups[date]) groups[date] = []; groups[date].push(set); return groups; }, {}) ) .sort(([a], [b]) => b.localeCompare(a)) .map(([date, sets]) => (
{date}
{(sets as SporadicSet[]).map(set => (
{set.exerciseName}
{set.type === ExerciseType.STRENGTH && `${set.weight || 0}kg x ${set.reps || 0}`} {set.type === ExerciseType.BODYWEIGHT && `${set.weight ? `+${set.weight}kg` : 'BW'} x ${set.reps || 0}`} {set.type === ExerciseType.CARDIO && `${set.durationSeconds || 0}s ${set.distanceMeters ? `/ ${set.distanceMeters}m` : ''}`} {set.type === ExerciseType.STATIC && `${set.durationSeconds || 0}s`} {set.type === ExerciseType.HIGH_JUMP && `${set.height || 0}cm`} {set.type === ExerciseType.LONG_JUMP && `${set.distanceMeters || 0}m`} {set.type === ExerciseType.PLYOMETRIC && `x ${set.reps || 0}`}
{new Date(set.timestamp).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}
))}
))}
)}
{/* DELETE CONFIRMATION DIALOG (MD3) */} {deletingId && (

{t('delete_workout', lang)}

{t('delete_confirm', lang)}

)} {/* EDIT SESSION FULLSCREEN DIALOG */} {editingSession && (

{t('edit', lang)}

{/* Meta Info */}
setEditingSession({ ...editingSession, startTime: parseDateFromInput(e.target.value) })} className="w-full bg-transparent text-on-surface focus:outline-none text-sm mt-1" />
setEditingSession({ ...editingSession, endTime: parseDateFromInput(e.target.value) })} className="w-full bg-transparent text-on-surface focus:outline-none text-sm mt-1" />
setEditingSession({ ...editingSession, userBodyWeight: parseFloat(e.target.value) })} className="w-full bg-transparent text-on-surface focus:outline-none text-lg mt-1" />

{t('sets_count', lang)} ({editingSession.sets.length})

{editingSession.sets.map((set, idx) => (
{idx + 1} {set.exerciseName}
{(set.type === ExerciseType.STRENGTH || set.type === ExerciseType.BODYWEIGHT || set.type === ExerciseType.STATIC) && (
handleUpdateSet(set.id, 'weight', parseFloat(e.target.value))} />
)} {(set.type === ExerciseType.STRENGTH || set.type === ExerciseType.BODYWEIGHT || set.type === ExerciseType.PLYOMETRIC) && (
handleUpdateSet(set.id, 'reps', parseInt(e.target.value))} />
)} {(set.type === ExerciseType.BODYWEIGHT || set.type === ExerciseType.STATIC) && (
handleUpdateSet(set.id, 'bodyWeightPercentage', parseFloat(e.target.value))} />
)} {(set.type === ExerciseType.CARDIO || set.type === ExerciseType.STATIC) && (
handleUpdateSet(set.id, 'durationSeconds', parseFloat(e.target.value))} />
)} {(set.type === ExerciseType.CARDIO || set.type === ExerciseType.LONG_JUMP) && (
handleUpdateSet(set.id, 'distanceMeters', parseFloat(e.target.value))} />
)} {(set.type === ExerciseType.HIGH_JUMP) && (
handleUpdateSet(set.id, 'height', parseFloat(e.target.value))} />
)}
))}
)} {/* Sporadic Set Delete Confirmation */} {deletingSporadicId && (

{t('delete', lang)}

{t('delete_confirm', lang)}

)}
); }; export default History;