Files
family_budget/frontend/src/api/client.ts
2026-03-10 13:54:27 +03:00

179 lines
6.1 KiB
TypeScript

import axios from 'axios';
import type {
Family,
Category,
Expense,
RemainingLimit,
LoginRequest,
LoginResponse,
CreateFamilyRequest,
CreateMyFamilyRequest,
CreateMyFamilyResponse,
CreateCategoryRequest,
CreateExpenseRequest,
VerifyFamilyPasswordRequest,
VerifyFamilyPasswordResponse,
ShoppingItem,
CreateShoppingItemRequest,
UpdateShoppingItemRequest,
MarkAsPurchasedRequest,
BulkOperationResponse,
User,
OAuthUrlResponse,
CreateInviteLinkRequest,
InviteLinkResponse,
ValidateInviteResponse,
JoinFamilyResponse,
FamilyMember,
LeaveFamilyResponse,
ExpenseHistoryResponse,
} from '../types';
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || '';
const apiClient = axios.create({
baseURL: API_BASE_URL,
withCredentials: true,
});
export const authApi = {
login: (data: LoginRequest) =>
apiClient.post<LoginResponse>('/login', data),
logout: () =>
apiClient.post('/logout'),
me: () =>
apiClient.get<User>('/me'),
getGoogleAuthUrl: (redirectUrl?: string, mobile?: boolean) =>
apiClient.get<OAuthUrlResponse>('/auth/google', {
params: {
...(redirectUrl ? { redirect_url: redirectUrl } : {}),
...(mobile ? { mobile: true } : {}),
},
}),
mobileCallback: (token: string) =>
apiClient.get('/auth/mobile-callback', { params: { token } }),
};
export const familyApi = {
getAll: () =>
apiClient.get<Family[]>('/families'),
getById: (id: number) =>
apiClient.get<Family>(`/families/${id}`),
create: (data: CreateFamilyRequest) =>
apiClient.post<Family>('/families', data),
createMyFamily: (data: CreateMyFamilyRequest) =>
apiClient.post<CreateMyFamilyResponse>('/my-family', data),
update: (id: number, data: { name: string }) =>
apiClient.put<Family>(`/families/${id}`, data),
delete: (id: number) =>
apiClient.delete(`/families/${id}`),
verifyPassword: (id: number, data: VerifyFamilyPasswordRequest) =>
apiClient.post<VerifyFamilyPasswordResponse>(`/families/${id}/verify`, data),
getMembers: (familyId: number) =>
apiClient.get<FamilyMember[]>(`/families/${familyId}/members`),
};
export const userApi = {
leaveFamily: () =>
apiClient.post<LeaveFamilyResponse>('/me/leave-family'),
};
export const categoryApi = {
getAllByFamily: (familyId: number) =>
apiClient.get<Category[]>(`/families/${familyId}/categories`),
getById: (familyId: number, categoryId: number) =>
apiClient.get<Category>(`/families/${familyId}/categories/${categoryId}`),
create: (familyId: number, data: CreateCategoryRequest) =>
apiClient.post<Category>(`/families/${familyId}/categories`, data),
update: (familyId: number, categoryId: number, data: Partial<CreateCategoryRequest>) =>
apiClient.put<Category>(`/families/${familyId}/categories/${categoryId}`, data),
delete: (familyId: number, categoryId: number) =>
apiClient.delete(`/families/${familyId}/categories/${categoryId}`),
resetLimit: (familyId: number, categoryId: number, newLimit: number) =>
apiClient.put<Category>(`/families/${familyId}/categories/${categoryId}`, { limit_amount: newLimit }),
};
export const expenseApi = {
getAllByCategory: (familyId: number, categoryId: number) =>
apiClient.get<Expense[]>(`/families/${familyId}/categories/${categoryId}/expenses`),
getById: (familyId: number, categoryId: number, expenseId: number) =>
apiClient.get<Expense>(`/families/${familyId}/categories/${categoryId}/expenses/${expenseId}`),
create: (familyId: number, categoryId: number, data: CreateExpenseRequest) =>
apiClient.post<Expense>(`/families/${familyId}/categories/${categoryId}/expenses`, data),
update: (familyId: number, categoryId: number, expenseId: number, data: Partial<CreateExpenseRequest>) =>
apiClient.put<Expense>(`/families/${familyId}/categories/${categoryId}/expenses/${expenseId}`, data),
delete: (familyId: number, categoryId: number, expenseId: number) =>
apiClient.delete(`/families/${familyId}/categories/${categoryId}/expenses/${expenseId}`),
getRemainingLimit: (familyId: number, categoryId: number) =>
apiClient.get<RemainingLimit>(`/families/${familyId}/categories/${categoryId}/remaining`),
getHistory: (familyId: number, categoryId: number, showArchive: boolean = false, sortOrder: string = 'desc') =>
apiClient.get<ExpenseHistoryResponse>(`/families/${familyId}/categories/${categoryId}/expenses/history`, {
params: { show_archive: showArchive, sort_order: sortOrder },
}),
};
export const shoppingItemApi = {
getAllByFamily: (familyId: number) =>
apiClient.get<ShoppingItem[]>(`/families/${familyId}/shopping-items`),
getById: (familyId: number, itemId: number) =>
apiClient.get<ShoppingItem>(`/families/${familyId}/shopping-items/${itemId}`),
create: (familyId: number, data: CreateShoppingItemRequest) =>
apiClient.post<ShoppingItem>(`/families/${familyId}/shopping-items`, data),
update: (familyId: number, itemId: number, data: UpdateShoppingItemRequest) =>
apiClient.put<ShoppingItem>(`/families/${familyId}/shopping-items/${itemId}`, data),
delete: (familyId: number, itemId: number) =>
apiClient.delete(`/families/${familyId}/shopping-items/${itemId}`),
markAsPurchased: (familyId: number, itemId: number, data: MarkAsPurchasedRequest) =>
apiClient.patch<ShoppingItem>(`/families/${familyId}/shopping-items/${itemId}/purchased`, data),
markAllAsPurchased: (familyId: number) =>
apiClient.post<BulkOperationResponse>(`/families/${familyId}/shopping-items/mark-all-purchased`),
clearAll: (familyId: number) =>
apiClient.delete<BulkOperationResponse>(`/families/${familyId}/shopping-items/clear-all`),
};
export const inviteLinkApi = {
create: (data: CreateInviteLinkRequest) =>
apiClient.post<InviteLinkResponse>('/my-family/invite-links', data),
getMyLinks: () =>
apiClient.get<InviteLinkResponse[]>('/my-family/invite-links'),
delete: (token: string) =>
apiClient.delete(`/my-family/invite-links/${token}`),
validate: (token: string) =>
apiClient.get<ValidateInviteResponse>(`/invite/${token}`),
join: (token: string) =>
apiClient.post<JoinFamilyResponse>(`/invite/${token}/join`),
};