mirror of
https://dev.azure.com/globalhealthx/EMR/_git/helix-engage
synced 2026-04-11 18:28:15 +00:00
feat: build all data pages — worklist table, call history, patients, dashboard, reports
Worklist (call-desk): - Upgrade to Untitled UI Table with columns: Priority, Patient, Phone, Type, SLA, Actions - Filter tabs: All Tasks / Missed Calls / Callbacks / Follow-ups with counts - Search by name or phone - SLA timer color-coded: green <15m, amber <30m, red >30m Call History: - Full table: Type (direction icon), Patient (matched from leads), Phone, Duration, Outcome, Agent, Recording (play/pause), Time - Search + All/Inbound/Outbound/Missed filter - Recording playback via native <audio> Patients: - New page with table: Patient (avatar+name+age), Contact, Type, Gender, Status, Actions - Search + status filter - Call + View Details actions - Added patients to DataProvider + transforms + queries - Route /patients added, sidebar nav updated for cc-agent + executive Supervisor Dashboard: - KPI cards: Total Calls, Inbound, Outbound, Missed - Performance metrics: Avg Response Time, Callback Time, Conversion % - Agent performance table with per-agent stats - Missed Call Queue - AI Assistant section - Day/Week/Month filter Reports: - ECharts bar chart: Call Volume Trend (7-day, Inbound vs Outbound) - ECharts donut chart: Call Outcomes (Booked, Follow-up, Info, Missed) - KPI cards with trend indicators (+/-%) - Route /reports, sidebar Analytics → /reports Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,7 @@ import {
|
||||
FOLLOW_UPS_QUERY,
|
||||
LEAD_ACTIVITIES_QUERY,
|
||||
CALLS_QUERY,
|
||||
PATIENTS_QUERY,
|
||||
} from '@/lib/queries';
|
||||
import {
|
||||
transformLeads,
|
||||
@@ -16,9 +17,10 @@ import {
|
||||
transformFollowUps,
|
||||
transformLeadActivities,
|
||||
transformCalls,
|
||||
transformPatients,
|
||||
} from '@/lib/transforms';
|
||||
|
||||
import type { Lead, Campaign, Ad, LeadActivity, FollowUp, WhatsAppTemplate, Agent, Call, LeadIngestionSource } from '@/types/entities';
|
||||
import type { Lead, Campaign, Ad, LeadActivity, FollowUp, WhatsAppTemplate, Agent, Call, LeadIngestionSource, Patient } from '@/types/entities';
|
||||
|
||||
type DataContextType = {
|
||||
leads: Lead[];
|
||||
@@ -29,6 +31,7 @@ type DataContextType = {
|
||||
templates: WhatsAppTemplate[];
|
||||
agents: Agent[];
|
||||
calls: Call[];
|
||||
patients: Patient[];
|
||||
ingestionSources: LeadIngestionSource[];
|
||||
loading: boolean;
|
||||
error: string | null;
|
||||
@@ -60,6 +63,7 @@ export const DataProvider = ({ children }: DataProviderProps) => {
|
||||
const [followUps, setFollowUps] = useState<FollowUp[]>([]);
|
||||
const [leadActivities, setLeadActivities] = useState<LeadActivity[]>([]);
|
||||
const [calls, setCalls] = useState<Call[]>([]);
|
||||
const [patients, setPatients] = useState<Patient[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
@@ -80,13 +84,14 @@ export const DataProvider = ({ children }: DataProviderProps) => {
|
||||
try {
|
||||
const gql = <T,>(query: string) => apiClient.graphql<T>(query, undefined, { silent: true }).catch(() => null);
|
||||
|
||||
const [leadsData, campaignsData, adsData, followUpsData, activitiesData, callsData] = await Promise.all([
|
||||
const [leadsData, campaignsData, adsData, followUpsData, activitiesData, callsData, patientsData] = await Promise.all([
|
||||
gql<any>(LEADS_QUERY),
|
||||
gql<any>(CAMPAIGNS_QUERY),
|
||||
gql<any>(ADS_QUERY),
|
||||
gql<any>(FOLLOW_UPS_QUERY),
|
||||
gql<any>(LEAD_ACTIVITIES_QUERY),
|
||||
gql<any>(CALLS_QUERY),
|
||||
gql<any>(PATIENTS_QUERY),
|
||||
]);
|
||||
|
||||
if (leadsData) setLeads(transformLeads(leadsData));
|
||||
@@ -95,6 +100,7 @@ export const DataProvider = ({ children }: DataProviderProps) => {
|
||||
if (followUpsData) setFollowUps(transformFollowUps(followUpsData));
|
||||
if (activitiesData) setLeadActivities(transformLeadActivities(activitiesData));
|
||||
if (callsData) setCalls(transformCalls(callsData));
|
||||
if (patientsData) setPatients(transformPatients(patientsData));
|
||||
} catch (err: any) {
|
||||
setError(err.message ?? 'Failed to load data');
|
||||
} finally {
|
||||
@@ -116,7 +122,7 @@ export const DataProvider = ({ children }: DataProviderProps) => {
|
||||
|
||||
return (
|
||||
<DataContext.Provider value={{
|
||||
leads, campaigns, ads, followUps, leadActivities, templates, agents, calls, ingestionSources,
|
||||
leads, campaigns, ads, followUps, leadActivities, templates, agents, calls, patients, ingestionSources,
|
||||
loading, error,
|
||||
updateLead, addCall, refresh: fetchData,
|
||||
}}>
|
||||
|
||||
Reference in New Issue
Block a user