"use client"; import { useEffect, useState } from "react"; import { motion } from "framer-motion"; import { getDatabaseIntegrity, repairDatabaseSchema, optimizeDatabaseIndices } from "@/lib/actions/admin"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { Loader2, RefreshCw, Wrench, Database, CheckCircle2, XCircle, Terminal } from "lucide-react"; import { createClient } from "@/lib/supabase/client"; import { useRouter } from "next/navigation"; interface TableStatus { exists: boolean; count: number; } interface IntegrityData { tables: Record; errors: { foreign_keys: number; }; } const containerVariants = { hidden: { opacity: 0 }, visible: { opacity: 1, transition: { staggerChildren: 0.1 } } }; const itemVariants = { hidden: { opacity: 0, y: 15 }, visible: { opacity: 1, y: 0, transition: { type: 'spring' as const, stiffness: 80, damping: 15 } } }; export default function AdminToolsPage() { const [integrity, setIntegrity] = useState(null); const [isLoading, setIsLoading] = useState(false); const [logs, setLogs] = useState([]); const [activeAction, setActiveAction] = useState(null); const [loading, setLoading] = useState(true); const router = useRouter(); const addLog = (message: string) => { const timestamp = new Date().toLocaleTimeString(); setLogs((prev) => [...prev, `[${timestamp}] ${message}`]); }; const loadStatus = async (quiet = false) => { if (!quiet) setIsLoading(true); addLog("Starte Integritätsscan der Datenbank..."); const res = await getDatabaseIntegrity(); if (res.success && res.data) { setIntegrity(res.data as IntegrityData); addLog("Integritätsscan erfolgreich abgeschlossen."); } else { addLog(`FEHLER beim Scannen: ${res.error}`); } if (!quiet) setIsLoading(false); }; const handleRepair = async () => { setIsLoading(true); setActiveAction("repair"); addLog("Starte automatische Schemareparatur..."); const res = await repairDatabaseSchema(); if (res.success && res.data) { const repaired = (res.data as any).repaired || []; if (repaired.length > 0) { addLog(`Erfolgreich reparierte Tabellen: ${repaired.join(", ")}`); } else { addLog("Keine fehlenden Tabellen gefunden. Schema intakt."); } await loadStatus(true); } else { addLog(`FEHLER bei Schemareparatur: ${res.error}`); } setIsLoading(false); setActiveAction(null); }; const handleOptimize = async () => { setIsLoading(true); setActiveAction("optimize"); addLog("Starte Reindexierung des Schemas public..."); const res = await optimizeDatabaseIndices(); if (res.success) { addLog("Reindexierung erfolgreich abgeschlossen. Suchindizes neu aufgebaut."); } else { addLog(`FEHLER bei Reindexierung: ${res.error}`); } setIsLoading(false); setActiveAction(null); }; useEffect(() => { async function checkAccess() { try { const supabase = createClient(); const { data: { user } } = await supabase.auth.getUser(); if (!user) { router.push('/auth/login'); return; } const [userRes] = await Promise.all([ supabase.from('users').select('role').eq('id', user.id).single(), loadStatus(true) ]); if (!userRes.data || userRes.data.role === 'verwaltung') { router.push('/admin'); return; } } catch (err) { console.error("Fehler beim Laden von Admin Tools:", err); } finally { setLoading(false); } } checkAccess(); }, [router]); if (loading) { return
; } return (
{/* Header */}

Datenbank Cockpit & Tools

Verwalten und reparieren Sie Systemtabellen, Sicherheitsrichtlinien (RLS) und Datenbank-Indizes.

{/* Bento Grid layout */} {/* Bento Card 1: Integritätsscan */}

Integritätsscan

Prüft die physische Existenz der Tabellen und zählt deren Zeilenanzahl.

{/* Bento Card 2: Schema Reparieren */}

Schema Reparieren

Erstellt fehlende Kerntabellen automatisch neu und konfiguriert RLS-Rechte.

{/* Bento Card 3: Index Optimieren */}

Index Optimieren

Baut Suchindizes im Schema public mittels REINDEX neu auf für maximale Performance.

{/* Bento Card 4: Tabellen-Diagnose (2 Spalten) */}

Tabellen-Status & Diagnose

{integrity?.tables ? ( Object.entries(integrity.tables).map(([name, status]) => (
{name.replace("_", " ")} Zeilen: {status.count}
{status.exists ? ( OK ) : ( Fehlt )}
)) ) : (

Keine Diagnose-Daten geladen.

)}
{/* Bento Card 5: Live Konsole / Logs (1 Spalte) */}

System-Konsole

{logs.length === 0 ? ( Warte auf Aktionen... ) : ( logs.map((log, i) =>
{log}
) )}
); }