eletrotupi / tcc/ frontend/app/(tabs)/settings.tsx00a1c753d286aaa005996dc78a2911f038825877
9.1 KB | 337 lines Raw
1
import {
2
  TouchableOpacity,
3
  StyleSheet,
4
  Text,
5
  SectionList,
6
  View,
7
  Alert,
8
  Switch,
9
  Pressable,
10
} from "react-native";
11
import { useState } from "react";
12
import { router } from "expo-router";
13
import { Card } from "@/components/ui/Cards";
14
import ScreenLayout from "@/components/ui/ScreenLayout";
15
import { BorderRadius, Colors, Fonts, Spacing } from "@/constants/theme";
16
import { useThemeColor } from "@/hooks/use-theme-color";
17
import { useAuth } from "@/context/AuthContext";
18
import { Section, SectionHeader } from "@/components/ui/Sections";
19
import { Ionicons, MaterialIcons } from "@expo/vector-icons";
20
import { Button } from "@/components/ui/Button";
21
import { TimePicker } from "@/components/ui/TimePicker";
22
import { usePatchUserMe } from "@/hooks/useUserPreferences.queries";
23

24
export default function Settings() {
25
  const { user, logout, updateAuthUser } = useAuth();
26
  const [allowWeeklyInsights, setAllowWeeklyInsights] = useState(false);
27

28
  const notificationsEnabled = user?.notificationsEnabled ?? true;
29
  const dailyReminderTime = user?.dailyReminderTime ?? "20:00";
30

31
  const patchUserMe = usePatchUserMe((updatedUser) => {
32
    updateAuthUser(updatedUser);
33
  });
34

35
  const handleNotificationToggle = (value: boolean) => {
36
    patchUserMe.mutate({ notificationsEnabled: value });
37
  };
38

39
  const handleTimeChange = (date: Date) => {
40
    const time = `${date.getHours().toString().padStart(2, "0")}:${date.getMinutes().toString().padStart(2, "0")}`;
41
    patchUserMe.mutate({ dailyReminderTime: time });
42
  };
43

44
  const textColor = useThemeColor({}, "text");
45

46
  const handleLogout = async () => {
47
    Alert.alert("Sair", "Tem certeza que quer sair?", [
48
      { text: "Cancelar", style: "cancel" },
49
      {
50
        text: "Sair",
51
        style: "destructive",
52
        onPress: logout,
53
      },
54
    ]);
55
  };
56

57
  const handleProfilePress = () => {
58
    router.push("/profile");
59
  };
60

61
  const handleInvisibleMode = () => {};
62

63
  const handleDataExport = () => {
64
    Alert.alert("Exportar dados", "Deseja exportar seus dados?", [
65
      { text: "Cancelar", style: "cancel" },
66
      {
67
        text: "Exportar",
68
        style: "destructive",
69
        onPress: () => {
70
          Alert.alert(
71
            "Exportar dados",
72
            "Você receberá um e-mail com os dados exportados.",
73
            [{ text: "OK", style: "default" }],
74
          );
75
        },
76
      },
77
    ]);
78
  };
79

80
  return (
81
    <ScreenLayout
82
      userName={user.firstName}
83
      userAvatar={user.avatarURL}
84
      showNotificationBadge={true}
85
    >
86
      <Section>
87
        <SectionHeader title="Perfil" />
88

89
        <Card style={{ padding: Spacing.cardGap }} onPress={handleProfilePress}>
90
          <View
91
            style={{
92
              flexDirection: "row",
93
              alignItems: "center",
94
              justifyContent: "space-between",
95
            }}
96
          >
97
            <View
98
              style={{
99
                flexDirection: "column",
100
                alignItems: "center",
101
                justifyContent: "space-between",
102
              }}
103
            >
104
              <Text style={styles.cardTitle}>Dados Pessoais</Text>
105
              <Text style={styles.cardSubtitle}>Nome, Email e senha</Text>
106
            </View>
107

108
            <Ionicons name="chevron-forward" size={24} color={textColor} />
109
          </View>
110
        </Card>
111
      </Section>
112

113
      <Section>
114
        <SectionHeader title="Notificações" />
115

116
        <Card style={{ padding: Spacing.cardGap }}>
117
          <View
118
            style={{
119
              flexDirection: "row",
120
              alignItems: "center",
121
              justifyContent: "space-between",
122
            }}
123
          >
124
            <View
125
              style={[
126
                styles.cardIcon,
127
                { backgroundColor: Colors.light.accentBlue },
128
              ]}
129
            >
130
              <Ionicons
131
                name="notifications-outline"
132
                size={20}
133
                color={Colors.light.black}
134
              />
135
            </View>
136

137
            <View
138
              style={{
139
                flexDirection: "column",
140
                alignItems: "flex-start",
141
                justifyContent: "space-between",
142
                marginLeft: 12,
143
                flex: 1,
144
              }}
145
            >
146
              <Text style={styles.cardTitle}>Lembrete diário de humor</Text>
147
              <Text>{notificationsEnabled ? `Diário às ${dailyReminderTime}` : "Desativado"}</Text>
148
            </View>
149

150
            <Switch
151
              onValueChange={handleNotificationToggle}
152
              thumbColor={Colors.light.tint}
153
              trackColor={{
154
                false: Colors.light.disabled,
155
                true: Colors.light.gray,
156
              }}
157
              value={notificationsEnabled}
158
              disabled={patchUserMe.isPending}
159
            />
160
          </View>
161

162
          {notificationsEnabled && (
163
            <TimePicker
164
              value={(() => {
165
                const [h, m] = dailyReminderTime.split(":").map(Number);
166
                const d = new Date();
167
                d.setHours(h, m, 0, 0);
168
                return d;
169
              })()}
170
              onChange={handleTimeChange}
171
            />
172
          )}
173

174
          <View style={styles.divider} />
175

176
          <View
177
            style={{
178
              flexDirection: "row",
179
              alignItems: "center",
180
              justifyContent: "space-between",
181
            }}
182
          >
183
            <View
184
              style={[
185
                styles.cardIcon,
186
                { backgroundColor: Colors.light.accentPurple },
187
              ]}
188
            >
189
              <Ionicons name="sparkles" size={20} color={Colors.light.black} />
190
            </View>
191

192
            <View
193
              style={{
194
                flexDirection: "column",
195
                alignItems: "flex-start",
196
                justifyContent: "space-between",
197
                marginLeft: 12,
198
                flex: 1,
199
              }}
200
            >
201
              <Text style={styles.cardTitle}>Indicadores semanais</Text>
202
              <Text>Relatórios de progressos</Text>
203
            </View>
204

205
            <Switch
206
              onValueChange={setAllowWeeklyInsights}
207
              value={allowWeeklyInsights}
208
              thumbColor={Colors.light.tint}
209
              trackColor={{
210
                false: Colors.light.disabled,
211
                true: Colors.light.gray,
212
              }}
213
            />
214
          </View>
215
        </Card>
216
      </Section>
217

218
      <Section>
219
        <SectionHeader title="Privacidade" />
220

221
        <Card style={{ padding: Spacing.cardGap }}>
222
          <TouchableOpacity
223
            style={{
224
              flexDirection: "row",
225
              alignItems: "center",
226
              justifyContent: "space-between",
227
            }}
228
            onPress={handleInvisibleMode}
229
          >
230
            <View style={{ flexDirection: "row", alignItems: "center" }}>
231
              <MaterialIcons
232
                name="lock"
233
                size={24}
234
                color={Colors.light.textSecondary}
235
              />
236

237
              <Text
238
                style={{
239
                  marginLeft: 8,
240
                  color: Colors.light.text,
241
                  fontSize: 14,
242
                  fontWeight: "500" as const,
243
                }}
244
              >
245
                Privacidade
246
              </Text>
247
            </View>
248

249
            <Ionicons name="chevron-forward" size={24} color={textColor} />
250
          </TouchableOpacity>
251

252
          <View style={styles.divider} />
253

254
          <TouchableOpacity
255
            style={{
256
              flexDirection: "row",
257
              alignItems: "center",
258
              justifyContent: "space-between",
259
            }}
260
            onPress={handleDataExport}
261
          >
262
            <View style={{ flexDirection: "row", alignItems: "center" }}>
263
              <MaterialIcons
264
                name="storage"
265
                size={24}
266
                color={Colors.light.textSecondary}
267
              />
268

269
              <Text
270
                style={{
271
                  marginLeft: 8,
272
                  color: Colors.light.text,
273
                  fontSize: 14,
274
                  fontWeight: "500" as const,
275
                }}
276
              >
277
                Exportar Meus Dados
278
              </Text>
279
            </View>
280

281
            <MaterialIcons
282
              name="file-download"
283
              size={24}
284
              color={Colors.light.textSecondary}
285
            />
286
          </TouchableOpacity>
287
        </Card>
288
      </Section>
289

290
      <Button
291
        title="Sair da Conta"
292
        onPress={handleLogout}
293
        variant="outline"
294
        style={{ borderColor: Colors.light.danger }}
295
        textStyle={{ color: Colors.light.danger }}
296
      />
297
    </ScreenLayout>
298
  );
299
}
300

301
const styles = StyleSheet.create({
302
  container: {
303
    flex: 1,
304
    marginHorizontal: 16,
305
    paddingTop: 10,
306
  },
307
  item: {
308
    paddingTop: 20,
309
    paddingBottom: 20,
310
  },
311
  header: {
312
    fontSize: 22,
313
    fontWeight: "bold",
314
  },
315
  cardIcon: {
316
    paddingVertical: 15,
317
    paddingHorizontal: 14,
318
    width: 48,
319
    borderRadius: BorderRadius.md,
320
  },
321
  cardTitle: {
322
    fontSize: 16,
323
    fontWeight: "bold",
324
  },
325
  cardSubtitle: {
326
    fontSize: 12,
327
    color: Colors.light.textSecondary,
328
  },
329
  logout: {
330
    color: "#FF2C2C",
331
  },
332
  divider: {
333
    height: StyleSheet.hairlineWidth,
334
    backgroundColor: "#D1D5DB",
335
    marginVertical: 16,
336
  },
337
});