'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"
/>
);
}