// API base URL const API_BASE_URL = 'http://localhost:8080/api/v1'; // Helper function for fetching data with authorization async function fetchWithAuth(url: string, options: RequestInit = {}) { // Get token from local storage const token = localStorage.getItem('token'); // Set up headers with authorization const headers = { 'Content-Type': 'application/json', ...(token ? { 'Authorization': `Bearer ${token}` } : {}), ...options.headers }; // Perform fetch const response = await fetch(`${API_BASE_URL}${url}`, { ...options, headers }); // Handle unauthorized responses if (response.status === 401) { localStorage.removeItem('token'); window.location.href = '/login'; throw new Error('Unauthorized'); } // Parse response if (!response.ok) { const errorData = await response.json().catch(() => null); throw new Error(errorData?.error || `API Error: ${response.status}`); } return response.json(); } // Auth API export const authApi = { login: async (email: string, password: string) => { const response = await fetch(`${API_BASE_URL}/auth/login`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email, password }) }); if (!response.ok) { const errorData = await response.json().catch(() => null); throw new Error(errorData?.error || 'Login failed'); } const data = await response.json(); localStorage.setItem('token', data.token); return data; }, signup: async (name: string, email: string, password: string) => { const response = await fetch(`${API_BASE_URL}/auth/signup`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name, email, password }) }); if (!response.ok) { const errorData = await response.json().catch(() => null); throw new Error(errorData?.error || 'Signup failed'); } return response.json(); }, logout: () => { localStorage.removeItem('token'); window.location.href = '/login'; } }; // Account API export interface Account { ID: number; CreatedAt: string; UpdatedAt: string; DeletedAt: string | null; UserID: number; Name: string; Type: string; Balance: number; } export interface AccountInput { name: string; type: string; balance: number; } export const accountApi = { getAccounts: () => fetchWithAuth('/accounts'), getAccount: (id: number) => fetchWithAuth(`/accounts/${id}`), createAccount: (account: AccountInput) => fetchWithAuth('/accounts', { method: 'POST', body: JSON.stringify(account) }), updateAccount: (id: number, account: Partial) => fetchWithAuth(`/accounts/${id}`, { method: 'PUT', body: JSON.stringify(account) }), deleteAccount: (id: number) => fetchWithAuth(`/accounts/${id}`, { method: 'DELETE' }) }; // Transaction API export interface Transaction { ID: number; CreatedAt: string; UpdatedAt: string; DeletedAt: string | null; UserID: number; AccountID: number | null; Description: string; Amount: number; Type: "Income" | "Expense"; Date: string; Category: string; } export interface TransactionInput { description: string; amount: number; type: "Income" | "Expense"; date: string; // YYYY-MM-DD format category: string; accountId?: number; } export interface TransactionFilters { type?: "Income" | "Expense"; accountId?: number; category?: string; startDate?: string; // YYYY-MM-DD format endDate?: string; // YYYY-MM-DD format } export const transactionApi = { getTransactions: (filters?: TransactionFilters) => { let queryParams = ''; if (filters) { const params = new URLSearchParams(); if (filters.type) params.append('type', filters.type); if (filters.accountId) params.append('account_id', filters.accountId.toString()); if (filters.category) params.append('category', filters.category); if (filters.startDate) params.append('start_date', filters.startDate); if (filters.endDate) params.append('end_date', filters.endDate); queryParams = `?${params.toString()}`; } return fetchWithAuth(`/transactions${queryParams}`); }, getTransaction: (id: number) => fetchWithAuth(`/transactions/${id}`), createTransaction: (transaction: TransactionInput) => fetchWithAuth('/transactions', { method: 'POST', body: JSON.stringify(transaction) }), updateTransaction: (id: number, transaction: Partial) => fetchWithAuth(`/transactions/${id}`, { method: 'PUT', body: JSON.stringify(transaction) }), deleteTransaction: (id: number) => fetchWithAuth(`/transactions/${id}`, { method: 'DELETE' }) }; // Loan API export interface Loan { ID: number; CreatedAt: string; UpdatedAt: string; DeletedAt: string | null; UserID: number; AccountID: number | null; Name: string; OriginalAmount: number; CurrentBalance: number; InterestRate: number; StartDate: string; EndDate: string; } export interface LoanInput { name: string; originalAmount: number; currentBalance: number; interestRate: number; startDate: string; endDate: string; accountId?: number; } export const loanApi = { getLoans: () => fetchWithAuth('/loans'), getLoan: (id: number) => fetchWithAuth(`/loans/${id}`), createLoan: (loan: LoanInput) => fetchWithAuth('/loans', { method: 'POST', body: JSON.stringify(loan) }), updateLoan: (id: number, loan: Partial) => fetchWithAuth(`/loans/${id}`, { method: 'PUT', body: JSON.stringify(loan) }), deleteLoan: (id: number) => fetchWithAuth(`/loans/${id}`, { method: 'DELETE' }) }; // User API export const userApi = { getProfile: () => fetchWithAuth('/users/me') };