Massive backend refactoring done
This commit is contained in:
@@ -85,9 +85,9 @@ export const useTracker = (props: any) => { // Props ignored/removed
|
||||
// Function to reload Quick Log session
|
||||
const loadQuickLogSession = async () => {
|
||||
try {
|
||||
const response = await api.get<{ success: boolean; session?: WorkoutSession }>('/sessions/quick-log');
|
||||
if (response.success && response.session) {
|
||||
setQuickLogSession(response.session);
|
||||
const response = await api.get<any>('/sessions/quick-log');
|
||||
if (response.success && response.data?.session) {
|
||||
setQuickLogSession(response.data.session);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to load quick log session:", error);
|
||||
|
||||
@@ -142,7 +142,7 @@ export const ActiveWorkoutProvider: React.FC<{ children: React.ReactNode }> = ({
|
||||
// or similar. I need to type the response properly or cast it.
|
||||
// Assuming response.newSet needs to be added.
|
||||
|
||||
if (response.success && response.newSet) {
|
||||
if (response && response.newSet) {
|
||||
setActiveSession(prev => prev ? ({
|
||||
...prev,
|
||||
sets: [...prev.sets, response.newSet]
|
||||
|
||||
@@ -1,21 +1,35 @@
|
||||
import { User, UserRole, UserProfile } from '../types';
|
||||
import { api, setAuthToken, removeAuthToken } from './api';
|
||||
|
||||
interface ApiResponse<T> {
|
||||
success: boolean;
|
||||
data: T;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export const getUsers = async (): Promise<{ success: boolean; users?: User[]; error?: string }> => {
|
||||
try {
|
||||
const res = await api.get('/auth/users');
|
||||
return res;
|
||||
} catch (e) {
|
||||
return { success: false, error: 'Failed to fetch users' };
|
||||
const res = await api.get<ApiResponse<{ users: User[] }>>('/auth/users');
|
||||
if (res.success && res.data) {
|
||||
return { success: true, users: res.data.users };
|
||||
}
|
||||
return { success: false, error: res.error };
|
||||
} catch (e: any) {
|
||||
try {
|
||||
const err = JSON.parse(e.message);
|
||||
return { success: false, error: err.error || 'Failed to fetch users' };
|
||||
} catch {
|
||||
return { success: false, error: 'Failed to fetch users' };
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const login = async (email: string, password: string): Promise<{ success: boolean; user?: User; error?: string }> => {
|
||||
try {
|
||||
const res = await api.post('/auth/login', { email, password });
|
||||
if (res.success) {
|
||||
setAuthToken(res.token);
|
||||
return { success: true, user: res.user };
|
||||
const res = await api.post<ApiResponse<{ user: User, token: string }>>('/auth/login', { email, password });
|
||||
if (res.success && res.data) {
|
||||
setAuthToken(res.data.token);
|
||||
return { success: true, user: res.data.user };
|
||||
}
|
||||
return { success: false, error: res.error };
|
||||
} catch (e: any) {
|
||||
@@ -30,9 +44,9 @@ export const login = async (email: string, password: string): Promise<{ success:
|
||||
|
||||
export const createUser = async (email: string, password: string): Promise<{ success: boolean; error?: string }> => {
|
||||
try {
|
||||
const res = await api.post('/auth/register', { email, password });
|
||||
if (res.success) {
|
||||
setAuthToken(res.token);
|
||||
const res = await api.post<ApiResponse<{ user: User, token: string }>>('/auth/register', { email, password });
|
||||
if (res.success && res.data) {
|
||||
setAuthToken(res.data.token);
|
||||
return { success: true };
|
||||
}
|
||||
return { success: false, error: res.error };
|
||||
@@ -48,50 +62,74 @@ export const createUser = async (email: string, password: string): Promise<{ suc
|
||||
|
||||
export const deleteUser = async (userId: string) => {
|
||||
try {
|
||||
const res = await api.delete(`/auth/users/${userId}`);
|
||||
const res = await api.delete<ApiResponse<any>>(`/auth/users/${userId}`);
|
||||
return res;
|
||||
} catch (e) {
|
||||
return { success: false, error: 'Failed to delete user' };
|
||||
} catch (e: any) {
|
||||
try {
|
||||
const err = JSON.parse(e.message);
|
||||
return { success: false, error: err.error || 'Failed to delete user' };
|
||||
} catch {
|
||||
return { success: false, error: 'Failed to delete user' };
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const toggleBlockUser = async (userId: string, block: boolean) => {
|
||||
try {
|
||||
const res = await api.patch(`/auth/users/${userId}/block`, { block });
|
||||
const res = await api.patch<ApiResponse<any>>(`/auth/users/${userId}/block`, { block });
|
||||
return res;
|
||||
} catch (e) {
|
||||
return { success: false, error: 'Failed to update user status' };
|
||||
} catch (e: any) {
|
||||
try {
|
||||
const err = JSON.parse(e.message);
|
||||
return { success: false, error: err.error || 'Failed to update user status' };
|
||||
} catch {
|
||||
return { success: false, error: 'Failed to update user status' };
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const adminResetPassword = async (userId: string, newPass: string) => {
|
||||
try {
|
||||
const res = await api.post(`/auth/users/${userId}/reset-password`, { newPassword: newPass });
|
||||
const res = await api.post<ApiResponse<any>>(`/auth/users/${userId}/reset-password`, { newPassword: newPass });
|
||||
return res;
|
||||
} catch (e) {
|
||||
return { success: false, error: 'Failed to reset password' };
|
||||
} catch (e: any) {
|
||||
try {
|
||||
const err = JSON.parse(e.message);
|
||||
return { success: false, error: err.error || 'Failed to reset password' };
|
||||
} catch {
|
||||
return { success: false, error: 'Failed to reset password' };
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const updateUserProfile = async (userId: string, profile: Partial<UserProfile>): Promise<{ success: boolean; error?: string }> => {
|
||||
try {
|
||||
const res = await api.patch('/auth/profile', profile);
|
||||
const res = await api.patch<ApiResponse<any>>('/auth/profile', profile);
|
||||
return res;
|
||||
} catch (e) {
|
||||
return { success: false, error: 'Failed to update profile' };
|
||||
} catch (e: any) {
|
||||
try {
|
||||
const err = JSON.parse(e.message);
|
||||
return { success: false, error: err.error || 'Failed to update profile' };
|
||||
} catch {
|
||||
return { success: false, error: 'Failed to update profile' };
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const changePassword = async (userId: string, newPassword: string) => {
|
||||
try {
|
||||
const res = await api.post('/auth/change-password', { userId, newPassword });
|
||||
const res = await api.post<ApiResponse<any>>('/auth/change-password', { userId, newPassword });
|
||||
if (!res.success) {
|
||||
console.error('Failed to change password:', res.error);
|
||||
}
|
||||
return res;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
return { success: false, error: 'Network error' };
|
||||
} catch (e: any) {
|
||||
try {
|
||||
const err = JSON.parse(e.message);
|
||||
return { success: false, error: err.error || 'Network error' };
|
||||
} catch {
|
||||
return { success: false, error: 'Network error' };
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -103,9 +141,12 @@ export const getCurrentUserProfile = (userId: string): UserProfile | undefined =
|
||||
|
||||
export const getMe = async (): Promise<{ success: boolean; user?: User; error?: string }> => {
|
||||
try {
|
||||
const res = await api.get('/auth/me');
|
||||
return res;
|
||||
} catch (e) {
|
||||
const res = await api.get<ApiResponse<{ user: User }>>('/auth/me');
|
||||
if (res.success && res.data) {
|
||||
return { success: true, user: res.data.user };
|
||||
}
|
||||
return { success: false, error: res.error };
|
||||
} catch (e: any) {
|
||||
return { success: false, error: 'Failed to fetch user' };
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,23 +1,30 @@
|
||||
import { ExerciseDef, WorkoutSet } from '../types';
|
||||
import { api } from './api';
|
||||
|
||||
interface ApiResponse<T> {
|
||||
success: boolean;
|
||||
data: T;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export const getExercises = async (userId: string): Promise<ExerciseDef[]> => {
|
||||
try {
|
||||
return await api.get<ExerciseDef[]>('/exercises');
|
||||
const res = await api.get<ApiResponse<ExerciseDef[]>>('/exercises');
|
||||
return res.data || [];
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
export const saveExercise = async (userId: string, exercise: ExerciseDef): Promise<void> => {
|
||||
await api.post('/exercises', exercise);
|
||||
await api.post<ApiResponse<any>>('/exercises', exercise);
|
||||
};
|
||||
|
||||
export const getLastSetForExercise = async (userId: string, exerciseId: string): Promise<WorkoutSet | undefined> => {
|
||||
try {
|
||||
const response = await api.get<{ success: boolean; set?: WorkoutSet }>(`/exercises/${exerciseId}/last-set`);
|
||||
if (response.success && response.set) {
|
||||
return response.set;
|
||||
const response = await api.get<ApiResponse<{ set?: WorkoutSet }>>(`/exercises/${exerciseId}/last-set`);
|
||||
if (response.success && response.data?.set) {
|
||||
return response.data.set;
|
||||
}
|
||||
return undefined;
|
||||
} catch (error) {
|
||||
|
||||
@@ -2,6 +2,12 @@ import { WorkoutSession, UserProfile, WorkoutPlan } from '../types';
|
||||
import { api } from './api';
|
||||
import { generateId } from '../utils/uuid';
|
||||
|
||||
interface ApiResponse<T> {
|
||||
success: boolean;
|
||||
data: T;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
interface FitnessChatOptions {
|
||||
history: WorkoutSession[];
|
||||
userProfile?: UserProfile;
|
||||
@@ -111,15 +117,15 @@ export const createFitnessChat = (
|
||||
|
||||
return {
|
||||
sendMessage: async (userMessage: string) => {
|
||||
const res = await api.post('/ai/chat', {
|
||||
const res = await api.post<ApiResponse<{ response: string }>>('/ai/chat', {
|
||||
systemInstruction,
|
||||
userMessage,
|
||||
sessionId
|
||||
});
|
||||
return {
|
||||
text: res.response,
|
||||
text: res.data.response,
|
||||
response: {
|
||||
text: () => res.response
|
||||
text: () => res.data.response
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,18 +1,25 @@
|
||||
import { WorkoutPlan } from '../types';
|
||||
import { api } from './api';
|
||||
|
||||
interface ApiResponse<T> {
|
||||
success: boolean;
|
||||
data: T;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export const getPlans = async (userId: string): Promise<WorkoutPlan[]> => {
|
||||
try {
|
||||
return await api.get<WorkoutPlan[]>('/plans');
|
||||
const res = await api.get<ApiResponse<WorkoutPlan[]>>('/plans');
|
||||
return res.data || [];
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
export const savePlan = async (userId: string, plan: WorkoutPlan): Promise<void> => {
|
||||
await api.post('/plans', plan);
|
||||
await api.post<ApiResponse<any>>('/plans', plan);
|
||||
};
|
||||
|
||||
export const deletePlan = async (userId: string, id: string): Promise<void> => {
|
||||
await api.delete(`/plans/${id}`);
|
||||
await api.delete<ApiResponse<any>>(`/plans/${id}`);
|
||||
};
|
||||
|
||||
@@ -13,9 +13,16 @@ interface ApiSession extends Omit<WorkoutSession, 'startTime' | 'endTime' | 'set
|
||||
})[];
|
||||
}
|
||||
|
||||
interface ApiResponse<T> {
|
||||
success: boolean;
|
||||
data: T;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export const getSessions = async (userId: string): Promise<WorkoutSession[]> => {
|
||||
try {
|
||||
const sessions = await api.get<ApiSession[]>('/sessions');
|
||||
const response = await api.get<ApiResponse<ApiSession[]>>('/sessions');
|
||||
const sessions = response.data || [];
|
||||
// Convert ISO date strings to timestamps
|
||||
return sessions.map((session) => ({
|
||||
...session,
|
||||
@@ -33,16 +40,17 @@ export const getSessions = async (userId: string): Promise<WorkoutSession[]> =>
|
||||
};
|
||||
|
||||
export const saveSession = async (userId: string, session: WorkoutSession): Promise<void> => {
|
||||
await api.post('/sessions', session);
|
||||
await api.post<ApiResponse<any>>('/sessions', session);
|
||||
};
|
||||
|
||||
export const getActiveSession = async (userId: string): Promise<WorkoutSession | null> => {
|
||||
try {
|
||||
const response = await api.get<{ success: boolean; session?: ApiSession }>('/sessions/active');
|
||||
if (!response.success || !response.session) {
|
||||
const response = await api.get<ApiResponse<{ session: ApiSession | null }>>('/sessions/active');
|
||||
|
||||
if (!response.success || !response.data?.session) {
|
||||
return null;
|
||||
}
|
||||
const session = response.session;
|
||||
const session = response.data.session;
|
||||
// Convert ISO date strings to timestamps
|
||||
return {
|
||||
...session,
|
||||
@@ -60,29 +68,35 @@ export const getActiveSession = async (userId: string): Promise<WorkoutSession |
|
||||
};
|
||||
|
||||
export const updateActiveSession = async (userId: string, session: WorkoutSession): Promise<void> => {
|
||||
await api.put('/sessions/active', session);
|
||||
await api.put<ApiResponse<any>>('/sessions/active', session);
|
||||
};
|
||||
|
||||
export const deleteSetFromActiveSession = async (userId: string, setId: string): Promise<void> => {
|
||||
await api.delete(`/sessions/active/set/${setId}`);
|
||||
await api.delete<ApiResponse<any>>(`/sessions/active/set/${setId}`);
|
||||
};
|
||||
|
||||
export const updateSetInActiveSession = async (userId: string, setId: string, setData: Partial<WorkoutSet>): Promise<WorkoutSet> => {
|
||||
const response = await api.put<{ success: boolean; updatedSet: WorkoutSet }>(`/sessions/active/set/${setId}`, setData);
|
||||
return response.updatedSet;
|
||||
const response = await api.put<ApiResponse<{ updatedSet: ApiSession['sets'][0] }>>(`/sessions/active/set/${setId}`, setData);
|
||||
const updatedSet = response.data.updatedSet;
|
||||
return {
|
||||
...updatedSet,
|
||||
exerciseName: updatedSet.exercise?.name || 'Unknown',
|
||||
type: updatedSet.exercise?.type || ExerciseType.STRENGTH
|
||||
} as WorkoutSet;
|
||||
};
|
||||
|
||||
export const deleteActiveSession = async (userId: string): Promise<void> => {
|
||||
await api.delete('/sessions/active');
|
||||
await api.delete<ApiResponse<any>>('/sessions/active');
|
||||
};
|
||||
|
||||
export const deleteSession = async (userId: string, id: string): Promise<void> => {
|
||||
await api.delete(`/sessions/${id}`);
|
||||
await api.delete<ApiResponse<any>>(`/sessions/${id}`);
|
||||
};
|
||||
|
||||
|
||||
export const addSetToActiveSession = async (userId: string, setData: any): Promise<any> => {
|
||||
return await api.post('/sessions/active/log-set', setData);
|
||||
const response = await api.post<ApiResponse<any>>('/sessions/active/log-set', setData);
|
||||
return response.data;
|
||||
};
|
||||
|
||||
export const deleteAllUserData = (userId: string) => {
|
||||
|
||||
@@ -1,23 +1,16 @@
|
||||
import { BodyWeightRecord } from '../types';
|
||||
import { api } from './api';
|
||||
|
||||
const API_URL = '/api';
|
||||
interface ApiResponse<T> {
|
||||
success: boolean;
|
||||
data: T;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export const getWeightHistory = async (): Promise<BodyWeightRecord[]> => {
|
||||
const token = localStorage.getItem('token');
|
||||
if (!token) return [];
|
||||
|
||||
try {
|
||||
const response = await fetch(`${API_URL}/weight`, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`
|
||||
}
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to fetch weight history');
|
||||
}
|
||||
|
||||
return await response.json();
|
||||
const res = await api.get<ApiResponse<BodyWeightRecord[]>>('/weight');
|
||||
return res.data || [];
|
||||
} catch (error) {
|
||||
console.error('Error fetching weight history:', error);
|
||||
return [];
|
||||
@@ -25,27 +18,12 @@ export const getWeightHistory = async (): Promise<BodyWeightRecord[]> => {
|
||||
};
|
||||
|
||||
export const logWeight = async (weight: number, dateStr?: string): Promise<BodyWeightRecord | null> => {
|
||||
const token = localStorage.getItem('token');
|
||||
if (!token) return null;
|
||||
|
||||
try {
|
||||
// Default to today if no date provided
|
||||
const date = dateStr || new Date().toISOString().split('T')[0];
|
||||
|
||||
const response = await fetch(`${API_URL}/weight`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${token}`
|
||||
},
|
||||
body: JSON.stringify({ weight, dateStr: date })
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to log weight');
|
||||
}
|
||||
|
||||
return await response.json();
|
||||
const res = await api.post<ApiResponse<BodyWeightRecord>>('/weight', { weight, dateStr: date });
|
||||
return res.data;
|
||||
} catch (error) {
|
||||
console.error('Error logging weight:', error);
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user