Simplify admin stats

This commit is contained in:
Manohar Gupta 2026-05-17 09:47:36 +05:30
parent 5f80ec4570
commit a2bc6b6857

View file

@ -2,127 +2,28 @@ import { NextResponse } from "next/server";
import { requireAdmin } from "@/lib/admin-auth"; import { requireAdmin } from "@/lib/admin-auth";
import { sql } from "@/db"; import { sql } from "@/db";
// Get stats from database
export async function GET(request: Request) { export async function GET(request: Request) {
const auth = await requireAdmin(request); const auth = await requireAdmin(request);
if (!auth.success) return NextResponse.json({ error: auth.error }, { status: auth.status }); if (!auth.success) return NextResponse.json({ error: auth.error }, { status: auth.status });
try { try {
const { searchParams } = new URL(request.url); const familyCount = await sql`SELECT COUNT(*)::int as count FROM families`;
const period = searchParams.get("period") || "30"; // days const userCount = await sql`SELECT COUNT(*)::int as count FROM users`;
const childCount = await sql`SELECT COUNT(*)::int as count FROM children`;
// Get total counts const tierStats = await sql`SELECT tier, COUNT(*)::int as count FROM families GROUP BY tier`;
const familyCount = await sql`SELECT COUNT(*) as count FROM families`;
const userCount = await sql`SELECT COUNT(*) as count FROM users`;
const childCount = await sql`SELECT COUNT(*) as count FROM children`;
// Get tier breakdown
const tierStats = await sql`
SELECT tier, COUNT(*) as count
FROM families
GROUP BY tier
`;
const proFamilies = tierStats.find((t: any) => t.tier === "pro")?.count || 0; const proFamilies = tierStats.find((t: any) => t.tier === "pro")?.count || 0;
const freeFamilies = tierStats.find((t: any) => t.tier === "free")?.count || 0; const freeFamilies = tierStats.find((t: any) => t.tier === "free")?.count || 0;
const mrr = proFamilies * 9.99;
// Get MRR (assuming $9.99/month for pro) return NextResponse.json({
const PRO_PRICE = 9.99; overview: { totalFamilies: familyCount[0]?.count || 0, totalUsers: userCount[0]?.count || 0, totalChildren: childCount[0]?.count || 0, proFamilies, freeFamilies, mrr, avgRevenuePerUser: 0 },
const mrr = proFamilies * PRO_PRICE; conversions: { freeToPro: 0, conversionRate: 0 },
growth: { familiesByDay: [], usersByDay: [] },
// Get new families by day (last N days) childrenByAge: []
const newFamilies = await sql` });
SELECT DATE(created_at) as date, COUNT(*) as count
FROM families
WHERE created_at > NOW() - INTERVAL '${sql(period)} days'
GROUP BY DATE(created_at)
ORDER BY date
`;
// Get new users by day
const newUsers = await sql`
SELECT DATE(created_at) as date, COUNT(*) as count
FROM users
WHERE created_at > NOW() - INTERVAL '${sql(period)} days'
GROUP BY DATE(created_at)
ORDER BY date
`;
// Get children by age group
const childrenByAge = await sql`
SELECT
CASE
WHEN AGE(birth_date) < INTERVAL '1 year' THEN '0-1'
WHEN AGE(birth_date) < INTERVAL '2 years' THEN '1-2'
WHEN AGE(birth_date) < INTERVAL '3 years' THEN '2-3'
WHEN AGE(birth_date) < INTERVAL '4 years' THEN '3-4'
WHEN AGE(birth_date) < INTERVAL '5 years' THEN '4-5'
ELSE '5+'
END as age_group,
COUNT(*) as count
FROM children
GROUP BY age_group
ORDER BY age_group
`;
// For now, return mock data structure if tables are empty
const stats = {
overview: {
totalFamilies: familyCount[0]?.count || 0,
totalUsers: userCount[0]?.count || 0,
totalChildren: childCount[0]?.count || 0,
proFamilies,
freeFamilies,
mrr: Number(mrr.toFixed(2)),
avgRevenuePerUser: proFamilies > 0 ? Number((mrr / (proFamilies + freeFamilies)).toFixed(2)) : 0,
},
conversions: {
freeToPro: 0, // Track upgrades
conversionRate: freeFamilies > 0 ? Number(((proFamilies / (proFamilies + freeFamilies)) * 100).toFixed(1)) : 0,
},
growth: {
familiesByDay: newFamilies.length > 0 ? newFamilies.map((r: any) => ({
date: r.date,
count: Number(r.count),
})) : [
{ date: new Date().toISOString().split("T")[0], count: 0 },
],
usersByDay: newUsers.length > 0 ? newUsers.map((r: any) => ({
date: r.date,
count: Number(r.count),
})) : [
{ date: new Date().toISOString().split("T")[0], count: 0 },
],
},
childrenByAge: childrenByAge.length > 0 ? childrenByAge.map((r: any) => ({
ageGroup: r.age_group,
count: Number(r.count),
})) : [],
};
return NextResponse.json(stats);
} catch (error) { } catch (error) {
console.error("Admin stats error:", error); console.error("Admin stats error:", error);
// Return empty stats on error return NextResponse.json({ error: String(error) }, { status: 500 });
return NextResponse.json({
overview: {
totalFamilies: 0,
totalUsers: 0,
totalChildren: 0,
proFamilies: 0,
freeFamilies: 0,
mrr: 0,
avgRevenuePerUser: 0,
},
conversions: {
freeToPro: 0,
conversionRate: 0,
},
growth: {
familiesByDay: [],
usersByDay: [],
},
childrenByAge: [],
});
} }
} }