Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | export const dynamic = "force-dynamic"; /** * Analytics Export API Route * * GET - Generate and download analytics report */ import { NextRequest, NextResponse } from "next/server"; import { withAdmin, withErrorHandling, } from "@/lib/api"; import { generateAnalyticsReport, type ReportFormat, type ReportData } from "@/lib/analytics/services"; import { subDays } from "date-fns"; /** * GET /api/admin/analytics/export * Export analytics report * * Query params: * - format: 'json' | 'csv' | 'html' (default: 'json') * - days: Number of days to include (default: 30) */ async function handleGet(request: NextRequest): Promise<NextResponse> { const { searchParams } = new URL(request.url); const formatParam = searchParams.get("format") || "json"; const days = parseInt(searchParams.get("days") || "30", 10); // Validate format const validFormats: ReportFormat[] = ["json", "csv", "html"]; const format: ReportFormat = validFormats.includes(formatParam as ReportFormat) ? (formatParam as ReportFormat) : "json"; // Validate days const validDays = Math.min(Math.max(days, 1), 365); // Calculate date range const endDate = new Date(); const startDate = subDays(endDate, validDays); const report = await generateAnalyticsReport(startDate, endDate, format); // Return appropriate response based on format switch (format) { case "csv": { const csvContent = report as string; return new NextResponse(csvContent, { headers: { "Content-Type": "text/csv", "Content-Disposition": `attachment; filename="analytics-report-${validDays}d.csv"`, }, }); } case "html": { const htmlContent = report as string; return new NextResponse(htmlContent, { headers: { "Content-Type": "text/html", "Content-Disposition": `inline; filename="analytics-report-${validDays}d.html"`, }, }); } default: { const jsonData = report as ReportData; return NextResponse.json({ success: true, data: jsonData, }); } } } export const GET = withErrorHandling(withAdmin(handleGet)); |