| "use client"; |
|
|
| import { useState } from "react"; |
| import { useRouter } from "next/navigation"; |
| import { |
| LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, |
| PieChart, Pie, Cell, BarChart, Bar, Legend |
| } from "recharts"; |
| import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card"; |
| import { Button } from "@/components/ui/button"; |
| import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; |
| import { RefreshCcw } from "lucide-react"; |
|
|
| interface AdminAnalyticsProps { |
| userGrowth: { date: string; count: number }[]; |
| businessCategories: { name: string; value: number }[]; |
| businessStatus: { name: string; value: number }[]; |
| } |
|
|
| const COLORS = ['#0088FE', '#00C49F', '#FFBB28', '#FF8042', '#8884d8']; |
|
|
| export function AdminAnalytics({ userGrowth, businessCategories, businessStatus }: AdminAnalyticsProps) { |
| const router = useRouter(); |
| const [isRefreshing, setIsRefreshing] = useState(false); |
|
|
| const handleRefresh = () => { |
| setIsRefreshing(true); |
| router.refresh(); |
| setTimeout(() => setIsRefreshing(false), 1000); |
| }; |
|
|
| return ( |
| <div className="space-y-4"> |
| <div className="flex items-center justify-between"> |
| <h2 className="text-xl font-semibold">Analytics & Activity</h2> |
| <div className="flex gap-2"> |
| <Button variant="outline" size="sm" onClick={handleRefresh} disabled={isRefreshing}> |
| <RefreshCcw className={`mr-2 h-4 w-4 ${isRefreshing ? "animate-spin" : ""}`} /> |
| Refresh Data |
| </Button> |
| </div> |
| </div> |
| |
| <Tabs defaultValue="growth" className="space-y-4"> |
| <TabsList> |
| <TabsTrigger value="growth">User Growth</TabsTrigger> |
| <TabsTrigger value="demographics">Demographics</TabsTrigger> |
| <TabsTrigger value="status">Lead Status</TabsTrigger> |
| </TabsList> |
| |
| <TabsContent value="growth"> |
| <Card> |
| <CardHeader> |
| <CardTitle>Active Graph (User Signups)</CardTitle> |
| <CardDescription>New user registrations over time</CardDescription> |
| </CardHeader> |
| <CardContent> |
| <div className="h-[300px] w-full"> |
| <ResponsiveContainer width="100%" height="100%"> |
| <LineChart data={userGrowth}> |
| <CartesianGrid strokeDasharray="3 3" /> |
| <XAxis dataKey="date" /> |
| <YAxis allowDecimals={false} /> |
| <Tooltip /> |
| <Line type="monotone" dataKey="count" stroke="#8884d8" strokeWidth={2} activeDot={{ r: 8 }} /> |
| </LineChart> |
| </ResponsiveContainer> |
| </div> |
| </CardContent> |
| </Card> |
| </TabsContent> |
| |
| <TabsContent value="demographics"> |
| <Card> |
| <CardHeader> |
| <CardTitle>Business Categories</CardTitle> |
| <CardDescription>Distribution of scraped businesses by category</CardDescription> |
| </CardHeader> |
| <CardContent> |
| <div className="h-[300px] w-full"> |
| <ResponsiveContainer width="100%" height="100%"> |
| <PieChart> |
| <Pie |
| data={businessCategories} |
| cx="50%" |
| cy="50%" |
| labelLine={false} |
| label={({ name, percent }) => `${name} ${(percent * 100).toFixed(0)}%`} |
| outerRadius={100} |
| fill="#8884d8" |
| dataKey="value" |
| > |
| {businessCategories.map((entry, index) => ( |
| <Cell key={`cell-${index}`} fill={COLORS[index % COLORS.length]} /> |
| ))} |
| </Pie> |
| <Tooltip /> |
| </PieChart> |
| </ResponsiveContainer> |
| </div> |
| </CardContent> |
| </Card> |
| </TabsContent> |
| |
| <TabsContent value="status"> |
| <Card> |
| <CardHeader> |
| <CardTitle>Business Status</CardTitle> |
| <CardDescription>Status breakdown of current leads</CardDescription> |
| </CardHeader> |
| <CardContent> |
| <div className="h-[300px] w-full"> |
| <ResponsiveContainer width="100%" height="100%"> |
| <BarChart data={businessStatus}> |
| <CartesianGrid strokeDasharray="3 3" /> |
| <XAxis dataKey="name" /> |
| <YAxis /> |
| <Tooltip /> |
| <Legend /> |
| <Bar dataKey="value" fill="#82ca9d" name="Count" /> |
| </BarChart> |
| </ResponsiveContainer> |
| </div> |
| </CardContent> |
| </Card> |
| </TabsContent> |
| </Tabs> |
| </div> |
| ); |
| } |
|
|