"use client"; import { Activity, BarChart3, Building2, Check, Copy, Database, LogOut, MoreVertical, Plus, Search, Settings, User, Users, } from "lucide-react"; import { useRouter } from "next/navigation"; import { useCallback, useEffect, useId, useState } from "react"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { ThemeToggle } from "@/components/ui/theme-toggle"; import { useToast } from "@/hooks/use-toast"; interface Company { id: string; name: string; status: string; createdAt: string; _count: { users: number; sessions: number; imports: number; }; } interface DashboardData { companies: Company[]; pagination: { total: number; pages: number; }; } interface PlatformSession { user: { id: string; email: string; name?: string; isPlatformUser: boolean; platformRole: string; }; } // Custom hook for platform session function usePlatformSession() { const [session, setSession] = useState(null); const [status, setStatus] = useState< "loading" | "authenticated" | "unauthenticated" >("loading"); useEffect(() => { const fetchSession = async () => { try { const response = await fetch("/api/platform/auth/session"); const sessionData = await response.json(); if (sessionData?.user?.isPlatformUser) { setSession(sessionData); setStatus("authenticated"); } else { setSession(null); setStatus("unauthenticated"); } } catch (error) { console.error("Platform session fetch error:", error); setSession(null); setStatus("unauthenticated"); } }; fetchSession(); }, []); return { data: session, status }; } export default function PlatformDashboard() { const { data: session, status } = usePlatformSession(); const router = useRouter(); const { toast } = useToast(); const [dashboardData, setDashboardData] = useState( null ); const [isLoading, setIsLoading] = useState(true); const [showAddCompany, setShowAddCompany] = useState(false); const [isCreating, setIsCreating] = useState(false); const [copiedEmail, setCopiedEmail] = useState(false); const [copiedPassword, setCopiedPassword] = useState(false); const [searchTerm, setSearchTerm] = useState(""); const [newCompanyData, setNewCompanyData] = useState({ name: "", csvUrl: "", csvUsername: "", csvPassword: "", adminEmail: "", adminName: "", adminPassword: "", maxUsers: 10, }); const companyNameId = useId(); const csvUrlId = useId(); const csvUsernameId = useId(); const csvPasswordId = useId(); const adminNameId = useId(); const adminEmailId = useId(); const adminPasswordId = useId(); const maxUsersId = useId(); const fetchDashboardData = useCallback(async () => { try { const response = await fetch("/api/platform/companies"); if (response.ok) { const data = await response.json(); setDashboardData(data); } } catch (error) { console.error("Failed to fetch dashboard data:", error); } finally { setIsLoading(false); } }, []); useEffect(() => { if (status === "loading") return; if (status === "unauthenticated" || !session?.user?.isPlatformUser) { router.push("/platform/login"); return; } fetchDashboardData(); }, [session, status, router, fetchDashboardData]); const copyToClipboard = async (text: string, type: "email" | "password") => { try { await navigator.clipboard.writeText(text); if (type === "email") { setCopiedEmail(true); setTimeout(() => setCopiedEmail(false), 2000); } else { setCopiedPassword(true); setTimeout(() => setCopiedPassword(false), 2000); } } catch (err) { console.error("Failed to copy: ", err); } }; const getFilteredCompanies = () => { if (!dashboardData?.companies) return []; return dashboardData.companies.filter((company) => company.name.toLowerCase().includes(searchTerm.toLowerCase()) ); }; const handleCreateCompany = async () => { if ( !newCompanyData.name || !newCompanyData.csvUrl || !newCompanyData.adminEmail || !newCompanyData.adminName ) { toast({ title: "Error", description: "Please fill in all required fields", variant: "destructive", }); return; } setIsCreating(true); try { const response = await fetch("/api/platform/companies", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(newCompanyData), }); if (response.ok) { const result = await response.json(); setShowAddCompany(false); const companyName = newCompanyData.name; setNewCompanyData({ name: "", csvUrl: "", csvUsername: "", csvPassword: "", adminEmail: "", adminName: "", adminPassword: "", maxUsers: 10, }); fetchDashboardData(); // Refresh the list // Show success message with copyable credentials if (result.generatedPassword) { toast({ title: "Company Created Successfully!", description: (

