Download src/pages/Analytics.tsx from sitcod3/modul-s: direct link, hf CLI and curl.
- Browser
- Download file 11.4 kB
-
https://huggingface.co/spaces/sitcod3/modul-s/resolve/main/src/pages/Analytics.tsx
- Command line
-
hf download hf://spaces/sitcod3/modul-s/src/pages/Analytics.tsx
-
curl -L -o Analytics.tsx https://huggingface.co/spaces/sitcod3/modul-s/resolve/main/src/pages/Analytics.tsx
11.4 kB
| import { useQuery } from "@tanstack/react-query"; | |
| import { apiClient } from "../lib/apiClient"; | |
| import { | |
| BarChart2, | |
| TrendingUp, | |
| Download, | |
| Calendar, | |
| Mail, | |
| Inbox, | |
| Flame, | |
| ShieldCheck, | |
| Percent, | |
| ArrowUpRight | |
| } from "lucide-react"; | |
| import { | |
| ResponsiveContainer, | |
| LineChart, | |
| Line, | |
| BarChart, | |
| Bar, | |
| XAxis, | |
| YAxis, | |
| CartesianGrid, | |
| Tooltip, | |
| Legend | |
| } from "recharts"; | |
| import { useState } from "react"; | |
| import StatCard from "../components/StatCard"; | |
| import CsvExportButton from "../components/CsvExportButton"; | |
| const timelineData = [ | |
| { date: "Oct 1", sent: 820, opens: 530, replies: 48, bounces: 4 }, | |
| { date: "Oct 5", sent: 1140, opens: 760, replies: 72, bounces: 8 }, | |
| { date: "Oct 10", sent: 1650, opens: 1120, replies: 98, bounces: 11 }, | |
| { date: "Oct 15", sent: 2100, opens: 1450, replies: 134, bounces: 15 }, | |
| { date: "Oct 20", sent: 2800, opens: 1980, replies: 182, bounces: 21 }, | |
| { date: "Oct 25", sent: 3400, opens: 2450, replies: 226, bounces: 28 }, | |
| { date: "Oct 30", sent: 4120, opens: 2980, replies: 280, bounces: 34 }, | |
| ]; | |
| const campaignComparisonData = [ | |
| { name: "SaaS Enterprise VPs", sent: 4200, opens: 2600, replies: 240 }, | |
| { name: "Series A Tech Founders", sent: 3100, opens: 2100, replies: 195 }, | |
| { name: "Agency Owners Q4", sent: 2400, opens: 1400, replies: 120 }, | |
| { name: "E-commerce Directors", sent: 1800, opens: 980, replies: 84 }, | |
| { name: "RevOps Decision Makers", sent: 1200, opens: 720, replies: 65 }, | |
| ]; | |
| export default function Analytics() { | |
| const [dateRange, setDateRange] = useState("30d"); | |
| const { data: analytics } = useQuery({ | |
| queryKey: ["analytics-campaigns"], | |
| queryFn: async () => { | |
| const res = await apiClient.get("/analytics/campaigns"); | |
| return res.data; | |
| }, | |
| }); | |
| const { data: emailAccounts = [] } = useQuery({ | |
| queryKey: ["email-accounts"], | |
| queryFn: async () => { | |
| const res = await apiClient.get("/email-accounts"); | |
| return res.data; | |
| }, | |
| }); | |
| return ( | |
| <div className="p-6 max-w-7xl mx-auto space-y-6"> | |
| {/* Header */} | |
| <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4"> | |
| <div> | |
| <h1 className="text-2xl font-bold tracking-tight text-zinc-100 flex items-center gap-2.5"> | |
| <BarChart2 className="w-6 h-6 text-indigo-400" /> | |
| Outbound Analytics & Intelligence | |
| </h1> | |
| <p className="text-zinc-400 text-sm mt-1"> | |
| Global deliverability performance, engagement conversion funnels, and mailbox health telemetry. | |
| </p> | |
| </div> | |
| <div className="flex items-center gap-3"> | |
| <select | |
| value={dateRange} | |
| onChange={(e) => setDateRange(e.target.value)} | |
| className="bg-zinc-900 border border-zinc-800 rounded-lg py-2 px-3 text-xs text-zinc-200 focus:outline-none focus:border-indigo-500" | |
| > | |
| <option value="7d">Last 7 Days</option> | |
| <option value="14d">Last 14 Days</option> | |
| <option value="30d">Last 30 Days</option> | |
| <option value="90d">Last 90 Days</option> | |
| </select> | |
| <CsvExportButton data={timelineData} filename="smartlead-analytics-export.csv" /> | |
| </div> | |
| </div> | |
| {/* KPI Conversion Cards */} | |
| <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4"> | |
| <StatCard | |
| title="Open Rate" | |
| value="64.8%" | |
| subtitle="4,890 unique opens" | |
| icon={Mail} | |
| iconColor="emerald" | |
| change={{ value: "+3.4%", isPositive: true, period: "vs benchmark" }} | |
| /> | |
| <StatCard | |
| title="Click Rate (CTR)" | |
| value="18.2%" | |
| subtitle="1,120 link clicks" | |
| icon={ArrowUpRight} | |
| iconColor="blue" | |
| change={{ value: "+1.1%", isPositive: true, period: "last 30 days" }} | |
| /> | |
| <StatCard | |
| title="Reply Rate" | |
| value="6.2%" | |
| subtitle="378 prospect responses" | |
| icon={Inbox} | |
| iconColor="purple" | |
| change={{ value: "+0.8%", isPositive: true, period: "positive intent" }} | |
| /> | |
| <StatCard | |
| title="Bounce Rate" | |
| value="0.7%" | |
| subtitle="Deliverability safe" | |
| icon={ShieldCheck} | |
| iconColor="teal" | |
| change={{ value: "-0.2%", isPositive: true, period: "health optimal" }} | |
| /> | |
| </div> | |
| {/* Timeline Chart */} | |
| <div className="bg-white/5 border border-white/10 backdrop-blur-md rounded-xl p-5 shadow-[0_8px_32px_-8px_rgba(0,0,0,0.5)]"> | |
| <div className="flex items-center justify-between mb-6"> | |
| <div> | |
| <h3 className="text-base font-semibold text-zinc-100">Cumulative Volume & Responses</h3> | |
| <p className="text-xs text-zinc-400 mt-0.5"> | |
| Daily trajectory of outbound sends, unique opens, and replied prospects. | |
| </p> | |
| </div> | |
| </div> | |
| <div className="h-[320px] w-full"> | |
| <ResponsiveContainer width="100%" height="100%"> | |
| <LineChart data={timelineData} margin={{ top: 5, right: 20, bottom: 5, left: 0 }}> | |
| <CartesianGrid strokeDasharray="3 3" stroke="rgba(255,255,255,0.05)" vertical={false} /> | |
| <XAxis dataKey="date" stroke="#a1a1aa" fontSize={12} tickLine={false} axisLine={false} /> | |
| <YAxis stroke="#a1a1aa" fontSize={12} tickLine={false} axisLine={false} tickFormatter={(val) => new Intl.NumberFormat('en-US').format(val)} className="font-mono" /> | |
| <Tooltip | |
| contentStyle={{ | |
| backgroundColor: "rgba(9, 9, 11, 0.8)", | |
| backdropFilter: "blur(12px)", | |
| borderColor: "rgba(255,255,255,0.1)", | |
| borderRadius: "12px", | |
| fontSize: "12px", | |
| color: "#e4e4e7" | |
| }} | |
| /> | |
| <Legend wrapperStyle={{ fontSize: "12px", paddingTop: "10px" }} /> | |
| <Line type="monotone" dataKey="sent" name="Emails Sent" stroke="#3b82f6" strokeWidth={3} dot={{ r: 4, fill: '#3b82f6', strokeWidth: 2, stroke: '#000' }} activeDot={{ r: 6, fill: '#60a5fa' }} animationDuration={1500} /> | |
| <Line type="monotone" dataKey="opens" name="Opens" stroke="#10b981" strokeWidth={3} dot={{ r: 4, fill: '#10b981', strokeWidth: 2, stroke: '#000' }} activeDot={{ r: 6, fill: '#34d399' }} animationDuration={1500} /> | |
| <Line type="monotone" dataKey="replies" name="Replies" stroke="#a855f7" strokeWidth={3} dot={{ r: 4, fill: '#a855f7', strokeWidth: 2, stroke: '#000' }} activeDot={{ r: 6, fill: '#c084fc' }} animationDuration={1500} /> | |
| </LineChart> | |
| </ResponsiveContainer> | |
| </div> | |
| </div> | |
| {/* Comparison Grid */} | |
| <div className="grid grid-cols-1 lg:grid-cols-2 gap-6"> | |
| {/* Top Campaigns Comparison */} | |
| <div className="bg-white/5 border border-white/10 backdrop-blur-md rounded-xl p-5 shadow-[0_8px_32px_-8px_rgba(0,0,0,0.5)]"> | |
| <h3 className="text-base font-semibold text-zinc-100 mb-1">Top Campaign Performance</h3> | |
| <p className="text-xs text-zinc-400 mb-4">Volume dispatched vs. engaged prospects.</p> | |
| <div className="h-[280px] w-full"> | |
| <ResponsiveContainer width="100%" height="100%"> | |
| <BarChart data={campaignComparisonData} layout="vertical" margin={{ top: 5, right: 20, bottom: 5, left: 40 }}> | |
| <defs> | |
| <linearGradient id="colorOpens" x1="0" y1="0" x2="1" y2="0"> | |
| <stop offset="0%" stopColor="#10b981" stopOpacity={0.8}/> | |
| <stop offset="100%" stopColor="#34d399" stopOpacity={1}/> | |
| </linearGradient> | |
| <linearGradient id="colorReplies" x1="0" y1="0" x2="1" y2="0"> | |
| <stop offset="0%" stopColor="#a855f7" stopOpacity={0.8}/> | |
| <stop offset="100%" stopColor="#c084fc" stopOpacity={1}/> | |
| </linearGradient> | |
| </defs> | |
| <CartesianGrid strokeDasharray="3 3" stroke="rgba(255,255,255,0.05)" horizontal={false} /> | |
| <XAxis type="number" stroke="#a1a1aa" fontSize={11} tickLine={false} axisLine={false} className="font-mono" /> | |
| <YAxis dataKey="name" type="category" stroke="#a1a1aa" fontSize={11} tickLine={false} axisLine={false} /> | |
| <Tooltip | |
| contentStyle={{ | |
| backgroundColor: "rgba(9, 9, 11, 0.8)", | |
| backdropFilter: "blur(12px)", | |
| borderColor: "rgba(255,255,255,0.1)", | |
| borderRadius: "12px", | |
| fontSize: "12px", | |
| }} | |
| /> | |
| <Bar dataKey="opens" name="Opens" fill="url(#colorOpens)" radius={[0, 4, 4, 0]} animationDuration={1500}> | |
| </Bar> | |
| <Bar dataKey="replies" name="Replies" fill="url(#colorReplies)" radius={[0, 4, 4, 0]} animationDuration={1500} /> | |
| </BarChart> | |
| </ResponsiveContainer> | |
| </div> | |
| </div> | |
| {/* Mailbox Deliverability Health Matrix */} | |
| <div className="bg-white/5 border border-white/10 backdrop-blur-md rounded-xl p-5 shadow-[0_8px_32px_-8px_rgba(0,0,0,0.5)] flex flex-col justify-between"> | |
| <div> | |
| <h3 className="text-base font-semibold text-zinc-100 mb-1">Mailbox Deliverability Matrix</h3> | |
| <p className="text-xs text-zinc-400 mb-4">DNS authentication, warmup status, and health metrics.</p> | |
| <div className="space-y-3"> | |
| {emailAccounts.map((acc: any) => ( | |
| <div | |
| key={acc.id} | |
| className="flex items-center justify-between p-3 bg-white/5 border border-white/10 rounded-lg text-xs hover:bg-white/10 transition-colors" | |
| > | |
| <div> | |
| <span className="font-semibold text-zinc-200">{acc.from_email}</span> | |
| <div className="text-[10px] text-zinc-400 mt-0.5"> | |
| SPF: PASS • DKIM: PASS • DMARC: PASS | |
| </div> | |
| </div> | |
| <div className="flex items-center gap-3 font-mono"> | |
| <span className="text-emerald-400 font-bold drop-shadow-[0_0_8px_rgba(52,211,153,0.5)]">99.4%</span> | |
| <span className="px-2 py-0.5 bg-emerald-500/20 text-emerald-300 border border-emerald-500/30 rounded text-[10px]"> | |
| Optimal | |
| </span> | |
| </div> | |
| </div> | |
| ))} | |
| </div> | |
| </div> | |
| <div className="mt-4 pt-3 border-t border-white/10 text-[11px] text-zinc-400 flex items-center justify-between"> | |
| <span>Global Reputation: <span className="font-mono text-zinc-300">98.4 / 100</span></span> | |
| <span className="text-emerald-400 flex items-center gap-1.5"><ShieldCheck className="w-3.5 h-3.5" /> All Nodes Secure</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| ); | |
| } | |