import { // Activity, BadgeCheck, BookOpen, // Coins, DollarSign, HelpCircle, TicketCheck, // TrendingUp, Users, Bell, UsersRound, } from "lucide-react" import { Area, AreaChart, Bar, BarChart, CartesianGrid, Cell, Pie, PieChart, ResponsiveContainer, Tooltip, XAxis, YAxis, } from "recharts" import { StatCard } from "../components/dashboard/StatCard" import { Card, CardContent, CardHeader, CardTitle } from "../components/ui/card" // import { cn } from "../lib/utils" import { getTeamMemberById } from "../api/team.api" import { getDashboard } from "../api/analytics.api" import { useEffect, useState } from "react" import type { DashboardData } from "../types/analytics.types" const PIE_COLORS = ["#9E2891", "#FFD23F", "#1DE9B6", "#C26FC0", "#6366F1", "#F97316", "#14B8A6", "#EF4444"] function formatDate(dateStr: string) { const d = new Date(dateStr) return d.toLocaleDateString("en-US", { month: "short", day: "numeric" }) } export function DashboardPage() { const [userFirstName, setUserFirstName] = useState("") const [dashboard, setDashboard] = useState(null) const [loading, setLoading] = useState(true) useEffect(() => { const fetchUser = async () => { try { const memberId = Number(localStorage.getItem("member_id")) const res = await getTeamMemberById(memberId) const member = res.data.data setUserFirstName(member.first_name) localStorage.setItem("user_first_name", member.first_name) localStorage.setItem("user_last_name", member.last_name) window.dispatchEvent(new Event("user-profile-updated")) } catch (err) { console.error(err) } } const fetchDashboard = async () => { try { const res = await getDashboard() setDashboard(res.data as unknown as DashboardData) } catch (err) { console.error(err) } finally { setLoading(false) } } fetchUser() fetchDashboard() }, []) const registrationData = dashboard?.users.registrations_last_30_days.map((d) => ({ date: formatDate(d.date), count: d.count, })) ?? [] const revenueData = dashboard?.payments.revenue_last_30_days.map((d) => ({ date: formatDate(d.date), revenue: d.revenue, })) ?? [] const subscriptionStatusData = dashboard?.subscriptions.by_status.map((s, i) => ({ name: s.label, value: s.count, color: PIE_COLORS[i % PIE_COLORS.length], })) ?? [] const issueStatusData = dashboard?.issues.by_status.map((s, i) => ({ name: s.label, value: s.count, color: PIE_COLORS[i % PIE_COLORS.length], })) ?? [] return (
Dashboard
Welcome, {userFirstName || localStorage.getItem("user_first_name")}
{loading ? (
Loading dashboard…
) : !dashboard ? (
Failed to load dashboard data.
) : ( <> {/* Stat Cards */}
0} /> 0} /> 0} /> 0.5} />
{/* Secondary Stats */}
{/* User Registrations Chart */}
User Registrations
{dashboard.users.total_users.toLocaleString()}
+{dashboard.users.new_today} today · +{dashboard.users.new_week} this week
Last 30 Days
{/* Subscription / Issue Status Pie */} {subscriptionStatusData.length > 0 ? "Subscription Status" : "Issue Status"} {(subscriptionStatusData.length > 0 ? subscriptionStatusData : issueStatusData).length > 0 ? ( <>
0 ? subscriptionStatusData : issueStatusData} dataKey="value" nameKey="name" innerRadius={55} outerRadius={80} paddingAngle={2} > {(subscriptionStatusData.length > 0 ? subscriptionStatusData : issueStatusData).map( (entry) => ( ), )}
{(subscriptionStatusData.length > 0 ? subscriptionStatusData : issueStatusData).map((s) => (
{s.name}
{s.value.toLocaleString()}
))}
) : (
No data available
)}
{/* Revenue Chart */}
Revenue Trend
ETB {dashboard.payments.total_revenue.toLocaleString()}
Last 30 Days (ETB)
[`${Number(v).toLocaleString()}`, "ETB"]} contentStyle={{ borderRadius: 12, border: "1px solid #E0E0E0", boxShadow: "0 10px 30px rgba(0,0,0,0.08)", }} />
{/* Users by Role / Region / Knowledge Level */}
{[ { title: "Users by Role", data: dashboard.users.by_role }, { title: "Users by Region", data: dashboard.users.by_region }, { title: "Users by Knowledge Level", data: dashboard.users.by_knowledge_level }, ].map(({ title, data }) => ( {title} {data.length > 0 ? (
{data.map((item, i) => (
{item.label}
{item.count.toLocaleString()}
))}
) : (
No data available
)}
))}
)}
) }