Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | 1x 1x 1x 1x 1x 1x 9x 9x 9x 8x 1x | import React, { forwardRef, useMemo } from 'react';
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import { Feather, Ionicons } from '@expo/vector-icons';
import SemLogo from '@/components/common/SemLogo';
import { useTheme } from '@/theme';
import type { Theme } from '@/theme';
interface HomeHeaderProps {
/** Whether dark mode is currently active — determines the sun/moon icon. */
isDark: boolean;
onPressThemeToggle: () => void;
onPressNotifications?: () => void;
unreadNotificationCount?: number;
}
const HomeHeader = forwardRef<any, HomeHeaderProps>(function HomeHeader(
{
isDark,
onPressThemeToggle,
onPressNotifications,
unreadNotificationCount = 0,
},
_ref,
) {
const { theme } = useTheme();
const styles = useMemo(() => makeStyles(theme), [theme]);
return (
<View style={styles.container}>
<View style={styles.logoWrap}>
<SemLogo height={52} color={theme.text} />
</View>
<View style={styles.rightWrap}>
{/* Bell */}
<TouchableOpacity
style={styles.iconButton}
activeOpacity={0.75}
onPress={onPressNotifications}
accessibilityRole="button"
accessibilityLabel="Open notifications"
>
<Ionicons name="notifications-outline" size={22} color={theme.text} />
{unreadNotificationCount > 0 ? (
<View style={styles.badge}>
<Text style={styles.badgeText}>
{unreadNotificationCount > 99 ? '99+' : String(unreadNotificationCount)}
</Text>
</View>
) : null}
</TouchableOpacity>
{/* Theme toggle */}
<TouchableOpacity
style={styles.iconButton}
activeOpacity={0.75}
onPress={onPressThemeToggle}
accessibilityRole="button"
accessibilityLabel={isDark ? 'Switch to light mode' : 'Switch to dark mode'}
testID="theme-toggle"
>
<Feather name={isDark ? 'sun' : 'moon'} size={20} color={theme.text} />
</TouchableOpacity>
</View>
</View>
);
});
function makeStyles(t: Theme) {
return StyleSheet.create({
container: {
marginTop: 12,
marginBottom: 10,
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
},
logoWrap: {
flexShrink: 0,
},
rightWrap: {
flexDirection: 'row',
alignItems: 'center',
gap: 4,
},
iconButton: {
width: 40,
height: 40,
borderRadius: 20,
alignItems: 'center',
justifyContent: 'center',
},
badge: {
position: 'absolute',
top: 4,
right: 4,
minWidth: 16,
height: 16,
borderRadius: 8,
backgroundColor: t.notificationBadge,
alignItems: 'center',
justifyContent: 'center',
paddingHorizontal: 3,
},
badgeText: {
color: '#FFFFFF',
fontSize: 9,
fontWeight: '700',
lineHeight: 12,
},
});
}
export default HomeHeader;
|