import { useQuery, useQueryClient } from "@tanstack/react-query"; import { apiClient } from "../lib/apiClient"; import { Megaphone, Users, Mail, Inbox, Flame, TrendingUp, Sparkles, Activity, Plus, ArrowUpRight, CheckCircle2, ShieldCheck, Radio, Zap } from "lucide-react"; import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, PieChart, Pie, Cell } from "recharts"; import { useState } from "react"; import { Link } from "react-router-dom"; import StatCard from "../components/StatCard"; import StatusBadge from "../components/StatusBadge"; import FormDrawer from "../components/FormDrawer"; import toast from "react-hot-toast"; const lineData = [ { date: "Day 1", sent: 480, open: 310, reply: 28, bounce: 6 }, { date: "Day 4", sent: 820, open: 530, reply: 46, bounce: 10 }, { date: "Day 7", sent: 1250, open: 820, reply: 74, bounce: 14 }, { date: "Day 10", sent: 1780, open: 1190, reply: 105, bounce: 19 }, { date: "Day 14", sent: 2420, open: 1650, reply: 148, bounce: 23 }, { date: "Day 18", sent: 3150, open: 2190, reply: 196, bounce: 31 }, { date: "Day 22", sent: 4020, open: 2840, reply: 254, bounce: 38 }, { date: "Day 26", sent: 4980, open: 3510, reply: 312, bounce: 46 }, { date: "Day 30", sent: 5890, open: 4120, reply: 378, bounce: 52 }, ]; const pieData = [ { name: "Interested", value: 340, color: "var(--nt-success)" }, { name: "Meeting Booked", value: 160, color: "var(--nt-accent)" }, { name: "Replied", value: 290, color: "var(--nt-info)" }, { name: "Not Interested", value: 180, color: "var(--nt-danger)" }, { name: "Bounced", value: 45, color: "var(--nt-espresso-700)" }, ]; export default function Dashboard() { const queryClient = useQueryClient(); const [isCreateCampaignOpen, setIsCreateCampaignOpen] = useState(false); const [activeMetric, setActiveMetric] = useState<"all" | "open" | "reply">("all"); const { data: analytics, isLoading: isAnalyticsLoading, isError: isAnalyticsError } = useQuery({ queryKey: ["analytics-summary"], queryFn: async () => { const res = await apiClient.get("/analytics/campaigns"); return res.data; }, }); const { data: campaigns, isLoading: isCampaignsLoading, isError: isCampaignsError } = useQuery({ queryKey: ["campaigns"], queryFn: async () => { const res = await apiClient.get("/campaigns"); return res.data; }, }); const { data: emailAccounts = [], isLoading: isEmailAccountsLoading } = useQuery({ queryKey: ["email-accounts"], queryFn: async () => { const res = await apiClient.get("/email-accounts"); return res.data; }, }); const warmupDailyCount = emailAccounts.reduce((total: number, account: any) => total + (account.warmup_daily_count || 0), 0); const connectedMailboxCount = emailAccounts.filter((account: any) => account.status === "CONNECTED").length; const warmupScoreValues = emailAccounts.map((account: any) => account.warmup_score).filter((score: any) => typeof score === "number"); const averageWarmupScore = warmupScoreValues.length ? (warmupScoreValues.reduce((total: number, score: number) => total + score, 0) / warmupScoreValues.length).toFixed(1) : null; return (
Real-time deliverability radar, campaign sequencing, and cold outreach throughput.
{connectedMailboxCount} connected mailboxes with {warmupDailyCount} daily warmup messages.
Sent volume, open rate, and reply convergence.
Classification of prospect responses.
Live status, recipient quotas, and response metrics.
| Campaign | Status | Leads | Sent | Opens | Replies | Action |
|---|---|---|---|---|---|---|
|
{camp.name}
{camp.timezone} • {camp.sequences?.length || 1} step sequence
|
|
{camp.lead_count || 0} | {camp.sent_count || 0} | {camp.open_count || 0} | {camp.reply_count || 0} |
Inspect |