import React, { useState, useEffect } from 'react'; import Navbar from './components/Navbar'; import Tracker from './components/Tracker/index'; import History from './components/History'; import Stats from './components/Stats'; import AICoach from './components/AICoach'; import Plans from './components/Plans'; import Login from './components/Login'; import Profile from './components/Profile'; import { TabView, WorkoutSession, WorkoutSet, WorkoutPlan, User, Language, SporadicSet } from './types'; import { getSessions, saveSession, deleteSession, getPlans, getActiveSession, updateActiveSession, deleteActiveSession, updateSetInActiveSession, deleteSetFromActiveSession } from './services/storage'; import { getSporadicSets, updateSporadicSet, deleteSporadicSet } from './services/sporadicSets'; import { getCurrentUserProfile, getMe } from './services/auth'; import { getSystemLanguage } from './services/i18n'; import { logWeight } from './services/weight'; import { generateId } from './utils/uuid'; function App() { const [currentUser, setCurrentUser] = useState(null); const [currentTab, setCurrentTab] = useState('TRACK'); const [language, setLanguage] = useState('en'); const [sessions, setSessions] = useState([]); const [plans, setPlans] = useState([]); const [activeSession, setActiveSession] = useState(null); const [activePlan, setActivePlan] = useState(null); const [sporadicSets, setSporadicSets] = useState([]); useEffect(() => { // Set initial language setLanguage(getSystemLanguage()); // Restore session const restoreSession = async () => { const token = localStorage.getItem('token'); if (token) { const res = await getMe(); if (res.success && res.user) { setCurrentUser(res.user); // Restore active workout session from database const activeSession = await getActiveSession(res.user.id); if (activeSession) { setActiveSession(activeSession); // Restore plan if session has planId if (activeSession.planId) { const plans = await getPlans(res.user.id); const plan = plans.find(p => p.id === activeSession.planId); if (plan) { setActivePlan(plan); } } } } else { localStorage.removeItem('token'); } } }; restoreSession(); }, []); useEffect(() => { const loadSessions = async () => { if (currentUser) { const s = await getSessions(currentUser.id); setSessions(s); // Load plans const p = await getPlans(currentUser.id); setPlans(p); // Load sporadic sets const sporadicSets = await getSporadicSets(); setSporadicSets(sporadicSets); } else { setSessions([]); setPlans([]); setSporadicSets([]); } }; loadSessions(); }, [currentUser]); const handleLogin = (user: User) => { setCurrentUser(user); setCurrentTab('TRACK'); }; const handleLogout = () => { localStorage.removeItem('token'); setCurrentUser(null); setActiveSession(null); setActivePlan(null); }; const handleLanguageChange = (lang: Language) => { setLanguage(lang); }; const handleUserUpdate = (updatedUser: User) => { setCurrentUser(updatedUser); }; const handleStartSession = async (plan?: WorkoutPlan, startWeight?: number) => { if (!currentUser) return; if (activeSession) return; // Get latest weight from profile or default const profile = getCurrentUserProfile(currentUser.id); // Use provided startWeight, or profile weight, or default 70 const currentWeight = startWeight || profile?.weight || 70; const newSession: WorkoutSession = { id: generateId(), startTime: Date.now(), userBodyWeight: currentWeight, sets: [], planId: plan?.id, planName: plan?.name }; setActivePlan(plan || null); setActiveSession(newSession); setCurrentTab('TRACK'); // Save to database immediately await saveSession(currentUser.id, newSession); // If startWeight was provided (meaning user explicitly entered it), log it to weight history if (startWeight) { await logWeight(startWeight); } }; const handleEndSession = async () => { if (activeSession && currentUser) { const finishedSession = { ...activeSession, endTime: Date.now() }; await updateActiveSession(currentUser.id, finishedSession); setSessions(prev => [finishedSession, ...prev]); setActiveSession(null); setActivePlan(null); // Refetch user to get updated weight const res = await getMe(); if (res.success && res.user) { setCurrentUser(res.user); } } }; const handleAddSet = (set: WorkoutSet) => { if (activeSession && currentUser) { const updatedSession = { ...activeSession, sets: [...activeSession.sets, set] }; setActiveSession(updatedSession); } }; const handleRemoveSetFromActive = async (setId: string) => { if (activeSession && currentUser) { await deleteSetFromActiveSession(currentUser.id, setId); const updatedSession = { ...activeSession, sets: activeSession.sets.filter(s => s.id !== setId) }; setActiveSession(updatedSession); } }; const handleUpdateSetInActive = async (updatedSet: WorkoutSet) => { if (activeSession && currentUser) { const response = await updateSetInActiveSession(currentUser.id, updatedSet.id, updatedSet); const updatedSession = { ...activeSession, sets: activeSession.sets.map(s => s.id === updatedSet.id ? response : s) }; setActiveSession(updatedSession); } }; const handleQuitSession = async () => { if (currentUser) { await deleteActiveSession(currentUser.id); setActiveSession(null); setActivePlan(null); } }; const handleUpdateSession = (updatedSession: WorkoutSession) => { if (!currentUser) return; saveSession(currentUser.id, updatedSession); setSessions(prev => prev.map(s => s.id === updatedSession.id ? updatedSession : s)); }; const handleDeleteSession = (sessionId: string) => { if (!currentUser) return; deleteSession(currentUser.id, sessionId); setSessions(prev => prev.filter(s => s.id !== sessionId)); }; const handleSporadicSetAdded = async () => { const sets = await getSporadicSets(); setSporadicSets(sets); }; const handleUpdateSporadicSet = async (set: SporadicSet) => { const updated = await updateSporadicSet(set.id, set); if (updated) { setSporadicSets(prev => prev.map(s => s.id === set.id ? updated : s)); } }; const handleDeleteSporadicSet = async (id: string) => { const success = await deleteSporadicSet(id); if (success) { setSporadicSets(prev => prev.filter(s => s.id !== id)); } }; if (!currentUser) { return ; } return (
{/* Desktop Navigation Rail (Left) */} {/* Main Content Area */}
{currentTab === 'TRACK' && ( )} {currentTab === 'PLANS' && ( )} {currentTab === 'HISTORY' && ( )} {currentTab === 'STATS' && } {currentTab === 'AI_COACH' && } {currentTab === 'PROFILE' && ( )}
{/* Mobile Navigation (rendered inside Navbar component, fixed to bottom) */}
); } export default App;