ui/src/services/api.ts (view raw)
1import type {
2 Exercise,
3 Routine,
4 RecordRoutine,
5 User,
6 Equipment,
7 MuscleGroup,
8 Set,
9 SuperSet,
10 RecordExercise,
11 WorkoutStats
12} from '../types/models';
13
14// Base API URL - should be configurable via environment variables in a real app
15const API_BASE_URL = '/api';
16
17// Generic fetch with error handling
18async function fetchApi<T>(
19 endpoint: string,
20 options: RequestInit = {}
21): Promise<T> {
22 const url = `${API_BASE_URL}${endpoint}`;
23
24 const response = await fetch(url, {
25 headers: {
26 'Content-Type': 'application/json',
27 ...options.headers,
28 },
29 ...options,
30 });
31
32 if (!response.ok) {
33 const error = await response.text();
34 throw new Error(error || `API request failed with status ${response.status}`);
35 }
36
37 return response.json();
38}
39
40// Equipment API services
41export const EquipmentService = {
42 getAll: () => fetchApi<Equipment[]>('/equipment'),
43
44 getById: (id: number) => fetchApi<Equipment>(`/equipment/${id}`),
45
46 create: (equipment: Equipment) => fetchApi<Equipment>('/equipment', {
47 method: 'POST',
48 body: JSON.stringify(equipment),
49 }),
50
51 update: (id: number, equipment: Equipment) => fetchApi<Equipment>(`/equipment/${id}`, {
52 method: 'PUT',
53 body: JSON.stringify(equipment),
54 }),
55
56 delete: (id: number) => fetchApi<void>(`/equipment/${id}`, {
57 method: 'DELETE',
58 }),
59};
60
61// MuscleGroup API services
62export const MuscleGroupService = {
63 getAll: () => fetchApi<MuscleGroup[]>('/musclegroups'),
64
65 getById: (id: number) => fetchApi<MuscleGroup>(`/musclegroups/${id}`),
66
67 create: (muscleGroup: MuscleGroup) => fetchApi<MuscleGroup>('/musclegroups', {
68 method: 'POST',
69 body: JSON.stringify(muscleGroup),
70 }),
71
72 update: (id: number, muscleGroup: MuscleGroup) => fetchApi<MuscleGroup>(`/musclegroups/${id}`, {
73 method: 'PUT',
74 body: JSON.stringify(muscleGroup),
75 }),
76
77 delete: (id: number) => fetchApi<void>(`/musclegroups/${id}`, {
78 method: 'DELETE',
79 }),
80};
81
82// Exercise API services
83export const ExerciseService = {
84 getAll: () => fetchApi<Exercise[]>('/exercises'),
85
86 getById: (id: number) => fetchApi<Exercise>(`/exercises/${id}`),
87
88 create: (exercise: Exercise) => fetchApi<Exercise>('/exercises', {
89 method: 'POST',
90 body: JSON.stringify(exercise),
91 }),
92
93 update: (id: number, exercise: Exercise) => fetchApi<Exercise>(`/exercises/${id}`, {
94 method: 'PUT',
95 body: JSON.stringify(exercise),
96 }),
97
98 delete: (id: number) => fetchApi<void>(`/exercises/${id}`, {
99 method: 'DELETE',
100 }),
101};
102
103// Set API services
104export const SetService = {
105 getAll: (exerciseId: number) => fetchApi<Set[]>(`/exercises/${exerciseId}/sets`),
106
107 getById: (id: number) => fetchApi<Set>(`/sets/${id}`),
108
109 create: (set: Set) => fetchApi<Set>('/sets', {
110 method: 'POST',
111 body: JSON.stringify(set),
112 }),
113
114 update: (id: number, set: Set) => fetchApi<Set>(`/sets/${id}`, {
115 method: 'PUT',
116 body: JSON.stringify(set),
117 }),
118
119 delete: (id: number) => fetchApi<void>(`/sets/${id}`, {
120 method: 'DELETE',
121 }),
122};
123
124// SuperSet API services
125export const SuperSetService = {
126 getAll: () => fetchApi<SuperSet[]>('/supersets'),
127
128 getById: (id: number) => fetchApi<SuperSet>(`/supersets/${id}`),
129
130 create: (superSet: SuperSet) => fetchApi<SuperSet>('/supersets', {
131 method: 'POST',
132 body: JSON.stringify(superSet),
133 }),
134
135 update: (id: number, superSet: SuperSet) => fetchApi<SuperSet>(`/supersets/${id}`, {
136 method: 'PUT',
137 body: JSON.stringify(superSet),
138 }),
139
140 delete: (id: number) => fetchApi<void>(`/supersets/${id}`, {
141 method: 'DELETE',
142 }),
143};
144
145// Routine API services
146export const RoutineService = {
147 getAll: () => fetchApi<Routine[]>('/routines'),
148
149 getById: (id: number) => fetchApi<Routine>(`/routines/${id}`),
150
151 create: (routine: Routine) => fetchApi<Routine>('/routines', {
152 method: 'POST',
153 body: JSON.stringify(routine),
154 }),
155
156 update: (id: number, routine: Routine) => fetchApi<Routine>(`/routines/${id}`, {
157 method: 'PUT',
158 body: JSON.stringify(routine),
159 }),
160
161 delete: (id: number) => fetchApi<void>(`/routines/${id}`, {
162 method: 'DELETE',
163 }),
164};
165
166// RecordRoutine (Workout) API services
167export const WorkoutService = {
168 getAll: () => fetchApi<RecordRoutine[]>('/recordroutines'),
169
170 getById: (id: number) => fetchApi<RecordRoutine>(`/recordroutines/${id}`),
171
172 create: (workout: RecordRoutine) => fetchApi<RecordRoutine>('/recordroutines', {
173 method: 'POST',
174 body: JSON.stringify(workout),
175 }),
176
177 update: (id: number, workout: RecordRoutine) => fetchApi<RecordRoutine>(`/recordroutines/${id}`, {
178 method: 'PUT',
179 body: JSON.stringify(workout),
180 }),
181
182 delete: (id: number) => fetchApi<void>(`/recordroutines/${id}`, {
183 method: 'DELETE',
184 }),
185
186 // Additional method to get workout statistics for the home page
187 getStats: () => fetchApi<WorkoutStats>('/stats'),
188};
189
190// RecordExercise API services
191export const RecordExerciseService = {
192 getAll: (recordRoutineId: number) => fetchApi<RecordExercise[]>(`/recordroutines/${recordRoutineId}/exercises`),
193
194 getById: (id: number) => fetchApi<RecordExercise>(`/recordexercises/${id}`),
195
196 create: (recordExercise: RecordExercise) => fetchApi<RecordExercise>('/recordexercises', {
197 method: 'POST',
198 body: JSON.stringify(recordExercise),
199 }),
200
201 update: (id: number, recordExercise: RecordExercise) => fetchApi<RecordExercise>(`/recordexercises/${id}`, {
202 method: 'PUT',
203 body: JSON.stringify(recordExercise),
204 }),
205
206 delete: (id: number) => fetchApi<void>(`/recordexercises/${id}`, {
207 method: 'DELETE',
208 }),
209};
210
211// User profile service
212export const ProfileService = {
213 get: async () => {
214 const user = await fetchApi<User>('/users/1');
215 user.birthDate = new Date(user.birthDate).toISOString();
216 return user;
217 },
218
219 update: async (profile: User) => {
220 profile.birthDate = new Date(profile.birthDate).toISOString();
221 profile.isFemale = profile.isFemale === 'true';
222 profile.weight = +profile.weight;
223 profile.height = +profile.height;
224
225 return await fetchApi<User>('/users/1', {
226 method: 'PUT',
227 body: JSON.stringify(profile),
228 })},
229};