Frontend API Guide
Complete reference for frontend integration with all 7 dashboard edge functions. Includes a reusable TypeScript client, per-page endpoint mapping, and UI component suggestions.
Supabase Client Wrapper
// lib/dashboard-api.ts
import { createClientComponentClient } from '@supabase/auth-helpers-nextjs';
const supabase = createClientComponentClient();
async function dashboardFetch<T>(
functionName: string,
params: Record<string, string> = {}
): Promise<T> {
const { data: { session } } = await supabase.auth.getSession();
if (!session) throw new Error('Not authenticated');
const url = new URL(
`${process.env.NEXT_PUBLIC_SUPABASE_URL}/functions/v1/${functionName}`
);
for (const [key, value] of Object.entries(params)) {
if (value !== undefined && value !== null) {
url.searchParams.set(key, value);
}
}
const res = await fetch(url.toString(), {
headers: {
'Authorization': `Bearer ${session.access_token}`,
'Content-Type': 'application/json',
},
});
if (!res.ok) {
const error = await res.json();
throw new Error(error.error || 'Dashboard API error');
}
return res.json();
}
// Typed helpers
export const getOverview = (params?: {
period?: string; campaign_id?: string; client_id?: string;
}) => dashboardFetch('dashboard-overview', params as any);
export const getTimeseries = (params?: {
period?: string; metrics?: string; campaign_id?: string; client_id?: string;
}) => dashboardFetch('dashboard-timeseries', params as any);
export const getFunnel = (params?: {
period?: string; campaign_id?: string; client_id?: string;
}) => dashboardFetch('dashboard-funnel', params as any);
export const getCampaigns = (params?: {
period?: string; status?: string; campaign_id?: string; limit?: string; offset?: string;
}) => dashboardFetch('dashboard-campaigns', params as any);
export const getQuality = (params?: {
period?: string; campaign_id?: string; client_id?: string;
}) => dashboardFetch('dashboard-quality', params as any);
export const getHeatmap = (params?: {
period?: string; metric?: string; campaign_id?: string; client_id?: string;
}) => dashboardFetch('dashboard-heatmap', params as any);
export const getObjections = (params?: {
period?: string; campaign_id?: string; client_id?: string; limit?: string;
}) => dashboardFetch('dashboard-objections', params as any);
Page Layout -- Which Endpoints to Call
Main Dashboard Page
Call these 3 endpoints in parallel on page load:
const [overview, timeseries, funnel] = await Promise.all([
getOverview({ period }),
getTimeseries({ period, metrics: 'total_calls,connected_calls,meetings_booked' }),
getFunnel({ period }),
]);
| Section | Endpoint | Data Used |
|---|---|---|
| KPI Cards | dashboard-overview | summary.* |
| Calls Over Time | dashboard-timeseries | data[].total_calls, connected_calls |
| Conversion Funnel | dashboard-funnel | funnel.*, rates.* |
| Disposition Breakdown | dashboard-overview | disposition_breakdown.* |
| Quality Summary | dashboard-overview | quality.* |
Campaigns Page
const campaigns = await getCampaigns({ period: '30d' });
| Section | Endpoint | Data Used |
|---|---|---|
| Active Batches | dashboard-campaigns | active_batches[] |
| Campaign Table | dashboard-campaigns | campaign_stats[] |
| Pagination | dashboard-campaigns | pagination |
Quality & Analytics Page
Call these 3 endpoints in parallel:
const [quality, heatmap, objections] = await Promise.all([
getQuality({ period: '30d' }),
getHeatmap({ period: '30d' }),
getObjections({ period: '30d' }),
]);
| Section | Endpoint | Data Used |
|---|---|---|
| Quality Metrics | dashboard-quality | quality.* |
| Quality Trends | dashboard-quality | trend[] |
| Best Time to Call | dashboard-heatmap | heatmap[], best_times[] |
| Top Objections | dashboard-objections | top_objections[] |
| Buying Signals | dashboard-objections | top_buying_signals[] |
Endpoint Reference
1. Dashboard Overview
GET /functions/v1/dashboard-overview -- Full reference
| Response Field | UI Component |
|---|---|
summary.total_calls | "Total Calls" KPI card |
summary.contact_rate | "Contact Rate" KPI card |
summary.meetings_booked | "Meetings Booked" KPI card |
summary.overall_conversion_rate | "Conversion Rate" KPI card |
summary.avg_duration_seconds | "Avg Call Duration" KPI card |
summary.qualified_leads | "Qualified Leads" KPI card |
summary.positive_sentiment_pct | Sentiment indicator / badge |
disposition_breakdown.* | Disposition pie/donut chart |
quality.avg_talk_ratio | Talk ratio gauge |
quality.avg_script_adherence | Script adherence gauge |
tool_usage.* | Tool usage stats section |
2. Dashboard Timeseries
GET /functions/v1/dashboard-timeseries -- Full reference
Recommended metrics param per chart type:
| Chart Type | Recommended metrics Param |
|---|---|
| Call volume line chart | total_calls,connected_calls,completed_calls |
| Conversion trend | total_calls,meetings_booked,qualified_leads |
| Sentiment over time | positive_sentiment_calls,neutral_sentiment_calls,negative_sentiment_calls |
| Quality over time | avg_talk_ratio,avg_script_adherence |
| Disposition trend | voicemail_calls,callback_requested_calls,not_interested_calls,no_answer_calls |
| Tool usage over time | emails_sent,sms_sent |
Days with zero calls will not have an entry. Fill gaps with zeros on the frontend.
3. Dashboard Funnel
GET /functions/v1/dashboard-funnel -- Full reference
Render as a horizontal or vertical funnel. Each stage shows the absolute count and the step-to-step conversion rate from rates:
Total Calls (150) -> Connected (110) -> Conversation (85) -> Qualified (25) -> Booked (12)
73.3% 77.3% 29.4% 48.0%
4. Dashboard Campaigns
GET /functions/v1/dashboard-campaigns -- Full reference
| Response Section | UI Component |
|---|---|
active_batches | Active batch progress cards/list |
campaign_stats | Campaign comparison table |
campaign_stats[].contact_rate | Campaign contact rate column |
campaign_stats[].conversion_rate | Campaign conversion column |
pagination | Table pagination controls |
5. Dashboard Quality
GET /functions/v1/dashboard-quality -- Full reference
| Response Field | UI Component |
|---|---|
quality.avg_talk_ratio | Talk/Listen ratio donut or gauge |
quality.avg_script_adherence | Script adherence progress bar |
quality.avg_interruptions_per_call | Interruptions KPI card |
quality.sentiment_distribution | Sentiment pie chart |
quality.objection_handling_rate | Objection handling KPI |
trend[] | Daily quality line charts |
6. Dashboard Heatmap
GET /functions/v1/dashboard-heatmap -- Full reference
| Response Field | UI Component |
|---|---|
heatmap[] | 7x24 heatmap grid (color intensity = value) |
best_times[] | "Top 5 Best Times" cards/badges |
Hours are in UTC. Convert to the user's timezone on the frontend before rendering.
7. Dashboard Objections
GET /functions/v1/dashboard-objections -- Full reference
| Response Field | UI Component |
|---|---|
top_objections[] | Objections ranked bar chart / table |
top_objections[].success_rate | Success rate badge per objection |
top_buying_signals[] | Buying signals word cloud or list |
objection_rate | "Objection Rate" KPI card |
Next.js Page Example
'use client';
import { useEffect, useState } from 'react';
import { getOverview, getTimeseries, getFunnel } from '@/lib/dashboard-api';
export default function DashboardPage() {
const [period, setPeriod] = useState('7d');
const [overview, setOverview] = useState(null);
const [timeseries, setTimeseries] = useState(null);
const [funnel, setFunnel] = useState(null);
useEffect(() => {
Promise.all([
getOverview({ period }),
getTimeseries({ period, metrics: 'total_calls,connected_calls,meetings_booked' }),
getFunnel({ period }),
]).then(([o, t, f]) => {
setOverview(o);
setTimeseries(t);
setFunnel(f);
});
}, [period]);
// Render KPI cards from overview.summary
// Render charts from timeseries.data
// Render funnel from funnel.funnel + funnel.rates
}
Real-time Batch Progress
For live batch progress updates, use Supabase Realtime:
const channel = supabase
.channel('batch-progress')
.on('postgres_changes', {
event: 'UPDATE',
schema: 'public',
table: 'call_batches',
filter: `id=eq.${batchId}`,
}, (payload) => {
setBatchProgress(payload.new);
})
.subscribe();