'use client'; import { useState, useEffect } from 'react'; import { motion } from 'framer-motion'; import { DollarSign, Package, Leaf, TrendingUp, Calendar, Loader2 } from 'lucide-react'; import { LineChart, Line, PieChart, Pie, Cell, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer, } from 'recharts'; interface DashboardStats { totalOrders: number; totalRevenue: number; totalCO2Offset: number; fulfillmentRate: number; ordersByStatus: { pending: number; paid: number; fulfilled: number; cancelled: number; }; } interface TimelineData { date: string; count: number; revenue: number; } type TimeRange = '7d' | '30d' | '90d' | 'all'; export default function AdminDashboard() { const [stats, setStats] = useState(null); const [timeline, setTimeline] = useState([]); const [isLoading, setIsLoading] = useState(true); const [timeRange, setTimeRange] = useState('30d'); const [error, setError] = useState(null); // Fetch dashboard data useEffect(() => { fetchDashboardData(); }, [timeRange]); const fetchDashboardData = async () => { setIsLoading(true); setError(null); try { // Calculate date range const dateTo = new Date().toISOString().split('T')[0]; let dateFrom: string | undefined; if (timeRange !== 'all') { const days = timeRange === '7d' ? 7 : timeRange === '30d' ? 30 : 90; const fromDate = new Date(); fromDate.setDate(fromDate.getDate() - days); dateFrom = fromDate.toISOString().split('T')[0]; } // Build query params const params = new URLSearchParams(); if (dateFrom) params.append('dateFrom', dateFrom); params.append('dateTo', dateTo); params.append('period', timeRange === '7d' ? 'day' : 'week'); const response = await fetch(`/api/admin/stats?${params}`); const data = await response.json(); if (!response.ok) { throw new Error(data.error || 'Failed to fetch dashboard data'); } setStats(data.data.stats); setTimeline(data.data.timeline); } catch (err) { console.error('Error fetching dashboard data:', err); setError(err instanceof Error ? err.message : 'Failed to load dashboard'); } finally { setIsLoading(false); } }; // Prepare pie chart data const pieChartData = stats ? [ { name: 'Pending', value: stats.ordersByStatus.pending, color: '#D68910' }, { name: 'Paid', value: stats.ordersByStatus.paid, color: '#008B8B' }, { name: 'Fulfilled', value: stats.ordersByStatus.fulfilled, color: '#1E8449' }, { name: 'Cancelled', value: stats.ordersByStatus.cancelled, color: '#DC2626' }, ] : []; const statCards = stats ? [ { title: 'Total Orders', value: stats.totalOrders.toLocaleString(), icon: , gradient: 'bg-gradient-to-br from-royal-purple to-purple-600', }, { title: 'Total CO₂ Offset', value: `${stats.totalCO2Offset.toFixed(2)} tons`, icon: , gradient: 'bg-gradient-to-br from-sea-green to-green-600', }, { title: 'Total Revenue', value: `$${stats.totalRevenue.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`, icon: , gradient: 'bg-gradient-to-br from-muted-gold to-orange-600', }, { title: 'Fulfillment Rate', value: `${stats.fulfillmentRate.toFixed(1)}%`, icon: , gradient: 'bg-gradient-to-br from-maritime-teal to-teal-600', }, ] : []; if (error) { return (

Dashboard

{error}

); } return (
{/* Header with Time Range Selector */}

Dashboard

Overview of your carbon offset operations

{(['7d', '30d', '90d', 'all'] as TimeRange[]).map((range) => ( ))}
{/* Loading State */} {isLoading ? (
) : ( <> {/* Stats Grid */}
{statCards.map((stat, index) => (
{stat.icon}

{stat.title}

{stat.value}

))}
{/* Charts */}
{/* Orders Timeline */}

Orders Over Time

{timeline.length > 0 ? ( ) : (
No orders data available for this time range
)}
{/* Status Distribution */}

Status Distribution

{stats && stats.totalOrders > 0 ? ( `${name}: ${(percent * 100).toFixed(0)}%`} outerRadius={80} fill="#8884d8" dataKey="value" > {pieChartData.map((entry, index) => ( ))} ) : (
No orders to display
)}
)}
); }