Company "{companyName}" has been created.

Admin Email:

{result.adminUser.email}

Admin Password:

{result.generatedPassword}

), duration: 15000, // Longer duration for credentials }); } else { toast({ title: "Success", description: `Company "${companyName}" created successfully`, }); } } else { const error = await response.json(); throw new Error(error.error || "Failed to create company"); } } catch (error) { toast({ title: "Error", description: error instanceof Error ? error.message : "Failed to create company", variant: "destructive", }); } finally { setIsCreating(false); } }; const getStatusBadgeVariant = (status: string) => { switch (status) { case "ACTIVE": return "default"; case "TRIAL": return "secondary"; case "SUSPENDED": return "destructive"; case "ARCHIVED": return "outline"; default: return "default"; } }; if (status === "loading" || isLoading) { return (
Loading platform dashboard...
); } if (status === "unauthenticated" || !session?.user?.isPlatformUser) { return null; } const filteredCompanies = getFilteredCompanies(); const totalCompanies = dashboardData?.pagination?.total || 0; const totalUsers = dashboardData?.companies?.reduce( (sum, company) => sum + company._count.users, 0 ) || 0; const totalSessions = dashboardData?.companies?.reduce( (sum, company) => sum + company._count.sessions, 0 ) || 0; return (

Platform Dashboard

Welcome back, {session.user.name || session.user.email}

{/* Search Filter */}
setSearchTerm(e.target.value)} className="pl-10 w-64" />

{session.user.name || session.user.email}

{session.user.platformRole || "Platform User"}

router.push("/platform/settings")} > Account Settings { await fetch("/api/platform/auth/logout", { method: "POST", }); router.push("/platform/login"); }} className="text-red-600" > Sign Out
{/* Stats Overview */}
Total Companies
{totalCompanies}
Total Users
{totalUsers}
Total Sessions
{totalSessions}
Active Companies
{dashboardData?.companies?.filter((c) => c.status === "ACTIVE") .length || 0}
{/* Companies List */}
Companies {searchTerm && ( {filteredCompanies.length} of {totalCompanies} shown )}
{searchTerm && ( Search: "{searchTerm}" )} Add New Company Create a new company and invite the first administrator.
setNewCompanyData((prev) => ({ ...prev, name: e.target.value, })) } placeholder="Acme Corporation" />
setNewCompanyData((prev) => ({ ...prev, csvUrl: e.target.value, })) } placeholder="https://api.company.com/sessions.csv" />
setNewCompanyData((prev) => ({ ...prev, csvUsername: e.target.value, })) } placeholder="Optional HTTP auth username" />
setNewCompanyData((prev) => ({ ...prev, csvPassword: e.target.value, })) } placeholder="Optional HTTP auth password" />
setNewCompanyData((prev) => ({ ...prev, adminName: e.target.value, })) } placeholder="John Doe" />
setNewCompanyData((prev) => ({ ...prev, adminEmail: e.target.value, })) } placeholder="admin@acme.com" />
setNewCompanyData((prev) => ({ ...prev, adminPassword: e.target.value, })) } placeholder="Leave empty to auto-generate" />
setNewCompanyData((prev) => ({ ...prev, maxUsers: Number.parseInt(e.target.value) || 10, })) } min="1" max="1000" />
{filteredCompanies.map((company) => (

{company.name}

{company.status}
{company._count.users} users {company._count.sessions} sessions {company._count.imports} imports Created{" "} {new Date(company.createdAt).toLocaleDateString()}
))} {!filteredCompanies.length && (
{searchTerm ? (

No companies match "{searchTerm}".

) : ( "No companies found. Create your first company to get started." )}
)}
); }