diff --git a/client/src/App.jsx b/client/src/App.jsx index 60c8dfa..e3f7ce8 100644 --- a/client/src/App.jsx +++ b/client/src/App.jsx @@ -13,6 +13,7 @@ import SettingsPage from './pages/SettingsPage' import { ToastContainer } from './components/shared/Toast' import { TranslationProvider } from './i18n' import DemoBanner from './components/Layout/DemoBanner' +import { authApi } from './api/client' function ProtectedRoute({ children, adminRequired = false }) { const { isAuthenticated, user, isLoading } = useAuthStore() @@ -61,12 +62,9 @@ export default function App() { if (token) { loadUser() } - // Check if demo mode is active - import('./api/client').then(({ authApi }) => { - authApi.getAppConfig?.().then(config => { - if (config?.demo_mode) setDemoMode(true) - }).catch(() => {}) - }) + authApi.getAppConfig().then(config => { + if (config?.demo_mode) setDemoMode(true) + }).catch(() => {}) }, []) const { settings } = useSettingsStore() diff --git a/client/src/components/Layout/DemoBanner.jsx b/client/src/components/Layout/DemoBanner.jsx index ef215f4..68da3be 100644 --- a/client/src/components/Layout/DemoBanner.jsx +++ b/client/src/components/Layout/DemoBanner.jsx @@ -1,16 +1,12 @@ -import React, { useState, useEffect } from 'react' -import { Info, Github, Shield, Key, Users, Database, ChevronDown, ChevronUp } from 'lucide-react' +import React, { useState } from 'react' +import { Info, Github, Shield, Key, Users, Database, X } from 'lucide-react' import { useTranslation } from '../../i18n' const texts = { de: { - title: 'Demo-Modus', - resetInfo: 'Aenderungen werden stuendlich zurueckgesetzt', - nextReset: 'naechster Reset in ~{min} Min.', - moreInfo: 'Mehr Info', - lessInfo: 'Weniger', - description: 'Du nutzt die NOMAD Demo. Du kannst Reisen ansehen, bearbeiten und eigene erstellen — alles wird jede Stunde automatisch zurueckgesetzt.', - fullVersionTitle: 'Diese Funktionen sind in der Vollversion verfuegbar:', + title: 'Willkommen zur NOMAD Demo', + description: 'Du kannst Reisen ansehen, bearbeiten und eigene erstellen. Alle Aenderungen werden jede Stunde automatisch zurueckgesetzt.', + fullVersionTitle: 'In der Vollversion zusaetzlich verfuegbar:', features: [ 'API-Schluessel verwalten (Google Maps, Wetter)', 'Benutzer & Rechte verwalten', @@ -19,15 +15,12 @@ const texts = { ], selfHost: 'NOMAD ist Open Source — ', selfHostLink: 'selbst hosten', + close: 'Verstanden', }, en: { - title: 'Demo Mode', - resetInfo: 'Changes are reset every hour', - nextReset: 'next reset in ~{min} min.', - moreInfo: 'More info', - lessInfo: 'Less', - description: 'You are using the NOMAD demo. You can view, edit and create trips — everything is automatically reset every hour.', - fullVersionTitle: 'These features are available in the full version:', + title: 'Welcome to the NOMAD Demo', + description: 'You can view, edit and create trips. All changes are automatically reset every hour.', + fullVersionTitle: 'Additionally available in the full version:', features: [ 'API key management (Google Maps, Weather)', 'User & permission management', @@ -36,128 +29,93 @@ const texts = { ], selfHost: 'NOMAD is open source — ', selfHostLink: 'self-host it', + close: 'Got it', }, } const featureIcons = [Key, Users, Database, Shield] export default function DemoBanner() { - const [expanded, setExpanded] = useState(false) - const [minutesLeft, setMinutesLeft] = useState(null) + const [dismissed, setDismissed] = useState(() => sessionStorage.getItem('demo_dismissed') === 'true') const { language } = useTranslation() const t = texts[language] || texts.en - useEffect(() => { - const update = () => setMinutesLeft(59 - new Date().getMinutes()) - update() - const interval = setInterval(update, 30000) - return () => clearInterval(interval) - }, []) + if (dismissed) return null - const bannerHeight = expanded ? undefined : 36 + const handleClose = () => { + sessionStorage.setItem('demo_dismissed', 'true') + setDismissed(true) + } return ( -
- {t.description} -
- -- {t.fullVersionTitle} -
- -+ {t.description} +
+ ++ {t.fullVersionTitle} +
+ +