From 9f8891395a61571e16998fd356bec3513c54b903 Mon Sep 17 00:00:00 2001 From: Dicken Date: Tue, 2 Jun 2026 21:15:22 +0200 Subject: [PATCH] Fix: doppelte SW-Registrierung entfernt, Reload bei App-Fokus; Schnellzugriff gleichgross; Kalender ohne Komma --- frontend/index.html | 9 --------- frontend/src/App.jsx | 7 +++---- frontend/src/calendar.jsx | 2 +- frontend/src/main.jsx | 32 ++++++++++++++++++++------------ 4 files changed, 24 insertions(+), 26 deletions(-) diff --git a/frontend/index.html b/frontend/index.html index 4ff9fe9..96d094f 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -17,14 +17,5 @@
- diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index f0cb773..2748bce 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -459,7 +459,7 @@ function QuickLinksCarousel({ links }) { }; if (pageCount <= 1) return ( -
+
{links.map(l => )}
); @@ -476,7 +476,6 @@ function QuickLinksCarousel({ links }) { display:'grid', gridTemplateColumns:`repeat(${perRow}, 1fr)`, gridTemplateRows:'repeat(2, auto)', - justifyItems:'center', gap, flexShrink:0, scrollSnapAlign:'start', width:'100%', minWidth:'100%', }}> @@ -507,7 +506,7 @@ function QuickLinkIcon({ l }) { style={{ display:'flex', flexDirection:'column', alignItems:'center', justifyContent:'center', gap:3, padding:'4px 2px', background:'rgba(255,255,255,0.04)', border:'1px solid rgba(255,255,255,0.08)', borderRadius:10, - textDecoration:'none', height:48, cursor:'pointer' }}> + textDecoration:'none', height:48, width:'100%', boxSizing:'border-box', cursor:'pointer' }}> {l.icon && l.icon.startsWith('http') ? e.target.style.display='none'}/> : {l.icon}} @@ -2381,7 +2380,7 @@ export default function App() { const [user,setUser]=useState(null); const [active,setActiveRaw]=useState('dashboard'); const setActive = (page) => { - import('./main.jsx').then(m => m.reloadIfNewBuild?.()).catch(()=>{}); + if (window.__newBuildAvailable) { window.location.reload(); return; } setActiveRaw(page); }; const [toastMsg,setToastMsg]=useState({msg:'',type:'success'}); diff --git a/frontend/src/calendar.jsx b/frontend/src/calendar.jsx index 0b40518..9cfb011 100644 --- a/frontend/src/calendar.jsx +++ b/frontend/src/calendar.jsx @@ -172,7 +172,7 @@ export default function CalendarWidget() { {nextEvent.allDay ? nextEvent.dtstart.toLocaleDateString('de-DE',{day:'numeric',month:'short'}) - : nextEvent.dtstart.toLocaleString('de-DE',{day:'2-digit',month:'2-digit',hour:'2-digit',minute:'2-digit'}) + : `${nextEvent.dtstart.toLocaleDateString('de-DE',{day:'2-digit',month:'2-digit'})} ${nextEvent.dtstart.toLocaleTimeString('de-DE',{hour:'2-digit',minute:'2-digit'})}` }
diff --git a/frontend/src/main.jsx b/frontend/src/main.jsx index 9c899fb..80066fd 100644 --- a/frontend/src/main.jsx +++ b/frontend/src/main.jsx @@ -2,13 +2,12 @@ import React from 'react' import ReactDOM from 'react-dom/client' import App from './App.jsx' -// ── Build-Zeit Check ────────────────────────────────────────────────────────── -// Globale Variable – synchron lesbar, kein dynamischer Import nötig +// ── Build-Zeit Check & Auto-Reload ─────────────────────────────────────────── window.__newBuildAvailable = false; const STORED_KEY = 'dd_build_time'; -async function checkBuildTime() { +async function checkBuildTime({ reloadIfChanged = false } = {}) { try { const r = await fetch('/api/build-time', { cache: 'no-store' }); const { buildTime } = await r.json(); @@ -18,33 +17,42 @@ async function checkBuildTime() { } else if (stored !== buildTime) { localStorage.setItem(STORED_KEY, buildTime); window.__newBuildAvailable = true; + // Wenn explizit gewünscht (App-Fokus): sofort neu laden + if (reloadIfChanged) window.location.reload(); } } catch {} } -// Sofort beim Start prüfen, dann alle 60s +// Beim Start prüfen checkBuildTime(); -setInterval(checkBuildTime, 60_000); +// Alle 60s im Hintergrund +setInterval(() => checkBuildTime(), 60_000); + +// Wenn die App/der Tab wieder in den Vordergrund kommt → prüfen und ggf. sofort neu laden +// Das deckt den Fall ab: PWA vom Homescreen öffnen +document.addEventListener('visibilitychange', () => { + if (document.visibilityState === 'visible') { + checkBuildTime({ reloadIfChanged: true }); + } +}); +window.addEventListener('focus', () => { + checkBuildTime({ reloadIfChanged: true }); +}); // ── Service Worker ──────────────────────────────────────────────────────────── if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw.js').then(reg => { if (reg.waiting) reg.waiting.postMessage('SKIP_WAITING'); - reg.addEventListener('updatefound', () => { const nw = reg.installing; nw?.addEventListener('statechange', () => { - if (nw.state === 'installed') { - nw.postMessage('SKIP_WAITING'); - } + if (nw.state === 'installed') nw.postMessage('SKIP_WAITING'); }); }); - - // Neuer SW aktiv → beim nächsten Seitenwechsel reloaden navigator.serviceWorker.addEventListener('controllerchange', () => { window.__newBuildAvailable = true; }); - }); + }).catch(()=>{}); } ReactDOM.createRoot(document.getElementById('root')).render(