eletrotupi / tcc/ frontend/components/ui/ScreenLayout.tsx92fe16c5883a76b1919f4c7dcb888c00e2912fc3
3.4 KB | 122 lines Raw
1
import {
2
  View,
3
  ScrollView,
4
  StyleSheet,
5
  Image,
6
  Pressable,
7
  StatusBar,
8
} from "react-native";
9

10
import { SafeAreaView } from "react-native-safe-area-context";
11
import { useRouter } from "expo-router";
12
import { IconSymbol } from "@/components/ui/icon-symbol";
13
import { useThemeColor } from "@/hooks/use-theme-color";
14
import { Typography, Spacing, BorderRadius } from "@/constants/theme";
15
import { Text } from "@/components/ui/Text";
16

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

25
export const ScreenLayout: React.FC<ScreenLayoutProps> = ({
26
  children,
27
  userName = "Usuário",
28
  userAvatar,
29
  onNotificationPress,
30
  scrollEnabled = true,
31
}) => {
32
  const router = useRouter();
33
  const textColor = useThemeColor({}, "text") as string;
34
  const backgroundColor = useThemeColor({}, "background") as string;
35
  const surfaceColor = useThemeColor({}, "surface") as string;
36
  const dividerColor = useThemeColor({}, "divider") as string;
37
  const accentBlue = useThemeColor({}, "accentBlue") as string;
38

39
  return (
40
    <View style={[styles.container, { backgroundColor }]}>
41
      <StatusBar barStyle="dark-content" />
42
      <SafeAreaView
43
        style={[styles.safeAreaView, { backgroundColor }]}
44
        edges={["top", "left", "right"]}
45
      >
46
        <View style={[styles.header, { backgroundColor: surfaceColor, borderBottomColor: dividerColor }]}>
47
          <View style={styles.headerLeft}>
48
            {userAvatar ? (
49
              <Image source={{ uri: userAvatar }} style={[styles.avatar, { backgroundColor: accentBlue }]} />
50
            ) : (
51
              <View style={[styles.avatar, { backgroundColor: accentBlue }]} />
52
            )}
53
            <View>
54
              <Text style={[styles.userName, { color: textColor }]}>Olá, {userName}</Text>
55
            </View>
56
          </View>
57

58
          <Pressable
59
            style={styles.notificationButton}
60
            onPress={onNotificationPress ?? (() => router.push("/notifications"))}
61
            hitSlop={8}
62
          >
63
            <IconSymbol size={24} name="notifications" color={textColor} />
64
          </Pressable>
65
        </View>
66

67
        <ScrollView
68
          scrollEnabled={scrollEnabled}
69
          showsVerticalScrollIndicator={false}
70
          contentContainerStyle={scrollEnabled ? undefined : { flex: 1 }}
71
          scrollEventThrottle={16}
72
        >
73
          <View style={styles.scrollContent}>{children}</View>
74
        </ScrollView>
75
      </SafeAreaView>
76
    </View>
77
  );
78
};
79

80
const styles = StyleSheet.create({
81
  container: {
82
    flex: 1,
83
  },
84
  safeAreaView: {
85
    flex: 1,
86
  },
87
  header: {
88
    paddingHorizontal: Spacing.containerPadding,
89
    paddingVertical: 12,
90
    borderBottomWidth: 1,
91
    flexDirection: "row",
92
    justifyContent: "space-between",
93
    alignItems: "center",
94
  },
95
  headerLeft: {
96
    flexDirection: "row",
97
    alignItems: "center",
98
    gap: Spacing.inlineGapSm,
99
  },
100
  avatar: {
101
    width: 40,
102
    height: 40,
103
    borderRadius: 20,
104
  },
105
  userName: {
106
    fontSize: Typography.bodyLg.fontSize,
107
    fontWeight: "600",
108
  },
109
  notificationButton: {
110
    width: 40,
111
    height: 40,
112
    borderRadius: BorderRadius.md,
113
    justifyContent: "center",
114
    alignItems: "center",
115
  },
116
  scrollContent: {
117
    paddingHorizontal: Spacing.containerPadding,
118
    paddingVertical: Spacing.sectionGap,
119
  },
120
});
121

122
export default ScreenLayout;