diff --git a/frontend/src/components/UpdateBanner.tsx b/frontend/src/components/UpdateBanner.tsx index d5bfe643..bcb43325 100644 --- a/frontend/src/components/UpdateBanner.tsx +++ b/frontend/src/components/UpdateBanner.tsx @@ -1,4 +1,4 @@ -import { useState } from 'react'; +import { useEffect, useLayoutEffect, useRef, useState } from 'react'; import { RefreshCw, X } from 'lucide-react'; import { useVersionCheck } from '../hooks/useVersionCheck'; @@ -7,15 +7,47 @@ import { useVersionCheck } from '../hooks/useVersionCheck'; * Version verfügbar ist (siehe useVersionCheck). "Jetzt neu laden" lädt die * Seite neu und holt damit den frischen Code; "später" blendet für die * laufende Session aus. + * + * Das Banner klebt (`sticky top-0`) an der Viewport-Oberkante, bleibt beim + * Scrollen also stehen. Damit die seitenspezifischen Sticky-Header + * (ContractDetail/ContractForm mit `top-[var(--app-banner-h)]`) nicht darunter + * verschwinden, meldet das Banner seine gemessene Höhe als CSS-Variable + * `--app-banner-h` am -Element; ohne Banner ist sie 0px. */ export default function UpdateBanner() { const updateAvailable = useVersionCheck(); const [dismissed, setDismissed] = useState(false); + const barRef = useRef(null); - if (!updateAvailable || dismissed) return null; + const visible = updateAvailable && !dismissed; + + useLayoutEffect(() => { + const root = document.documentElement; + if (!visible) { + root.style.setProperty('--app-banner-h', '0px'); + return; + } + const el = barRef.current; + if (!el) return; + const apply = () => root.style.setProperty('--app-banner-h', `${el.offsetHeight}px`); + apply(); + const ro = new ResizeObserver(apply); + ro.observe(el); + return () => { + ro.disconnect(); + root.style.setProperty('--app-banner-h', '0px'); + }; + }, [visible]); + + // Sicherstellen, dass die Variable auch beim Unmount zurückgesetzt wird. + useEffect(() => () => { + document.documentElement.style.setProperty('--app-banner-h', '0px'); + }, []); + + if (!visible) return null; return ( -
+
diff --git a/frontend/src/pages/contracts/ContractDetail.tsx b/frontend/src/pages/contracts/ContractDetail.tsx index 0c2aa94b..7685fe9a 100644 --- a/frontend/src/pages/contracts/ContractDetail.tsx +++ b/frontend/src/pages/contracts/ContractDetail.tsx @@ -1828,7 +1828,7 @@ export default function ContractDetail() { {/* Sticky-Header: Vertragsnummer + Kunde + Aktionsbuttons bleiben beim Scrollen oben stehen. -mx-8 px-8 zieht den Balken auf die Layout-Padding-Kante, damit's optisch bündig ist. */} -
+