'use client'; import React, { useState, useEffect } from 'react'; import { useRouter } from 'next/navigation'; import { Card } from '@/components/ui/Card'; import { Button } from '@/components/ui/Button'; import { Badge } from '@/components/ui/Badge'; import { Mail, Users, QrCode, BarChart3, TrendingUp, Crown, Activity, Loader2, Lock, LogOut, Zap, Send, CheckCircle2, } from 'lucide-react'; interface AdminStats { users: { total: number; premium: number; newThisWeek: number; newThisMonth: number; recent: Array<{ email: string; name: string | null; plan: string; createdAt: string; }>; }; qrCodes: { total: number; dynamic: number; static: number; active: number; }; scans: { total: number; dynamicOnly: number; avgPerDynamicQR: string; }; newsletter: { subscribers: number; }; topQRCodes: Array<{ id: string; title: string; type: string; scans: number; owner: string; createdAt: string; }>; } export default function AdminDashboard() { const router = useRouter(); const [isAuthenticated, setIsAuthenticated] = useState(false); const [isAuthenticating, setIsAuthenticating] = useState(true); const [loginError, setLoginError] = useState(''); const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [stats, setStats] = useState(null); const [loading, setLoading] = useState(true); // Newsletter management state const [newsletterData, setNewsletterData] = useState<{ total: number; recent: Array<{ email: string; createdAt: string }>; } | null>(null); const [sendingBroadcast, setSendingBroadcast] = useState(false); const [broadcastResult, setBroadcastResult] = useState<{ success: boolean; message: string; } | null>(null); useEffect(() => { checkAuth(); }, []); const checkAuth = async () => { try { const response = await fetch('/api/admin/stats'); if (response.ok) { setIsAuthenticated(true); const data = await response.json(); setStats(data); setLoading(false); // Also fetch newsletter data fetchNewsletterData(); } else { setIsAuthenticated(false); } } catch (error) { setIsAuthenticated(false); } finally { setIsAuthenticating(false); } }; const fetchNewsletterData = async () => { try { const response = await fetch('/api/newsletter/broadcast'); if (response.ok) { const data = await response.json(); setNewsletterData(data); } } catch (error) { console.error('Failed to fetch newsletter data:', error); } }; const handleSendBroadcast = async () => { if (!confirm(`Are you sure you want to send the AI Feature Launch email to all ${newsletterData?.total || 0} subscribers?`)) { return; } setSendingBroadcast(true); setBroadcastResult(null); try { const response = await fetch('/api/newsletter/broadcast', { method: 'POST', }); const data = await response.json(); if (response.ok) { setBroadcastResult({ success: true, message: data.message || `Successfully sent to ${data.sent} subscribers!`, }); } else { setBroadcastResult({ success: false, message: data.error || 'Failed to send broadcast', }); } } catch (error) { setBroadcastResult({ success: false, message: 'Network error. Please try again.', }); } finally { setSendingBroadcast(false); } }; const handleLogin = async (e: React.FormEvent) => { e.preventDefault(); setLoginError(''); setIsAuthenticating(true); try { const response = await fetch('/api/newsletter/admin-login', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ email, password }), }); if (response.ok) { setIsAuthenticated(true); await checkAuth(); } else { const data = await response.json(); setLoginError(data.error || 'Invalid credentials'); } } catch (error) { setLoginError('Login failed. Please try again.'); } finally { setIsAuthenticating(false); } }; const handleLogout = async () => { await fetch('/api/auth/logout', { method: 'POST' }); router.push('/'); }; // Login Screen if (!isAuthenticated) { return (

Admin Dashboard

Sign in to access admin panel

setEmail(e.target.value)} placeholder="admin@example.com" required className="w-full px-4 py-3 rounded-xl bg-background border border-border focus:border-purple-500 focus:ring-2 focus:ring-purple-500/20 outline-none transition-all" />
setPassword(e.target.value)} placeholder="••••••••" required className="w-full px-4 py-3 rounded-xl bg-background border border-border focus:border-purple-500 focus:ring-2 focus:ring-purple-500/20 outline-none transition-all" />
{loginError && (

{loginError}

)}

Admin credentials required

); } // Loading if (loading) { return (
); } // Admin Dashboard return (
{/* Header */}

Admin Dashboard

Platform overview and statistics

{/* Main Stats Grid */}
{/* All Time Users */}
All Time

{stats?.users.total || 0}

Total Users

This Month +{stats?.users.newThisMonth || 0}
This Week +{stats?.users.newThisWeek || 0}
{/* Dynamic QR Codes */}
Dynamic

{stats?.qrCodes.dynamic || 0}

Dynamic QR Codes

Static {stats?.qrCodes.static || 0}
{/* Total Scans */}
All Time

{stats?.scans.dynamicOnly.toLocaleString() || 0}

Dynamic QR Scans

Avg per QR {stats?.scans.avgPerDynamicQR || 0}
{/* Total QR Codes */}
All Time

{stats?.qrCodes.total || 0}

Total QR Codes

Dynamic {stats?.qrCodes.dynamic || 0}
Static {stats?.qrCodes.static || 0}
{/* Secondary Stats Row */}
{/* Total All Scans */}

{stats?.scans.total.toLocaleString() || 0}

Total All Scans

{/* Total QR Codes */}

{stats?.qrCodes.total || 0}

Total QR Codes

{/* Premium Users */}

{stats?.users.premium || 0}

Premium Users

{/* Bottom Grid */}
{/* Top QR Codes */}

Top QR Codes

Most scanned

{stats?.topQRCodes && stats.topQRCodes.length > 0 ? (
{stats.topQRCodes.map((qr, index) => (
#{index + 1}

{qr.title}

{qr.owner}

{qr.scans.toLocaleString()}

scans

))}
) : (

No QR codes yet

)}
{/* Recent Users */}

Recent Users

Latest signups

{stats?.users.recent && stats.users.recent.length > 0 ? (
{stats.users.recent.map((user, index) => (
{(user.name || user.email).charAt(0).toUpperCase()}

{user.name || user.email}

{new Date(user.createdAt).toLocaleDateString()}

{user.plan === 'PRO' && } {user.plan}
))}
) : (

No users yet

)}
{/* Newsletter Management Section */}

Newsletter Management

Manage AI feature launch notifications

{newsletterData?.total || 0}

Total Subscribers

Active
{/* Broadcast Section */}

Broadcast AI Feature Launch

Send the AI feature launch announcement to all {newsletterData?.total || 0} subscribers. This will inform them that the features are now available.

{/* Resend Free Tier Warning */} {(newsletterData?.total || 0) > 100 && (
Warning: Resend Free Limit

You have more than 100 subscribers. The Resend Free Tier only allows 100 emails per day. Sending this broadcast might fail for some users or block your account.

)} {broadcastResult && (
{broadcastResult.success && } {broadcastResult.message}
)}
{/* Recent Subscribers */}

Recent Subscribers

{newsletterData?.recent && newsletterData.recent.length > 0 ? (
{newsletterData.recent.map((subscriber, index) => (
{subscriber.email}
{new Date(subscriber.createdAt).toLocaleDateString()}
))}
) : (

No subscribers yet

)}
{/* Tip */}

💡 Tip: View all subscribers in{' '} Prisma Studio {' '}(NewsletterSubscription table)

); }