mirror of
https://github.com/urosran/cally.git
synced 2026-10-23 08:37:55 +00:00
Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
@@ -2,19 +2,38 @@ import React from "react";
|
||||
import { View } from "react-native-ui-lib";
|
||||
import HeaderTemplate from "@/components/shared/HeaderTemplate";
|
||||
import { InnerCalendar } from "@/components/pages/calendar/InnerCalendar";
|
||||
import { useSetAtom } from "jotai";
|
||||
import { refreshEnabledAtom } from "./atoms";
|
||||
|
||||
export default function CalendarPage() {
|
||||
const setRefreshEnabled = useSetAtom(refreshEnabledAtom);
|
||||
|
||||
const disableRefreshControl = () => setRefreshEnabled(false);
|
||||
const enableRefreshControl = () => setRefreshEnabled(true);
|
||||
return (
|
||||
<View
|
||||
style={{ flex: 1, height: "100%", padding: 10 }}
|
||||
paddingH-22
|
||||
paddingT-0
|
||||
>
|
||||
<HeaderTemplate
|
||||
message={"Let's get your week started !"}
|
||||
isWelcome
|
||||
isCalendar={true}
|
||||
/>
|
||||
<View
|
||||
onStartShouldSetResponder={() => {
|
||||
enableRefreshControl();
|
||||
console.log("yeah");
|
||||
return true;
|
||||
}}
|
||||
onResponderRelease={() => {
|
||||
disableRefreshControl();
|
||||
console.log("sure");
|
||||
console.log(refreshEnabledAtom)
|
||||
}}
|
||||
>
|
||||
<HeaderTemplate
|
||||
message={"Let's get your week started !"}
|
||||
isWelcome
|
||||
isCalendar={true}
|
||||
/>
|
||||
</View>
|
||||
<InnerCalendar />
|
||||
</View>
|
||||
);
|
||||
|
||||
@@ -12,3 +12,4 @@ export const settingsPageIndex = atom<number>(0);
|
||||
export const userSettingsView = atom<boolean>(true);
|
||||
export const toDosPageIndex = atom<number>(0);
|
||||
export const refreshTriggerAtom = atom<boolean>(false);
|
||||
export const refreshEnabledAtom = atom<boolean>(true);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, {useCallback, useEffect, useRef, useState} from "react";
|
||||
import React, { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { StyleSheet, TouchableOpacity } from "react-native";
|
||||
import { ScrollView } from "react-native-gesture-handler";
|
||||
import * as ImagePicker from "expo-image-picker";
|
||||
@@ -20,11 +20,17 @@ import { useUpdateUserData } from "@/hooks/firebase/useUpdateUserData";
|
||||
import { useChangeProfilePicture } from "@/hooks/firebase/useChangeProfilePicture";
|
||||
import { colorMap } from "@/constants/colorMap";
|
||||
import DeleteProfileDialogs from "../user_components/DeleteProfileDialogs";
|
||||
import {AntDesign} from "@expo/vector-icons";
|
||||
import {useDeleteUser} from "@/hooks/firebase/useDeleteUser";
|
||||
import { AntDesign } from "@expo/vector-icons";
|
||||
import { useDeleteUser } from "@/hooks/firebase/useDeleteUser";
|
||||
import { useUpdateHouseholdName } from "@/hooks/firebase/useUpdateHouseholdName";
|
||||
import { useGetHouseholdName } from "@/hooks/firebase/useGetHouseholdName";
|
||||
|
||||
const MyProfile = () => {
|
||||
const { user, profileData } = useAuthContext();
|
||||
const { data: hhName, refetch: refetchHHName } = useGetHouseholdName(
|
||||
profileData.familyId
|
||||
);
|
||||
const [householdName, setHouseholdName] = useState<string>("");
|
||||
const [timeZone, setTimeZone] = useState<string>(
|
||||
profileData?.timeZone! ?? Localization.getCalendars()[0].timeZone
|
||||
);
|
||||
@@ -37,10 +43,10 @@ const MyProfile = () => {
|
||||
>(profileData?.pfp || null);
|
||||
|
||||
const [selectedColor, setSelectedColor] = useState<string>(
|
||||
profileData?.eventColor ?? colorMap.pink
|
||||
profileData?.eventColor ?? colorMap.pink
|
||||
);
|
||||
const [previousSelectedColor, setPreviousSelectedColor] = useState<string>(
|
||||
profileData?.eventColor ?? colorMap.pink
|
||||
profileData?.eventColor ?? colorMap.pink
|
||||
);
|
||||
|
||||
const [showDeleteDialog, setShowDeleteDialog] = useState<boolean>(false);
|
||||
@@ -52,15 +58,25 @@ const MyProfile = () => {
|
||||
setShowDeleteDialog(true);
|
||||
};
|
||||
|
||||
const { mutateAsync: updateHouseholdName } = useUpdateHouseholdName();
|
||||
const { mutateAsync: updateUserData } = useUpdateUserData();
|
||||
const { mutateAsync: changeProfilePicture } = useChangeProfilePicture();
|
||||
const { mutateAsync: deleteAsync } = useDeleteUser()
|
||||
const { mutateAsync: deleteAsync } = useDeleteUser();
|
||||
const isFirstRender = useRef(true);
|
||||
|
||||
const handleUpdateUserData = async () => {
|
||||
await updateUserData({ newUserData: { firstName, lastName, timeZone } });
|
||||
};
|
||||
|
||||
const handleUpdateHouseholdName = async () => {
|
||||
if (profileData?.familyId) {
|
||||
await updateHouseholdName({
|
||||
familyId: profileData.familyId,
|
||||
name: householdName,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const debouncedUserDataUpdate = debounce(handleUpdateUserData, 500);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -71,6 +87,10 @@ const MyProfile = () => {
|
||||
debouncedUserDataUpdate();
|
||||
}, [timeZone, lastName, firstName]);
|
||||
|
||||
useEffect(() => {
|
||||
handleUpdateHouseholdName();
|
||||
}, [householdName]);
|
||||
|
||||
useEffect(() => {
|
||||
if (profileData) {
|
||||
setFirstName(profileData.firstName || "");
|
||||
@@ -81,6 +101,16 @@ const MyProfile = () => {
|
||||
}
|
||||
}, [profileData]);
|
||||
|
||||
useEffect(() => {
|
||||
if (profileData?.familyId) {
|
||||
refetchHHName();
|
||||
}
|
||||
}, [profileData?.familyId]);
|
||||
|
||||
useEffect(() => {
|
||||
setHouseholdName(hhName);
|
||||
}, [hhName])
|
||||
|
||||
const pickImage = async () => {
|
||||
const permissionResult =
|
||||
await ImagePicker.requestMediaLibraryPermissionsAsync();
|
||||
@@ -119,19 +149,19 @@ const MyProfile = () => {
|
||||
};
|
||||
|
||||
const debouncedUpdateUserData = useCallback(
|
||||
debounce(async (color: string) => {
|
||||
try {
|
||||
await updateUserData({
|
||||
newUserData: {
|
||||
eventColor: color,
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Failed to update color:", error);
|
||||
setSelectedColor(previousSelectedColor);
|
||||
}
|
||||
}, 500),
|
||||
[]
|
||||
debounce(async (color: string) => {
|
||||
try {
|
||||
await updateUserData({
|
||||
newUserData: {
|
||||
eventColor: color,
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Failed to update color:", error);
|
||||
setSelectedColor(previousSelectedColor);
|
||||
}
|
||||
}, 500),
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
@@ -177,6 +207,18 @@ const MyProfile = () => {
|
||||
)}
|
||||
</View>
|
||||
<View paddingH-15>
|
||||
<Text text80 marginT-10 marginB-7 style={styles.label}>
|
||||
Household
|
||||
</Text>
|
||||
<TextField
|
||||
text70
|
||||
placeholder="Household name"
|
||||
style={styles.txtBox}
|
||||
value={householdName}
|
||||
onChangeText={async (value) => {
|
||||
setHouseholdName(value);
|
||||
}}
|
||||
/>
|
||||
<Text text80 marginT-10 marginB-7 style={styles.label}>
|
||||
First name
|
||||
</Text>
|
||||
@@ -255,39 +297,35 @@ const MyProfile = () => {
|
||||
<TouchableOpacity onPress={() => handleChangeColor(colorMap.pink)}>
|
||||
<View style={styles.colorBox} backgroundColor={colorMap.pink}>
|
||||
{selectedColor == colorMap.pink && (
|
||||
<AntDesign name="check" size={30} color="white"/>
|
||||
<AntDesign name="check" size={30} color="white" />
|
||||
)}
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
onPress={() => handleChangeColor(colorMap.orange)}
|
||||
>
|
||||
<TouchableOpacity onPress={() => handleChangeColor(colorMap.orange)}>
|
||||
<View style={styles.colorBox} backgroundColor={colorMap.orange}>
|
||||
{selectedColor == colorMap.orange && (
|
||||
<AntDesign name="check" size={30} color="white"/>
|
||||
<AntDesign name="check" size={30} color="white" />
|
||||
)}
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity onPress={() => handleChangeColor(colorMap.green)}>
|
||||
<View style={styles.colorBox} backgroundColor={colorMap.green}>
|
||||
{selectedColor == colorMap.green && (
|
||||
<AntDesign name="check" size={30} color="white"/>
|
||||
<AntDesign name="check" size={30} color="white" />
|
||||
)}
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity onPress={() => handleChangeColor(colorMap.teal)}>
|
||||
<View style={styles.colorBox} backgroundColor={colorMap.teal}>
|
||||
{selectedColor == colorMap.teal && (
|
||||
<AntDesign name="check" size={30} color="white"/>
|
||||
<AntDesign name="check" size={30} color="white" />
|
||||
)}
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
onPress={() => handleChangeColor(colorMap.purple)}
|
||||
>
|
||||
<TouchableOpacity onPress={() => handleChangeColor(colorMap.purple)}>
|
||||
<View style={styles.colorBox} backgroundColor={colorMap.purple}>
|
||||
{selectedColor == colorMap.purple && (
|
||||
<AntDesign name="check" size={30} color="white"/>
|
||||
<AntDesign name="check" size={30} color="white" />
|
||||
)}
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
|
||||
Reference in New Issue
Block a user