'use client'; import { useEffect, useState } from 'react'; import { Grid, Card, CardContent, Typography, Box, Chip, CircularProgress, Alert } from '@mui/material'; import { People, Chat, FavoriteBorder, TrendingUp, TrendingDown } from '@mui/icons-material'; interface OverviewStats { totalUsers: number; dailyActiveUsers: number; conversationsToday: number; prayerRequestsToday: number; userGrowthChange: number; conversationChange: number; prayerChange: number; usersToday: number; } interface MetricCardProps { title: string; value: number; change?: number; icon: React.ReactNode; color: 'primary' | 'secondary' | 'success' | 'warning' | 'error' | 'info'; subtitle?: string; } function MetricCard({ title, value, change, icon, color, subtitle }: MetricCardProps) { const isPositiveChange = change !== undefined && change >= 0; return ( {title} {value.toLocaleString()} {subtitle && ( {subtitle} )} {icon} {change !== undefined && ( {isPositiveChange ? ( ) : ( )} vs yesterday )} ); } export function OverviewCards() { const [stats, setStats] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(''); useEffect(() => { const fetchStats = async () => { try { const response = await fetch('/api/admin/stats/overview', { credentials: 'include' }); const data = await response.json(); if (response.ok) { setStats(data); } else { setError(data.error || 'Failed to load stats'); } } catch (error) { setError('Network error loading stats'); } finally { setLoading(false); } }; fetchStats(); // Refresh stats every 30 seconds const interval = setInterval(fetchStats, 30000); return () => clearInterval(interval); }, []); if (loading) { return ( ); } if (error) { return ( {error} ); } if (!stats) return null; return ( } color="primary" subtitle={`${stats.usersToday} new today`} /> } color="success" subtitle="Logged in today" /> } color="info" subtitle="Today" /> } color="warning" subtitle="Today" /> ); }