import type { ReactNode } from 'react'; import { createContext, useCallback, useContext, useEffect, useState } from 'react'; import { apiClient } from '@/lib/api-client'; import { LEADS_QUERY, CAMPAIGNS_QUERY, ADS_QUERY, FOLLOW_UPS_QUERY, LEAD_ACTIVITIES_QUERY, CALLS_QUERY, APPOINTMENTS_QUERY, PATIENTS_QUERY, } from '@/lib/queries'; import { transformLeads, transformCampaigns, transformAds, transformFollowUps, transformLeadActivities, transformCalls, transformAppointments, transformPatients, } from '@/lib/transforms'; import type { Lead, Campaign, Ad, LeadActivity, FollowUp, WhatsAppTemplate, Agent, Call, LeadIngestionSource, Patient, Appointment } from '@/types/entities'; type DataContextType = { leads: Lead[]; campaigns: Campaign[]; ads: Ad[]; followUps: FollowUp[]; leadActivities: LeadActivity[]; templates: WhatsAppTemplate[]; agents: Agent[]; calls: Call[]; appointments: Appointment[]; patients: Patient[]; ingestionSources: LeadIngestionSource[]; loading: boolean; error: string | null; updateLead: (id: string, updates: Partial) => void; addCall: (call: Call) => void; refresh: () => void; }; const DataContext = createContext(undefined); export const useData = (): DataContextType => { const context = useContext(DataContext); if (context === undefined) { throw new Error('useData must be used within a DataProvider'); } return context; }; interface DataProviderProps { children: ReactNode; } export const DataProvider = ({ children }: DataProviderProps) => { const [leads, setLeads] = useState([]); const [campaigns, setCampaigns] = useState([]); const [ads, setAds] = useState([]); const [followUps, setFollowUps] = useState([]); const [leadActivities, setLeadActivities] = useState([]); const [calls, setCalls] = useState([]); const [appointments, setAppointments] = useState([]); const [patients, setPatients] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); // These don't have platform entities yet — empty for now const [templates] = useState([]); const [agents] = useState([]); const [ingestionSources] = useState([]); const fetchData = useCallback(async () => { if (!apiClient.isAuthenticated()) { setLoading(false); return; } setLoading(true); setError(null); try { const gql = (query: string) => apiClient.graphql(query, undefined, { silent: true }).catch(() => null); const [leadsData, campaignsData, adsData, followUpsData, activitiesData, callsData, appointmentsData, patientsData] = await Promise.all([ gql(LEADS_QUERY), gql(CAMPAIGNS_QUERY), gql(ADS_QUERY), gql(FOLLOW_UPS_QUERY), gql(LEAD_ACTIVITIES_QUERY), gql(CALLS_QUERY), gql(APPOINTMENTS_QUERY), gql(PATIENTS_QUERY), ]); if (leadsData) setLeads(transformLeads(leadsData)); if (campaignsData) setCampaigns(transformCampaigns(campaignsData)); if (adsData) setAds(transformAds(adsData)); if (followUpsData) setFollowUps(transformFollowUps(followUpsData)); if (activitiesData) setLeadActivities(transformLeadActivities(activitiesData)); if (callsData) setCalls(transformCalls(callsData)); if (appointmentsData) setAppointments(transformAppointments(appointmentsData)); if (patientsData) setPatients(transformPatients(patientsData)); } catch (err: any) { setError(err.message ?? 'Failed to load data'); } finally { setLoading(false); } }, []); useEffect(() => { fetchData(); }, [fetchData]); const updateLead = (id: string, updates: Partial) => { setLeads((prev) => prev.map((lead) => (lead.id === id ? { ...lead, ...updates } : lead))); }; const addCall = (call: Call) => { setCalls((prev) => [call, ...prev]); }; return ( {children} ); };