import { useState } from 'react'; import { View, Text, Pressable, Image } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { Ionicons } from '@expo/vector-icons'; import { useRouter, type RelativePathString } from 'expo-router'; import { useTranslation } from 'react-i18next'; import { useAuthStore } from '../stores/auth'; import { useNotificationStore } from '../stores/notifications'; import { resolveAvatar } from '../lib/resolveAvatar'; import { useColors } from '../lib/theme'; import { useMe } from '../hooks/useMe'; import { NotificationsDropdown } from './NotificationsDropdown'; import { HeaderDropdownMenu } from './header/HeaderDropdownMenu'; type Props = { notifCount?: number; showBack?: boolean; title?: string; }; export function AppHeader({ notifCount, showBack, title }: Props = {}) { const insets = useSafeAreaInsets(); const router = useRouter(); const { t } = useTranslation(); const { user } = useAuthStore(); const colors = useColors(); const { me } = useMe(); const storeUnread = useNotificationStore((s) => s.unread); const badge = notifCount ?? storeUnread; const [notifOpen, setNotifOpen] = useState(false); const [menuOpen, setMenuOpen] = useState(false); const firstName = (user?.user_metadata?.first_name as string | undefined) ?? ''; const lastName = (user?.user_metadata?.last_name as string | undefined) ?? ''; const email = user?.email ?? ''; const initials = (() => { if (me?.nickname) return me.nickname.slice(0, 2).toUpperCase(); return ((firstName.charAt(0) + (lastName.charAt(0) || email.charAt(0))).toUpperCase() || '?'); })(); // Avatar: aus DB (`/api/auth/me` → profiles.avatar). Kann Hero-Avatar-ID // ("spider"/"hulk"/...) ODER Custom-Photo-URL (https://... von Foto-Upload) // sein. resolveAvatar handlet beide Fälle. const avatarUrl = me ? resolveAvatar(me.avatar, me.nickname ?? '') : ''; const [avatarLoadFailed, setAvatarLoadFailed] = useState(false); const showAvatarImage = !!avatarUrl && !avatarLoadFailed && !!me?.avatar; const headerHeight = insets.top + 56; return ( {showBack ? ( router.back()} hitSlop={10} style={({ pressed }) => ({ opacity: pressed ? 0.6 : 1, marginLeft: -8, width: 36, height: 36, borderRadius: 18, alignItems: 'center', justifyContent: 'center', })} accessibilityLabel="Zurück" > ) : null} {title ?? t('appHeader.appName')} setNotifOpen(true)} hitSlop={{ top: 4, bottom: 4, left: 4, right: 4 }} style={({ pressed }) => ({ opacity: pressed ? 0.7 : 1, width: 36, height: 36, borderRadius: 18, backgroundColor: colors.surface, alignItems: 'center', justifyContent: 'center', })} > {badge > 0 && ( {badge > 9 ? '9+' : String(badge)} )} {/* Avatar = Trigger für Dropdown-Menu (kein separates 3-Punkte-Icon) */} setMenuOpen(true)} hitSlop={{ top: 4, bottom: 4, left: 4, right: 4 }} style={({ pressed }) => ({ opacity: pressed ? 0.7 : 1, width: 36, height: 36, borderRadius: 18, alignItems: 'center', justifyContent: 'center', overflow: 'hidden', backgroundColor: showAvatarImage ? colors.surfaceElevated : colors.brandOrange, })} > {showAvatarImage ? ( setAvatarLoadFailed(true)} style={{ width: 36, height: 36, borderRadius: 18 }} /> ) : ( {initials} )} setMenuOpen(false)} topOffset={headerHeight + 6} /> setNotifOpen(false)} topOffset={headerHeight} /> ); }