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
Parents:
120e1cd4 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 + };