Files
EmployeeManagementSystem/src/services/api.ts

361 lines
11 KiB
TypeScript

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<T>(endpoint: string, options: RequestInit = {}): Promise<T> {
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<any>('/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<any[]>(`/users${query ? `?${query}` : ''}`);
}
async getUser(id: number) {
return this.request<any>(`/users/${id}`);
}
async createUser(data: any) {
return this.request<any>('/users', {
method: 'POST',
body: JSON.stringify(data),
});
}
async updateUser(id: number, data: any) {
return this.request<any>(`/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<any[]>('/departments');
}
async getDepartment(id: number) {
return this.request<any>(`/departments/${id}`);
}
async getSubDepartments(departmentId: number) {
return this.request<any[]>(`/departments/${departmentId}/sub-departments`);
}
async createDepartment(name: string) {
return this.request<any>('/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<any[]>(`/work-allocations${query ? `?${query}` : ''}`);
}
async getWorkAllocation(id: number) {
return this.request<any>(`/work-allocations/${id}`);
}
async createWorkAllocation(data: any) {
return this.request<any>('/work-allocations', {
method: 'POST',
body: JSON.stringify(data),
});
}
async updateWorkAllocationStatus(id: number, status: string, completionDate?: string) {
return this.request<any>(`/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<any[]>(`/attendance${query ? `?${query}` : ''}`);
}
async checkIn(employeeId: number, workDate: string) {
return this.request<any>('/attendance/check-in', {
method: 'POST',
body: JSON.stringify({ employeeId, workDate }),
});
}
async checkOut(employeeId: number, workDate: string) {
return this.request<any>('/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<any[]>(`/attendance/summary/stats${query ? `?${query}` : ''}`);
}
async updateAttendanceStatus(id: number, status: string, remark?: string) {
return this.request<any>(`/attendance/${id}/status`, {
method: 'PUT',
body: JSON.stringify({ status, remark }),
});
}
async markAbsent(employeeId: number, workDate: string, remark?: string) {
return this.request<any>('/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<any[]>(`/employee-swaps${query ? `?${query}` : ''}`);
}
async getEmployeeSwap(id: number) {
return this.request<any>(`/employee-swaps/${id}`);
}
async createEmployeeSwap(data: {
employeeId: number;
targetDepartmentId: number;
targetContractorId?: number;
swapReason: string;
reasonDetails?: string;
workCompletionPercentage?: number;
swapDate: string;
}) {
return this.request<any>('/employee-swaps', {
method: 'POST',
body: JSON.stringify(data),
});
}
async completeEmployeeSwap(id: number) {
return this.request<any>(`/employee-swaps/${id}/complete`, {
method: 'PUT',
});
}
async cancelEmployeeSwap(id: number) {
return this.request<any>(`/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<any[]>(`/contractor-rates${query ? `?${query}` : ''}`);
}
async getCurrentRate(contractorId: number, subDepartmentId?: number) {
const query = subDepartmentId ? `?subDepartmentId=${subDepartmentId}` : '';
return this.request<any>(`/contractor-rates/contractor/${contractorId}/current${query}`);
}
async setContractorRate(data: {
contractorId: number;
subDepartmentId?: number;
activity?: string;
rate: number;
effectiveDate: string
}) {
return this.request<any>('/contractor-rates', {
method: 'POST',
body: JSON.stringify(data),
});
}
async updateContractorRate(id: number, data: { rate?: number; activity?: string; effectiveDate?: string }) {
return this.request<any>(`/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<any[]>(`/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<any>('/standard-rates', {
method: 'POST',
body: JSON.stringify(data),
});
}
async updateStandardRate(id: number, data: { rate?: number; activity?: string; effectiveDate?: string }) {
return this.request<any>(`/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<any[]>(`/activities${query ? `?${query}` : ''}`);
}
async getActivity(id: number) {
return this.request<any>(`/activities/${id}`);
}
async createActivity(data: { sub_department_id: number; name: string; unit_of_measurement?: string }) {
return this.request<any>('/activities', {
method: 'POST',
body: JSON.stringify(data),
});
}
async updateActivity(id: number, data: { name?: string; unit_of_measurement?: string }) {
return this.request<any>(`/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);