eletrotupi / tcc/ commit / 95b0a7d

frontend: wire Settings notification preferences to PATCH /users/me

Finally user can customize their notifications time. I need to get rid
of the AuthContext asap, it's a fucking mess
Pedro Lucas Porcellis porcellis@eletrotupi.com 1 month ago 95b0a7d7b379540440909110b748904954048374
Parents: 120e1cd
4 file(s) changed
  • frontend/app/(tabs)/settings.tsx +36 -6
  • frontend/context/AuthContext.tsx +2 -0
  • frontend/hooks/index.ts +2 -0
  • frontend/hooks/useUserPreferences.queries.ts +11 -0
frontend/app/(tabs)/settings.tsx
1 1
import {
2 2
  TouchableOpacity,
3 3
  StyleSheet,
4 4
  Text,
5 5
  SectionList,
▸ 10 unchanged lines
16 16
import { useThemeColor } from "@/hooks/use-theme-color";
17 17
import { useAuth } from "@/context/AuthContext";
18 18
import { Section, SectionHeader } from "@/components/ui/Sections";
19 19
import { Ionicons, MaterialIcons } from "@expo/vector-icons";
20 20
import { Button } from "@/components/ui/Button";
21 +
import { TimePicker } from "@/components/ui/TimePicker";
22 +
import { usePatchUserMe } from "@/hooks/useUserPreferences.queries";
21 23

22 24
export default function Settings() {
23 -
  const { user, logout } = useAuth();
24 -
  const [allowNotifications, setAllowNotifications] = useState(false);
25 +
  const { user, logout, updateAuthUser } = useAuth();
25 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 +
  };
26 43

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

29 46
  const handleLogout = async () => {
30 47
    Alert.alert("Sair", "Tem certeza que quer sair?", [
▸ 93 unchanged lines
124 141
                justifyContent: "space-between",
125 142
                marginLeft: 12,
126 143
                flex: 1,
127 144
              }}
128 145
            >
129 -
              <Text style={styles.cardTitle}>Notificações</Text>
130 -
              <Text>Diário as 20:00</Text>
146 +
              <Text style={styles.cardTitle}>Lembrete diário de humor</Text>
147 +
              <Text>{notificationsEnabled ? `Diário às ${dailyReminderTime}` : "Desativado"}</Text>
131 148
            </View>
132 149

133 150
            <Switch
134 -
              onValueChange={setAllowNotifications}
151 +
              onValueChange={handleNotificationToggle}
135 152
              thumbColor={Colors.light.tint}
136 153
              trackColor={{
137 154
                false: Colors.light.disabled,
138 155
                true: Colors.light.gray,
139 156
              }}
140 -
              value={allowNotifications}
157 +
              value={notificationsEnabled}
158 +
              disabled={patchUserMe.isPending}
141 159
            />
142 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 +
          )}
143 173

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

146 176
          <View
147 177
            style={{
▸ 155 unchanged lines
303 333
    height: StyleSheet.hairlineWidth,
304 334
    backgroundColor: "#D1D5DB",
305 335
    marginVertical: 16,
306 336
  },
307 337
});
frontend/context/AuthContext.tsx
1 1
import React, { createContext, useContext, useEffect, useState } from "react";
2 2
import { apiClient, User } from "@/lib/api";
3 3
import { queryClient, storage } from "@/lib/queryClient";
4 4

5 5
interface AuthProviderProps {
▸ 29 unchanged lines
35 35
    lastName: data.lastName,
36 36
    updatedAt: data.updatedAt,
37 37
    avatarKey: data.avatarKey,
38 38
    avatarURL: data.avatarURL,
39 39
    active: data.active,
40 +
    notificationsEnabled: data.notificationsEnabled,
41 +
    dailyReminderTime: data.dailyReminderTime,
40 42
  };
41 43
}
42 44

43 45
const AuthContext = createContext<AuthContextType | null>(null);
44 46

▸ 133 unchanged lines
178 180
    requestActivateCode,
179 181
  };
180 182

181 183
  return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
182 184
};
frontend/hooks/index.ts
1 1
// Legacy shit from react native
2 2
export { useThemeColor } from "@/hooks/use-theme-color";
3 3

4 4
export { useColorScheme } from "@/hooks/use-color-scheme";
5 5

▸ 35 unchanged lines
41 41
export {
42 42
  medicineTodayKeys,
43 43
  useMedicineToday,
44 44
} from "@/hooks/useMedicineToday.queries";
45 45

46 +
export { usePatchUserMe } from "@/hooks/useUserPreferences.queries";
47 +

46 48
export {
47 49
  careActionKeys,
48 50
  useCareActions,
49 51
  useCareAction,
50 52
  useCreateCareAction,
51 53
  usePatchCareAction,
52 54
  useDeleteCareAction,
53 55
} from "@/hooks/useCareAction.queries";
frontend/hooks/useUserPreferences.queries.ts
@@ -0,0 +1,11 @@
1 + import { useMutation } from "@tanstack/react-query";
2 + import { apiClient, UserPreferencesPayload } from "@/lib/api";
3 +
4 + export const usePatchUserMe = (onSuccess?: (user: any) => void) => {
5 + return useMutation({
6 + mutationFn: (payload: UserPreferencesPayload) => apiClient.patchUserMe(payload),
7 + onSuccess: (data) => {
8 + onSuccess?.(data.user);
9 + },
10 + });
11 + };