Admin Dashboard Components
Analytics charts, user management tables, and business intelligence.
Analytics
- • Revenue tracking (MRR/ARR)
- • User growth metrics
- • Churn analysis
- • Subscription analytics
Management
- • User search & filtering
- • Subscription management
- • Account status controls
- • Bulk operations
Revenue Metrics
src/components/admin/RevenueChart.tsx
1"use client";23import { useMRRAnalytics } from "~/hooks/useAnalytics";45export function RevenueChart() {6 const { data, isLoading } = useMRRAnalytics();7 if (isLoading || !data) return <div>Loading...</div>;89 const current = data[data.length - 1];10 const previous = data[data.length - 2];11 const growth = previous12 ? ((current.totalMRR - previous.totalMRR) / previous.totalMRR) * 10013 : 0;1415 return (16 <div className="grid gap-4 md:grid-cols-3">17 <div className="rounded-xl border bg-card p-4">18 <p className="text-sm text-muted-foreground">Monthly Revenue</p>19 <p className="text-2xl font-bold">${current.totalMRR.toLocaleString()}</p>20 <p className="text-xs text-muted-foreground">21 {growth > 0 ? "+" : ""}{growth.toFixed(1)}% from last month22 </p>23 </div>24 <div className="rounded-xl border bg-card p-4">25 <p className="text-sm text-muted-foreground">New MRR</p>26 <p className="text-2xl font-bold text-green-600">27 +${current.newMRR.toLocaleString()}28 </p>29 </div>30 <div className="rounded-xl border bg-card p-4">31 <p className="text-sm text-muted-foreground">Churned MRR</p>32 <p className="text-2xl font-bold text-red-600">33 -${current.churnMRR.toLocaleString()}34 </p>35 </div>36 </div>37 );38}
User Management Table
src/components/admin/UserManagementTable.tsx
1"use client";23import { useState, useEffect } from "react";45export function UserManagementTable({ users, onUserAction }) {6 const [searchTerm, setSearchTerm] = useState("");7 const [filteredUsers, setFilteredUsers] = useState(users);89 useEffect(() => {10 const filtered = users.filter(user =>11 user.email.toLowerCase().includes(searchTerm.toLowerCase())12 );13 setFilteredUsers(filtered);14 }, [users, searchTerm]);1516 return (17 <div className="space-y-4">18 <input19 placeholder="Search users..."20 value={searchTerm}21 onChange={(e) => setSearchTerm(e.target.value)}22 className="rounded-lg border px-3 py-2"23 />2425 <table className="w-full rounded-lg border">26 <thead>27 <tr className="border-b bg-muted/50">28 <th className="p-3 text-left">User</th>29 <th className="p-3 text-left">Status</th>30 <th className="p-3 text-left">Joined</th>31 <th className="p-3 text-left">Actions</th>32 </tr>33 </thead>34 <tbody>35 {filteredUsers.map((user) => (36 <tr key={user.id} className="border-b">37 <td className="p-3">38 <div className="font-medium">{user.name || "Anonymous"}</div>39 <div className="text-sm text-muted-foreground">{user.email}</div>40 </td>41 <td className="p-3">42 <span className="rounded-full bg-muted px-2 py-1 text-xs">43 {user.subscription?.status || "Free"}44 </span>45 </td>46 <td className="p-3 text-sm text-muted-foreground">47 {new Date(user.createdAt).toLocaleDateString()}48 </td>49 <td className="p-3">50 <button onClick={() => onUserAction(user.id, "view")}>51 View52 </button>53 </td>54 </tr>55 ))}56 </tbody>57 </table>58 </div>59 );60}
Best Practices
Security
- • Role-based access control
- • Log all admin actions
- • Secure session management
- • Server-side validation
Performance
- • Use React Query for caching
- • Paginate large datasets
- • Debounce filter inputs
- • Add database indexes
Next: Pricing Section
Component documentation