"use client"; import { useMemo } from "react"; import { useQuery } from "convex/react"; import { Activity, BarChart3, Filter, MousePointerClick } from "lucide-react"; import { api } from "@/convex/_generated/api"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Skeleton } from "@/components/ui/skeleton"; const metricLabels: Record = { foundLeads: "Gefundene Leads", leadsWithContact: "Mit Kontakt", missingContact: "Kontakt fehlt", auditsCreated: "Audits erstellt", approvalsOpen: "Freigaben offen", emailsSent: "E-Mails gesendet", followUpsPlanned: "Follow-ups geplant", followUpsSent: "Follow-ups gesendet", responses: "Antworten", conversations: "Gespräche", offers: "Angebote", wins: "Gewonnen", losses: "Verloren", skippedDuplicates: "Duplikate übersprungen", skippedBlacklisted: "Sperrliste übersprungen", rybbitAuditOpens: "Audit-Öffnungen", rybbitCtaClicks: "CTA-Klicks", }; export function AnalyticsDashboard() { const dashboard = useQuery(api.campaignMetrics.getDashboard, { limit: 20 }); const metricEntries = useMemo(() => { if (!dashboard) { return []; } return Object.entries(dashboard.metrics).filter(([key]) => key in metricLabels); }, [dashboard]); if (dashboard === undefined) { return (
); } return (

Kampagnen-Reporting

Analytics

Filter Kampagne, Nische, PLZ, Radius, Priorität, Status und Zeitraum.

Kampagne: {dashboard.filters.campaigns.length}

Nische: {dashboard.filters.niches.length}

PLZ: {dashboard.filters.postalCodes.length}

Radius: Kampagnenradius

Priorität: Hoch/Mittel/Niedrig

Status: Funnel-Status

Zeitraum: Erstellungsdatum

{metricEntries.map(([key, value]) => (

{metricLabels[key]}

{value}

))}
Run-Details Neue Leads, übersprungene Duplikate, Sperrliste, Fehler und erzeugte Audits. {dashboard.runs.length === 0 ? (

Noch keine Kampagnenläufe.

) : ( dashboard.runs.map((run) => (

{run.status}

Leads {run.newLeads} · Audits {run.auditsGenerated} · Fehler {run.errors}

{run.errorSummary ? (

{run.errorSummary}

) : null}
)) )}
Rybbit Audit-Öffnungen und CTA-Aktivität werden bei Bedarf aus der Rybbit API geladen.

Rybbit-Daten konnten nicht geladen werden, wenn API-URL, Site-ID oder API-Key fehlen.

Public-Audit Tracking läuft nur auf veröffentlichten Audit-Seiten.

); }