import client from '../client'; import type { PaginatedResponse } from '../types'; // --- Types --- export interface PointsRule { id: string; event_type: string; name: string; description: string | null; points_value: number; daily_cap: number; streak_7d_bonus: number; streak_14d_bonus: number; streak_30d_bonus: number; is_active: boolean; created_at: string; updated_at: string; version: number; } export interface CreatePointsRuleReq { event_type: string; name: string; description?: string; points_value: number; daily_cap?: number; streak_7d_bonus?: number; streak_14d_bonus?: number; streak_30d_bonus?: number; } export interface PointsProduct { id: string; name: string; product_type: string; // physical / service / privilege points_cost: number; stock: number; image_url: string | null; description: string | null; is_active: boolean; sort_order: number; created_at: string; updated_at: string; version: number; } export interface CreatePointsProductReq { name: string; product_type: string; points_cost: number; stock: number; description?: string; image_url?: string; sort_order?: number; } export interface PointsOrder { id: string; patient_id: string; product_id: string; product_name: string | null; points_cost: number; status: string; // pending / verified / cancelled / expired qr_code: string; verified_by: string | null; verified_at: string | null; expires_at: string | null; notes: string | null; created_at: string; updated_at: string; version: number; } export interface VerifyOrderReq { qr_code: string; } export interface OfflineEvent { id: string; title: string; description: string | null; event_date: string; start_time: string | null; end_time: string | null; location: string | null; points_reward: number; max_participants: number; current_participants: number; status: string; // draft / published / ongoing / completed / cancelled image_url: string | null; created_at: string; updated_at: string; version: number; } export interface CreateOfflineEventReq { title: string; description?: string; event_date: string; start_time?: string; end_time?: string; location?: string; points_reward?: number; max_participants?: number; status?: string; image_url?: string; } export interface PointsStatistics { total_issued: number; total_spent: number; total_expired: number; active_accounts: number; top_earners: Array<{ account_id: string; patient_id: string; total_earned: number; }>; } export interface PatientStatistics { total_patients: number; new_this_month: number; new_this_week: number; active_this_month: number; } export interface ConsultationStatistics { total_sessions: number; pending_reply: number; avg_response_time_minutes: number | null; this_month: number; } export interface FollowUpStatistics { total_tasks: number; completed: number; pending: number; overdue: number; completion_rate: number; } export interface PersonalStats { my_patients: number; new_patients_this_month: number; follow_up_rate: number; consultations_this_month: number; pending_consultations: number; vital_signs_report_rate: number; today_appointments: number; overdue_follow_ups: number; today_follow_ups: number; abnormal_vital_signs: number; vital_signs_reported: number; vital_signs_total: number; pending_lab_reviews: number; yesterday_my_patients?: number; yesterday_today_appointments?: number; yesterday_consultations_this_month?: number; yesterday_follow_up_rate?: number; yesterday_today_follow_ups?: number; yesterday_overdue_follow_ups?: number; } export interface OverviewStatistics { patients: PatientStatistics; consultations: ConsultationStatistics; follow_ups: FollowUpStatistics; points: PointsStatistics; } // --- Health Data Statistics Types --- export interface NameValue { name: string; value: number; } export interface DialysisStatistics { total_records: number; this_month: number; type_distribution: NameValue[]; complication_rate: number; avg_ultrafiltration: number | null; avg_duration: number | null; pending_review: number; } export interface LabReportStatistics { total_reports: number; this_month: number; type_distribution: NameValue[]; abnormal_items: number; pending_review: number; reviewed: number; } export interface AppointmentStatistics { total_appointments: number; this_month: number; status_distribution: NameValue[]; type_distribution: NameValue[]; cancel_rate: number; } export interface DailyReportRate { date: string; reported: number; total: number; rate: number; } export interface VitalSignsReportRate { total_patients: number; reported_patients: number; report_rate: number; total_records: number; daily_trend: DailyReportRate[]; } export interface HealthDataStats { lab_reports: LabReportStatistics; appointments: AppointmentStatistics; vital_signs_report_rate: VitalSignsReportRate; } // --- API --- export interface PointsAccountDetail { id: string; patient_id: string; balance: number; total_earned: number; total_spent: number; total_expired: number; } export interface PointsTransactionDetail { id: string; account_id: string; transaction_type: string; amount: number; remaining_amount: number; status: string; expires_at: string | null; balance_after: number; description: string | null; created_at: string; } export const pointsAdminApi = { getPatientAccount: async (patientId: string) => { const { data } = await client.get<{ success: boolean; data: PointsAccountDetail; }>(`/health/admin/points/patients/${patientId}/account`); return data.data; }, listPatientTransactions: async ( patientId: string, params: { page?: number; page_size?: number }, ) => { const { data } = await client.get<{ success: boolean; data: PaginatedResponse; }>(`/health/admin/points/patients/${patientId}/transactions`, { params }); return data.data; }, }; // --- API (original) --- export const pointsApi = { // Rules listRules: async () => { const { data } = await client.get<{ success: boolean; data: PointsRule[]; }>('/health/admin/points/rules'); return data.data; }, createRule: async (req: CreatePointsRuleReq) => { const { data } = await client.post<{ success: boolean; data: PointsRule; }>('/health/admin/points/rules', req); return data.data; }, updateRule: async (id: string, req: Partial & { is_active?: boolean; version: number }) => { const { data } = await client.put<{ success: boolean; data: PointsRule; }>(`/health/admin/points/rules/${id}`, { data: req, version: req.version }); return data.data; }, deleteRule: async (id: string, version: number) => { await client.delete(`/health/admin/points/rules/${id}`, { data: { version }, }); }, // Products listProducts: async (params?: Record) => { const { data } = await client.get<{ success: boolean; data: PaginatedResponse; }>('/health/points/products', { params }); return data.data; }, createProduct: async (req: CreatePointsProductReq) => { const { data } = await client.post<{ success: boolean; data: PointsProduct; }>('/health/admin/points/products', req); return data.data; }, updateProduct: async (id: string, req: Partial & { is_active?: boolean; version: number }) => { const { data } = await client.put<{ success: boolean; data: PointsProduct; }>(`/health/admin/points/products/${id}`, { data: req, version: req.version }); return data.data; }, deleteProduct: async (id: string, version: number) => { await client.delete(`/health/admin/points/products/${id}`, { data: { version }, }); }, // Orders listOrders: async (params?: Record) => { const { data } = await client.get<{ success: boolean; data: PaginatedResponse; }>('/health/admin/points/orders', { params }); return data.data; }, verifyOrder: async (req: VerifyOrderReq) => { const { data } = await client.post<{ success: boolean; data: PointsOrder; }>('/health/points/verify', req); return data.data; }, // Offline Events listOfflineEvents: async (params?: Record) => { const { data } = await client.get<{ success: boolean; data: PaginatedResponse; }>('/health/admin/offline-events', { params }); return data.data; }, createOfflineEvent: async (req: CreateOfflineEventReq) => { const { data } = await client.post<{ success: boolean; data: OfflineEvent; }>('/health/admin/offline-events', req); return data.data; }, updateOfflineEvent: async (id: string, req: Partial & { version: number }) => { const { data } = await client.put<{ success: boolean; data: OfflineEvent; }>(`/health/admin/offline-events/${id}`, req); return data.data; }, deleteOfflineEvent: async (id: string, version: number) => { await client.delete(`/health/admin/offline-events/${id}`, { data: { version }, }); }, // Points Statistics getStatistics: async () => { const { data } = await client.get<{ success: boolean; data: PointsStatistics; }>('/health/admin/points/statistics'); return data.data; }, // --- Dashboard Statistics --- getPatientStats: async (): Promise => { const { data } = await client.get<{ success: boolean; data: PatientStatistics; }>('/health/admin/statistics/patients'); return data.data; }, getConsultationStats: async (): Promise => { const { data } = await client.get<{ success: boolean; data: ConsultationStatistics; }>('/health/admin/statistics/consultations'); return data.data; }, getFollowUpStats: async (): Promise => { const { data } = await client.get<{ success: boolean; data: FollowUpStatistics; }>('/health/admin/statistics/follow-ups'); return data.data; }, getHealthDataStats: async (): Promise => { const { data } = await client.get<{ success: boolean; data: HealthDataStats; }>('/health/admin/statistics/health-data'); return data.data; }, getDialysisStats: async (): Promise => { const { data } = await client.get<{ success: boolean; data: DialysisStatistics; }>('/health/admin/statistics/dialysis'); return data.data; }, getPersonalStats: async (): Promise => { const { data } = await client.get<{ success: boolean; data: PersonalStats; }>('/health/admin/statistics/personal-stats'); return data.data; }, };