user settings, points slider

This commit is contained in:
ivic00
2024-09-20 19:47:21 +02:00
parent 39ef35022c
commit b46fb1b2a8
12 changed files with 203 additions and 113 deletions

View File

@ -1,12 +1,15 @@
import SettingsPage from "@/components/pages/settings/SettingsPage"; import SettingsPage from "@/components/pages/settings/SettingsPage";
import { AuthContextProvider } from "@/contexts/AuthContext";
import { SettingsContextProvider } from "@/contexts/SettingsContext"; import { SettingsContextProvider } from "@/contexts/SettingsContext";
import React from "react"; import React from "react";
import { View } from "react-native-ui-lib"; import { View } from "react-native-ui-lib";
export default function Screen() { export default function Screen() {
return ( return (
<AuthContextProvider>
<SettingsContextProvider> <SettingsContextProvider>
<SettingsPage /> <SettingsPage />
</SettingsContextProvider> </SettingsContextProvider>
</AuthContextProvider>
); );
} }

View File

@ -26,7 +26,7 @@ const SignUpPage = (props: { unsetRegister: () => any }) => {
const { mutateAsync: signUp } = useSignUp(); const { mutateAsync: signUp } = useSignUp();
const handleSignUp = async () => { const handleSignUp = async () => {
await signUp({ email, password }); await signUp({ email, password, firstName, lastName });
}; };
return ( return (

View File

@ -5,6 +5,7 @@ import { Entypo, Ionicons, Octicons } from "@expo/vector-icons";
import CalendarSettingsPage from "./CalendarSettingsPage"; import CalendarSettingsPage from "./CalendarSettingsPage";
import ChoreRewardSettings from "./ChoreRewardSettings"; import ChoreRewardSettings from "./ChoreRewardSettings";
import UserSettings from "./UserSettings"; import UserSettings from "./UserSettings";
import { AuthContextProvider } from "@/contexts/AuthContext";
const styles = StyleSheet.create({ const styles = StyleSheet.create({
mainBtn: { mainBtn: {
@ -55,7 +56,9 @@ const SettingsPage = () => {
style={{ marginRight: 10 }} style={{ marginRight: 10 }}
/> />
)} )}
onPress={() => {setSelectedPage(pageIndex.calendar)}} onPress={() => {
setSelectedPage(pageIndex.calendar);
}}
/> />
<Button <Button
backgroundColor="white" backgroundColor="white"
@ -88,9 +91,15 @@ const SettingsPage = () => {
/> />
</View> </View>
)} )}
{selectedPage == pageIndex.calendar && <CalendarSettingsPage setSelectedPage={setSelectedPage} />} {selectedPage == pageIndex.calendar && (
{selectedPage == pageIndex.chore && <ChoreRewardSettings setSelectedPage={setSelectedPage} />} <CalendarSettingsPage setSelectedPage={setSelectedPage} />
{selectedPage == pageIndex.user && <UserSettings setSelectedPage={setSelectedPage} />} )}
{selectedPage == pageIndex.chore && (
<ChoreRewardSettings setSelectedPage={setSelectedPage} />
)}
{selectedPage == pageIndex.user && (
<UserSettings setSelectedPage={setSelectedPage} />
)}
</View> </View>
); );
}; };

View File

