import { useMutation, useQuery } from "@tanstack/react-query"; import { createFileRoute, Link, redirect, useNavigate, } from "@tanstack/react-router"; import { Check, Download, LogOut, Search, Users, X } from "lucide-react"; import { useState } from "react"; import { toast } from "sonner"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { authClient } from "@/lib/auth-client"; import { orpc } from "@/utils/orpc"; export const Route = createFileRoute("/admin")({ component: AdminPage, beforeLoad: async () => { const session = await authClient.getSession(); if (!session.data?.user) { throw redirect({ to: "/login" }); } const user = session.data.user as { role?: string }; if (user.role !== "admin") { throw redirect({ to: "/login" }); } }, }); function AdminPage() { const navigate = useNavigate(); const [search, setSearch] = useState(""); const [artForm, setArtForm] = useState(""); const [fromDate, setFromDate] = useState(""); const [toDate, setToDate] = useState(""); const [page, setPage] = useState(1); const pageSize = 20; const statsQuery = useQuery(orpc.getRegistrationStats.queryOptions()); const registrationsQuery = useQuery( orpc.getRegistrations.queryOptions({ input: { search: search || undefined, artForm: artForm || undefined, fromDate: fromDate || undefined, toDate: toDate || undefined, page, pageSize, }, }), ); const adminRequestsQuery = useQuery(orpc.getAdminRequests.queryOptions()); const exportMutation = useMutation({ ...orpc.exportRegistrations.mutationOptions(), onSuccess: (data: { csv: string; filename: string }) => { const blob = new Blob([data.csv], { type: "text/csv" }); const url = window.URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = data.filename; document.body.appendChild(a); a.click(); document.body.removeChild(a); window.URL.revokeObjectURL(url); }, }); const approveRequestMutation = useMutation({ ...orpc.approveAdminRequest.mutationOptions(), onSuccess: () => { toast.success("Admin toegang goedgekeurd"); adminRequestsQuery.refetch(); }, onError: (error) => { toast.error(`Fout: ${error.message}`); }, }); const rejectRequestMutation = useMutation({ ...orpc.rejectAdminRequest.mutationOptions(), onSuccess: () => { toast.success("Admin toegang geweigerd"); adminRequestsQuery.refetch(); }, onError: (error) => { toast.error(`Fout: ${error.message}`); }, }); const handleSignOut = async () => { await authClient.signOut(); navigate({ to: "/" }); }; const handleExport = () => { exportMutation.mutate(undefined); }; const handleApprove = (requestId: string) => { approveRequestMutation.mutate({ requestId }); }; const handleReject = (requestId: string) => { rejectRequestMutation.mutate({ requestId }); }; const stats = statsQuery.data; const registrations = registrationsQuery.data?.data ?? []; const pagination = registrationsQuery.data?.pagination; const adminRequests = adminRequestsQuery.data ?? []; const pendingRequests = adminRequests.filter((r) => r.status === "pending"); return (
{/* Header */}
← Terug naar website

Admin Dashboard

{/* Main Content */}
{/* Pending Admin Requests */} {pendingRequests.length > 0 && ( Openstaande Admin Aanvragen ({pendingRequests.length}) Gebruikers die admin toegang hebben aangevraagd
{pendingRequests.map((request) => (

{request.userName}

{request.userEmail}

Aangevraagd:{" "} {new Date(request.requestedAt).toLocaleDateString( "nl-BE", )}

))}
)} {/* Stats Cards */}
Totaal inschrijvingen {stats?.total ?? 0} Vandaag ingeschreven {stats?.today ?? 0} Nieuwe registraties vandaag Per kunstvorm
{stats?.byArtForm.slice(0, 5).map((item) => (
{item.artForm} {item.count}
))}
{/* Filters */} Filters
setSearch(e.target.value)} className="border-white/20 bg-white/10 pl-10 text-white placeholder:text-white/40" />
setArtForm(e.target.value)} className="border-white/20 bg-white/10 text-white placeholder:text-white/40" />
setFromDate(e.target.value)} className="border-white/20 bg-white/10 text-white [color-scheme:dark]" />
setToDate(e.target.value)} className="border-white/20 bg-white/10 text-white [color-scheme:dark]" />
{/* Export Button */}

{pagination?.total ?? 0} registraties gevonden

{/* Registrations Table */}
{registrationsQuery.isLoading ? ( ) : registrations.length === 0 ? ( ) : ( registrations.map((reg) => ( )) )}
Naam Email Telefoon Kunstvorm Ervaring Datum
Laden...
Geen registraties gevonden
{reg.firstName} {reg.lastName} {reg.email} {reg.phone || "-"} {reg.artForm} {reg.experience || "-"} {new Date(reg.createdAt).toLocaleDateString("nl-BE")}
{/* Pagination */} {pagination && pagination.totalPages > 1 && (
Pagina {page} van {pagination.totalPages}
)}
); }