Update guest v2 branding and theming
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import React from 'react';
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Theme } from '@tamagui/core';
|
||||
import { Image as ImageIcon, RefreshCcw, UploadCloud, Trash2, ChevronDown, Save, Droplets, Lock } from 'lucide-react';
|
||||
import { YStack, XStack } from '@tamagui/stacks';
|
||||
import { SizableText as Text } from '@tamagui/text';
|
||||
@@ -240,6 +241,27 @@ export default function MobileBrandingPage() {
|
||||
const previewLogoUrl = previewForm.logoMode === 'upload' ? previewForm.logoDataUrl : '';
|
||||
const previewLogoValue = previewForm.logoMode === 'emoticon' ? previewForm.logoValue : '';
|
||||
const previewInitials = getInitials(previewTitle);
|
||||
const previewThemeName = previewForm.mode === 'dark' ? 'guestNight' : 'guestLight';
|
||||
const previewIsDark = previewThemeName === 'guestNight';
|
||||
const previewVariables = {
|
||||
'--guest-primary': previewForm.primary,
|
||||
'--guest-secondary': previewForm.accent,
|
||||
'--guest-background': previewBackground,
|
||||
'--guest-surface': previewSurface,
|
||||
'--guest-font-scale': String(previewScale),
|
||||
'--guest-body-font': previewBodyFont,
|
||||
'--guest-heading-font': previewHeadingFont,
|
||||
'--guest-button-radius': `${previewForm.buttonRadius}px`,
|
||||
'--guest-radius': `${previewForm.buttonRadius}px`,
|
||||
'--guest-link': previewForm.linkColor,
|
||||
} as React.CSSProperties;
|
||||
const previewAmbient = previewIsDark
|
||||
? 'radial-gradient(circle at 18% 12%, rgba(255, 110, 110, 0.22), transparent 46%), radial-gradient(circle at 82% 18%, rgba(78, 205, 196, 0.18), transparent 44%), linear-gradient(180deg, rgba(6, 9, 20, 0.96), rgba(10, 14, 28, 1))'
|
||||
: 'radial-gradient(circle at 18% 12%, color-mix(in oklab, var(--guest-primary, #FF6B6B) 24%, white), transparent 50%), radial-gradient(circle at 82% 18%, color-mix(in oklab, var(--guest-secondary, #4ECDC4) 20%, white), transparent 48%), linear-gradient(180deg, color-mix(in oklab, var(--guest-background, #FFF5F5) 96%, white), color-mix(in oklab, var(--guest-background, #FFF5F5) 72%, white))';
|
||||
const previewSurfaceShadow = previewIsDark
|
||||
? '0 18px 32px rgba(2, 6, 23, 0.55)'
|
||||
: '0 16px 28px rgba(15, 23, 42, 0.15)';
|
||||
const previewIconSurface = previewIsDark ? 'rgba(255, 255, 255, 0.12)' : 'rgba(15, 23, 42, 0.08)';
|
||||
const watermarkAllowed = isWatermarkAllowed(event ?? null);
|
||||
const watermarkRemovalAllowed = isWatermarkRemovalAllowed(event ?? null);
|
||||
const brandingAllowed = isBrandingAllowed(event ?? null);
|
||||
@@ -616,79 +638,158 @@ 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={previewBorder} backgroundColor={previewBackground} padding="$3" gap="$2" alignItems="center">
|
||||
<YStack width="100%" borderRadius={12} backgroundColor={previewSurface} borderWidth={1} borderColor={previewBorder} overflow="hidden">
|
||||
<Theme name={previewThemeName}>
|
||||
<YStack
|
||||
borderRadius={18}
|
||||
borderWidth={1}
|
||||
borderColor={previewBorder}
|
||||
overflow="hidden"
|
||||
style={previewVariables}
|
||||
>
|
||||
<YStack
|
||||
height={64}
|
||||
style={{ background: `linear-gradient(135deg, ${previewForm.primary}, ${previewForm.accent})` }}
|
||||
/>
|
||||
<YStack padding="$3" gap="$2">
|
||||
<XStack
|
||||
alignItems="center"
|
||||
gap="$2"
|
||||
flexDirection={previewForm.logoPosition === 'center' ? 'column' : previewForm.logoPosition === 'right' ? 'row-reverse' : 'row'}
|
||||
justifyContent={previewForm.logoPosition === 'center' ? 'center' : 'flex-start'}
|
||||
>
|
||||
<YStack
|
||||
width={previewLogoSize}
|
||||
height={previewLogoSize}
|
||||
borderRadius={previewLogoSize}
|
||||
padding="$3"
|
||||
gap="$3"
|
||||
style={{
|
||||
backgroundImage: previewAmbient,
|
||||
backgroundSize: '140% 140%, 140% 140%, 100% 100%',
|
||||
}}
|
||||
>
|
||||
<XStack alignItems="center" justifyContent="space-between" gap="$3">
|
||||
<XStack
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
backgroundColor={previewForm.accent}
|
||||
gap="$2"
|
||||
flexDirection={previewForm.logoPosition === 'center' ? 'column' : previewForm.logoPosition === 'right' ? 'row-reverse' : 'row'}
|
||||
justifyContent={previewForm.logoPosition === 'center' ? 'center' : 'flex-start'}
|
||||
flex={1}
|
||||
>
|
||||
{previewLogoUrl ? (
|
||||
<img
|
||||
src={previewLogoUrl}
|
||||
alt={t('events.branding.logoAlt', 'Logo')}
|
||||
style={{ width: previewLogoSize - 6, height: previewLogoSize - 6, borderRadius: previewLogoSize, objectFit: 'cover' }}
|
||||
/>
|
||||
) : (
|
||||
<Text fontSize="$sm" color={previewSurfaceText} fontWeight="700">
|
||||
{previewLogoValue || previewInitials}
|
||||
</Text>
|
||||
)}
|
||||
</YStack>
|
||||
<YStack>
|
||||
<Text
|
||||
fontWeight="800"
|
||||
color={previewSurfaceText}
|
||||
style={{ fontFamily: previewHeadingFont, fontSize: 18 * previewScale }}
|
||||
<YStack
|
||||
width={previewLogoSize}
|
||||
height={previewLogoSize}
|
||||
borderRadius={previewLogoSize}
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
backgroundColor={previewForm.accent}
|
||||
>
|
||||
{previewTitle}
|
||||
{previewLogoUrl ? (
|
||||
<img
|
||||
src={previewLogoUrl}
|
||||
alt={t('events.branding.logoAlt', 'Logo')}
|
||||
style={{ width: previewLogoSize - 6, height: previewLogoSize - 6, borderRadius: previewLogoSize, objectFit: 'cover' }}
|
||||
/>
|
||||
) : (
|
||||
<Text fontSize="$sm" color={previewSurfaceText} fontWeight="700">
|
||||
{previewLogoValue || previewInitials}
|
||||
</Text>
|
||||
)}
|
||||
</YStack>
|
||||
<YStack gap="$1">
|
||||
<Text
|
||||
fontWeight="800"
|
||||
color={previewSurfaceText}
|
||||
style={{ fontFamily: previewHeadingFont, fontSize: 18 * previewScale }}
|
||||
>
|
||||
{previewTitle}
|
||||
</Text>
|
||||
<Text
|
||||
color={previewMutedForeground}
|
||||
style={{ fontFamily: previewBodyFont, fontSize: 13 * previewScale }}
|
||||
>
|
||||
{t('events.branding.previewSubtitle', 'Aktuelle Farben & Schriften')}
|
||||
</Text>
|
||||
</YStack>
|
||||
</XStack>
|
||||
<XStack gap="$2">
|
||||
<YStack width={28} height={28} borderRadius={999} backgroundColor={previewIconSurface} />
|
||||
<YStack width={28} height={28} borderRadius={999} backgroundColor={previewIconSurface} />
|
||||
</XStack>
|
||||
</XStack>
|
||||
|
||||
<YStack gap="$2">
|
||||
<YStack
|
||||
padding="$3"
|
||||
borderRadius={14}
|
||||
backgroundColor={previewSurface}
|
||||
borderWidth={1}
|
||||
borderColor={previewBorder}
|
||||
style={{ boxShadow: previewSurfaceShadow }}
|
||||
>
|
||||
<Text
|
||||
fontWeight="700"
|
||||
color={previewSurfaceText}
|
||||
style={{ fontFamily: previewHeadingFont, fontSize: 14 * previewScale }}
|
||||
>
|
||||
{t('events.branding.previewTitleShort', 'Dein Event-Hub')}
|
||||
</Text>
|
||||
<Text
|
||||
color={previewMutedForeground}
|
||||
style={{ fontFamily: previewBodyFont, fontSize: 13 * previewScale }}
|
||||
style={{ fontFamily: previewBodyFont, fontSize: 12 * previewScale }}
|
||||
>
|
||||
{t('events.branding.previewSubtitle', 'Aktuelle Farben & Schriften')}
|
||||
{t('events.branding.previewSubtitleShort', 'Gäste, Fotos, Highlights')}
|
||||
</Text>
|
||||
<XStack gap="$2" marginTop="$2">
|
||||
<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>
|
||||
</YStack>
|
||||
</XStack>
|
||||
<XStack gap="$2" marginTop="$1">
|
||||
<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
|
||||
style={{
|
||||
padding: '8px 14px',
|
||||
borderRadius: previewForm.buttonRadius,
|
||||
background: previewForm.buttonStyle === 'outline' ? 'transparent' : previewButtonColor,
|
||||
color: previewForm.buttonStyle === 'outline' ? previewForm.linkColor : previewButtonText,
|
||||
border: previewForm.buttonStyle === 'outline' ? `1px solid ${previewForm.linkColor}` : 'none',
|
||||
fontWeight: 700,
|
||||
fontSize: 13 * previewScale,
|
||||
}}
|
||||
>
|
||||
{t('events.branding.previewCta', 'Fotos hochladen')}
|
||||
</div>
|
||||
|
||||
<XStack alignItems="center" justifyContent="space-between" gap="$2">
|
||||
<YStack
|
||||
padding="$2"
|
||||
borderRadius="$pill"
|
||||
backgroundColor={previewSurface}
|
||||
borderWidth={1}
|
||||
borderColor={previewBorder}
|
||||
flex={1}
|
||||
>
|
||||
<Text fontSize="$2" color={previewMutedForeground}>
|
||||
{t('events.branding.previewStat', 'Online Guests')}
|
||||
</Text>
|
||||
<Text fontWeight="800" color={previewSurfaceText} style={{ fontSize: 14 * previewScale }}>
|
||||
148
|
||||
</Text>
|
||||
</YStack>
|
||||
<div
|
||||
style={{
|
||||
padding: '8px 14px',
|
||||
borderRadius: previewForm.buttonRadius,
|
||||
background: previewForm.buttonStyle === 'outline' ? 'transparent' : previewButtonColor,
|
||||
color: previewForm.buttonStyle === 'outline' ? previewForm.linkColor : previewButtonText,
|
||||
border: previewForm.buttonStyle === 'outline' ? `1px solid ${previewForm.linkColor}` : 'none',
|
||||
fontWeight: 700,
|
||||
fontSize: 13 * previewScale,
|
||||
}}
|
||||
>
|
||||
{t('events.branding.previewCta', 'Fotos hochladen')}
|
||||
</div>
|
||||
</XStack>
|
||||
</YStack>
|
||||
|
||||
<XStack
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
gap="$2"
|
||||
padding="$2"
|
||||
borderRadius="$pill"
|
||||
backgroundColor={previewSurface}
|
||||
borderWidth={1}
|
||||
borderColor={previewBorder}
|
||||
>
|
||||
<XStack gap="$2">
|
||||
<YStack width={28} height={28} borderRadius={999} backgroundColor={previewIconSurface} />
|
||||
<YStack width={28} height={28} borderRadius={999} backgroundColor={previewIconSurface} />
|
||||
<YStack width={28} height={28} borderRadius={999} backgroundColor={previewIconSurface} />
|
||||
</XStack>
|
||||
<YStack width={36} height={36} borderRadius={999} backgroundColor={previewButtonColor} />
|
||||
<XStack gap="$2">
|
||||
<YStack width={28} height={28} borderRadius={999} backgroundColor={previewIconSurface} />
|
||||
<YStack width={28} height={28} borderRadius={999} backgroundColor={previewIconSurface} />
|
||||
</XStack>
|
||||
</XStack>
|
||||
</YStack>
|
||||
</YStack>
|
||||
</YStack>
|
||||
</Theme>
|
||||
</MobileCard>
|
||||
|
||||
{!brandingAllowed ? (
|
||||
|
||||
@@ -99,6 +99,10 @@ vi.mock('@tamagui/text', () => ({
|
||||
SizableText: ({ children }: { children: React.ReactNode }) => <span>{children}</span>,
|
||||
}));
|
||||
|
||||
vi.mock('@tamagui/core', () => ({
|
||||
Theme: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
|
||||
}));
|
||||
|
||||
vi.mock('@tamagui/react-native-web-lite', () => ({
|
||||
Pressable: ({ children, onPress }: { children: React.ReactNode; onPress?: () => void }) => (
|
||||
<button type="button" onClick={onPress}>
|
||||
|
||||
Reference in New Issue
Block a user