Spaces:
Configuration error
Configuration error
| import { Metadata } from "next" | |
| import { redirect } from "next/navigation" | |
| import { stackServerApp } from "@/lib/stack-server" | |
| import prisma from "@/lib/prisma" | |
| import { AnalyticsDashboard } from "@/components/analytics/analytics-dashboard" | |
| export const metadata: Metadata = { | |
| title: "Analytics Dashboard | OpenPrompt", | |
| description: "View your prompt analytics and performance metrics", | |
| } | |
| export const dynamic = "force-dynamic" | |
| async function getCreatorAnalytics(userId: string) { | |
| // Get all prompts by this user | |
| const prompts = await prisma.prompt.findMany({ | |
| where: { creatorId: userId }, | |
| select: { | |
| id: true, | |
| title: true, | |
| slug: true, | |
| totalRuns: true, | |
| starsCount: true, | |
| remixesCount: true, | |
| createdAt: true, | |
| }, | |
| orderBy: { totalRuns: "desc" }, | |
| }) | |
| // Get runs data for the last 30 days | |
| const thirtyDaysAgo = new Date() | |
| thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30) | |
| const runs = await prisma.run.findMany({ | |
| where: { | |
| prompt: { creatorId: userId }, | |
| createdAt: { gte: thirtyDaysAgo }, | |
| }, | |
| select: { | |
| id: true, | |
| model: true, | |
| tokens: true, | |
| createdAt: true, | |
| promptId: true, | |
| }, | |
| orderBy: { createdAt: "desc" }, | |
| }) | |
| // Aggregate runs by day | |
| const runsByDay: Record<string, number> = {} | |
| runs.forEach((run: { createdAt: Date }) => { | |
| const day = run.createdAt.toISOString().split("T")[0] | |
| runsByDay[day] = (runsByDay[day] || 0) + 1 | |
| }) | |
| // Prepare daily data for chart | |
| const dailyData = [] | |
| for (let i = 29; i >= 0; i--) { | |
| const date = new Date() | |
| date.setDate(date.getDate() - i) | |
| const dateStr = date.toISOString().split("T")[0] | |
| dailyData.push({ | |
| date: dateStr, | |
| runs: runsByDay[dateStr] || 0, | |
| }) | |
| } | |
| // Model usage stats | |
| const modelUsage: Record<string, number> = {} | |
| runs.forEach((run: { model: string }) => { | |
| modelUsage[run.model] = (modelUsage[run.model] || 0) + 1 | |
| }) | |
| // Total tokens used | |
| const totalTokens = runs.reduce((sum: number, run: { tokens: number | null }) => sum + (run.tokens || 0), 0) | |
| // Calculate totals | |
| const totalRuns = prompts.reduce((sum: number, p: { totalRuns: number }) => sum + p.totalRuns, 0) | |
| const totalStars = prompts.reduce((sum: number, p: { starsCount: number }) => sum + p.starsCount, 0) | |
| const totalRemixes = prompts.reduce((sum: number, p: { remixesCount: number }) => sum + p.remixesCount, 0) | |
| return { | |
| prompts, | |
| dailyData, | |
| modelUsage, | |
| totalTokens, | |
| totals: { | |
| runs: totalRuns, | |
| stars: totalStars, | |
| remixes: totalRemixes, | |
| prompts: prompts.length, | |
| }, | |
| } | |
| } | |
| export default async function AnalyticsPage() { | |
| const user = await stackServerApp.getUser() | |
| if (!user) { | |
| redirect("/sign-in?returnUrl=/analytics") | |
| } | |
| const analytics = await getCreatorAnalytics(user.id) | |
| return ( | |
| <div className="container mx-auto px-4 py-8 max-w-7xl"> | |
| <div className="mb-8"> | |
| <h1 className="text-3xl font-serif font-medium mb-2"> | |
| Analytics <span className="text-gradient italic">Dashboard</span> | |
| </h1> | |
| <p className="text-muted-foreground"> | |
| Track your prompts performance and usage metrics | |
| </p> | |
| </div> | |
| <AnalyticsDashboard data={analytics} /> | |
| </div> | |
| ) | |
| } | |