9c5c22d92b
Flexbox-Items haben default min-width: auto. Ohne overflow-auto
(das ich in 6479598 rausgenommen habe, damit Sticky-Header
funktionieren) wächst der Wrapper mit jedem breiten Kind – lange
E-Mail-Adressen, breite Tabellen, PDF-URL-Anhänge – horizontal
über die Viewport-Breite hinaus.
min-w-0 cappt die Flex-Basis auf die verfügbare Breite, ohne
einen Scroll-Kontext zu schaffen (im Gegensatz zu overflow-auto),
also bleiben die Sticky-Header weiter wirksam.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
94 lines
3.2 KiB
TypeScript
94 lines
3.2 KiB
TypeScript
import { Outlet, Link } from 'react-router-dom';
|
||
import { useQuery } from '@tanstack/react-query';
|
||
import { useAuth } from '../../context/AuthContext';
|
||
import { gdprApi } from '../../services/api';
|
||
import Sidebar from './Sidebar';
|
||
import ScrollToTopButton from '../ScrollToTopButton';
|
||
import BirthdayModal from '../BirthdayModal';
|
||
import { AlertTriangle, ArrowRight, Building, Shield } from 'lucide-react';
|
||
|
||
function ConsentBanner() {
|
||
const { user, isCustomerPortal } = useAuth();
|
||
|
||
const { data } = useQuery({
|
||
queryKey: ['my-consent-status'],
|
||
queryFn: () => gdprApi.getMyConsentStatus(),
|
||
enabled: isCustomerPortal && !!user?.customerId,
|
||
staleTime: 30_000,
|
||
});
|
||
|
||
if (!isCustomerPortal || !data?.data) return null;
|
||
|
||
if (data.data.hasConsent) return null;
|
||
|
||
return (
|
||
<div className="bg-amber-50 border-b border-amber-200 px-6 py-3">
|
||
<div className="flex items-center justify-between">
|
||
<div className="flex items-center gap-3">
|
||
<AlertTriangle className="w-5 h-5 text-amber-600 flex-shrink-0" />
|
||
<p className="text-sm text-amber-800">
|
||
Bitte stimmen Sie unserer Datenschutzerklärung zu, damit wir Sie beraten können.
|
||
</p>
|
||
</div>
|
||
<Link
|
||
to="/privacy"
|
||
className="flex items-center gap-1 text-sm font-medium text-amber-700 hover:text-amber-900 whitespace-nowrap"
|
||
>
|
||
Jetzt zustimmen
|
||
<ArrowRight className="w-4 h-4" />
|
||
</Link>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
function PortalFooter() {
|
||
const { isCustomerPortal } = useAuth();
|
||
if (!isCustomerPortal) return null;
|
||
|
||
return (
|
||
<footer className="border-t bg-gray-50 px-8 py-4">
|
||
<div className="flex items-center justify-center gap-6 text-sm text-gray-500">
|
||
<Link to="/imprint" className="flex items-center gap-1 hover:text-blue-600 transition-colors">
|
||
<Building className="w-3 h-3" />
|
||
Impressum
|
||
</Link>
|
||
<span className="text-gray-300">|</span>
|
||
<Link to="/website-privacy" className="flex items-center gap-1 hover:text-blue-600 transition-colors">
|
||
<Shield className="w-3 h-3" />
|
||
Datenschutzerklärung
|
||
</Link>
|
||
</div>
|
||
</footer>
|
||
);
|
||
}
|
||
|
||
export default function Layout() {
|
||
return (
|
||
// `overflow-auto` auf dem Content-Wrapper wurde entfernt: dadurch
|
||
// wurde jeder Sticky-Header (ContractDetail/ContractForm) unwirksam,
|
||
// weil sein Scroll-Ancestor der Wrapper war – der aber wegen der
|
||
// Flexbox-`min-h-auto`-Regel nicht selbst scrollte. Jetzt scrollt
|
||
// wieder das Window, und Sticky sitzt an der Viewport-Kante.
|
||
//
|
||
// `min-w-0` auf dem Content-Wrapper: Flex-Items haben default
|
||
// `min-width: auto`, wodurch der Wrapper von einem sehr breiten
|
||
// Kind (lange E-Mail-Adressen, breite Tabellen, PDF-URL-Anhänge)
|
||
// horizontal aufgebläht wird. Ohne overflow-auto fehlte der
|
||
// stille Cap; jetzt cappt min-w-0 die Flex-Basis auf die
|
||
// Viewport-Breite.
|
||
<div className="flex min-h-screen">
|
||
<Sidebar />
|
||
<div className="flex-1 flex flex-col min-w-0">
|
||
<ConsentBanner />
|
||
<main className="flex-1 p-8">
|
||
<Outlet />
|
||
</main>
|
||
<PortalFooter />
|
||
</div>
|
||
<ScrollToTopButton />
|
||
<BirthdayModal />
|
||
</div>
|
||
);
|
||
}
|