@ -4,6 +4,7 @@ import { Ionicons } from "@expo/vector-icons";
import { ScrollView, StyleSheet } from "react-native"; import { ScrollView, StyleSheet } from "react-native";
import MyProfile from "./user_settings_views/MyProfile"; import MyProfile from "./user_settings_views/MyProfile";
import MyGroup from "./user_settings_views/MyGroup"; import MyGroup from "./user_settings_views/MyGroup";
import { useAuthContext } from "@/contexts/AuthContext";
const UserSettings = (props: { setSelectedPage: (page: number) => void }) => { const UserSettings = (props: { setSelectedPage: (page: number) => void }) => {
const [selectedView, setSelectedView] = useState<boolean>(true); const [selectedView, setSelectedView] = useState<boolean>(true);

View File

@ -1,8 +1,19 @@
import { View, Text, TextField } from "react-native-ui-lib"; import { View, Text, TextField } from "react-native-ui-lib";
import React from "react"; import React, { useState } from "react";
import { StyleSheet } from "react-native"; import { StyleSheet } from "react-native";
import { ScrollView } from "react-native-gesture-handler"; import { ScrollView } from "react-native-gesture-handler";
import { useAuthContext } from "@/contexts/AuthContext";
import { useSettingsContext } from "@/contexts/SettingsContext";
import { useUpdateUserData } from "@/hooks/firebase/useUpdateUserData";
const MyProfile = () => { const MyProfile = () => {
const { user, profileData } = useAuthContext();
const [lastName, setLastName] = useState<string>(profileData?.lastName || "");
const [firstName, setFirstName] = useState<string>(
profileData?.firstName || ""
);
const { mutateAsync: updateUserData } = useUpdateUserData();
return ( return (
<View> <View>
<View style={styles.card}> <View style={styles.card}>
@ -18,15 +29,38 @@ const MyProfile = () => {
<Text text80 marginT-10 marginB-7 color="#a1a1a1"> <Text text80 marginT-10 marginB-7 color="#a1a1a1">
First name First name
</Text> </Text>
<TextField text70 placeholder="First name" style={styles.txtBox} /> <TextField
text70
placeholder="First name"
style={styles.txtBox}
value={firstName}
onChangeText={async (value) => {
setFirstName(value);
await updateUserData({ newUserData: { firstName: value } });
}}
/>
<Text text80 marginT-10 marginB-7 color="#a1a1a1"> <Text text80 marginT-10 marginB-7 color="#a1a1a1">
Last name Last name
</Text> </Text>
<TextField text70 placeholder="Last name" style={styles.txtBox} /> <TextField
text70
placeholder="Last name"
style={styles.txtBox}
value={lastName}
onChangeText={async (value) => {
setLastName(value);
await updateUserData({ newUserData: { lastName: value } });
}}
/>
<Text text80 marginT-10 marginB-7 color="#a1a1a1"> <Text text80 marginT-10 marginB-7 color="#a1a1a1">
Email address Email address
</Text> </Text>
<TextField text70 placeholder="Email address" style={styles.txtBox} /> <TextField
text70
placeholder="Email address"
value={user?.email?.toString()}
style={styles.txtBox}
/>
</View> </View>
</View> </View>
@ -35,7 +69,7 @@ const MyProfile = () => {
<Text text80 marginT-20 marginB-7 color="#a1a1a1"> <Text text80 marginT-20 marginB-7 color="#a1a1a1">
Time Zone Time Zone
</Text> </Text>
<TextField text70 placeholder="Email address" style={styles.txtBox} /> <TextField text70 placeholder="Time Zone" style={styles.txtBox} />
</View> </View>
</View> </View>
); );

View File

@ -20,6 +20,7 @@ import LinearGradient from "react-native-linear-gradient";
import { PanningDirectionsEnum } from "react-native-ui-lib/src/components/panningViews/panningProvider"; import { PanningDirectionsEnum } from "react-native-ui-lib/src/components/panningViews/panningProvider";
import { repeatOptions, useToDosContext } from "@/contexts/ToDosContext"; import { repeatOptions, useToDosContext } from "@/contexts/ToDosContext";
import { setDate } from "date-fns"; import { setDate } from "date-fns";
import PointsSlider from "@/components/shared/PointsSlider";
const AddChore = () => { const AddChore = () => {
const { addToDo, toDos } = useToDosContext(); const { addToDo, toDos } = useToDosContext();
@ -232,36 +233,11 @@ const AddChore = () => {
Reward Points Reward Points
</Text> </Text>
</View> </View>
<View marginH-30 row spread> <PointsSlider
<View width={"80%"}> points={points}
<Slider setPoints={setPoints}
value={points} handleChange={handleChange}
onValueChange={(value) => setPoints(value)}
minimumValue={0}
step={10}
maximumValue={100}
/> />
<View row spread>
<Text>0</Text>
<Text>50</Text>
<Text>100</Text>
</View>
</View>
<View style={{ marginLeft: "auto" }}>
<TextField
value={points.toString()}
onChangeText={(text) => {
handleChange(text);
}}
containerStyle={{
borderWidth: 1,
borderColor: "#d9d9d9",
width: 45,
borderRadius: 5,
}}
/>
</View>
</View>
</Dialog> </Dialog>
</LinearGradient> </LinearGradient>
); );

View File

@ -0,0 +1,43 @@
import { View, Text, Slider, TextField } from "react-native-ui-lib";
import React from "react";
const PointsSlider = (props: {
points: number;
setPoints(value: number): void;
handleChange(value: string): void;
}) => {
return (
<View marginH-30 row spread>
<View width={"80%"}>
<Slider
value={props.points}
onValueChange={(value) => props.setPoints(value)}
minimumValue={0}
step={10}
maximumValue={100}
/>
<View row spread>
<Text>0</Text>
<Text>50</Text>
<Text>100</Text>
</View>
</View>
<View style={{ marginLeft: "auto" }}>
<TextField
value={props.points.toString()}
onChangeText={(text) => {
props.handleChange(text);
}}
containerStyle={{
borderWidth: 1,
borderColor: "#d9d9d9",
width: 45,
borderRadius: 5,
}}
/>
</View>
</View>
);
};
export default PointsSlider;

View File

@ -1,4 +1,5 @@
import { createContext, FC, ReactNode, useContext, useState } from "react"; import { createContext, FC, ReactNode, useContext, useState } from "react";
import { useAuthContext } from "./AuthContext";
export const colorMap = { export const colorMap = {
pink: "#ea156c", pink: "#ea156c",
@ -8,8 +9,16 @@ export const colorMap = {
purple: "#7305d4", purple: "#7305d4",
}; };
interface IUserDetails {
email: string | undefined;
firstName: string;
lastName: string;
}
interface ISettingsContext { interface ISettingsContext {
calendarColor: string; calendarColor: string;
userDetails: IUserDetails;
editUserDetails: (details: Partial<IUserDetails>) => void;
setCalendarColor: (color: string) => void; setCalendarColor: (color: string) => void;
} }
@ -18,10 +27,24 @@ const SettingsContext = createContext<ISettingsContext>(undefined!);
export const SettingsContextProvider: FC<{ children: ReactNode }> = ({ export const SettingsContextProvider: FC<{ children: ReactNode }> = ({
children, children,
}) => { }) => {
const { user } = useAuthContext();
const [userDetails, setUserDetails] = useState<IUserDetails>({
email: user?.email?.toString(),
firstName: "",
lastName: "",
});
const [calendarColor, setCalendarColor] = useState<string>(colorMap.pink); const [calendarColor, setCalendarColor] = useState<string>(colorMap.pink);
const editUserDetails = (details: Partial<IUserDetails>) => {
setUserDetails((prevDetails) => ({
...prevDetails,
...details,
}));
};
return ( return (
<SettingsContext.Provider value={{ calendarColor, setCalendarColor }}> <SettingsContext.Provider
value={{ calendarColor, setCalendarColor, userDetails, editUserDetails }}
>
{children} {children}
</SettingsContext.Provider> </SettingsContext.Provider>
); );

View File

@ -13,7 +13,7 @@ service cloud.firestore {
// all client requests to your Firestore database will be denied until you Update // all client requests to your Firestore database will be denied until you Update
// your rules // your rules
match /{document=**} { match /{document=**} {
allow read, write: if request.time < timestamp.date(2024, 9, 5); allow read, write;
} }
} }
} }

View File

@ -7,7 +7,8 @@ export interface User {
export interface UserProfile { export interface UserProfile {
userType: ProfileType; userType: ProfileType;
name: string; firstName: string;
lastName: string;
childrenIds?: string[]; childrenIds?: string[];
birthday?: Date; birthday?: Date;
parentId?: string; parentId?: string;

View File

@ -8,9 +8,9 @@ export const useSignUp = () => {
return useMutation({ return useMutation({
mutationKey: ["signUp"], mutationKey: ["signUp"],
mutationFn: async ({email, password}: { email: string, password: string }) => { mutationFn: async ({email, password, firstName, lastName}: { email: string, password: string, firstName: string, lastName: string }) => {
const res = await auth().createUserWithEmailAndPassword(email, password); const res = await auth().createUserWithEmailAndPassword(email, password);
await updateUserData({newUserData: {userType: ProfileType.PARENT}, customUser: res.user}); await updateUserData({newUserData: {userType: ProfileType.PARENT, firstName: firstName, lastName: lastName}, customUser: res.user});
} }
}); });
} }

View File

@ -17,7 +17,7 @@ export const useUpdateUserData = () => {
await firestore() await firestore()
.collection("Profiles") .collection("Profiles")
.doc(user.uid) .doc(user.uid)
.set(newUserData); .update(newUserData);
const profileData = await firestore().collection("Profiles").doc(user?.uid!).get() const profileData = await firestore().collection("Profiles").doc(user?.uid!).get()
setProfileData(profileData.data() as UserProfile) setProfileData(profileData.data() as UserProfile)