eletrotupi / tcc/ frontend/components/ui/ScreenLayout.tsxe942921e5baaa9a7ed8ee6a62c1ad3a5d5eae07d
4.0 KB | 158 lines Raw
1
import React from 'react';
2

3
import {
4
  View,
5
  ScrollView,
6
  StyleSheet,
7
  Image,
8
  Pressable,
9
  StatusBar,
10
} from 'react-native';
11

12
import { SafeAreaView } from 'react-native-safe-area-context';
13
import { IconSymbol } from '@/components/ui/icon-symbol';
14
import { useThemeColor } from '@/hooks/use-theme-color';
15
import { Typography, Spacing, BorderRadius } from '@/constants/theme'
16
import { ThemedText } from '@/components/misc/themed-text'
17

18
interface ScreenLayoutProps {
19
  children: React.ReactNode;
20
  userName?: string;
21
  userAvatar?: string;
22
  onNotificationPress?: () => void;
23
  showNotificationBadge?: boolean;
24
  scrollEnabled?: boolean;
25
}
26

27
export const ScreenLayout: React.FC<ScreenLayoutProps> = ({
28
  children,
29
  userName = 'Usuário',
30
  userAvatar,
31
  onNotificationPress,
32
  showNotificationBadge = false,
33
  scrollEnabled = true,
34
}) => {
35
  const textColor = useThemeColor({}, 'text');
36
  const backgroundColor = useThemeColor({}, 'background');
37
  const surfaceColor = useThemeColor({}, 'surface');
38
  const dividerColor = useThemeColor({}, 'divider');
39
  const accentBlue = useThemeColor({}, 'accentBlue');
40
  const tintColor = useThemeColor({}, 'tint');
41

42
  const styles = StyleSheet.create({
43
    container: {
44
      flex: 1,
45
      backgroundColor: backgroundColor,
46
    },
47
    safeAreaView: {
48
      flex: 1,
49
      backgroundColor: backgroundColor,
50
    },
51
    header: {
52
      paddingHorizontal: Spacing.containerPadding,
53
      paddingVertical: 12,
54
      backgroundColor: surfaceColor,
55
      borderBottomWidth: 1,
56
      borderBottomColor: dividerColor,
57
      flexDirection: 'row',
58
      justifyContent: 'space-between',
59
      alignItems: 'center',
60
    },
61
    headerLeft: {
62
      flexDirection: 'row',
63
      alignItems: 'center',
64
      gap: Spacing.inlineGapSm,
65
    },
66
    avatar: {
67
      width: 40,
68
      height: 40,
69
      borderRadius: 20,
70
      backgroundColor: accentBlue,
71
    },
72
    userName: {
73
      fontSize: Typography.bodyLg.fontSize,
74
      fontWeight: '600',
75
      color: textColor,
76
    },
77
    notificationButton: {
78
      width: 40,
79
      height: 40,
80
      borderRadius: BorderRadius.md,
81
      justifyContent: 'center',
82
      alignItems: 'center',
83
      activeOpacity: 0.7,
84
    },
85
    notificationBadge: {
86
      position: 'absolute',
87
      top: 4,
88
      right: 4,
89
      width: 8,
90
      height: 8,
91
      borderRadius: 4,
92
      backgroundColor: tintColor,
93
    },
94
    scrollContent: {
95
      paddingHorizontal: Spacing.containerPadding,
96
      paddingVertical: Spacing.sectionGap,
97
    },
98
  });
99
 
100
  return (
101
    <View style={styles.container}>
102
      <StatusBar
103
        barStyle="dark-content"
104
        backgroundColor={surfaceColor}
105
      />
106
      <SafeAreaView style={styles.safeAreaView}>
107
        <View style={styles.header}>
108
          <View style={styles.headerLeft}>
109
            {userAvatar ? (
110
              <Image
111
                source={{ uri: userAvatar }}
112
                style={styles.avatar}
113
              />
114
            ) : (
115
              <View style={styles.avatar} />
116
            )}
117
            <View>
118
              <ThemedText style={styles.userName}>
119
                Olá, {userName}
120
              </ThemedText>
121
            </View>
122
          </View>
123

124
          <Pressable
125
            style={styles.notificationButton}
126
            onPress={onNotificationPress}
127
            hitSlop={8}
128
          >
129
            <View
130
              style={{
131
                fontSize: 24,
132
                color: textColor,
133
              }}
134
            >
135
            <IconSymbol size={24} name="notifications" color={textColor} />
136
            </View>
137
            {showNotificationBadge && (
138
              <View style={styles.notificationBadge} />
139
            )}
140
          </Pressable>
141
        </View>
142

143
        <ScrollView
144
          scrollEnabled={scrollEnabled}
145
          showsVerticalScrollIndicator={false}
146
          contentContainerStyle={scrollEnabled ? undefined : { flex: 1 }}
147
          scrollEventThrottle={16}
148
        >
149
          <View style={styles.scrollContent}>
150
            {children}
151
          </View>
152
        </ScrollView>
153
      </SafeAreaView>
154
    </View>
155
  );
156
};
157

158
export default ScreenLayout;