import { NextRequest, NextResponse } from 'next/server'; import { cookies } from 'next/headers'; import { db } from '@/lib/db'; export const dynamic = 'force-dynamic'; export async function GET(request: NextRequest) { try { // Check newsletter-admin cookie authentication const cookieStore = cookies(); const adminCookie = cookieStore.get('newsletter-admin'); if (!adminCookie || adminCookie.value !== 'authenticated') { return NextResponse.json( { error: 'Unauthorized - Admin login required' }, { status: 401 } ); } // Get 30 days ago date const thirtyDaysAgo = new Date(); thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30); // Get 7 days ago date const sevenDaysAgo = new Date(); sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7); // Get start of current month const startOfMonth = new Date(); startOfMonth.setDate(1); startOfMonth.setHours(0, 0, 0, 0); // Fetch all statistics in parallel const [ totalUsers, premiumUsers, newUsersThisWeek, newUsersThisMonth, totalQRCodes, dynamicQRCodes, staticQRCodes, totalScans, dynamicQRCodesWithScans, activeQRCodes, newsletterSubscribers, ] = await Promise.all([ // Total users db.user.count(), // Premium users (PRO or BUSINESS) db.user.count({ where: { plan: { in: ['PRO', 'BUSINESS'], }, }, }), // New users this week db.user.count({ where: { createdAt: { gte: sevenDaysAgo, }, }, }), // New users this month db.user.count({ where: { createdAt: { gte: startOfMonth, }, }, }), // Total QR codes db.qRCode.count(), // Dynamic QR codes db.qRCode.count({ where: { type: 'DYNAMIC', }, }), // Static QR codes db.qRCode.count({ where: { type: 'STATIC', }, }), // Total scans db.qRScan.count(), // Get all dynamic QR codes with their scan counts db.qRCode.findMany({ where: { type: 'DYNAMIC', }, include: { _count: { select: { scans: true, }, }, }, }), // Active QR codes (scanned in last 30 days) db.qRCode.findMany({ where: { scans: { some: { ts: { gte: thirtyDaysAgo, }, }, }, }, distinct: ['id'], }), // Newsletter subscribers db.newsletterSubscription.count({ where: { status: 'subscribed', }, }), ]); // Calculate dynamic QR scans const dynamicQRScans = dynamicQRCodesWithScans.reduce( (total, qr) => total + qr._count.scans, 0 ); // Calculate average scans per dynamic QR const avgScansPerDynamicQR = dynamicQRCodes > 0 ? (dynamicQRScans / dynamicQRCodes).toFixed(1) : '0'; // Get top 5 most scanned QR codes const topQRCodes = await db.qRCode.findMany({ take: 5, include: { _count: { select: { scans: true, }, }, user: { select: { email: true, name: true, }, }, }, orderBy: { scans: { _count: 'desc', }, }, }); // Get recent users const recentUsers = await db.user.findMany({ take: 5, orderBy: { createdAt: 'desc', }, select: { email: true, name: true, plan: true, createdAt: true, }, }); return NextResponse.json({ users: { total: totalUsers, premium: premiumUsers, newThisWeek: newUsersThisWeek, newThisMonth: newUsersThisMonth, recent: recentUsers, }, qrCodes: { total: totalQRCodes, dynamic: dynamicQRCodes, static: staticQRCodes, active: activeQRCodes.length, }, scans: { total: totalScans, dynamicOnly: dynamicQRScans, avgPerDynamicQR: avgScansPerDynamicQR, }, newsletter: { subscribers: newsletterSubscribers, }, topQRCodes: topQRCodes.map((qr) => ({ id: qr.id, title: qr.title, type: qr.type, scans: qr._count.scans, owner: qr.user.name || qr.user.email, createdAt: qr.createdAt, })), }); } catch (error) { console.error('Error fetching admin stats:', error); return NextResponse.json( { error: 'Failed to fetch statistics' }, { status: 500 } ); } }