Fix guest demo UX and enforce guest limits
This commit is contained in:
@@ -17,25 +17,26 @@ import { MobileSheet } from './components/Sheet';
|
||||
import toast from 'react-hot-toast';
|
||||
import { adminPath } from '../constants';
|
||||
import { useBackNavigation } from './hooks/useBackNavigation';
|
||||
import { ADMIN_COLORS, ADMIN_GRADIENTS, useAdminTheme } from './theme';
|
||||
import { ADMIN_GRADIENTS, useAdminTheme } from './theme';
|
||||
import { extractBrandingForm, type BrandingFormValues } from '../lib/brandingForm';
|
||||
import { getContrastingTextColor } from '@/guest/lib/color';
|
||||
import { DEFAULT_EVENT_BRANDING } from '@/guest/context/EventBrandingContext';
|
||||
import { getContrastingTextColor, relativeLuminance } from '@/guest/lib/color';
|
||||
|
||||
const BRANDING_FORM_DEFAULTS = {
|
||||
primary: ADMIN_COLORS.primary,
|
||||
accent: ADMIN_COLORS.accent,
|
||||
background: '#ffffff',
|
||||
surface: '#ffffff',
|
||||
mode: 'auto' as const,
|
||||
buttonStyle: 'filled' as const,
|
||||
buttonRadius: 12,
|
||||
buttonPrimary: ADMIN_COLORS.primary,
|
||||
buttonSecondary: ADMIN_COLORS.accent,
|
||||
linkColor: ADMIN_COLORS.accent,
|
||||
fontSize: 'm' as const,
|
||||
logoMode: 'upload' as const,
|
||||
logoPosition: 'left' as const,
|
||||
logoSize: 'm' as const,
|
||||
primary: DEFAULT_EVENT_BRANDING.primaryColor,
|
||||
accent: DEFAULT_EVENT_BRANDING.secondaryColor,
|
||||
background: DEFAULT_EVENT_BRANDING.backgroundColor,
|
||||
surface: DEFAULT_EVENT_BRANDING.palette?.surface ?? DEFAULT_EVENT_BRANDING.backgroundColor,
|
||||
mode: DEFAULT_EVENT_BRANDING.mode ?? 'auto',
|
||||
buttonStyle: DEFAULT_EVENT_BRANDING.buttons?.style ?? 'filled',
|
||||
buttonRadius: DEFAULT_EVENT_BRANDING.buttons?.radius ?? 12,
|
||||
buttonPrimary: DEFAULT_EVENT_BRANDING.buttons?.primary ?? DEFAULT_EVENT_BRANDING.primaryColor,
|
||||
buttonSecondary: DEFAULT_EVENT_BRANDING.buttons?.secondary ?? DEFAULT_EVENT_BRANDING.secondaryColor,
|
||||
linkColor: DEFAULT_EVENT_BRANDING.buttons?.linkColor ?? DEFAULT_EVENT_BRANDING.secondaryColor,
|
||||
fontSize: DEFAULT_EVENT_BRANDING.typography?.sizePreset ?? 'm',
|
||||
logoMode: DEFAULT_EVENT_BRANDING.logo?.mode ?? 'emoticon',
|
||||
logoPosition: DEFAULT_EVENT_BRANDING.logo?.position ?? 'left',
|
||||
logoSize: DEFAULT_EVENT_BRANDING.logo?.size ?? 'm',
|
||||
};
|
||||
|
||||
const BRANDING_FORM_BASE: BrandingFormValues = {
|
||||
@@ -176,10 +177,22 @@ export default function MobileBrandingPage() {
|
||||
}, [tenantBrandingLoaded]);
|
||||
|
||||
const previewForm = form.useDefaultBranding && tenantBranding ? tenantBranding : form;
|
||||
const previewBackground = previewForm.background;
|
||||
const previewSurfaceCandidate = previewForm.surface || previewBackground;
|
||||
const backgroundLuminance = relativeLuminance(previewBackground);
|
||||
const surfaceLuminance = relativeLuminance(previewSurfaceCandidate);
|
||||
const previewSurface = Math.abs(surfaceLuminance - backgroundLuminance) < 0.06
|
||||
? backgroundLuminance >= 0.6
|
||||
? '#ffffff'
|
||||
: '#0f172a'
|
||||
: previewSurfaceCandidate;
|
||||
const previewForeground = backgroundLuminance >= 0.6 ? '#1f2937' : '#f8fafc';
|
||||
const previewMutedForeground = backgroundLuminance >= 0.6 ? '#6b7280' : '#cbd5e1';
|
||||
const previewBorder = backgroundLuminance >= 0.6 ? '#e6d9d6' : '#334155';
|
||||
const previewTitle = event ? renderName(event.name) : t('events.placeholders.untitled', 'Unbenanntes Event');
|
||||
const previewHeadingFont = previewForm.headingFont || 'Archivo Black';
|
||||
const previewBodyFont = previewForm.bodyFont || 'Manrope';
|
||||
const previewSurfaceText = getContrastingTextColor(previewForm.surface, '#ffffff', '#0f172a');
|
||||
const previewHeadingFont = previewForm.headingFont || DEFAULT_EVENT_BRANDING.typography?.heading || DEFAULT_EVENT_BRANDING.fontFamily;
|
||||
const previewBodyFont = previewForm.bodyFont || DEFAULT_EVENT_BRANDING.typography?.body || DEFAULT_EVENT_BRANDING.fontFamily;
|
||||
const previewSurfaceText = previewForeground;
|
||||
const previewScale = FONT_SIZE_SCALE[previewForm.fontSize] ?? 1;
|
||||
const previewButtonColor = previewForm.buttonPrimary || previewForm.primary;
|
||||
const previewButtonText = getContrastingTextColor(previewButtonColor, '#ffffff', '#0f172a');
|
||||
@@ -560,8 +573,8 @@ export default function MobileBrandingPage() {
|
||||
<Text fontSize="$sm" fontWeight="700" color={textStrong}>
|
||||
{t('events.branding.previewTitle', 'Guest App Preview')}
|
||||
</Text>
|
||||
<YStack borderRadius={16} borderWidth={1} borderColor={border} backgroundColor={previewForm.background} padding="$3" space="$2" alignItems="center">
|
||||
<YStack width="100%" borderRadius={12} backgroundColor={previewForm.surface} borderWidth={1} borderColor={border} overflow="hidden">
|
||||
<YStack borderRadius={16} borderWidth={1} borderColor={previewBorder} backgroundColor={previewBackground} padding="$3" space="$2" alignItems="center">
|
||||
<YStack width="100%" borderRadius={12} backgroundColor={previewSurface} borderWidth={1} borderColor={previewBorder} overflow="hidden">
|
||||
<YStack
|
||||
height={64}
|
||||
style={{ background: `linear-gradient(135deg, ${previewForm.primary}, ${previewForm.accent})` }}
|
||||
@@ -602,18 +615,18 @@ export default function MobileBrandingPage() {
|
||||
{previewTitle}
|
||||
</Text>
|
||||
<Text
|
||||
color={previewSurfaceText}
|
||||
style={{ fontFamily: previewBodyFont, opacity: 0.7, fontSize: 13 * previewScale }}
|
||||
color={previewMutedForeground}
|
||||
style={{ fontFamily: previewBodyFont, fontSize: 13 * previewScale }}
|
||||
>
|
||||
{t('events.branding.previewSubtitle', 'Aktuelle Farben & Schriften')}
|
||||
</Text>
|
||||
</YStack>
|
||||
</XStack>
|
||||
<XStack space="$2" marginTop="$1">
|
||||
<ColorSwatch color={previewForm.primary} label={t('events.branding.primary', 'Primary')} />
|
||||
<ColorSwatch color={previewForm.accent} label={t('events.branding.accent', 'Accent')} />
|
||||
<ColorSwatch color={previewForm.background} label={t('events.branding.background', 'Background')} />
|
||||
<ColorSwatch color={previewForm.surface} label={t('events.branding.surface', 'Surface')} />
|
||||
<ColorSwatch color={previewForm.primary} label={t('events.branding.primary', 'Primary')} borderColor={previewBorder} />
|
||||
<ColorSwatch color={previewForm.accent} label={t('events.branding.accent', 'Accent')} borderColor={previewBorder} />
|
||||
<ColorSwatch color={previewBackground} label={t('events.branding.background', 'Background')} borderColor={previewBorder} />
|
||||
<ColorSwatch color={previewSurface} label={t('events.branding.surface', 'Surface')} borderColor={previewBorder} />
|
||||
</XStack>
|
||||
<XStack marginTop="$2">
|
||||
<div
|
||||
@@ -1220,11 +1233,11 @@ function ColorField({
|
||||
);
|
||||
}
|
||||
|
||||
function ColorSwatch({ color, label }: { color: string; label: string }) {
|
||||
function ColorSwatch({ color, label, borderColor }: { color: string; label: string; borderColor?: string }) {
|
||||
const { border, muted } = useAdminTheme();
|
||||
return (
|
||||
<YStack alignItems="center" space="$1">
|
||||
<YStack width={40} height={40} borderRadius={12} borderWidth={1} borderColor={border} backgroundColor={color} />
|
||||
<YStack width={40} height={40} borderRadius={12} borderWidth={1} borderColor={borderColor ?? border} backgroundColor={color} />
|
||||
<Text fontSize="$xs" color={muted}>
|
||||
{label}
|
||||
</Text>
|
||||
|
||||
Reference in New Issue
Block a user