die tenant admin oauth authentifizierung wurde implementiert und funktioniert jetzt. Zudem wurde das marketing frontend dashboard implementiert.
This commit is contained in:
115
resources/js/guest/context/EventBrandingContext.tsx
Normal file
115
resources/js/guest/context/EventBrandingContext.tsx
Normal file
@@ -0,0 +1,115 @@
|
||||
import React, { createContext, useContext, useEffect, useMemo } from 'react';
|
||||
import type { EventBranding } from '../types/event-branding';
|
||||
|
||||
type EventBrandingContextValue = {
|
||||
branding: EventBranding;
|
||||
isCustom: boolean;
|
||||
};
|
||||
|
||||
export const DEFAULT_EVENT_BRANDING: EventBranding = {
|
||||
primaryColor: '#f43f5e',
|
||||
secondaryColor: '#fb7185',
|
||||
backgroundColor: '#ffffff',
|
||||
fontFamily: null,
|
||||
logoUrl: null,
|
||||
};
|
||||
const DEFAULT_PRIMARY = DEFAULT_EVENT_BRANDING.primaryColor.toLowerCase();
|
||||
const DEFAULT_SECONDARY = DEFAULT_EVENT_BRANDING.secondaryColor.toLowerCase();
|
||||
const DEFAULT_BACKGROUND = DEFAULT_EVENT_BRANDING.backgroundColor.toLowerCase();
|
||||
|
||||
const EventBrandingContext = createContext<EventBrandingContextValue | undefined>(undefined);
|
||||
|
||||
function normaliseHexColor(value: string | null | undefined, fallback: string): string {
|
||||
if (typeof value !== 'string') {
|
||||
return fallback;
|
||||
}
|
||||
|
||||
const trimmed = value.trim();
|
||||
return /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(trimmed) ? trimmed : fallback;
|
||||
}
|
||||
|
||||
function resolveBranding(input?: EventBranding | null): EventBranding {
|
||||
if (!input) {
|
||||
return DEFAULT_EVENT_BRANDING;
|
||||
}
|
||||
|
||||
return {
|
||||
primaryColor: normaliseHexColor(input.primaryColor, DEFAULT_EVENT_BRANDING.primaryColor),
|
||||
secondaryColor: normaliseHexColor(input.secondaryColor, DEFAULT_EVENT_BRANDING.secondaryColor),
|
||||
backgroundColor: normaliseHexColor(input.backgroundColor, DEFAULT_EVENT_BRANDING.backgroundColor),
|
||||
fontFamily: input.fontFamily?.trim() || null,
|
||||
logoUrl: input.logoUrl?.trim() || null,
|
||||
};
|
||||
}
|
||||
|
||||
function applyCssVariables(branding: EventBranding) {
|
||||
if (typeof document === 'undefined') {
|
||||
return;
|
||||
}
|
||||
|
||||
const root = document.documentElement;
|
||||
root.style.setProperty('--guest-primary', branding.primaryColor);
|
||||
root.style.setProperty('--guest-secondary', branding.secondaryColor);
|
||||
root.style.setProperty('--guest-background', branding.backgroundColor);
|
||||
|
||||
if (branding.fontFamily) {
|
||||
root.style.setProperty('--guest-font-family', branding.fontFamily);
|
||||
} else {
|
||||
root.style.removeProperty('--guest-font-family');
|
||||
}
|
||||
}
|
||||
|
||||
function resetCssVariables() {
|
||||
if (typeof document === 'undefined') {
|
||||
return;
|
||||
}
|
||||
|
||||
const root = document.documentElement;
|
||||
root.style.removeProperty('--guest-primary');
|
||||
root.style.removeProperty('--guest-secondary');
|
||||
root.style.removeProperty('--guest-background');
|
||||
root.style.removeProperty('--guest-font-family');
|
||||
}
|
||||
|
||||
export function EventBrandingProvider({
|
||||
branding,
|
||||
children,
|
||||
}: {
|
||||
branding?: EventBranding | null;
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
const resolved = useMemo(() => resolveBranding(branding), [branding]);
|
||||
|
||||
useEffect(() => {
|
||||
applyCssVariables(resolved);
|
||||
|
||||
return () => {
|
||||
resetCssVariables();
|
||||
applyCssVariables(DEFAULT_EVENT_BRANDING);
|
||||
};
|
||||
}, [resolved]);
|
||||
|
||||
const value = useMemo<EventBrandingContextValue>(() => ({
|
||||
branding: resolved,
|
||||
isCustom:
|
||||
resolved.primaryColor.toLowerCase() !== DEFAULT_PRIMARY
|
||||
|| resolved.secondaryColor.toLowerCase() !== DEFAULT_SECONDARY
|
||||
|| resolved.backgroundColor.toLowerCase() !== DEFAULT_BACKGROUND,
|
||||
}), [resolved]);
|
||||
|
||||
return <EventBrandingContext.Provider value={value}>{children}</EventBrandingContext.Provider>;
|
||||
}
|
||||
|
||||
export function useEventBranding(): EventBrandingContextValue {
|
||||
const context = useContext(EventBrandingContext);
|
||||
|
||||
if (!context) {
|
||||
throw new Error('useEventBranding must be used within an EventBrandingProvider');
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
export function useOptionalEventBranding(): EventBrandingContextValue | undefined {
|
||||
return useContext(EventBrandingContext);
|
||||
}
|
||||
Reference in New Issue
Block a user