Files
opencrm/frontend/src/components/layout/Layout.tsx
T
duffyduck 9c5c22d92b Layout: min-w-0 auf Content-Wrapper, sonst horizontales Overflow
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>
2026-07-03 08:35:00 +02:00

94 lines
3.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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>
);
}