TreasureTrails/frontend/src/services/api.ts

92 lines
4.2 KiB
TypeScript

import axios from 'axios';
import type { Game, Route, RouteLeg, Team, User, AuthResponse, LocationHistory, UserGameHistory } from '../types';
const api = axios.create({
baseURL: 'http://localhost:3001/api',
});
api.interceptors.request.use((config) => {
const token = localStorage.getItem('token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
export const authService = {
register: (data: { email: string; password: string; name: string }) =>
api.post<AuthResponse>('/auth/register', data),
login: (data: { email: string; password: string }) =>
api.post<AuthResponse>('/auth/login', data),
me: () => api.get<User>('/auth/me'),
};
export const gameService = {
list: (params?: { search?: string; status?: string }) =>
api.get<Game[]>('/games', { params }),
myGames: () => api.get<Game[]>('/games/my-games'),
get: (id: string) => api.get<Game>(`/games/${id}`),
getByInvite: (code: string) => api.get<Game>(`/games/invite/${code}`),
create: (data: Partial<Game>) => api.post<Game>('/games', data),
update: (id: string, data: Partial<Game>) => api.put<Game>(`/games/${id}`, data),
delete: (id: string) => api.delete(`/games/${id}`),
publish: (id: string) => api.post<Game>(`/games/${id}/publish`),
end: (id: string) => api.post<Game>(`/games/${id}/end`),
archive: (id: string) => api.post<Game>(`/games/${id}/archive`),
unarchive: (id: string) => api.post<Game>(`/games/${id}/unarchive`),
getInvite: (id: string) => api.get<{ inviteCode: string }>(`/games/${id}/invite`),
};
export const routeService = {
getByGame: (gameId: string) => api.get<Route[]>(`/routes/game/${gameId}`),
get: (routeId: string) => api.get<Route>(`/routes/${routeId}`),
create: (data: { gameId: string; name: string; description?: string; color?: string }) =>
api.post<Route>('/routes', data),
update: (routeId: string, data: Partial<Route>) =>
api.put<Route>(`/routes/${routeId}`, data),
delete: (routeId: string) => api.delete(`/routes/${routeId}`),
copy: (routeId: string) => api.post<Route>(`/routes/${routeId}/copy`),
addLeg: (routeId: string, data: Partial<RouteLeg>) =>
api.post<RouteLeg>(`/routes/${routeId}/legs`, data),
updateLeg: (routeId: string, legId: string, data: Partial<RouteLeg>) =>
api.put<RouteLeg>(`/routes/${routeId}/legs/${legId}`, data),
deleteLeg: (routeId: string, legId: string) =>
api.delete(`/routes/${routeId}/legs/${legId}`),
};
export const teamService = {
getByGame: (gameId: string) => api.get<Team[]>(`/teams/game/${gameId}`),
create: (gameId: string, data: { name: string }) => api.post<Team>(`/teams/game/${gameId}`, data),
get: (teamId: string) => api.get<Team>(`/teams/${teamId}`),
join: (teamId: string) => api.post(`/teams/${teamId}/join`),
leave: (teamId: string) => api.post(`/teams/${teamId}/leave`),
assignRoute: (teamId: string, routeId: string) =>
api.post(`/teams/${teamId}/assign-route`, { routeId }),
advance: (teamId: string) => api.post<Team>(`/teams/${teamId}/advance`),
deduct: (teamId: string, seconds: number) => api.post<Team>(`/teams/${teamId}/deduct`, { seconds }),
disqualify: (teamId: string) => api.post<Team>(`/teams/${teamId}/disqualify`),
updateLocation: (teamId: string, lat: number, lng: number) =>
api.post(`/teams/${teamId}/location`, { lat, lng }),
};
export const uploadService = {
upload: (file: File) => {
const formData = new FormData();
formData.append('photo', file);
return api.post<{ url: string }>('/upload/upload', formData, {
headers: { 'Content-Type': 'multipart/form-data' },
});
},
};
export const userService = {
getProfile: () => api.get<User>('/users/me'),
updateProfile: (data: { name?: string; screenName?: string; avatarUrl?: string; unitPreference?: 'METRIC' | 'IMPERIAL' }) =>
api.put<User>('/users/me', data),
getLocationHistory: () => api.get<{ totalLocations: number; byGame: { game: { id: string; name: string }; locations: LocationHistory[]; locationCount: number }[] }>('/users/me/location-history'),
getGamesHistory: () => api.get<UserGameHistory[]>('/users/me/games'),
deleteLocationData: () => api.delete('/users/me/location-data'),
deleteAccount: () => api.delete('/users/me/account'),
};
export default api;