"use client" import { useState, useCallback } from "react" import { Card, CardHeader, CardTitle, CardDescription, CardContent, } from "@/components/ui/card" import { Button } from "@/components/ui/button" import { Badge } from "@/components/ui/badge" import { Table, TableHeader, TableBody, TableHead, TableRow, TableCell, } from "@/components/ui/table" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select" import { Tooltip, TooltipTrigger, TooltipContent, } from "@/components/ui/tooltip" import { Progress } from "@/components/ui/progress" import { KeyRound, Users, Search, ChevronLeft, ChevronRight, } from "lucide-react" import { Input } from "@/components/ui/input" interface UserRow { id: string email: string status: "active" | "suspended" | "pending" tier: "free" | "pro" usage: number maxUsage: number apiKeys: number lastActive: string } const initialUsers: UserRow[] = [ { id: "1", email: "sarah.chen@acme.com", status: "active", tier: "pro", usage: 423, maxUsage: 500, apiKeys: 3, lastActive: "2 min ago", }, { id: "2", email: "m.rodriguez@startup.io", status: "active", tier: "pro", usage: 189, maxUsage: 500, apiKeys: 1, lastActive: "1 hour ago", }, { id: "3", email: "j.mueller@berlin-corp.de", status: "active", tier: "free", usage: 18, maxUsage: 50, apiKeys: 1, lastActive: "3 hours ago", }, { id: "4", email: "alex.kim@design.co", status: "pending", tier: "free", usage: 0, maxUsage: 50, apiKeys: 0, lastActive: "Never", }, { id: "5", email: "nina.patel@healthco.org", status: "active", tier: "pro", usage: 501, maxUsage: 500, apiKeys: 2, lastActive: "18 min ago", }, { id: "6", email: "tom.wright@legal.uk", status: "suspended", tier: "free", usage: 47, maxUsage: 50, apiKeys: 0, lastActive: "14 days ago", }, { id: "7", email: "l.tanaka@jp-trade.co.jp", status: "active", tier: "pro", usage: 312, maxUsage: 500, apiKeys: 2, lastActive: "45 min ago", }, { id: "8", email: "c.dubois@paris-finance.fr", status: "active", tier: "free", usage: 34, maxUsage: 50, apiKeys: 1, lastActive: "6 hours ago", }, ] const statusConfig = { active: { label: "Active", dotClass: "bg-[oklch(0.59_0.16_145)]", textClass: "text-[oklch(0.45_0.12_145)]", }, suspended: { label: "Suspended", dotClass: "bg-destructive", textClass: "text-destructive", }, pending: { label: "Pending", dotClass: "bg-[oklch(0.75_0.18_55)]", textClass: "text-[oklch(0.55_0.16_55)]", }, } export function UserManagementTable() { const [users, setUsers] = useState(initialUsers) const [searchQuery, setSearchQuery] = useState("") const [revokedUsers, setRevokedUsers] = useState>(new Set()) const updateTier = useCallback((userId: string, newTier: "free" | "pro") => { setUsers((prev) => prev.map((u) => u.id === userId ? { ...u, tier: newTier, maxUsage: newTier === "pro" ? 500 : 50, } : u ) ) }, []) const revokeKeys = useCallback((userId: string) => { setUsers((prev) => prev.map((u) => (u.id === userId ? { ...u, apiKeys: 0 } : u)) ) setRevokedUsers((prev) => { const next = new Set(prev) next.add(userId) return next }) setTimeout(() => { setRevokedUsers((prev) => { const next = new Set(prev) next.delete(userId) return next }) }, 2000) }, []) const filtered = users.filter((u) => u.email.toLowerCase().includes(searchQuery.toLowerCase()) ) const proCount = users.filter((u) => u.tier === "pro").length const activeCount = users.filter((u) => u.status === "active").length return (
User Management {users.length} total users | {activeCount} active | {proCount} pro
setSearchQuery(e.target.value)} className="h-8 pl-8 text-xs" />
User Email Status Tier Usage Keys Actions {filtered.map((user) => { const sConfig = statusConfig[user.status] const usagePercent = Math.min( (user.usage / user.maxUsage) * 100, 100 ) const isOverQuota = user.usage > user.maxUsage const justRevoked = revokedUsers.has(user.id) return (
{user.email} Last active: {user.lastActive}
{sConfig.label}
{user.usage} / {user.maxUsage} {isOverQuota && ( Over )}
[data-slot=progress-indicator]]:bg-destructive" : usagePercent > 80 ? "[&>[data-slot=progress-indicator]]:bg-[oklch(0.75_0.18_55)]" : "[&>[data-slot=progress-indicator]]:bg-accent" }`} />
{user.apiKeys} {user.apiKeys === 0 ? "No active keys" : `Revoke ${user.apiKeys} active key${user.apiKeys > 1 ? "s" : ""}`}
) })} {filtered.length === 0 && ( No users match your filter. )}
{/* Pagination footer */}
Showing {filtered.length} of {users.length} users
1 / 1
) }