Files
fotospiel-app/resources/js/guest-v2/layouts/EventLayout.tsx
2026-02-02 13:01:20 +01:00

75 lines
2.6 KiB
TypeScript

import React from 'react';
import { Navigate, Outlet, useParams } from 'react-router-dom';
import { LocaleProvider } from '@/guest/i18n/LocaleContext';
import { DEFAULT_LOCALE, isLocaleCode } from '@/guest/i18n/messages';
import { NotificationCenterProvider } from '@/guest/context/NotificationCenterContext';
import { EventBrandingProvider } from '@/guest/context/EventBrandingContext';
import { EventDataProvider, useEventData } from '../context/EventDataContext';
import { GuestIdentityProvider, useOptionalGuestIdentity } from '../context/GuestIdentityContext';
import { mapEventBranding } from '../lib/eventBranding';
import { BrandingTheme } from '../lib/brandingTheme';
type EventLayoutProps = {
tasksEnabledFallback?: boolean;
requireProfile?: boolean;
};
export default function EventLayout({ tasksEnabledFallback = true, requireProfile = false }: EventLayoutProps) {
const { token } = useParams<{ token: string }>();
return (
<EventDataProvider token={token} tasksEnabledFallback={tasksEnabledFallback}>
<EventProviders token={token} requireProfile={requireProfile}>
<Outlet />
</EventProviders>
</EventDataProvider>
);
}
function EventProviders({
token,
children,
requireProfile,
}: {
token?: string;
children: React.ReactNode;
requireProfile: boolean;
}) {
const { event } = useEventData();
const eventLocale = event && isLocaleCode(event.default_locale) ? event.default_locale : DEFAULT_LOCALE;
const localeStorageKey = event
? `guestLocale_event_${event.id ?? token ?? 'global'}`
: `guestLocale_event_${token ?? 'global'}`;
const branding = mapEventBranding(
event?.branding ?? (event as unknown as { settings?: { branding?: any } })?.settings?.branding ?? null
);
const content = (
<EventBrandingProvider branding={branding}>
<LocaleProvider defaultLocale={eventLocale} storageKey={localeStorageKey}>
<GuestIdentityProvider eventKey={token ?? ''}>
<BrandingTheme>
{requireProfile ? <ProfileGate token={token}>{children}</ProfileGate> : children}
</BrandingTheme>
</GuestIdentityProvider>
</LocaleProvider>
</EventBrandingProvider>
);
if (!token) {
return content;
}
return <NotificationCenterProvider eventToken={token}>{content}</NotificationCenterProvider>;
}
function ProfileGate({ token, children }: { token?: string; children: React.ReactNode }) {
const identity = useOptionalGuestIdentity();
if (token && identity?.hydrated && !identity.name) {
return <Navigate to={`/setup/${encodeURIComponent(token)}`} replace />;
}
return <>{children}</>;
}