Unified Admin Panel: 3 Plugin-Settings in ein zentrales Modal

- Neues AdminPanel.tsx mit Sidebar-Navigation (Soundboard/Streaming/Game Library)
- Lazy-Loading: Daten werden erst beim Tab-Wechsel geladen
- Admin-Button im Header öffnet jetzt das zentrale Panel (Rechtsklick = Logout)
- Admin-Code aus SoundboardTab, StreamingTab und GameLibraryTab entfernt
- ~500 Zeilen Plugin-Code entfernt, durch ~620 Zeilen zentrales Panel ersetzt

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Daniel 2026-03-09 22:33:09 +01:00
parent 4b23d013f9
commit 3f175ca02c
10 changed files with 6137 additions and 5320 deletions

View file

@ -5,6 +5,7 @@ import LolstatsTab from './plugins/lolstats/LolstatsTab';
import StreamingTab from './plugins/streaming/StreamingTab';
import WatchTogetherTab from './plugins/watch-together/WatchTogetherTab';
import GameLibraryTab from './plugins/game-library/GameLibraryTab';
import AdminPanel from './AdminPanel';
interface PluginInfo {
name: string;
@ -43,6 +44,7 @@ export default function App() {
// Centralized admin login state
const [isAdmin, setIsAdmin] = useState(false);
const [showAdminLogin, setShowAdminLogin] = useState(false);
const [showAdminPanel, setShowAdminPanel] = useState(false);
const [adminPwd, setAdminPwd] = useState('');
const [adminError, setAdminError] = useState('');
@ -238,8 +240,9 @@ export default function App() {
)}
<button
className={`hub-admin-btn ${isAdmin ? 'active' : ''}`}
onClick={() => isAdmin ? handleAdminLogout() : setShowAdminLogin(true)}
title={isAdmin ? 'Admin abmelden' : 'Admin Login'}
onClick={() => isAdmin ? setShowAdminPanel(true) : setShowAdminLogin(true)}
onContextMenu={e => { if (isAdmin) { e.preventDefault(); handleAdminLogout(); } }}
title={isAdmin ? 'Admin Panel (Rechtsklick = Abmelden)' : 'Admin Login'}
>
{isAdmin ? '\uD83D\uDD13' : '\uD83D\uDD12'}
</button>
@ -390,6 +393,10 @@ export default function App() {
</div>
)}
{showAdminPanel && isAdmin && (
<AdminPanel onClose={() => setShowAdminPanel(false)} />
)}
<main className="hub-content">
{plugins.length === 0 ? (
<div className="hub-empty">