const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:3000/api'; class ApiService { private baseURL: string; constructor(baseURL: string) { this.baseURL = baseURL; } private getToken(): string | null { return localStorage.getItem('token'); } private async request(endpoint: string, options: RequestInit = {}): Promise { const token = this.getToken(); const headers: HeadersInit = { 'Content-Type': 'application/json', ...options.headers, }; if (token) { headers['Authorization'] = `Bearer ${token}`; } const response = await fetch(`${this.baseURL}${endpoint}`, { ...options, headers, }); if (response.status === 401) { localStorage.removeItem('token'); localStorage.removeItem('user'); window.location.href = '/'; throw new Error('Unauthorized'); } if (!response.ok) { const error = await response.json().catch(() => ({ error: 'Request failed' })); throw new Error(error.error || 'Request failed'); } return response.json(); } // Auth async login(username: string, password: string) { return this.request<{ token: string; user: any }>('/auth/login', { method: 'POST', body: JSON.stringify({ username, password }), }); } async getMe() { return this.request('/auth/me'); } async changePassword(currentPassword: string, newPassword: string) { return this.request<{ message: string }>('/auth/change-password', { method: 'POST', body: JSON.stringify({ currentPassword, newPassword }), }); } // Users async getUsers(params?: { role?: string; departmentId?: number }) { const query = new URLSearchParams(params as any).toString(); return this.request(`/users${query ? `?${query}` : ''}`); } async getUser(id: number) { return this.request(`/users/${id}`); } async createUser(data: any) { return this.request('/users', { method: 'POST', body: JSON.stringify(data), }); } async updateUser(id: number, data: any) { return this.request(`/users/${id}`, { method: 'PUT', body: JSON.stringify(data), }); } async deleteUser(id: number) { return this.request<{ message: string }>(`/users/${id}`, { method: 'DELETE', }); } // Departments async getDepartments() { return this.request('/departments'); } async getDepartment(id: number) { return this.request(`/departments/${id}`); } async getSubDepartments(departmentId: number) { return this.request(`/departments/${departmentId}/sub-departments`); } async createDepartment(name: string) { return this.request('/departments', { method: 'POST', body: JSON.stringify({ name }), }); } // Work Allocations async getWorkAllocations(params?: { employeeId?: number; status?: string; departmentId?: number }) { const query = new URLSearchParams(params as any).toString(); return this.request(`/work-allocations${query ? `?${query}` : ''}`); } async getWorkAllocation(id: number) { return this.request(`/work-allocations/${id}`); } async createWorkAllocation(data: any) { return this.request('/work-allocations', { method: 'POST', body: JSON.stringify(data), }); } async updateWorkAllocationStatus(id: number, status: string, completionDate?: string) { return this.request(`/work-allocations/${id}/status`, { method: 'PUT', body: JSON.stringify({ status, completionDate }), }); } async deleteWorkAllocation(id: number) { return this.request<{ message: string }>(`/work-allocations/${id}`, { method: 'DELETE', }); } // Attendance async getAttendance(params?: { employeeId?: number; startDate?: string; endDate?: string; status?: string }) { const query = new URLSearchParams(params as any).toString(); return this.request(`/attendance${query ? `?${query}` : ''}`); } async checkIn(employeeId: number, workDate: string) { return this.request('/attendance/check-in', { method: 'POST', body: JSON.stringify({ employeeId, workDate }), }); } async checkOut(employeeId: number, workDate: string) { return this.request('/attendance/check-out', { method: 'POST', body: JSON.stringify({ employeeId, workDate }), }); } async getAttendanceSummary(params?: { startDate?: string; endDate?: string; departmentId?: number }) { const query = new URLSearchParams(params as any).toString(); return this.request(`/attendance/summary/stats${query ? `?${query}` : ''}`); } async updateAttendanceStatus(id: number, status: string, remark?: string) { return this.request(`/attendance/${id}/status`, { method: 'PUT', body: JSON.stringify({ status, remark }), }); } async markAbsent(employeeId: number, workDate: string, remark?: string) { return this.request('/attendance/mark-absent', { method: 'POST', body: JSON.stringify({ employeeId, workDate, remark }), }); } // Employee Swaps async getEmployeeSwaps(params?: { status?: string; employeeId?: number; startDate?: string; endDate?: string }) { const query = params ? new URLSearchParams(params as any).toString() : ''; return this.request(`/employee-swaps${query ? `?${query}` : ''}`); } async getEmployeeSwap(id: number) { return this.request(`/employee-swaps/${id}`); } async createEmployeeSwap(data: { employeeId: number; targetDepartmentId: number; targetContractorId?: number; swapReason: string; reasonDetails?: string; workCompletionPercentage?: number; swapDate: string; }) { return this.request('/employee-swaps', { method: 'POST', body: JSON.stringify(data), }); } async completeEmployeeSwap(id: number) { return this.request(`/employee-swaps/${id}/complete`, { method: 'PUT', }); } async cancelEmployeeSwap(id: number) { return this.request(`/employee-swaps/${id}/cancel`, { method: 'PUT', }); } // Contractor Rates async getContractorRates(params?: { contractorId?: number; subDepartmentId?: number }) { const query = params ? new URLSearchParams(params as any).toString() : ''; return this.request(`/contractor-rates${query ? `?${query}` : ''}`); } async getCurrentRate(contractorId: number, subDepartmentId?: number) { const query = subDepartmentId ? `?subDepartmentId=${subDepartmentId}` : ''; return this.request(`/contractor-rates/contractor/${contractorId}/current${query}`); } async setContractorRate(data: { contractorId: number; subDepartmentId?: number; activity?: string; rate: number; effectiveDate: string }) { return this.request('/contractor-rates', { method: 'POST', body: JSON.stringify(data), }); } async updateContractorRate(id: number, data: { rate?: number; activity?: string; effectiveDate?: string }) { return this.request(`/contractor-rates/${id}`, { method: 'PUT', body: JSON.stringify(data), }); } async deleteContractorRate(id: number) { return this.request<{ message: string }>(`/contractor-rates/${id}`, { method: 'DELETE', }); } // Reports async getCompletedAllocationsReport(params?: { startDate?: string; endDate?: string; departmentId?: number; contractorId?: number; employeeId?: number; }) { const query = params ? new URLSearchParams(params as any).toString() : ''; return this.request<{ allocations: any[]; summary: { totalAllocations: number; totalAmount: string; totalUnits: string } }>(`/reports/completed-allocations${query ? `?${query}` : ''}`); } async getReportSummary(params?: { startDate?: string; endDate?: string }) { const query = params ? new URLSearchParams(params as any).toString() : ''; return this.request<{ byContractor: any[]; bySubDepartment: any[]; byActivity: any[]; }>(`/reports/summary${query ? `?${query}` : ''}`); } // Standard Rates async getStandardRates(params?: { departmentId?: number; subDepartmentId?: number; activity?: string }) { const query = params ? new URLSearchParams(params as any).toString() : ''; return this.request(`/standard-rates${query ? `?${query}` : ''}`); } async getAllRates(params?: { departmentId?: number; startDate?: string; endDate?: string }) { const query = params ? new URLSearchParams(params as any).toString() : ''; return this.request<{ allRates: any[]; summary: { totalContractorRates: number; totalStandardRates: number; totalRates: number }; }>(`/standard-rates/all-rates${query ? `?${query}` : ''}`); } async compareRates(params?: { contractorId?: number; subDepartmentId?: number }) { const query = params ? new URLSearchParams(params as any).toString() : ''; return this.request<{ standardRates: any[]; contractorRates: any[]; comparisons: any[]; }>(`/standard-rates/compare${query ? `?${query}` : ''}`); } async createStandardRate(data: { subDepartmentId?: number; activity?: string; rate: number; effectiveDate: string }) { return this.request('/standard-rates', { method: 'POST', body: JSON.stringify(data), }); } async updateStandardRate(id: number, data: { rate?: number; activity?: string; effectiveDate?: string }) { return this.request(`/standard-rates/${id}`, { method: 'PUT', body: JSON.stringify(data), }); } async deleteStandardRate(id: number) { return this.request<{ message: string }>(`/standard-rates/${id}`, { method: 'DELETE', }); } // Activities async getActivities(params?: { departmentId?: number; subDepartmentId?: number }) { const query = params ? new URLSearchParams(params as any).toString() : ''; return this.request(`/activities${query ? `?${query}` : ''}`); } async getActivity(id: number) { return this.request(`/activities/${id}`); } async createActivity(data: { sub_department_id: number; name: string; unit_of_measurement?: string }) { return this.request('/activities', { method: 'POST', body: JSON.stringify(data), }); } async updateActivity(id: number, data: { name?: string; unit_of_measurement?: string }) { return this.request(`/activities/${id}`, { method: 'PUT', body: JSON.stringify(data), }); } async deleteActivity(id: number) { return this.request<{ message: string }>(`/activities/${id}`, { method: 'DELETE', }); } } export const api = new ApiService(API_BASE_URL);