From 111244e178998d7ba86c914b2fa7e419839c9440 Mon Sep 17 00:00:00 2001
From: ivic00 <102467664+ivic00@users.noreply.github.com>
Date: Sun, 17 Nov 2024 23:53:28 +0100
Subject: [PATCH] added household name
---
app/(auth)/calendar/index.tsx | 15 ++-
app/(unauth)/cal_sync.tsx | 12 ++-
components/pages/calendar/CalendarPage.tsx | 29 +++++-
components/pages/calendar/atoms.ts | 1 +
.../user_settings_views/MyProfile.tsx | 98 +++++++++++++------
hooks/firebase/useGetHouseholdName.ts | 36 +++++++
hooks/firebase/useUpdateHouseholdName.ts | 50 ++++++++++
7 files changed, 204 insertions(+), 37 deletions(-)
create mode 100644 hooks/firebase/useGetHouseholdName.ts
create mode 100644 hooks/firebase/useUpdateHouseholdName.ts
diff --git a/app/(auth)/calendar/index.tsx b/app/(auth)/calendar/index.tsx
index 53fa094..1ced3d2 100644
--- a/app/(auth)/calendar/index.tsx
+++ b/app/(auth)/calendar/index.tsx
@@ -3,6 +3,7 @@ import { ScrollView, RefreshControl } from "react-native";
import { useSetAtom } from "jotai";
import CalendarPage from "@/components/pages/calendar/CalendarPage";
import { refreshTriggerAtom } from "@/components/pages/calendar/atoms";
+import { colorMap } from "@/constants/colorMap";
export default function Screen() {
const [refreshing, setRefreshing] = useState(false);
@@ -29,7 +30,19 @@ export default function Screen() {
style={{ flex: 1 }}
contentContainerStyle={{ flex: 1 }}
refreshControl={
-
+
}
bounces={true}
showsVerticalScrollIndicator={false}
diff --git a/app/(unauth)/cal_sync.tsx b/app/(unauth)/cal_sync.tsx
index 0e9f15b..4eb6cba 100644
--- a/app/(unauth)/cal_sync.tsx
+++ b/app/(unauth)/cal_sync.tsx
@@ -1,17 +1,24 @@
import {SafeAreaView} from "react-native-safe-area-context";
import {Button, Text, View} from "react-native-ui-lib";
-import React from "react";
+import React, { useEffect } from "react";
import {useCalSync} from "@/hooks/useCalSync";
import GoogleIcon from "@/assets/svgs/GoogleIcon";
import AppleIcon from "@/assets/svgs/AppleIcon";
import OutlookIcon from "@/assets/svgs/OutlookIcon";
import {useAuthContext} from "@/contexts/AuthContext";
import {StyleSheet} from "react-native";
+import { useGetHouseholdName } from "@/hooks/firebase/useGetHouseholdName";
export default function Screen() {
const {profileData, setRedirectOverride} = useAuthContext()
const {handleStartGoogleSignIn, handleAppleSignIn, handleMicrosoftSignIn} = useCalSync()
+ const {data: householdName, refetch} = useGetHouseholdName(profileData?.familyId);
+
+ useEffect(() => {
+ refetch();
+ }, [profileData?.familyId])
+
const hasSomeCalendarsSynced =
!!profileData?.appleAccounts || !!profileData?.microsoftAccounts || !!profileData?.googleAccounts
@@ -19,6 +26,9 @@ export default function Screen() {
+ {householdName &&
+ You Joined {householdName}
+ }
Let's get started!
diff --git a/components/pages/calendar/CalendarPage.tsx b/components/pages/calendar/CalendarPage.tsx
index d6d2d7e..960beee 100644
--- a/components/pages/calendar/CalendarPage.tsx
+++ b/components/pages/calendar/CalendarPage.tsx
@@ -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 (
-
+ {
+ enableRefreshControl();
+ console.log("yeah");
+ return true;
+ }}
+ onResponderRelease={() => {
+ disableRefreshControl();
+ console.log("sure");
+ console.log(refreshEnabledAtom)
+ }}
+ >
+
+
);
diff --git a/components/pages/calendar/atoms.ts b/components/pages/calendar/atoms.ts
index 3f24905..a2095dc 100644
--- a/components/pages/calendar/atoms.ts
+++ b/components/pages/calendar/atoms.ts
@@ -12,3 +12,4 @@ export const settingsPageIndex = atom(0);
export const userSettingsView = atom(true);
export const toDosPageIndex = atom(0);
export const refreshTriggerAtom = atom(false);
+export const refreshEnabledAtom = atom(true);
diff --git a/components/pages/settings/user_settings_views/MyProfile.tsx b/components/pages/settings/user_settings_views/MyProfile.tsx
index 8c5be87..e0ecc2e 100644
--- a/components/pages/settings/user_settings_views/MyProfile.tsx
+++ b/components/pages/settings/user_settings_views/MyProfile.tsx
@@ -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("");
const [timeZone, setTimeZone] = useState(
profileData?.timeZone! ?? Localization.getCalendars()[0].timeZone
);
@@ -37,10 +43,10 @@ const MyProfile = () => {
>(profileData?.pfp || null);
const [selectedColor, setSelectedColor] = useState(
- profileData?.eventColor ?? colorMap.pink
+ profileData?.eventColor ?? colorMap.pink
);
const [previousSelectedColor, setPreviousSelectedColor] = useState(
- profileData?.eventColor ?? colorMap.pink
+ profileData?.eventColor ?? colorMap.pink
);
const [showDeleteDialog, setShowDeleteDialog] = useState(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 = () => {
)}
+
+ Household
+
+ {
+ setHouseholdName(value);
+ }}
+ />
First name
@@ -255,39 +297,35 @@ const MyProfile = () => {
handleChangeColor(colorMap.pink)}>
{selectedColor == colorMap.pink && (
-
+
)}
- handleChangeColor(colorMap.orange)}
- >
+ handleChangeColor(colorMap.orange)}>
{selectedColor == colorMap.orange && (
-
+
)}
handleChangeColor(colorMap.green)}>
{selectedColor == colorMap.green && (
-
+
)}
handleChangeColor(colorMap.teal)}>
{selectedColor == colorMap.teal && (
-
+
)}
- handleChangeColor(colorMap.purple)}
- >
+ handleChangeColor(colorMap.purple)}>
{selectedColor == colorMap.purple && (
-
+
)}
diff --git a/hooks/firebase/useGetHouseholdName.ts b/hooks/firebase/useGetHouseholdName.ts
new file mode 100644
index 0000000..bf85b75
--- /dev/null
+++ b/hooks/firebase/useGetHouseholdName.ts
@@ -0,0 +1,36 @@
+import { useQuery } from "react-query";
+import firestore from "@react-native-firebase/firestore";
+
+export const useGetHouseholdName = (familyId: string) => {
+ return useQuery(
+ ["getHouseholdName", familyId], // Unique query key
+ async () => {
+ console.log(`Fetching household name for familyId: ${familyId}`);
+
+ try {
+ // Query the Households collection for the given familyId
+ const snapshot = await firestore()
+ .collection("Households")
+ .where("familyId", "==", familyId)
+ .get();
+
+ if (!snapshot.empty) {
+ // Extract the name from the first matching document
+ const householdData = snapshot.docs[0].data();
+ console.log("Household found:", householdData);
+ return householdData.name || null; // Return the name or null if missing
+ } else {
+ console.log("No household found for the given familyId.");
+ return null; // Return null if no household found
+ }
+ } catch (e) {
+ console.error("Error fetching household name:", e);
+ throw e; // Ensure error propagates to the query error handling
+ }
+ },
+ {
+ enabled: !!familyId, // Only fetch if familyId is provided
+ staleTime: 5 * 60 * 1000, // Cache the data for 5 minutes
+ }
+ );
+};
diff --git a/hooks/firebase/useUpdateHouseholdName.ts b/hooks/firebase/useUpdateHouseholdName.ts
new file mode 100644
index 0000000..f601745
--- /dev/null
+++ b/hooks/firebase/useUpdateHouseholdName.ts
@@ -0,0 +1,50 @@
+import firestore from "@react-native-firebase/firestore";
+import { useMutation, useQueryClient } from "react-query";
+
+export const useUpdateHouseholdName = () => {
+ const queryClient = useQueryClient();
+
+ return useMutation({
+ mutationKey: ["updateHouseholdName"],
+ mutationFn: async ({
+ familyId,
+ name,
+ }: {
+ familyId: string;
+ name: string;
+ }) => {
+ console.log("Mutation function called with data:", { familyId, name });
+
+ try {
+ // Reference to the Households collection
+ const householdRef = firestore().collection("Households");
+
+ // Query to check if the household exists
+ const snapshot = await householdRef.where("familyId", "==", familyId).get();
+
+ if (!snapshot.empty) {
+ // If a household with the familyId exists, update the name
+ const docId = snapshot.docs[0].id;
+ console.log(`Household found with ID ${docId}, updating name...`);
+
+ await householdRef.doc(docId).update({ name });
+
+ console.log("Household name updated successfully.");
+ } else {
+ // If no household exists, create a new one with familyId and name
+ console.log("No household found, creating a new one...");
+
+ await householdRef.add({ familyId, name });
+
+ console.log("New household created successfully.");
+ }
+ } catch (e) {
+ console.error("Error updating or creating household:", e);
+ throw e; // Ensure error propagates to the mutation error handling
+ }
+ },
+ onSuccess: () => {
+ queryClient.invalidateQueries("households"); // Invalidate the "households" query to refresh data
+ },
+ });
+};