import { useEffect, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { apiFetch } from '@core/lib/api'
import { Card, CardContent, CardHeader, CardTitle } from '@core/components/ui/card'
import { Skeleton } from '@core/components/ui/skeleton'
import { Building2, Headphones, MessageSquare, BookOpen, GraduationCap, TrendingUp } from 'lucide-react'
interface Stats {
accounts: number
openTickets: number
unansweredPosts: number
kbArticles: number
pipeline: number
deals: number
}
function StatCard({
title, value, sub, icon: Icon, href, loading
}: {
title: string; value: string | number; sub?: string; icon: React.ElementType; href: string; loading: boolean
}) {
const navigate = useNavigate()
return (
navigate(href)}>
{title}
{loading ? (
) : (
{value}
)}
{sub && {sub}
}
)
}
export default function CortexDashboard() {
const [stats, setStats] = useState({ accounts: 0, openTickets: 0, unansweredPosts: 0, kbArticles: 0, pipeline: 0, deals: 0 })
const [loading, setLoading] = useState(true)
useEffect(() => {
Promise.all([
apiFetch('/api/admin-data?action=list&entity=accounts&limit=1').then(r => r.json()),
apiFetch('/api/admin-data?action=list&entity=items&type_slug=support_ticket&limit=200').then(r => r.json()),
apiFetch('/api/admin-data?action=list&entity=items&type_slug=community_post&limit=200').then(r => r.json()),
apiFetch('/api/admin-data?action=list&entity=items&type_slug=kb_article&limit=1').then(r => r.json()),
apiFetch('/api/admin-data?action=list&entity=items&type_slug=deal&limit=200').then(r => r.json()),
]).then(([ar, tr, pr, kr, dr]) => {
const accounts = ar?.data ?? ar
const tickets = tr?.data ?? tr
const posts = pr?.data ?? pr
const kbArticles = kr?.data ?? kr
const deals = dr?.data ?? dr
const openTickets = (tickets || []).filter((t: any) => !['resolved', 'closed'].includes(t.status))
const pipeline = (deals || [])
.filter((d: any) => !['closed_won', 'closed_lost'].includes(d.data?.stage))
.reduce((sum: number, d: any) => sum + (d.data?.value || 0), 0)
setStats({
accounts: ar?.meta?.total ?? (accounts || []).length,
openTickets: openTickets.length,
unansweredPosts: (posts || []).length,
kbArticles: kr?.meta?.total ?? (kbArticles || []).length,
pipeline,
deals: (deals || []).length,
})
}).catch(() => {}).finally(() => setLoading(false))
}, [])
return (
Cortex
Operations overview
)
}