AutoLoop / components /analytics-dashboard.tsx
shubhjn's picture
Deploy Clean V1
8dd52b2
"use client";
import { useEffect, useState } from "react";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { TrendingUp, TrendingDown, Mail, MousePointer, Reply } from "lucide-react";
import { useApi } from "@/hooks/use-api";
interface CampaignMetrics {
totalSent: number;
delivered: number;
opened: number;
clicked: number;
replied: number;
bounced: number;
deliveryRate: number;
openRate: number;
clickRate: number;
replyRate: number;
}
interface AnalyticsDashboardProps {
userId?: string;
}
export function AnalyticsDashboard({ userId }: AnalyticsDashboardProps) {
const [metrics, setMetrics] = useState<CampaignMetrics | null>(null);
const { get, loading } = useApi<CampaignMetrics>();
useEffect(() => {
async function fetchAnalytics() {
const data = await get("/api/analytics");
if (data) {
setMetrics(data);
}
}
fetchAnalytics();
}, [get, userId]);
if (loading) {
return (
<div className="space-y-6">
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
{Array.from({ length: 4 }).map((_, i) => (
<Card key={i}>
<CardHeader className="space-y-2">
<div className="h-4 w-24 bg-muted animate-pulse rounded" />
<div className="h-8 w-32 bg-muted animate-pulse rounded" />
</CardHeader>
</Card>
))}
</div>
</div>
);
}
// Default values if no data
const data = metrics || {
totalSent: 0,
delivered: 0,
opened: 0,
clicked: 0,
replied: 0,
bounced: 0,
deliveryRate: 0,
openRate: 0,
clickRate: 0,
replyRate: 0,
};
return (
<div className="space-y-6">
<div>
<h2 className="text-3xl font-bold tracking-tight">Analytics Dashboard</h2>
<p className="text-muted-foreground">
Track your email campaign performance and metrics
</p>
</div>
<Tabs defaultValue="overview" className="space-y-4">
<TabsList>
<TabsTrigger value="overview">Overview</TabsTrigger>
<TabsTrigger value="campaigns">Campaigns</TabsTrigger>
<TabsTrigger value="engagement">Engagement</TabsTrigger>
</TabsList>
<TabsContent value="overview" className="space-y-4">
{/* Key Metrics */}
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium">Emails Sent</CardTitle>
<Mail className="h-4 w-4 text-muted-foreground" />
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">{data.totalSent.toLocaleString()}</div>
<p className="text-xs text-muted-foreground">
{data.delivered} delivered ({data.deliveryRate.toFixed(1)}%)
</p>
</CardContent>
</Card>
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium">Open Rate</CardTitle>
{data.openRate > 25 ? (
<TrendingUp className="h-4 w-4 text-green-600" />
) : (
<TrendingDown className="h-4 w-4 text-red-600" />
)}
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">{data.openRate.toFixed(1)}%</div>
<p className="text-xs text-muted-foreground">
{data.opened} of {data.delivered} emails
</p>
</CardContent>
</Card>
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium">Click Rate</CardTitle>
<MousePointer className="h-4 w-4 text-muted-foreground" />
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">{data.clickRate.toFixed(1)}%</div>
<p className="text-xs text-muted-foreground">
{data.clicked} clicks
</p>
</CardContent>
</Card>
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium">Reply Rate</CardTitle>
<Reply className="h-4 w-4 text-muted-foreground" />
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">{data.replyRate.toFixed(1)}%</div>
<p className="text-xs text-muted-foreground">
{data.replied} replies
</p>
</CardContent>
</Card>
</div>
{/* Detailed Metrics */}
<Card>
<CardHeader>
<CardTitle>Performance Breakdown</CardTitle>
<CardDescription>Detailed metrics for your campaigns</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<div className="space-y-2">
<div className="flex items-center justify-between">
<span className="text-sm font-medium">Delivery Rate</span>
<span className="text-sm text-muted-foreground">{data.deliveryRate.toFixed(1)}%</span>
</div>
<div className="h-2 rounded-full bg-muted overflow-hidden">
<div
className="h-full bg-green-600 transition-all"
style={{ width: `${data.deliveryRate}%` }}
/>
</div>
</div>
<div className="space-y-2">
<div className="flex items-center justify-between">
<span className="text-sm font-medium">Open Rate</span>
<span className="text-sm text-muted-foreground">{data.openRate.toFixed(1)}%</span>
</div>
<div className="h-2 rounded-full bg-muted overflow-hidden">
<div
className="h-full bg-blue-600 transition-all"
style={{ width: `${data.openRate}%` }}
/>
</div>
</div>
<div className="space-y-2">
<div className="flex items-center justify-between">
<span className="text-sm font-medium">Click Rate</span>
<span className="text-sm text-muted-foreground">{data.clickRate.toFixed(1)}%</span>
</div>
<div className="h-2 rounded-full bg-muted overflow-hidden">
<div
className="h-full bg-purple-600 transition-all"
style={{ width: `${data.clickRate}%` }}
/>
</div>
</div>
<div className="space-y-2">
<div className="flex items-center justify-between">
<span className="text-sm font-medium">Reply Rate</span>
<span className="text-sm text-muted-foreground">{data.replyRate.toFixed(1)}%</span>
</div>
<div className="h-2 rounded-full bg-muted overflow-hidden">
<div
className="h-full bg-orange-600 transition-all"
style={{ width: `${data.replyRate}%` }}
/>
</div>
</div>
{data.bounced > 0 && (
<div className="pt-4 border-t">
<div className="flex items-center justify-between text-sm">
<span className="text-muted-foreground">Bounced Emails</span>
<span className="font-medium text-destructive">{data.bounced}</span>
</div>
</div>
)}
</CardContent>
</Card>
</TabsContent>
<TabsContent value="campaigns" className="space-y-4">
<Card>
<CardHeader>
<CardTitle>Campaign Overview</CardTitle>
<CardDescription>Performance metrics across all campaigns</CardDescription>
</CardHeader>
<CardContent>
<div className="text-center py-8 text-muted-foreground">
<p>Campaign comparison data will be available once you have multiple active campaigns.</p>
</div>
</CardContent>
</Card>
</TabsContent>
<TabsContent value="engagement" className="space-y-4">
<Card>
<CardHeader>
<CardTitle>Engagement Metrics</CardTitle>
<CardDescription>Track how recipients interact with your emails</CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-4">
<div className="grid gap-4 md:grid-cols-3">
<div className="space-y-2">
<p className="text-sm font-medium">Total Engagements</p>
<p className="text-3xl font-bold">{data.opened + data.clicked + data.replied}</p>
</div>
<div className="space-y-2">
<p className="text-sm font-medium">Unique Opens</p>
<p className="text-3xl font-bold">{data.opened}</p>
</div>
<div className="space-y-2">
<p className="text-sm font-medium">Link Clicks</p>
<p className="text-3xl font-bold">{data.clicked}</p>
</div>
</div>
</div>
</CardContent>
</Card>
</TabsContent>
</Tabs>
</div>
);
}