From 00d4a3cc073db64d0c9604552b2d56014711b0a4 Mon Sep 17 00:00:00 2001 From: bender Date: Wed, 11 Mar 2026 19:33:41 +0000 Subject: [PATCH] Update src/lib/storage/workoutStorage.ts --- src/lib/storage/workoutStorage.ts | 313 +++++------------------------- 1 file changed, 46 insertions(+), 267 deletions(-) diff --git a/src/lib/storage/workoutStorage.ts b/src/lib/storage/workoutStorage.ts index 4286eee..d521603 100644 --- a/src/lib/storage/workoutStorage.ts +++ b/src/lib/storage/workoutStorage.ts @@ -1,285 +1,64 @@ -// User data persistence layer for workouts and metrics +'use client'; + +export interface ExerciseLog { + id: string; + name: string; + sets: number; + reps: number; + weight?: number; +} export interface WorkoutSession { id: string; date: string; type: 'cardio' | 'training' | 'nutrition'; - duration?: number; distance?: number; - calories?: number; + duration: number; pace?: string; + calories?: number; steps?: number; exercises?: ExerciseLog[]; - meals?: MealLog[]; + meals?: Array<{ + id: string; + name: string; + calories: number; + protein: number; + carbs: number; + fats: number; + timestamp: string; + }>; notes?: string; } -export interface ExerciseLog { - id: string; - name: string; - muscleGroup: string; - sets: SetLog[]; - totalVolume?: number; -} +const STORAGE_KEY = 'workout_sessions'; -export interface SetLog { - reps: number; - weight: number; - restTime?: number; -} +export const workoutStorage = { + getSessions: (): WorkoutSession[] => { + if (typeof window === 'undefined') return []; + const stored = localStorage.getItem(STORAGE_KEY); + return stored ? JSON.parse(stored) : []; + }, -export interface MealLog { - id: string; - name: string; - calories: number; - protein: number; - carbs: number; - fats: number; - timestamp: string; -} - -export interface UserMetrics { - totalSteps: number; - totalDistance: number; - totalCalories: number; - totalVolume: number; - workoutStreak: number; - lastWorkoutDate?: string; - personalRecords: Record; -} - -const STORAGE_KEY = 'fitflow_workouts'; -const METRICS_KEY = 'fitflow_metrics'; - -// Workout Session Management -export const saveWorkoutSession = (session: WorkoutSession): boolean => { - try { - const existing = getWorkoutSessions(); - const updated = [...existing, { ...session, id: session.id || Date.now().toString() }]; - localStorage.setItem(STORAGE_KEY, JSON.stringify(updated)); - return true; - } catch (error) { - console.error('Error saving workout session:', error); - return false; - } -}; - -export const getWorkoutSessions = (): WorkoutSession[] => { - try { - const data = localStorage.getItem(STORAGE_KEY); - return data ? JSON.parse(data) : []; - } catch (error) { - console.error('Error retrieving workout sessions:', error); - return []; - } -}; - -export const getWorkoutById = (id: string): WorkoutSession | null => { - try { - const sessions = getWorkoutSessions(); - return sessions.find(s => s.id === id) || null; - } catch (error) { - console.error('Error retrieving workout by id:', error); - return null; - } -}; - -export const updateWorkoutSession = (id: string, updates: Partial): boolean => { - try { - const sessions = getWorkoutSessions(); - const index = sessions.findIndex(s => s.id === id); - if (index === -1) return false; - sessions[index] = { ...sessions[index], ...updates, id }; - localStorage.setItem(STORAGE_KEY, JSON.stringify(sessions)); - return true; - } catch (error) { - console.error('Error updating workout session:', error); - return false; - } -}; - -export const deleteWorkoutSession = (id: string): boolean => { - try { - const sessions = getWorkoutSessions(); - const filtered = sessions.filter(s => s.id !== id); - localStorage.setItem(STORAGE_KEY, JSON.stringify(filtered)); - return true; - } catch (error) { - console.error('Error deleting workout session:', error); - return false; - } -}; - -export const getWorkoutsByType = (type: 'cardio' | 'training' | 'nutrition'): WorkoutSession[] => { - try { - const sessions = getWorkoutSessions(); - return sessions.filter(s => s.type === type); - } catch (error) { - console.error('Error filtering workouts by type:', error); - return []; - } -}; - -export const getWorkoutsByDateRange = (startDate: string, endDate: string): WorkoutSession[] => { - try { - const sessions = getWorkoutSessions(); - return sessions.filter(s => { - const sessionDate = new Date(s.date); - return sessionDate >= new Date(startDate) && sessionDate <= new Date(endDate); - }); - } catch (error) { - console.error('Error filtering workouts by date range:', error); - return []; - } -}; - -// Metrics Management -export const saveUserMetrics = (metrics: UserMetrics): boolean => { - try { - localStorage.setItem(METRICS_KEY, JSON.stringify(metrics)); - return true; - } catch (error) { - console.error('Error saving user metrics:', error); - return false; - } -}; - -export const getUserMetrics = (): UserMetrics => { - try { - const data = localStorage.getItem(METRICS_KEY); - return data ? JSON.parse(data) : getDefaultMetrics(); - } catch (error) { - console.error('Error retrieving user metrics:', error); - return getDefaultMetrics(); - } -}; - -export const updateUserMetrics = (updates: Partial): boolean => { - try { - const current = getUserMetrics(); - const updated = { ...current, ...updates }; - return saveUserMetrics(updated); - } catch (error) { - console.error('Error updating user metrics:', error); - return false; - } -}; - -export const calculateMetricsFromSessions = (): UserMetrics => { - try { - const sessions = getWorkoutSessions(); - let totalSteps = 0; - let totalDistance = 0; - let totalCalories = 0; - let totalVolume = 0; - const personalRecords: Record = {}; - - sessions.forEach(session => { - if (session.steps) totalSteps += session.steps; - if (session.distance) totalDistance += session.distance; - if (session.calories) totalCalories += session.calories; - if (session.exercises) { - session.exercises.forEach(ex => { - ex.sets.forEach(set => { - totalVolume += set.weight * set.reps; - const key = ex.name; - if (!personalRecords[key] || set.weight > personalRecords[key]) { - personalRecords[key] = set.weight; - } - }); - }); - } - }); - - const metrics: UserMetrics = { - totalSteps, - totalDistance, - totalCalories, - totalVolume, - workoutStreak: calculateWorkoutStreak(sessions), - lastWorkoutDate: sessions.length > 0 ? sessions[sessions.length - 1].date : undefined, - personalRecords + addSession: (session: Omit): WorkoutSession => { + const sessions = workoutStorage.getSessions(); + const newSession: WorkoutSession = { + ...session, + id: `session-${Date.now()}`, }; - - return metrics; - } catch (error) { - console.error('Error calculating metrics:', error); - return getDefaultMetrics(); - } -}; - -export const calculateWorkoutStreak = (sessions: WorkoutSession[]): number => { - if (sessions.length === 0) return 0; - - const sortedSessions = [...sessions].sort((a, b) => - new Date(b.date).getTime() - new Date(a.date).getTime() - ); - - let streak = 0; - let currentDate = new Date(); - currentDate.setHours(0, 0, 0, 0); - - for (const session of sortedSessions) { - const sessionDate = new Date(session.date); - sessionDate.setHours(0, 0, 0, 0); - - const dayDiff = Math.floor((currentDate.getTime() - sessionDate.getTime()) / (1000 * 60 * 60 * 24)); - - if (dayDiff === streak) { - streak++; - } else { - break; + sessions.push(newSession); + if (typeof window !== 'undefined') { + localStorage.setItem(STORAGE_KEY, JSON.stringify(sessions)); } - } + return newSession; + }, - return streak; -}; - -const getDefaultMetrics = (): UserMetrics => ({ - totalSteps: 0, - totalDistance: 0, - totalCalories: 0, - totalVolume: 0, - workoutStreak: 0, - personalRecords: {} -}); - -// Bulk operations -export const exportWorkoutData = (): string => { - try { - const sessions = getWorkoutSessions(); - const metrics = getUserMetrics(); - const data = { sessions, metrics, exportDate: new Date().toISOString() }; - return JSON.stringify(data, null, 2); - } catch (error) { - console.error('Error exporting data:', error); - return ''; - } -}; - -export const importWorkoutData = (jsonData: string): boolean => { - try { - const data = JSON.parse(jsonData); - if (data.sessions) { - localStorage.setItem(STORAGE_KEY, JSON.stringify(data.sessions)); - } - if (data.metrics) { - localStorage.setItem(METRICS_KEY, JSON.stringify(data.metrics)); - } - return true; - } catch (error) { - console.error('Error importing data:', error); - return false; - } -}; - -export const clearAllData = (): boolean => { - try { - localStorage.removeItem(STORAGE_KEY); - localStorage.removeItem(METRICS_KEY); - return true; - } catch (error) { - console.error('Error clearing data:', error); - return false; - } + getSessionsByDate: (date: string): WorkoutSession[] => { + const sessions = workoutStorage.getSessions(); + return sessions.filter((s) => s.date.startsWith(date)); + }, + + getTodaysSessions: (): WorkoutSession[] => { + const currentDate = new Date().toISOString().split('T')[0]; + return workoutStorage.getSessionsByDate(currentDate); + }, };