ifixkart-admin/services/api/adminService.ts

337 lines
10 KiB
TypeScript

import { apiFetch } from './client';
import { API_ENDPOINTS } from './config';
export interface SessionInfo {
session_id: string;
user_id: string;
device_name: string;
device_type: string;
browser: string;
operating_system: string;
ip_address: string;
expires_at: string;
is_active: boolean;
}
export interface AuditLogEntry {
audit_id: string;
request_id: string;
user_id: string | null;
entity_type: string;
entity_id: string;
action: string;
old_value: Record<string, unknown> | null;
new_value: Record<string, unknown> | null;
ip_address: string;
user_agent: string | null;
created_at: string;
user?: {
name: string;
avatarInitials: string;
} | null;
}
export interface DashboardRevenuePoint {
date: string;
revenue: number;
orders: number;
}
export interface DashboardMonthlyPoint {
label: string;
revenue: number;
orders: number;
}
export interface DashboardTopProduct {
name: string;
total_sold: number;
total_revenue: number;
}
export interface DashboardRecentOrder {
order_no: string;
amount: number;
status: string;
payment_status: string;
created_at: string | null;
customer_name: string;
customer_email: string | null;
}
export interface DashboardStats {
total_users: number;
total_orders: number;
total_products: number;
total_brands: number;
total_device_models: number;
total_device_series: number;
total_categories: number;
revenue_all_time: number;
revenue_last_30_days: number;
revenue_last_7_days: number;
orders_by_status: Record<string, number>;
revenue_chart_daily: DashboardRevenuePoint[];
revenue_chart_monthly: DashboardMonthlyPoint[];
top_products: DashboardTopProduct[];
recent_orders: DashboardRecentOrder[];
low_stock_variants: number;
out_of_stock_variants: number;
total_stock_units: number;
}
export const adminService = {
async listSessions(skip = 0, limit = 100): Promise<{ sessions: SessionInfo[] }> {
return apiFetch<{ sessions: SessionInfo[] }>(
`${API_ENDPOINTS.ADMIN_LIST_SESSIONS}?skip=${skip}&limit=${limit}`
);
},
async revokeSession(sessionId: string): Promise<{ detail: string }> {
return apiFetch<{ detail: string }>(
`${API_ENDPOINTS.ADMIN_REVOKE_SESSION}?session_id=${sessionId}`,
{ method: 'POST' }
);
},
async getFailedLogins(limit = 10): Promise<AuditLogEntry[]> {
return apiFetch<AuditLogEntry[]>(
`${API_ENDPOINTS.ADMIN_FAILED_LOGINS}?limit=${limit}`
);
},
async getAuditLogs(limit = 100): Promise<AuditLogEntry[]> {
return apiFetch<AuditLogEntry[]>(
`${API_ENDPOINTS.ADMIN_AUDIT_LOGS}?limit=${limit}`
);
},
async requestKillSwitch(approverId: string, mfaCode: string): Promise<{ detail: string }> {
return apiFetch<{ detail: string }>(
`${API_ENDPOINTS.ADMIN_KILL_SWITCH}?approver_id=${approverId}&mfa_code=${mfaCode}`,
{ method: 'POST' }
);
},
async cancelKillSwitch(adminId: string): Promise<{ detail: string }> {
return apiFetch<{ detail: string }>(
`${API_ENDPOINTS.ADMIN_CANCEL_KILL_SWITCH}?admin_id=${adminId}`,
{ method: 'POST' }
);
},
async selfDestruct(adminId: string, mfaCode: string): Promise<{ detail: string }> {
return apiFetch<{ detail: string }>(
`${API_ENDPOINTS.ADMIN_SELF_DESTRUCT}?admin_id=${adminId}&mfa_code=${mfaCode}`,
{ method: 'POST' }
);
},
async getDashboardStats(): Promise<DashboardStats> {
return apiFetch<DashboardStats>(API_ENDPOINTS.DASHBOARD_STATS);
},
async listServiceJobs(): Promise<any[]> {
return apiFetch<any[]>('/api/v1/service/jobs');
},
async fetchServiceCatalog(): Promise<any[]> {
return apiFetch<any[]>('/api/v1/service/catalog');
},
async createServiceBooking(payload: any): Promise<any> {
return apiFetch<any>('/api/v1/service/booking/create', {
method: 'POST',
body: JSON.stringify(payload)
});
},
async getServiceJobDetailsAdmin(jobId: string): Promise<any> {
return apiFetch<any>(`/api/v1/service/jobs/${jobId}`);
},
async submitDeviceIntake(jobId: string, payload: any): Promise<any> {
return apiFetch<any>(`/api/v1/service/jobs/${jobId}/intake`, {
method: 'POST',
body: JSON.stringify(payload)
});
},
async submitDiagnosticInspection(jobId: string, payload: any): Promise<any> {
return apiFetch<any>(`/api/v1/service/jobs/${jobId}/inspect`, {
method: 'POST',
body: JSON.stringify(payload)
});
},
async createOrReviseQuote(jobId: string, payload: any): Promise<any> {
return apiFetch<any>(`/api/v1/service/jobs/${jobId}/quotes`, {
method: 'POST',
body: JSON.stringify(payload)
});
},
async rescheduleAppointmentAdmin(jobId: string, payload: any): Promise<any> {
return apiFetch<any>(`/api/v1/service/jobs/${jobId}/reschedule`, {
method: 'POST',
body: JSON.stringify(payload)
});
},
async fetchDeviceTypes(): Promise<any[]> {
return apiFetch<any[]>('/api/v1/catalog/device-types');
},
async fetchBrands(): Promise<any[]> {
return apiFetch<any[]>('/api/v1/catalog/brands/all');
},
async fetchDeviceSeries(): Promise<any[]> {
return apiFetch<any[]>('/api/v1/catalog/device-series/all');
},
async fetchDeviceModels(): Promise<any[]> {
return apiFetch<any[]>('/api/v1/catalog/device-models/all');
},
async updateServiceJobStatus(jobId: string, status: string): Promise<any> {
return apiFetch<any>(`/api/v1/service/jobs/${jobId}/status?status=${encodeURIComponent(status)}`, {
method: 'POST'
});
},
async updateServiceJobLogistics(jobId: string, payload: { courier_name?: string; awb_number?: string; pickup_status?: string }): Promise<any> {
return apiFetch<any>(`/api/v1/service/jobs/${jobId}/logistics`, {
method: 'POST',
body: JSON.stringify(payload)
});
},
async fetchServiceTypes(): Promise<any[]> {
return apiFetch<any[]>('/api/v1/catalog/service-types/all');
},
async createServiceType(payload: { name: string; description?: string; icon_url?: string }): Promise<any> {
return apiFetch<any>('/api/v1/catalog/service-types/create', {
method: 'POST',
body: JSON.stringify(payload)
});
},
async fetchRepairServices(): Promise<any[]> {
return apiFetch<any[]>('/api/v1/catalog/repair-services/all');
},
async createRepairService(payload: { model_id: string; service_type_id: string; description?: string }): Promise<any> {
return apiFetch<any>('/api/v1/catalog/repair-services/create', {
method: 'POST',
body: JSON.stringify(payload)
});
},
async fetchRepairVariants(): Promise<any[]> {
return apiFetch<any[]>('/api/v1/catalog/repair-variants/all');
},
async createRepairVariant(payload: {
repair_service_id: string;
name: string;
price: number;
cost?: number;
duration_minutes?: number;
warranty_days?: number;
parts?: { part_id: string; quantity: number }[];
}): Promise<any> {
return apiFetch<any>('/api/v1/catalog/repair-variants/create', {
method: 'POST',
body: JSON.stringify(payload)
});
},
async attachJobMedia(jobId: string, category: string, fileIds: string[]): Promise<any> {
return apiFetch<any>(`/api/v1/service/jobs/${jobId}/media`, {
method: 'POST',
body: JSON.stringify({ category, file_ids: fileIds })
});
},
async uploadMediaFile(file: File): Promise<{ file_id: string; webp_path?: string; raw_path?: string }> {
const formData = new FormData();
formData.append('file', file);
return apiFetch<{ file_id: string; webp_path?: string; raw_path?: string }>('/api/v1/files/upload', {
method: 'POST',
body: formData
});
},
async uploadStorefrontImage(file: File): Promise<{ image_url: string; thumbnail_url: string; medium_url: string; large_url: string }> {
const formData = new FormData();
formData.append('file', file);
return apiFetch<{ image_url: string; thumbnail_url: string; medium_url: string; large_url: string }>('/api/v1/admin/storefront/upload-image', {
method: 'POST',
body: formData,
});
},
// ─── Storefront CMS ────────────────────────────────────────────────────────
async getCmsFooterInfo(): Promise<any> {
return apiFetch<any>('/api/v1/admin/storefront/cms/footer-info');
},
async updateCmsFooterInfo(payload: Record<string, unknown>): Promise<any> {
return apiFetch<any>('/api/v1/admin/storefront/cms/footer-info', {
method: 'PUT', body: JSON.stringify(payload),
});
},
async getCmsSettings(): Promise<any> {
return apiFetch<any>('/api/v1/admin/storefront/cms/settings');
},
async updateCmsSettings(payload: Record<string, unknown>): Promise<any> {
return apiFetch<any>('/api/v1/admin/storefront/cms/settings', {
method: 'PUT', body: JSON.stringify(payload),
});
},
async getCmsMegaMenu(): Promise<any> {
return apiFetch<any>('/api/v1/admin/storefront/cms/mega-menu');
},
async updateCmsMegaMenu(payload: { nav_key: string; groups?: unknown[]; promo?: unknown; featured_category_ids?: string[] }): Promise<any> {
return apiFetch<any>('/api/v1/admin/storefront/cms/mega-menu', {
method: 'PUT', body: JSON.stringify(payload),
});
},
async getCmsCatalogFilters(): Promise<any> {
return apiFetch<any>('/api/v1/admin/storefront/cms/catalog-filters');
},
async updateCmsCatalogFilters(payload: { highlights?: unknown[]; price_ranges?: unknown[] }): Promise<any> {
return apiFetch<any>('/api/v1/admin/storefront/cms/catalog-filters', {
method: 'PUT', body: JSON.stringify(payload),
});
},
async updateCmsCategory(categoryId: string, payload: Record<string, unknown>): Promise<any> {
return apiFetch<any>(`/api/v1/admin/storefront/cms/categories/${categoryId}`, {
method: 'PUT', body: JSON.stringify(payload),
});
},
async getCmsReviews(approved?: boolean): Promise<any[]> {
const q = approved !== undefined ? `?approved=${approved}` : '';
return apiFetch<any[]>(`/api/v1/admin/storefront/cms/reviews${q}`);
},
async approveReview(reviewId: string, adminReply?: string): Promise<any> {
return apiFetch<any>(`/api/v1/admin/storefront/cms/reviews/${reviewId}/approve`, {
method: 'PUT', body: JSON.stringify({ admin_reply: adminReply ?? null }),
});
},
async rejectReview(reviewId: string): Promise<any> {
return apiFetch<any>(`/api/v1/admin/storefront/cms/reviews/${reviewId}/reject`, { method: 'PUT' });
},
async fetchCustomers(): Promise<any[]> {
return apiFetch<any[]>('/api/v1/admin/customers');
},
};