diff --git a/App.tsx b/App.tsx index aed79ae..b022053 100644 --- a/App.tsx +++ b/App.tsx @@ -73,12 +73,13 @@ function App() { setCurrentUser(updatedUser); }; - const handleStartSession = (plan?: WorkoutPlan) => { + const handleStartSession = (plan?: WorkoutPlan, startWeight?: number) => { if (!currentUser) return; // Get latest weight from profile or default const profile = getCurrentUserProfile(currentUser.id); - const currentWeight = profile?.weight || 70; + // Use provided startWeight, or profile weight, or default 70 + const currentWeight = startWeight || profile?.weight || 70; const newSession: WorkoutSession = { id: crypto.randomUUID(), @@ -155,6 +156,7 @@ function App() { {currentTab === 'TRACK' && ( void; + onSessionStart: (plan?: WorkoutPlan, startWeight?: number) => void; onSessionEnd: () => void; onSetAdded: (set: WorkoutSet) => void; onRemoveSet: (setId: string) => void; lang: Language; } -const Tracker: React.FC = ({ userId, activeSession, activePlan, onSessionStart, onSessionEnd, onSetAdded, onRemoveSet, lang }) => { +const Tracker: React.FC = ({ userId, userWeight, activeSession, activePlan, onSessionStart, onSessionEnd, onSetAdded, onRemoveSet, lang }) => { const [exercises, setExercises] = useState([]); const [plans, setPlans] = useState([]); const [selectedExercise, setSelectedExercise] = useState(null); @@ -35,7 +36,7 @@ const Tracker: React.FC = ({ userId, activeSession, activePlan, on const [bwPercentage, setBwPercentage] = useState('100'); // User Weight State - const [userBodyWeight, setUserBodyWeight] = useState('70'); + const [userBodyWeight, setUserBodyWeight] = useState(userWeight ? userWeight.toString() : '70'); // Create Exercise State const [isCreating, setIsCreating] = useState(false); @@ -57,17 +58,12 @@ const Tracker: React.FC = ({ userId, activeSession, activePlan, on if (activeSession?.userBodyWeight) { setUserBodyWeight(activeSession.userBodyWeight.toString()); - } else { - // Profile fetch needs to be async too if we updated it, - // but for now let's assume we can get it or it's passed. - // Actually getCurrentUserProfile returns undefined now. - // We should probably fetch it properly. - // For now, default to 70. - setUserBodyWeight('70'); + } else if (userWeight) { + setUserBodyWeight(userWeight.toString()); } }; loadData(); - }, [activeSession, userId]); + }, [activeSession, userId, userWeight]); // Timer Logic useEffect(() => { @@ -128,7 +124,7 @@ const Tracker: React.FC = ({ userId, activeSession, activePlan, on if (plan && plan.description) { setShowPlanPrep(plan); } else { - onSessionStart(plan); + onSessionStart(plan, parseFloat(userBodyWeight)); } }; @@ -358,10 +354,10 @@ const Tracker: React.FC = ({ userId, activeSession, activePlan, on key={step.id} onClick={() => jumpToStep(idx)} className={`w-full text-left px-4 py-3 rounded-full text-sm flex items-center justify-between transition-colors ${idx === currentStepIndex - ? 'bg-primary-container text-on-primary-container font-medium' - : idx < currentStepIndex - ? 'text-on-surface-variant opacity-50' - : 'text-on-surface hover:bg-white/5' + ? 'bg-primary-container text-on-primary-container font-medium' + : idx < currentStepIndex + ? 'text-on-surface-variant opacity-50' + : 'text-on-surface hover:bg-white/5' }`} > {idx + 1}. {step.exerciseName} @@ -556,8 +552,8 @@ const Tracker: React.FC = ({ userId, activeSession, activePlan, on key={type.id} onClick={() => setNewType(type.id)} className={`px-4 py-2 rounded-lg flex items-center gap-2 text-xs font-medium border transition-all ${newType === type.id - ? 'bg-secondary-container text-on-secondary-container border-transparent' - : 'bg-transparent text-on-surface-variant border-outline hover:border-on-surface-variant' + ? 'bg-secondary-container text-on-secondary-container border-transparent' + : 'bg-transparent text-on-surface-variant border-outline hover:border-on-surface-variant' }`} > {type.label} diff --git a/server/prisma/dev.db b/server/prisma/dev.db index bfbc96e..7037aa4 100644 Binary files a/server/prisma/dev.db and b/server/prisma/dev.db differ diff --git a/server/src/routes/sessions.ts b/server/src/routes/sessions.ts index 9e8f94f..8e7e023 100644 --- a/server/src/routes/sessions.ts +++ b/server/src/routes/sessions.ts @@ -42,6 +42,11 @@ router.post('/', async (req: any, res) => { const userId = req.user.userId; const { id, startTime, endTime, userBodyWeight, note, sets } = req.body; + // Convert timestamps to Date objects if they are numbers + const start = new Date(startTime); + const end = endTime ? new Date(endTime) : null; + const weight = userBodyWeight ? parseFloat(userBodyWeight) : null; + // Check if session exists const existing = await prisma.workoutSession.findUnique({ where: { id } }); @@ -53,9 +58,9 @@ router.post('/', async (req: any, res) => { const updated = await prisma.workoutSession.update({ where: { id }, data: { - startTime, - endTime, - userBodyWeight, + startTime: start, + endTime: end, + userBodyWeight: weight, note, sets: { create: sets.map((s: any, idx: number) => ({ @@ -65,7 +70,7 @@ router.post('/', async (req: any, res) => { reps: s.reps, distanceMeters: s.distanceMeters, durationSeconds: s.durationSeconds, - completed: s.completed + completed: s.completed !== undefined ? s.completed : true })) } }, @@ -78,9 +83,9 @@ router.post('/', async (req: any, res) => { data: { id, // Use provided ID or let DB gen? Frontend usually generates UUIDs. userId, - startTime, - endTime, - userBodyWeight, + startTime: start, + endTime: end, + userBodyWeight: weight, note, sets: { create: sets.map((s: any, idx: number) => ({ @@ -90,7 +95,7 @@ router.post('/', async (req: any, res) => { reps: s.reps, distanceMeters: s.distanceMeters, durationSeconds: s.durationSeconds, - completed: s.completed + completed: s.completed !== undefined ? s.completed : true })) } },