Files
2026-03-18 18:26:24 +08:00

85 lines
3.1 KiB
TypeScript
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client';
import { useUser } from '@auth0/nextjs-auth0/client';
import { useEffect, useState } from 'react';
import Link from 'next/link';
interface Metrics {
total_sessions: number;
paid_sessions: number;
total_leads: number;
total_tokens: number;
by_tool: { tool: string; count: string }[];
}
export default function AdminDashboard() {
const { user, isLoading } = useUser();
const [metrics, setMetrics] = useState<Metrics | null>(null);
useEffect(() => {
if (user) {
fetch('/api/admin/metrics').then((r) => r.json()).then(setMetrics);
}
}, [user]);
if (isLoading) return <div className="p-8 text-center">Loading...</div>;
if (!user) {
return (
<div className="p-8 text-center">
<h1 className="text-2xl font-bold mb-4">Admin Access Required</h1>
<a href="/api/auth/login" className="bg-accent text-white px-6 py-2 rounded-lg">
Sign In
</a>
</div>
);
}
return (
<div className="max-w-6xl mx-auto px-4 py-8">
<div className="flex justify-between items-center mb-8">
<h1 className="text-2xl font-bold">Admin Dashboard</h1>
<div className="flex gap-4">
<Link href="/admin/config" className="text-sm text-accent hover:underline"> Config</Link>
<Link href="/admin/leads" className="text-sm text-accent hover:underline">👥 Leads</Link>
<a href="/api/auth/logout" className="text-sm text-gray-500 hover:underline">Sign Out</a>
</div>
</div>
{metrics && (
<div className="grid md:grid-cols-4 gap-4 mb-8">
<div className="bg-white border rounded-xl p-6">
<div className="text-3xl font-bold text-accent">{metrics.total_sessions}</div>
<div className="text-sm text-gray-500">Total Sessions</div>
</div>
<div className="bg-white border rounded-xl p-6">
<div className="text-3xl font-bold text-green-600">{metrics.paid_sessions}</div>
<div className="text-sm text-gray-500">Paid Sessions</div>
</div>
<div className="bg-white border rounded-xl p-6">
<div className="text-3xl font-bold text-blue-600">{metrics.total_leads}</div>
<div className="text-sm text-gray-500">Leads Captured</div>
</div>
<div className="bg-white border rounded-xl p-6">
<div className="text-3xl font-bold text-purple-600">{metrics.total_tokens.toLocaleString()}</div>
<div className="text-sm text-gray-500">Tokens Used</div>
</div>
</div>
)}
{metrics?.by_tool && (
<div className="bg-white border rounded-xl p-6">
<h2 className="font-semibold mb-4">Usage by Tool</h2>
<div className="space-y-2">
{metrics.by_tool.map((t) => (
<div key={t.tool} className="flex justify-between">
<span className="capitalize">{t.tool.replace(/-/g, ' ')}</span>
<span className="font-mono">{t.count}</span>
</div>
))}
</div>
</div>
)}
</div>
);
}