Files
zerp/frontend/src/lib/api/admin.ts

336 lines
9.3 KiB
TypeScript

import { api } from '../api';
// Users API
export interface User {
id: string;
email: string;
username: string;
isActive: boolean;
lastLogin?: string | null;
employeeId?: string | null;
employee?: {
id: string;
firstName: string;
lastName: string;
firstNameAr?: string | null;
lastNameAr?: string | null;
position?: { id: string; title: string; titleAr?: string | null };
department?: { name: string; nameAr?: string | null };
};
createdAt: string;
updatedAt: string;
}
export interface CreateUserData {
email: string;
username: string;
password: string;
employeeId: string;
isActive?: boolean;
}
export interface UpdateUserData {
email?: string;
username?: string;
password?: string;
employeeId?: string | null;
isActive?: boolean;
}
export interface UserFilters {
search?: string;
status?: 'active' | 'inactive';
positionId?: string;
page?: number;
pageSize?: number;
}
export interface PaginatedResponse<T> {
success: boolean;
data: T[];
pagination: {
total: number;
page: number;
pageSize: number;
totalPages: number;
};
}
export const usersAPI = {
getAll: async (filters?: UserFilters): Promise<PaginatedResponse<User>> => {
const params = new URLSearchParams();
if (filters?.search) params.append('search', filters.search);
if (filters?.status) params.append('status', filters.status);
if (filters?.positionId) params.append('positionId', filters.positionId);
if (filters?.page) params.append('page', String(filters.page));
if (filters?.pageSize) params.append('pageSize', String(filters.pageSize));
const response = await api.get(`/admin/users?${params.toString()}`);
return {
success: true,
data: response.data.data || [],
pagination: response.data.pagination || { total: 0, page: 1, pageSize: 20, totalPages: 0 },
};
},
getById: async (id: string): Promise<User> => {
const response = await api.get(`/admin/users/${id}`);
return response.data.data;
},
create: async (data: CreateUserData): Promise<User> => {
const response = await api.post('/admin/users', data);
return response.data.data;
},
update: async (id: string, data: UpdateUserData): Promise<User> => {
const response = await api.put(`/admin/users/${id}`, data);
return response.data.data;
},
toggleActive: async (id: string): Promise<User> => {
const response = await api.patch(`/admin/users/${id}/toggle-active`);
return response.data.data;
},
delete: async (id: string): Promise<void> => {
await api.delete(`/admin/users/${id}`);
},
};
// Stats API
export interface AdminStats {
totalUsers: number;
activeUsers: number;
inactiveUsers: number;
loginsToday: number;
}
export const statsAPI = {
get: async (): Promise<AdminStats> => {
const response = await api.get('/admin/stats');
return response.data.data || response.data;
},
};
// Positions (Roles) API - maps to HR positions with permissions
export interface PositionPermission {
id: string;
module: string;
resource: string;
actions: string[];
}
export interface PositionRole {
id: string;
title: string;
titleAr?: string | null;
code: string;
department?: { name: string; nameAr?: string | null };
permissions: PositionPermission[];
usersCount: number;
_count?: { employees: number };
}
export interface CreatePositionData {
title: string;
titleAr?: string;
code: string;
departmentId: string;
level?: number;
description?: string;
}
export const positionsAPI = {
getAll: async (): Promise<PositionRole[]> => {
const response = await api.get('/admin/positions');
return response.data.data || [];
},
create: async (data: CreatePositionData): Promise<PositionRole> => {
const response = await api.post('/admin/positions', data);
return response.data.data;
},
update: async (
id: string,
data: Partial<CreatePositionData & { isActive?: boolean }>
): Promise<PositionRole> => {
const response = await api.put(`/admin/positions/${id}`, data);
return response.data.data;
},
updatePermissions: async (
positionId: string,
permissions: Array<{ module: string; resource: string; actions: string[] }>
): Promise<PositionRole> => {
const response = await api.put(`/admin/positions/${positionId}/permissions`, {
permissions,
});
return response.data.data;
},
};
// Roles API - alias for positions (for compatibility with existing frontend)
export interface Role {
id: string;
name: string;
nameAr?: string;
title?: string;
titleAr?: string;
permissions: { id?: string; module: string; resource: string; actions: string[] }[];
usersCount?: number;
}
export const rolesAPI = {
getAll: async (): Promise<Role[]> => {
const positions = await positionsAPI.getAll();
return positions.map((p) => ({
id: p.id,
name: p.title,
nameAr: p.titleAr || undefined,
title: p.title,
titleAr: p.titleAr || undefined,
permissions: p.permissions,
usersCount: p.usersCount,
}));
},
update: async (
id: string,
permissions: Array<{ module: string; resource: string; actions: string[] }>
): Promise<Role> => {
const position = await positionsAPI.updatePermissions(id, permissions);
return {
id: position.id,
name: position.title,
nameAr: position.titleAr || undefined,
permissions: position.permissions,
usersCount: position.usersCount,
};
},
};
// Permission Groups API (Phase 3 - multi-group)
export interface PermissionGroup {
id: string;
name: string;
nameAr?: string | null;
description?: string | null;
isActive: boolean;
permissions: { id: string; module: string; resource: string; actions: string[] }[];
_count?: { userRoles: number };
}
export const permissionGroupsAPI = {
getAll: async (): Promise<PermissionGroup[]> => {
const response = await api.get('/admin/permission-groups');
return response.data.data || [];
},
create: async (data: { name: string; nameAr?: string; description?: string }) => {
const response = await api.post('/admin/permission-groups', data);
return response.data.data;
},
update: async (id: string, data: Partial<{ name: string; nameAr: string; description: string; isActive: boolean }>) => {
const response = await api.put(`/admin/permission-groups/${id}`, data);
return response.data.data;
},
updatePermissions: async (
id: string,
permissions: Array<{ module: string; resource: string; actions: string[] }>
) => {
const response = await api.put(`/admin/permission-groups/${id}/permissions`, { permissions });
return response.data.data;
},
};
export const userRolesAPI = {
getAll: async (userId: string) => {
const response = await api.get(`/admin/users/${userId}/roles`);
return response.data.data || [];
},
assign: async (userId: string, roleId: string) => {
const response = await api.post(`/admin/users/${userId}/roles`, { roleId });
return response.data.data;
},
remove: async (userId: string, roleId: string) => {
await api.delete(`/admin/users/${userId}/roles/${roleId}`);
},
};
// Audit Logs API
export interface AuditLog {
id: string;
entityType: string;
entityId: string;
action: string;
userId: string;
user?: { id: string; username: string; email: string };
changes?: unknown;
createdAt: string;
}
export interface AuditLogFilters {
entityType?: string;
action?: string;
userId?: string;
startDate?: string;
endDate?: string;
page?: number;
pageSize?: number;
}
export const auditLogsAPI = {
getAll: async (filters?: AuditLogFilters): Promise<PaginatedResponse<AuditLog>> => {
const params = new URLSearchParams();
if (filters?.entityType) params.append('entityType', filters.entityType);
if (filters?.action) params.append('action', filters.action);
if (filters?.userId) params.append('userId', filters.userId);
if (filters?.startDate) params.append('startDate', filters.startDate);
if (filters?.endDate) params.append('endDate', filters.endDate);
if (filters?.page) params.append('page', String(filters.page));
if (filters?.pageSize) params.append('pageSize', String(filters.pageSize));
const response = await api.get(`/admin/audit-logs?${params.toString()}`);
return {
success: true,
data: response.data.data || [],
pagination: response.data.pagination || { total: 0, page: 1, pageSize: 20, totalPages: 0 },
};
},
};
// System Settings API (placeholder - out of scope)
export interface SystemSetting {
key: string;
value: unknown;
description?: string;
}
export const settingsAPI = {
getAll: async (): Promise<SystemSetting[]> => {
const response = await api.get('/admin/settings').catch(() => ({ data: { data: [] } }));
return response.data?.data || [];
},
update: async (key: string, value: unknown): Promise<SystemSetting> => {
const response = await api.put(`/admin/settings/${key}`, { value });
return response.data.data;
},
};
// System Health API (placeholder - optional)
export interface SystemHealth {
status: string;
database: string;
memory?: unknown;
uptime?: number;
}
export const healthAPI = {
check: async (): Promise<SystemHealth> => {
const response = await api.get('/admin/health').catch(() => ({ data: { data: {} } }));
return response.data?.data || response.data || {};
},
};