// A reference dashboard for an app built on Outlevo: credits left, each campaign's numbers, the Readiness Cards // waiting for a rep and the queued Revenue Actions. Copy it and change what you like. // Data comes through your own server route (/api/outlevo, see allow.ts); no key reaches the browser. // Needs @outlevo/components (install line: https://developers.outlevo.com/components.html) and React 18+. import { useEffect, useState } from 'react'; import { OutlevoProvider, ReadinessCard, RevenueActionList } from '@outlevo/components'; const BASE = '/api/outlevo'; const fetcher = (path: string, init?: RequestInit) => fetch(`${BASE}${path}`, init); type Usage = { plan: string; monthly: { granted: number; remaining: number }; available: number }; type Campaign = { id: string; name: string; status: string }; type Stats = { leads: number; sent: number; emails_sent: number; replied: number; bounced: number; reply_rate: number | null }; type Handoff = { id: string }; function useJson(path: string | null) { const [data, setData] = useState(null); const [error, setError] = useState(null); useEffect(() => { if (!path) return; let live = true; fetcher(path).then(async (r) => { const body = await r.json(); if (!live) return; if (r.ok) setData(body as T); else setError(body?.error?.message ?? `HTTP ${r.status}`); // error.fix says what to do next }).catch((e) => live && setError(String(e))); return () => { live = false; }; }, [path]); return { data, error }; } const pct = (n: number | null | undefined) => (n == null ? '–' : `${(n * 100).toFixed(1)}%`); function Credits() { const { data, error } = useJson('/v1/usage'); if (error) return

{error}

; if (!data) return

Loading credits…

; return

{data.available.toLocaleString()} credits available · {data.monthly.remaining.toLocaleString()} of {data.monthly.granted.toLocaleString()} left this cycle ({data.plan})

; } function CampaignRow({ c }: { c: Campaign }) { const { data } = useJson(`/v1/campaigns/${c.id}/stats`); return ( {c.name}{c.status} {data?.leads ?? '…'}{data?.emails_sent ?? '…'}{data?.replied ?? '…'}{pct(data?.reply_rate)}{data?.bounced ?? '…'} ); } function Campaigns() { const { data, error } = useJson<{ data: Campaign[] }>('/v1/campaigns?limit=20'); if (error) return

{error}

; if (!data) return

Loading campaigns…

; if (!data.data.length) return

No campaigns yet. They are set up and started in Outlevo.

; return ( {data.data.map((c) => )}
CampaignStatusLeadsEmails sentRepliedReply rateBounced
); } function WaitingCards() { const { data, error } = useJson<{ data: Handoff[] }>('/v1/handoffs?status=delivered&limit=5'); if (error) return

{error}

; if (!data) return

Loading Readiness Cards…

; if (!data.data.length) return

No Readiness Cards waiting.

; return <>{data.data.map((h) => )}; } export function Dashboard() { return (

Outbound

Campaigns

Readiness Cards waiting for a rep

Queued actions

); } export default Dashboard;