Design: Geruest mit Textmenue, Schublade fuers Handy, Logo; Footer und Einklappen entfallen
Weisses Geruest (.shell, feste Seitenleiste, Dokument-Scroll), Menue als Textliste mit Zaehlern und Serverpuls-Punkt, Schublade mit Scrim und Esc auf dem Handy, Logo-Komponente und Favicon. Footer, Einklappen (lib/sidebar.js) und das alte Menue-CSS (.side*, .app-*) sind entfernt. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c19e19968d
commit
5a0307c9d6
14 files changed
+102
-234
No files matched your search
+31
-14
@@ -1,7 +1,8 @@
|
||||
import { BrowserRouter, Routes, Route, Navigate, useLocation } from 'react-router-dom'
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
import { BrowserRouter, Routes, Route, Navigate, Link, useLocation } from 'react-router-dom'
|
||||
import { AuthProvider, useAuth } from './context/AuthContext'
|
||||
import Sidebar from './components/Navbar'
|
||||
import Footer from './components/Footer'
|
||||
import Logo from './components/Logo'
|
||||
import LoginPage from './pages/LoginPage'
|
||||
import TicketsPage from './pages/TicketsPage'
|
||||
import PlanboardPage from './pages/PlanboardPage'
|
||||
@@ -28,12 +29,7 @@ function ProtectedRoute({ children }) {
|
||||
const location = useLocation()
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="text-center p-4" style={{ marginTop: 80 }}>
|
||||
<div className="spinner"></div>
|
||||
<p>Loading...</p>
|
||||
</div>
|
||||
)
|
||||
return <div className="loading">Wird geladen …</div>
|
||||
}
|
||||
|
||||
if (!user) {
|
||||
@@ -79,19 +75,40 @@ function AppRoutes() {
|
||||
|
||||
function AppContent() {
|
||||
const { user } = useAuth()
|
||||
const location = useLocation()
|
||||
// Schublade des Menues auf dem Handy; auf dem Desktop steht das Menue fest und menuOpen bleibt ohne Wirkung
|
||||
const [menuOpen, setMenuOpen] = useState(false)
|
||||
const open = useCallback(() => setMenuOpen(true), [])
|
||||
const close = useCallback(() => setMenuOpen(false), [])
|
||||
|
||||
// Seitenwechsel (nur der Pfad, nicht ?woid= oder ?tab=): Schublade zu und wieder nach oben
|
||||
useEffect(() => {
|
||||
setMenuOpen(false)
|
||||
window.scrollTo(0, 0)
|
||||
}, [location.pathname])
|
||||
|
||||
// Esc schliesst die Schublade, nur solange sie offen ist
|
||||
useEffect(() => {
|
||||
if (!menuOpen) return undefined
|
||||
const onKey = (e) => { if (e.key === 'Escape') setMenuOpen(false) }
|
||||
document.addEventListener('keydown', onKey)
|
||||
return () => document.removeEventListener('keydown', onKey)
|
||||
}, [menuOpen])
|
||||
|
||||
if (!user) {
|
||||
return <AppRoutes />
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="app-shell">
|
||||
<Sidebar />
|
||||
<div className="app-main">
|
||||
<div className="app-scroll">
|
||||
<AppRoutes />
|
||||
<div className={`shell${menuOpen ? ' menu-open' : ''}`}>
|
||||
<Sidebar onNavigate={close} />
|
||||
<div className="scrim" onClick={close} />
|
||||
<div className="main">
|
||||
<div className="mobile-bar">
|
||||
<Link className="brand" to="/tickets"><Logo />WEBklar</Link>
|
||||
<button type="button" className="btn btn-quiet" onClick={open} aria-expanded={menuOpen} aria-controls="menue">Menü</button>
|
||||
</div>
|
||||
<Footer />
|
||||
<main id="inhalt"><AppRoutes /></main>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
Reference in new issue
Block a user