diff --git a/shop/app/admin/einstellungen/page.tsx b/shop/app/admin/einstellungen/page.tsx index 319a72c..4dd8c8e 100644 --- a/shop/app/admin/einstellungen/page.tsx +++ b/shop/app/admin/einstellungen/page.tsx @@ -1,16 +1,43 @@ -/* Admin Settings with Database Import / Export functionality */ +/* Admin Settings with Bento Grid Layout & Motion Animations */ 'use client'; import { useState, useEffect } from 'react'; +import { motion } from 'framer-motion'; import { Switch } from '@/components/ui/switch'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; -import { Download, Upload, Database, AlertTriangle, Loader2, KeyRound, Server, CheckCircle2, XCircle, Eye, EyeOff, Wifi } from 'lucide-react'; +import { + Download, Upload, Database, AlertTriangle, Loader2, KeyRound, + Server, CheckCircle2, XCircle, Eye, EyeOff, Wifi, Sliders, ShieldAlert, FileArchive +} from 'lucide-react'; import { createClient } from '@/lib/supabase/client'; import { saveLicServerConfig, testLicServerConnection } from '@/lib/actions/licserver-config'; import { useRouter } from 'next/navigation'; +const containerVariants = { + hidden: { opacity: 0 }, + visible: { + opacity: 1, + transition: { + staggerChildren: 0.1 + } + } +}; + +const cardVariants = { + hidden: { opacity: 0, y: 20 }, + visible: { + opacity: 1, + y: 0, + transition: { + type: 'spring' as const, + stiffness: 80, + damping: 15 + } + } +}; + export default function AdminSettings() { const [demoActive, setDemoActive] = useState(true); const [exporting, setExporting] = useState(false); @@ -40,13 +67,14 @@ export default function AdminSettings() { router.push('/auth/login'); return; } - const { data: userData, error: userError } = await supabase - .from('users') - .select('role') - .eq('id', user.id) - .single(); - if (userError || !userData || userData.role === 'verwaltung') { + // Parallele Abfrage von User-Rolle & LicServer Settings + const [userRes, licRes] = await Promise.all([ + supabase.from('users').select('role').eq('id', user.id).single(), + supabase.from('settings').select('licserver_base_url, licserver_api_key').eq('id', 'licserver').maybeSingle() + ]); + + if (userRes.error || !userRes.data || userRes.data.role === 'verwaltung') { router.push('/admin'); return; } @@ -54,19 +82,9 @@ export default function AdminSettings() { const state = localStorage.getItem('demo_banner_disabled') !== 'true'; setDemoActive(state); - // Load current LicServer config from DB - try { - const { data: licRow } = await supabase - .from('settings') - .select('licserver_base_url, licserver_api_key') - .eq('id', 'licserver') - .single(); - if (licRow) { - setLicUrl(licRow.licserver_base_url || ''); - setLicKey(licRow.licserver_api_key || ''); - } - } catch (dbErr) { - console.error("Fehler beim Laden der LicServer-Einstellungen:", dbErr); + if (licRes.data) { + setLicUrl(licRes.data.licserver_base_url || ''); + setLicKey(licRes.data.licserver_api_key || ''); } } catch (err) { console.error("Fehler bei checkAccess in Einstellungen:", err); @@ -148,204 +166,230 @@ export default function AdminSettings() { } return ( -
- {/* Page Header */} -
-

Admin Einstellungen

-

- Verwalten Sie globale Shopeinstellungen. -

-
- - {/* Allgemeine Einstellungen */} -
-

- Allgemeine Einstellungen -

-
-
-

Demo-Warnmeldungen

-

Schaltet gelbe Banner ein oder aus.

-
- -
-
- - {/* Datenimport & -export */} -
+
+ {/* Header */} +
-

- - Datenimport & -export -

-

- Sichern Sie Ihre gesamte Instanz oder stellen Sie Daten wieder her. +

Admin Einstellungen

+

+ Zentrales Bento-Dashboard für System-, Backup- und Lizenz-Konfigurationen.

+
- {statusMsg && ( -
- {statusMsg} -
- )} + 'bg-sky-500/10 border-sky-500/20 text-sky-400' + }`} + > + {statusMsg} + + )} -
- {/* Export Card */} -
-
-

- - Daten exportieren -

-

- Lädt alle Kategorien, Produkte, Module, Firmen, Endkunden, Bestellungen und SMTP-Einstellungen als ZIP-Datei herunter. + {/* Bento Grid Container */} + + {/* Bento Item 1: System Modus & Banner (1 Spalte) */} + +

+
+ +
+
+

System Banner

+

+ Gelbe Demo-Warnmeldungen im gesamten Shop aktivieren oder stummschalten.

+
+
+ Banner aktiv + +
+ + + {/* Bento Item 2: Daten Export (1 Spalte) */} + +
+
+ +
+
+

DB Backup

+

+ Lädt alle Produkte, Firmen, Lizenzen & Einstellungen als ZIP-Archiv herunter. +

+
+
+ +
+ + {/* Bento Item 3: Daten Import (2 Spalten / Span 2 auf Desktop) */} + +
+
+
+ +
+ + Überschreibt DB + +
+
+

Daten Wiederherstellung

+

+ Spielen Sie eine gesicherte ZIP-Sicherungsdatei ein. Warnung: Überschreibt aktuelle Datenbankinhalte. +

+
+
+ +
+
+ setSelectedFile(e.target.files?.[0] || null)} + disabled={exporting || importing} + className="absolute inset-0 w-full h-full opacity-0 cursor-pointer disabled:cursor-not-allowed" + /> + + + {selectedFile ? selectedFile.name : 'ZIP-Datei auswählen'} + +
+
+
- {/* Import Card */} -
-
-

- - Daten importieren -

-
- - - Warnung: Der Import überschreibt alle Daten dieser Instanz unwiderruflich! - + {/* Bento Item 4: LicServer Konfiguration (Breites Bento: 4 Spalten auf Large) */} + +
+
+
+ +
+
+

CASPOS Lizenzserver (LicServer)

+

REST API-Anbindung für automatisierte Lizenzierung

-
-
- setSelectedFile(e.target.files?.[0] || null)} - disabled={exporting || importing} - className="absolute inset-0 w-full h-full opacity-0 cursor-pointer disabled:cursor-not-allowed" - /> -
- {selectedFile ? ( - {selectedFile.name} - ) : ( - "ZIP-Datei auswählen oder hierher ziehen" - )} -
+ {/* LicServer Status Pill */} + {licStatus && ( +
+ {licStatus.ok ? : } + {licStatus.message}
+ )} +
- + {licMsg && ( +
+ {licMsg}
-
-
-
- {/* LicServer Konfiguration */} -
-
-

- - LicServer Konfiguration -

-

- Verbindungseinstellungen zum CASPOS Lizenzserver. -

-
+ )} - {/* Status Message */} - {licMsg && ( -
- {licMsg} -
- )} - - {/* Connection Test Result */} - {licStatus && ( -
- {licStatus.ok - ? - : } - {licStatus.message} -
- )} - -
- {/* Base URL */} -
- - setLicUrl(e.target.value)} - placeholder="http://192.168.178.174:9980" - className="text-sm font-mono" - /> -

URL des CASPOS Lizenzservers

-
- - {/* API Key */} -
- -
+
+ {/* Base URL */} +
+ setLicKey(e.target.value)} - placeholder="Ihr X-Api-Key" - className="text-sm font-mono pr-10" + id="lic-url" + value={licUrl} + onChange={e => setLicUrl(e.target.value)} + placeholder="http://192.168.178.174:9980" + className="text-sm font-mono bg-slate-950/80 border-slate-800 text-white rounded-xl" /> -
+ {/* API Key */} +
+ +
+ setLicKey(e.target.value)} + placeholder="Ihr X-Api-Key" + className="text-sm font-mono pr-10 bg-slate-950/80 border-slate-800 text-white rounded-xl" + /> + +
- {/* Actions */} -
+ {/* Action Buttons */} +
-
-
+
+ +
); } -