import { prisma } from "@/lib/db"; import { checkUserStatus } from "@/lib/dto/user"; import { TIME_RANGES } from "@/lib/enums"; import { getCurrentUser } from "@/lib/session"; import { getStartDate } from "@/lib/utils"; export const revalidate = 60; export async function GET(req: Request) { try { const user = checkUserStatus(await getCurrentUser()); if (user instanceof Response) return user; if (user.role !== "ADMIN") { return Response.json("Unauthorized", { status: 401, statusText: "Unauthorized", }); } const url = new URL(req.url); const range = url.searchParams.get("range") || "7d"; const startDate = getStartDate(range); if (!startDate) { return Response.json({ statusText: "Invalid range" }, { status: 400 }); } // Calculate previous period start and end dates const rangeDuration = TIME_RANGES[range]; const prevStartDate = new Date(startDate.getTime() - rangeDuration); const prevEndDate = startDate; const users = await prisma.user.findMany({ where: { createdAt: { gte: startDate, }, }, orderBy: { createdAt: "desc", }, select: { createdAt: true, }, }); const records = await prisma.userRecord.findMany({ where: { created_on: { gte: startDate, }, }, orderBy: { created_on: "desc", }, select: { created_on: true, }, }); const urls = await prisma.userUrl.findMany({ where: { createdAt: { gte: startDate, }, }, orderBy: { createdAt: "desc", }, select: { createdAt: true, }, }); const emails = await prisma.userEmail.findMany({ where: { createdAt: { gte: startDate, }, }, orderBy: { createdAt: "desc", }, select: { createdAt: true, }, }); const inbox = await prisma.forwardEmail.findMany({ where: { createdAt: { gte: startDate, }, }, orderBy: { createdAt: "desc", }, select: { createdAt: true, }, }); const sends = await prisma.userSendEmail.findMany({ where: { createdAt: { gte: startDate, }, }, orderBy: { createdAt: "desc", }, select: { createdAt: true, }, }); // Fetch previous period data const prevUsers = await prisma.user.findMany({ where: { createdAt: { gte: prevStartDate, lt: prevEndDate, }, }, select: { createdAt: true, }, }); const prevRecords = await prisma.userRecord.findMany({ where: { created_on: { gte: prevStartDate, lt: prevEndDate, }, }, select: { created_on: true, }, }); const prevUrls = await prisma.userUrl.findMany({ where: { createdAt: { gte: prevStartDate, lt: prevEndDate, }, }, select: { createdAt: true, }, }); const prevEmails = await prisma.userEmail.findMany({ where: { createdAt: { gte: prevStartDate, lt: prevEndDate, }, }, select: { createdAt: true, }, }); const prevInbox = await prisma.forwardEmail.findMany({ where: { createdAt: { gte: prevStartDate, lt: prevEndDate, }, }, select: { createdAt: true, }, }); const prevSends = await prisma.userSendEmail.findMany({ where: { createdAt: { gte: prevStartDate, lt: prevEndDate, }, }, select: { createdAt: true, }, }); // Process current period data const userCountByDate: { [date: string]: number } = {}; const recordCountByDate: { [date: string]: number } = {}; const urlCountByDate: { [date: string]: number } = {}; const emailCountByDate: { [date: string]: number } = {}; const inboxCountByDate: { [date: string]: number } = {}; const sendCountByDate: { [date: string]: number } = {}; users.forEach((user) => { const date = user.createdAt!.toISOString().split("T")[0]; userCountByDate[date] = (userCountByDate[date] || 0) + 1; }); records.forEach((record) => { const date = record.created_on!.toISOString().split("T")[0]; recordCountByDate[date] = (recordCountByDate[date] || 0) + 1; }); urls.forEach((url) => { const date = url.createdAt.toISOString().split("T")[0]; urlCountByDate[date] = (urlCountByDate[date] || 0) + 1; }); emails.forEach((email) => { const date = email.createdAt.toISOString().split("T")[0]; emailCountByDate[date] = (emailCountByDate[date] || 0) + 1; }); inbox.forEach((email) => { const date = email.createdAt.toISOString().split("T")[0]; inboxCountByDate[date] = (inboxCountByDate[date] || 0) + 1; }); sends.forEach((send) => { const date = send.createdAt.toISOString().split("T")[0]; sendCountByDate[date] = (sendCountByDate[date] || 0) + 1; }); const allDates = Array.from( new Set([ ...Object.keys(userCountByDate), ...Object.keys(recordCountByDate), ...Object.keys(urlCountByDate), ...Object.keys(emailCountByDate), ...Object.keys(inboxCountByDate), ...Object.keys(sendCountByDate), ]), ); const combinedData = allDates.map((date) => ({ date, records: recordCountByDate[date] || 0, urls: urlCountByDate[date] || 0, users: userCountByDate[date] || 0, emails: emailCountByDate[date] || 0, inbox: inboxCountByDate[date] || 0, sends: sendCountByDate[date] || 0, })); const total = { records: combinedData.reduce((acc, curr) => acc + curr.records, 0), urls: combinedData.reduce((acc, curr) => acc + curr.urls, 0), users: combinedData.reduce((acc, curr) => acc + curr.users, 0), emails: combinedData.reduce((acc, curr) => acc + curr.emails, 0), inbox: combinedData.reduce((acc, curr) => acc + curr.inbox, 0), sends: combinedData.reduce((acc, curr) => acc + curr.sends, 0), }; // Calculate totals for previous period const prevTotal = { records: prevRecords.length, urls: prevUrls.length, users: prevUsers.length, emails: prevEmails.length, inbox: prevInbox.length, sends: prevSends.length, }; // Calculate growth rates const growthRates = { records: prevTotal.records === 0 ? total.records > 0 ? 100 : 0 : ((total.records - prevTotal.records) / prevTotal.records) * 100, urls: prevTotal.urls === 0 ? total.urls > 0 ? 100 : 0 : ((total.urls - prevTotal.urls) / prevTotal.urls) * 100, users: prevTotal.users === 0 ? total.users > 0 ? 100 : 0 : ((total.users - prevTotal.users) / prevTotal.users) * 100, emails: prevTotal.emails === 0 ? total.emails > 0 ? 100 : 0 : ((total.emails - prevTotal.emails) / prevTotal.emails) * 100, inbox: prevTotal.inbox === 0 ? total.inbox > 0 ? 100 : 0 : ((total.inbox - prevTotal.inbox) / prevTotal.inbox) * 100, sends: prevTotal.sends === 0 ? total.sends > 0 ? 100 : 0 : ((total.sends - prevTotal.sends) / prevTotal.sends) * 100, }; return Response.json({ list: combinedData.reverse(), total, growthRates, }); } catch (error) { return Response.json({ statusText: "Server error" }, { status: 500 }); } }