'use client'; import { useState, useEffect } from 'react'; import Link from 'next/link'; import { useLanguage } from '@/context/LanguageContext'; import { useAuth } from '@/context/AuthContext'; import { adminApi, DashboardData } from '@/lib/api'; import Card from '@/components/ui/Card'; import { UsersIcon, CalendarIcon, TicketIcon, CurrencyDollarIcon, EnvelopeIcon, UserGroupIcon, ExclamationTriangleIcon, } from '@heroicons/react/24/outline'; export default function AdminDashboardPage() { const { t, locale } = useLanguage(); const { user } = useAuth(); const [data, setData] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { adminApi.getDashboard() .then(({ dashboard }) => setData(dashboard)) .catch(console.error) .finally(() => setLoading(false)); }, []); const formatDate = (dateStr: string) => { return new Date(dateStr).toLocaleDateString(locale === 'es' ? 'es-ES' : 'en-US', { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit', timeZone: 'America/Asuncion', }); }; const statCards = data ? [ { label: t('admin.dashboard.stats.users'), value: data.stats.totalUsers, icon: UsersIcon, color: 'bg-blue-100 text-blue-600', href: '/admin/users', }, { label: t('admin.dashboard.stats.events'), value: data.stats.totalEvents, icon: CalendarIcon, color: 'bg-purple-100 text-purple-600', href: '/admin/events', }, { label: t('admin.dashboard.stats.tickets'), value: data.stats.confirmedTickets, icon: TicketIcon, color: 'bg-green-100 text-green-600', href: '/admin/tickets', }, { label: t('admin.dashboard.stats.revenue'), value: `${data.stats.totalRevenue.toLocaleString()} PYG`, icon: CurrencyDollarIcon, color: 'bg-yellow-100 text-yellow-600', href: '/admin/payments', }, ] : []; if (loading) { return (
); } return (

{t('admin.dashboard.title')}

{t('admin.dashboard.welcome')}, {user?.name}

{/* Stats Grid */}
{statCards.map((stat) => (

{stat.label}

{stat.value}

))}
{/* Alerts */}

Alerts

{/* Low capacity warnings */} {data?.upcomingEvents .filter(event => { const spotsLeft = Math.max(0, event.capacity - (event.bookedCount || 0)); const percentFull = ((event.bookedCount || 0) / event.capacity) * 100; return percentFull >= 80 && spotsLeft > 0; }) .map(event => { const spotsLeft = Math.max(0, event.capacity - (event.bookedCount || 0)); const percentFull = Math.round(((event.bookedCount || 0) / event.capacity) * 100); return (
{event.title}

Only {spotsLeft} spots left ({percentFull}% full)

Low capacity ); })} {/* Sold out events */} {data?.upcomingEvents .filter(event => Math.max(0, event.capacity - (event.bookedCount || 0)) === 0) .map(event => (
{event.title}

Event is sold out!

Sold out ))} {data && data.stats.pendingPayments > 0 && (
Pending payments
{data.stats.pendingPayments} )} {data && data.stats.newContacts > 0 && (
New messages
{data.stats.newContacts} )} {/* No alerts */} {data && data.stats.pendingPayments === 0 && data.stats.newContacts === 0 && !data.upcomingEvents.some(e => ((e.bookedCount || 0) / e.capacity) >= 0.8) && (

No alerts at this time

)}
{/* Upcoming Events */}

Upcoming Events

{t('common.viewAll')}
{data?.upcomingEvents.length === 0 ? (

No upcoming events

) : (
{data?.upcomingEvents.slice(0, 5).map((event) => (

{event.title}

{formatDate(event.startDatetime)}

{event.bookedCount || 0}/{event.capacity} ))}
)}
{/* Quick Stats */}

Quick Stats

{data?.stats.totalSubscribers || 0}

Subscribers

{data?.stats.totalTickets || 0}

Total Bookings

); }