Files
fotospiel-app/resources/js/guest-v2/components/TopBar.tsx
2026-02-03 15:18:44 +01:00

130 lines
4.1 KiB
TypeScript

import React from 'react';
import { XStack } from '@tamagui/stacks';
import { SizableText as Text } from '@tamagui/text';
import { Button } from '@tamagui/button';
import { Bell, Settings } from 'lucide-react';
import { DEFAULT_EVENT_BRANDING, useOptionalEventBranding } from '@/guest/context/EventBrandingContext';
import EventLogo from './EventLogo';
import { useGuestThemeVariant } from '../lib/guestTheme';
type TopBarProps = {
eventName: string;
eventIcon?: string | null;
onProfilePress?: () => void;
onNotificationsPress?: () => void;
notificationCount?: number;
};
export default function TopBar({
eventName,
eventIcon,
onProfilePress,
onNotificationsPress,
notificationCount = 0,
}: TopBarProps) {
const { isDark } = useGuestThemeVariant();
const brandingContext = useOptionalEventBranding();
const branding = brandingContext?.branding ?? DEFAULT_EVENT_BRANDING;
const logoPosition = branding.logo?.position ?? 'left';
const [animationKey, setAnimationKey] = React.useState(0);
React.useEffect(() => {
setAnimationKey((prev) => prev + 1);
}, [eventName]);
const identityDirection = logoPosition === 'right'
? 'row-reverse'
: logoPosition === 'center'
? 'column'
: 'row';
const identityAlign = logoPosition === 'center' ? 'center' : 'flex-start';
return (
<XStack
alignItems="center"
justifyContent="space-between"
paddingHorizontal="$4"
paddingVertical="$3"
style={{
backgroundColor: 'transparent',
backdropFilter: 'saturate(120%) blur(8px)',
WebkitBackdropFilter: 'saturate(120%) blur(8px)',
}}
>
<XStack
key={animationKey}
alignItems={identityAlign}
gap="$2"
flexDirection={identityDirection}
flexShrink={1}
minWidth={0}
>
<EventLogo name={eventName} icon={eventIcon} logo={branding.logo} size="s" />
<Text
fontSize="$8"
fontFamily="$display"
fontWeight="$8"
numberOfLines={1}
className="guest-topbar-title"
textAlign={logoPosition === 'center' ? 'center' : 'left'}
flexShrink={1}
minWidth={0}
style={{ fontSize: 'clamp(20px, 4.6vw, 30px)', lineHeight: '1.1' }}
>
{eventName}
</Text>
</XStack>
<XStack gap="$2" alignItems="center">
<Button
size="$3"
circular
borderWidth={1}
borderColor={isDark ? 'rgba(255, 255, 255, 0.14)' : 'rgba(15, 23, 42, 0.14)'}
style={{
backgroundColor: isDark ? 'rgba(255, 255, 255, 0.08)' : 'rgba(15, 23, 42, 0.06)',
boxShadow: isDark ? '0 8px 18px rgba(2, 6, 23, 0.4)' : '0 8px 18px rgba(15, 23, 42, 0.12)',
position: 'relative',
}}
onPress={onNotificationsPress}
>
<Bell size={16} color={isDark ? '#F8FAFF' : '#0F172A'} />
{notificationCount > 0 ? (
<span
style={{
position: 'absolute',
top: -2,
right: -2,
width: 18,
height: 18,
borderRadius: 999,
backgroundColor: '#F97316',
color: '#0B101E',
fontSize: 10,
fontWeight: 700,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
>
{notificationCount > 9 ? '9+' : notificationCount}
</span>
) : null}
</Button>
<Button
size="$3"
circular
borderWidth={1}
borderColor={isDark ? 'rgba(255, 255, 255, 0.14)' : 'rgba(15, 23, 42, 0.14)'}
style={{
backgroundColor: isDark ? 'rgba(255, 255, 255, 0.08)' : 'rgba(15, 23, 42, 0.06)',
boxShadow: isDark ? '0 8px 18px rgba(2, 6, 23, 0.4)' : '0 8px 18px rgba(15, 23, 42, 0.12)',
}}
onPress={onProfilePress}
>
<Settings size={16} color={isDark ? '#F8FAFF' : '#0F172A'} />
</Button>
</XStack>
</XStack>
);
}