import React, { useState } from 'react'; import { BrowserRouter as Router, Routes, Route, Link, Outlet, useNavigate } from 'react-router-dom'; import { SidebarComponent } from '@syncfusion/ej2-react-navigations'; import { ButtonComponent } from '@syncfusion/ej2-react-buttons'; import { DropDownButtonComponent } from '@syncfusion/ej2-react-splitbuttons'; import type { MenuEventArgs } from '@syncfusion/ej2-splitbuttons'; import { TooltipComponent } from '@syncfusion/ej2-react-popups'; import logo from './assets/logo.png'; import './App.css'; // Lucide Icons importieren import { LayoutDashboard, Calendar, Boxes, Image, User, Settings, Monitor, MonitorDotIcon, LogOut, Wrench, Info, } from 'lucide-react'; import { ToastProvider } from './components/ToastProvider'; const sidebarItems = [ { name: 'Dashboard', path: '/', icon: LayoutDashboard }, { name: 'Termine', path: '/termine', icon: Calendar }, { name: 'Ressourcen', path: '/ressourcen', icon: Boxes }, { name: 'Raumgruppen', path: '/infoscr_groups', icon: MonitorDotIcon }, { name: 'Infoscreen-Clients', path: '/clients', icon: Monitor }, { name: 'Erweiterungsmodus', path: '/setup', icon: Wrench }, { name: 'Medien', path: '/medien', icon: Image }, { name: 'Benutzer', path: '/benutzer', icon: User }, { name: 'Einstellungen', path: '/einstellungen', icon: Settings }, { name: 'Programminfo', path: '/programminfo', icon: Info }, ]; // Dummy Components (können in eigene Dateien ausgelagert werden) import Dashboard from './dashboard'; import Appointments from './appointments'; import Ressourcen from './ressourcen'; import Infoscreens from './clients'; import Infoscreen_groups from './infoscreen_groups'; import Media from './media'; import Benutzer from './users'; import Einstellungen from './settings'; import SetupMode from './SetupMode'; import Programminfo from './programminfo'; import Logout from './logout'; import Login from './login'; import { useAuth } from './useAuth'; // ENV aus .env holen (Platzhalter, im echten Projekt über process.env oder API) // const ENV = import.meta.env.VITE_ENV || 'development'; const Layout: React.FC = () => { const [version, setVersion] = useState(''); const [isCollapsed, setIsCollapsed] = useState(false); let sidebarRef: SidebarComponent | null; const { user } = useAuth(); const navigate = useNavigate(); React.useEffect(() => { fetch('/program-info.json') .then(res => res.json()) .then(data => setVersion(data.version)) .catch(err => console.error('Failed to load version info:', err)); }, []); const toggleSidebar = () => { if (sidebarRef) { sidebarRef.toggle(); } }; const onSidebarChange = () => { // Syncfusion unterscheidet zwischen isOpen (true/false) und dem Dock-Modus // Im Dock-Modus ist isOpen=true, aber die Sidebar ist kollabiert const sidebar = sidebarRef?.element; if (sidebar) { const currentWidth = sidebar.style.width; const newCollapsedState = currentWidth === '60px' || currentWidth.includes('60'); setIsCollapsed(newCollapsedState); } }; const sidebarTemplate = () => (
Logo
{(() => { const logoutContent = ( Abmelden ); // Syncfusion Tooltip nur im collapsed state return isCollapsed ? ( {logoutContent} ) : ( logoutContent ); })()} {version && (
Version {version}
)}
); return (
{ sidebarRef = sidebar; }} width="256px" target=".layout-container" isOpen={true} closeOnDocumentClick={false} enableGestures={false} type="Auto" enableDock={true} dockSize="60px" change={onSidebarChange} > {sidebarTemplate()}
Logo Infoscreen-Management
[Organisationsname] {user && ( { if (args.item.id === 'profile') { navigate('/benutzer'); } else if (args.item.id === 'logout') { navigate('/logout'); } }} cssClass="e-inherit" >
{user.username} {user.role}
)}
); }; const App: React.FC = () => { // Automatische Navigation zu /clients bei leerer Beschreibung entfernt const RequireAuth: React.FC<{ children: React.ReactNode }> = ({ children }) => { const { isAuthenticated, loading } = useAuth(); if (loading) return
Lade ...
; if (!isAuthenticated) return ; return <>{children}; }; return ( } > } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> ); }; const AppWrapper: React.FC = () => ( ); export default AppWrapper;