Adjust branding defaults and tenant presets
This commit is contained in:
@@ -28,6 +28,8 @@ const BRANDING_FORM_DEFAULTS = {
|
||||
accent: DEFAULT_EVENT_BRANDING.secondaryColor,
|
||||
background: DEFAULT_EVENT_BRANDING.backgroundColor,
|
||||
surface: DEFAULT_EVENT_BRANDING.palette?.surface ?? DEFAULT_EVENT_BRANDING.backgroundColor,
|
||||
headingFont: DEFAULT_EVENT_BRANDING.typography?.heading ?? DEFAULT_EVENT_BRANDING.fontFamily ?? '',
|
||||
bodyFont: DEFAULT_EVENT_BRANDING.typography?.body ?? DEFAULT_EVENT_BRANDING.fontFamily ?? '',
|
||||
mode: DEFAULT_EVENT_BRANDING.mode ?? 'auto',
|
||||
buttonStyle: DEFAULT_EVENT_BRANDING.buttons?.style ?? 'filled',
|
||||
buttonRadius: DEFAULT_EVENT_BRANDING.buttons?.radius ?? 12,
|
||||
@@ -40,14 +42,11 @@ const BRANDING_FORM_DEFAULTS = {
|
||||
logoSize: DEFAULT_EVENT_BRANDING.logo?.size ?? 'm',
|
||||
};
|
||||
|
||||
const BRANDING_FORM_BASE: BrandingFormValues = {
|
||||
...BRANDING_FORM_DEFAULTS,
|
||||
headingFont: '',
|
||||
bodyFont: '',
|
||||
const buildBrandingFormBase = (defaults: typeof BRANDING_FORM_DEFAULTS): BrandingFormValues => ({
|
||||
...defaults,
|
||||
logoDataUrl: '',
|
||||
logoValue: '',
|
||||
useDefaultBranding: false,
|
||||
};
|
||||
});
|
||||
|
||||
const FONT_SIZE_SCALE: Record<BrandingFormValues['fontSize'], number> = {
|
||||
s: 0.94,
|
||||
@@ -61,6 +60,38 @@ const LOGO_SIZE_PREVIEW: Record<BrandingFormValues['logoSize'], number> = {
|
||||
l: 44,
|
||||
};
|
||||
|
||||
const resolveBrandingDefaults = (tenantBranding: BrandingFormValues | null) => {
|
||||
if (!tenantBranding) {
|
||||
return BRANDING_FORM_DEFAULTS;
|
||||
}
|
||||
|
||||
const primary = tenantBranding.primary.trim() ? tenantBranding.primary : BRANDING_FORM_DEFAULTS.primary;
|
||||
const accent = tenantBranding.accent.trim() ? tenantBranding.accent : BRANDING_FORM_DEFAULTS.accent;
|
||||
const background = tenantBranding.background.trim() ? tenantBranding.background : BRANDING_FORM_DEFAULTS.background;
|
||||
const surface = tenantBranding.surface.trim() ? tenantBranding.surface : BRANDING_FORM_DEFAULTS.surface;
|
||||
const headingFont = tenantBranding.headingFont.trim()
|
||||
? tenantBranding.headingFont
|
||||
: BRANDING_FORM_DEFAULTS.headingFont;
|
||||
const bodyFont = tenantBranding.bodyFont.trim()
|
||||
? tenantBranding.bodyFont
|
||||
: BRANDING_FORM_DEFAULTS.bodyFont;
|
||||
|
||||
return {
|
||||
...BRANDING_FORM_DEFAULTS,
|
||||
primary,
|
||||
accent,
|
||||
background,
|
||||
surface,
|
||||
headingFont,
|
||||
bodyFont,
|
||||
fontSize: tenantBranding.fontSize ?? BRANDING_FORM_DEFAULTS.fontSize,
|
||||
mode: tenantBranding.mode ?? BRANDING_FORM_DEFAULTS.mode,
|
||||
buttonPrimary: primary,
|
||||
buttonSecondary: accent,
|
||||
linkColor: accent,
|
||||
};
|
||||
};
|
||||
|
||||
type WatermarkPosition =
|
||||
| 'top-left'
|
||||
| 'top-center'
|
||||
@@ -95,7 +126,7 @@ export default function MobileBrandingPage() {
|
||||
const { textStrong, muted, subtle, border, primary, accentSoft, danger, surfaceMuted, surface } = useAdminTheme();
|
||||
|
||||
const [event, setEvent] = React.useState<TenantEvent | null>(null);
|
||||
const [form, setForm] = React.useState<BrandingFormValues>(BRANDING_FORM_BASE);
|
||||
const [form, setForm] = React.useState<BrandingFormValues>(() => buildBrandingFormBase(BRANDING_FORM_DEFAULTS));
|
||||
const [watermarkForm, setWatermarkForm] = React.useState<WatermarkForm>({
|
||||
mode: 'base',
|
||||
assetPath: '',
|
||||
@@ -120,10 +151,13 @@ export default function MobileBrandingPage() {
|
||||
const [fontsLoaded, setFontsLoaded] = React.useState(false);
|
||||
const [tenantBranding, setTenantBranding] = React.useState<BrandingFormValues | null>(null);
|
||||
const [tenantBrandingLoaded, setTenantBrandingLoaded] = React.useState(false);
|
||||
const [formInitialized, setFormInitialized] = React.useState(false);
|
||||
const resolvedDefaults = React.useMemo(() => resolveBrandingDefaults(tenantBranding), [tenantBranding]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!slug) return;
|
||||
(async () => {
|
||||
setFormInitialized(false);
|
||||
setLoading(true);
|
||||
try {
|
||||
const data = await getEvent(slug);
|
||||
@@ -132,7 +166,6 @@ export default function MobileBrandingPage() {
|
||||
return;
|
||||
}
|
||||
setEvent(data);
|
||||
setForm(extractBrandingForm(data.settings ?? {}, BRANDING_FORM_DEFAULTS));
|
||||
setWatermarkForm(extractWatermark(data));
|
||||
setError(null);
|
||||
} catch (err) {
|
||||
@@ -145,6 +178,12 @@ export default function MobileBrandingPage() {
|
||||
})();
|
||||
}, [slug, t]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!event || !tenantBrandingLoaded || formInitialized) return;
|
||||
setForm(extractBrandingForm(event.settings ?? {}, resolvedDefaults));
|
||||
setFormInitialized(true);
|
||||
}, [event, tenantBrandingLoaded, formInitialized, resolvedDefaults]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!showFontsSheet || fontsLoaded) return;
|
||||
setFontsLoading(true);
|
||||
@@ -177,7 +216,7 @@ export default function MobileBrandingPage() {
|
||||
};
|
||||
}, [tenantBrandingLoaded]);
|
||||
|
||||
const previewForm = form.useDefaultBranding && tenantBranding ? tenantBranding : form;
|
||||
const previewForm = form;
|
||||
const previewBackground = previewForm.background;
|
||||
const previewSurfaceCandidate = previewForm.surface || previewBackground;
|
||||
const backgroundLuminance = relativeLuminance(previewBackground);
|
||||
@@ -206,7 +245,7 @@ export default function MobileBrandingPage() {
|
||||
const brandingAllowed = isBrandingAllowed(event ?? null);
|
||||
const customWatermarkAllowed = watermarkAllowed && brandingAllowed;
|
||||
const watermarkLocked = watermarkAllowed && !brandingAllowed;
|
||||
const brandingDisabled = !brandingAllowed || form.useDefaultBranding;
|
||||
const brandingDisabled = !brandingAllowed;
|
||||
|
||||
React.useEffect(() => {
|
||||
setWatermarkForm((prev) => {
|
||||
@@ -243,7 +282,6 @@ export default function MobileBrandingPage() {
|
||||
|
||||
settings.branding = {
|
||||
...(typeof settings.branding === 'object' ? (settings.branding as Record<string, unknown>) : {}),
|
||||
use_default_branding: form.useDefaultBranding,
|
||||
primary_color: form.primary,
|
||||
secondary_color: form.accent,
|
||||
accent_color: form.accent,
|
||||
@@ -334,7 +372,7 @@ export default function MobileBrandingPage() {
|
||||
|
||||
function handleReset() {
|
||||
if (event) {
|
||||
setForm(extractBrandingForm(event.settings ?? {}, BRANDING_FORM_DEFAULTS));
|
||||
setForm(extractBrandingForm(event.settings ?? {}, resolvedDefaults));
|
||||
setWatermarkForm(extractWatermark(event));
|
||||
}
|
||||
}
|
||||
@@ -662,36 +700,7 @@ export default function MobileBrandingPage() {
|
||||
/>
|
||||
) : null}
|
||||
|
||||
<MobileCard space="$3">
|
||||
<Text fontSize="$md" fontWeight="800" color={textStrong}>
|
||||
{t('events.branding.source', 'Branding Source')}
|
||||
</Text>
|
||||
<Text fontSize="$sm" color={muted}>
|
||||
{t('events.branding.sourceHint', 'Use the default branding or customize this event only.')}
|
||||
</Text>
|
||||
<XStack space="$2">
|
||||
<ModeButton
|
||||
label={t('events.branding.useDefault', 'Default')}
|
||||
active={form.useDefaultBranding}
|
||||
onPress={() => setForm((prev) => ({ ...prev, useDefaultBranding: true }))}
|
||||
disabled={!brandingAllowed}
|
||||
/>
|
||||
<ModeButton
|
||||
label={t('events.branding.useCustom', 'This event')}
|
||||
active={!form.useDefaultBranding}
|
||||
onPress={() => setForm((prev) => ({ ...prev, useDefaultBranding: false }))}
|
||||
disabled={!brandingAllowed}
|
||||
/>
|
||||
</XStack>
|
||||
<Text fontSize="$xs" color={muted}>
|
||||
{form.useDefaultBranding
|
||||
? t('events.branding.usingDefault', 'Account-Branding aktiv')
|
||||
: t('events.branding.usingCustom', 'Event-Branding aktiv')}
|
||||
</Text>
|
||||
</MobileCard>
|
||||
|
||||
{form.useDefaultBranding ? null : (
|
||||
<>
|
||||
<>
|
||||
<MobileCard space="$3">
|
||||
<Text fontSize="$md" fontWeight="800" color={textStrong}>
|
||||
{t('events.branding.mode', 'Theme')}
|
||||
@@ -1024,8 +1033,7 @@ export default function MobileBrandingPage() {
|
||||
disabled={brandingDisabled}
|
||||
/>
|
||||
</MobileCard>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
</>
|
||||
) : (
|
||||
renderWatermarkTab()
|
||||
|
||||
Reference in New Issue
Block a user