75 lines
2.6 KiB
TypeScript
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}</>;
|
|
}
|