eletrotupi / tcc/ frontend/components/ui/ScreenLayout.tsx5d2d8805510eedeef6c368247dedf274a649742c
3.9 KB | 149 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 barStyle="dark-content" backgroundColor={surfaceColor} />
103
      <SafeAreaView
104
        style={styles.safeAreaView}
105
        edges={["top", "left", "right"]}
106
      >
107
        <View style={styles.header}>
108
          <View style={styles.headerLeft}>
109
            {userAvatar ? (
110
              <Image source={{ uri: userAvatar }} style={styles.avatar} />
111
            ) : (
112
              <View style={styles.avatar} />
113
            )}
114
            <View>
115
              <ThemedText style={styles.userName}>Olá, {userName}</ThemedText>
116
            </View>
117
          </View>
118

119
          <Pressable
120
            style={styles.notificationButton}
121
            onPress={onNotificationPress}
122
            hitSlop={8}
123
          >
124
            <View
125
              style={{
126
                fontSize: 24,
127
                color: textColor,
128
              }}
129
            >
130
              <IconSymbol size={24} name="notifications" color={textColor} />
131
            </View>
132
            {showNotificationBadge && <View style={styles.notificationBadge} />}
133
          </Pressable>
134
        </View>
135

136
        <ScrollView
137
          scrollEnabled={scrollEnabled}
138
          showsVerticalScrollIndicator={false}
139
          contentContainerStyle={scrollEnabled ? undefined : { flex: 1 }}
140
          scrollEventThrottle={16}
141
        >
142
          <View style={styles.scrollContent}>{children}</View>
143
        </ScrollView>
144
      </SafeAreaView>
145
    </View>
146
  );
147
};
148

149
export default ScreenLayout;