Microsoft sync added

This commit is contained in:
Milan Paunovic
2024-10-05 22:22:29 +02:00
parent 2234fac075
commit aed2333404
13 changed files with 865 additions and 1277 deletions

View File

@ -29,6 +29,7 @@
<data android:scheme="myapp"/> <data android:scheme="myapp"/>
<data android:scheme="com.cally.app"/> <data android:scheme="com.cally.app"/>
<data android:scheme="exp+cally"/> <data android:scheme="exp+cally"/>
<data android:scheme="callyplanner"/>
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" android:exported="false"/> <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" android:exported="false"/>

View File

@ -5,7 +5,7 @@
"version": "1.0.0", "version": "1.0.0",
"orientation": "portrait", "orientation": "portrait",
"icon": "./assets/images/icon.png", "icon": "./assets/images/icon.png",
"scheme": "myapp", "scheme": "callyplanner",
"userInterfaceStyle": "light", "userInterfaceStyle": "light",
"splash": { "splash": {
"image": "./assets/images/splash.png", "image": "./assets/images/splash.png",

View File

@ -10,6 +10,8 @@ export async function fetchMicrosoftCalendarEvents(token, startDate, endDate) {
const data = await response.json(); const data = await response.json();
console.log(data, startDate, endDate)
const microsoftEvents = []; const microsoftEvents = [];
data?.value?.forEach((item) => { data?.value?.forEach((item) => {
const start = item.start; const start = item.start;
@ -33,6 +35,8 @@ export async function fetchMicrosoftCalendarEvents(token, startDate, endDate) {
endDate: endDateTime, endDate: endDateTime,
allDay: item.isAllDay, allDay: item.isAllDay,
}; };
microsoftEvents.push(microsoftEvent); microsoftEvents.push(microsoftEvent);
}); });

View File

@ -16,11 +16,11 @@ import {
} from "react-native-ui-lib"; } from "react-native-ui-lib";
import { TouchableOpacity } from "react-native"; import { TouchableOpacity } from "react-native";
import { ManuallyAddEventModal } from "@/components/pages/calendar/ManuallyAddEventModal"; import { ManuallyAddEventModal } from "@/components/pages/calendar/ManuallyAddEventModal";
import AddChore from "../todos/AddChore";
import AddChoreDialog from "../todos/AddChoreDialog"; import AddChoreDialog from "../todos/AddChoreDialog";
import { ToDosContextProvider } from "@/contexts/ToDosContext"; import { ToDosContextProvider } from "@/contexts/ToDosContext";
import UploadImageDialog from "./UploadImageDialog"; import UploadImageDialog from "./UploadImageDialog";
export const AddEventDialog = () => { export const AddEventDialog = () => {
const [show, setShow] = useState(false); const [show, setShow] = useState(false);
const [showManualInputModal, setShowManualInputModal] = useState(false); const [showManualInputModal, setShowManualInputModal] = useState(false);

View File

@ -1,321 +1,371 @@
import { AntDesign, Ionicons } from "@expo/vector-icons"; import {AntDesign, Ionicons} from "@expo/vector-icons";
import React, { useState } from "react"; import React, {useState} from "react";
import { Button, Checkbox, Text, View } from "react-native-ui-lib"; import {Button, Checkbox, Text, View} from "react-native-ui-lib";
import { StyleSheet } from "react-native"; import {ScrollView, StyleSheet} from "react-native";
import { colorMap } from "@/contexts/SettingsContext"; import {colorMap} from "@/contexts/SettingsContext";
import { TouchableOpacity } from "react-native-gesture-handler"; import {TouchableOpacity} from "react-native-gesture-handler";
import { fetchGoogleCalendarEvents } from "@/calendar-integration/google-calendar-utils"; import {fetchGoogleCalendarEvents} from "@/calendar-integration/google-calendar-utils";
import { fetchMicrosoftCalendarEvents } from "@/calendar-integration/microsoft-calendar-utils"; import {fetchMicrosoftCalendarEvents} from "@/calendar-integration/microsoft-calendar-utils";
import { useCreateEventFromProvider } from "@/hooks/firebase/useCreateEvent"; import {useCreateEventFromProvider} from "@/hooks/firebase/useCreateEvent";
import { useAuthContext } from "@/contexts/AuthContext"; import {useAuthContext} from "@/contexts/AuthContext";
import { useUpdateUserData } from "@/hooks/firebase/useUpdateUserData"; import {useUpdateUserData} from "@/hooks/firebase/useUpdateUserData";
import { GoogleSignin } from "@react-native-google-signin/google-signin"; import {GoogleSignin} from "@react-native-google-signin/google-signin";
import { authorize } from "react-native-app-auth"; import * as AuthSession from "expo-auth-session";
GoogleSignin.configure({ GoogleSignin.configure({
webClientId: webClientId:
"406146460310-hjadmfa1gg4ptaouira5rkhu0djlo5ut.apps.googleusercontent.com", "406146460310-hjadmfa1gg4ptaouira5rkhu0djlo5ut.apps.googleusercontent.com",
scopes: ["profile", "email"], // Note: add calendar scope scopes: ["profile", "email"], // Note: add calendar scope
}); });
const GoogleLogin = async () => { const GoogleLogin = async () => {
return await GoogleSignin.signIn(); return await GoogleSignin.signIn();
}; };
const microsoftConfig = { const microsoftConfig = {
issuer: "https://login.microsoftonline.com/common", clientId: "13c79071-1066-40a9-9f71-b8c4b138b4af", // Replace with your Microsoft client ID
clientId: "<your-client-id>", // Replace with your microsoft client id redirectUri: AuthSession.makeRedirectUri({path: "settings"}), // Generate redirect URI automatically for Expo
redirectUrl: "<your-redirect-uri>", // replace with your redirect uri added in microsoft portal scopes: [
scopes: ["openid", "profile", "email"], // Add calendar scope "openid",
serviceConfiguration: { "profile",
"email",
"offline_access",
"Calendars.ReadWrite", // Scope for reading calendar events
],
authorizationEndpoint: authorizationEndpoint:
"https://login.microsoftonline.com/common/oauth2/v2.0/authorize", "https://login.microsoftonline.com/common/oauth2/v2.0/authorize",
tokenEndpoint: "https://login.microsoftonline.com/common/oauth2/v2.0/token", tokenEndpoint: "https://login.microsoftonline.com/common/oauth2/v2.0/token"
revocationEndpoint:
"https://login.microsoftonline.com/common/oauth2/v2.0/logout",
},
useNonce: true,
usePKCE: true, //For iOS, we have added the useNonce and usePKCE parameters, which are recommended for security reasons.
additionalParameters: {
prompt: "consent",
},
}; };
const CalendarSettingsPage = (props: { const CalendarSettingsPage = (props: {
setSelectedPage: (page: number) => void; setSelectedPage: (page: number) => void;
}) => { }) => {
const [selectedColor, setSelectedColor] = useState<string>(colorMap.pink); const [selectedColor, setSelectedColor] = useState<string>(colorMap.pink);
const [startDate, setStartDate] = useState<boolean>(true); const [startDate, setStartDate] = useState<boolean>(true);
const { profileData } = useAuthContext(); const {profileData} = useAuthContext();
const { mutateAsync: createEventFromProvider } = useCreateEventFromProvider(); const {mutateAsync: createEventFromProvider} = useCreateEventFromProvider();
const { mutateAsync: updateUserData } = useUpdateUserData(); const {mutateAsync: updateUserData} = useUpdateUserData();
const fetchAndSaveGoogleEvents = () => { const fetchAndSaveGoogleEvents = () => {
const timeMin = new Date(new Date().setHours(0, 0, 0, 0)); const timeMin = new Date(new Date().setHours(0, 0, 0, 0));
const timeMax = new Date( const timeMax = new Date(
new Date(new Date().setHours(0, 0, 0, 0)).setDate(timeMin.getDate() + 30), new Date(new Date().setHours(0, 0, 0, 0)).setDate(timeMin.getDate() + 30)
); );
fetchGoogleCalendarEvents( fetchGoogleCalendarEvents(
profileData?.googleToken, profileData?.googleToken,
timeMin.toISOString().slice(0, -5) + "Z", timeMin.toISOString().slice(0, -5) + "Z",
timeMax.toISOString().slice(0, -5) + "Z", timeMax.toISOString().slice(0, -5) + "Z",
).then((response) => { ).then((response) => {
response?.forEach((item) => saveData(item)); response?.forEach((item) => saveData(item));
}); });
}; };
async function saveData(item) { async function saveData(item: any) {
await createEventFromProvider(item); await createEventFromProvider(item);
} }
const fetchAndSaveMicrosoftEvents = () => { const fetchAndSaveMicrosoftEvents = () => {
const startDateTime = new Date(new Date().setHours(0, 0, 0, 0)); const startDateTime = new Date(new Date().setHours(0, 0, 0, 0));
const endDateTime = new Date( const endDateTime = new Date(
new Date(new Date().setHours(0, 0, 0, 0)).setDate( new Date(new Date().setHours(0, 0, 0, 0)).setDate(
startDateTime.getDate() + 30, startDateTime.getDate() + 30
), )
); );
fetchMicrosoftCalendarEvents(
profileData?.microsoftToken,
startDateTime.toISOString().slice(0, -5) + "Z",
endDateTime.toISOString().slice(0, -5) + "Z",
).then((response) => {
response?.forEach((item) => saveData(item));
});
};
const handleGoogleLogin = async () => { fetchMicrosoftCalendarEvents(
try { profileData?.microsoftToken,
const response = await GoogleLogin(); startDateTime.toISOString().slice(0, -5) + "Z",
if (response) { endDateTime.toISOString().slice(0, -5) + "Z"
const googleUserData = response.data; ).then((response) => {
let idToken = googleUserData?.idToken; console.log(response)
response?.forEach((item) => saveData(item));
});
};
if (idToken) { const handleGoogleLogin = async () => {
await updateUserData({ newUserData: { googleToken: idToken } }); try {
const response = await GoogleLogin();
if (response) {
const googleUserData = response.data;
let idToken = googleUserData?.idToken;
if (idToken) {
await updateUserData({newUserData: {googleToken: idToken}});
}
}
} catch (apiError) {
console.log(apiError || "Something went wrong");
} }
} };
} catch (apiError) {
console.log(apiError || "Something went wrong");
}
};
const handleMicrosoftSignIn = async () => { const handleMicrosoftSignIn = async () => {
try { try {
const { idToken } = await authorize(microsoftConfig); console.log("Starting Microsoft sign-in...");
if (idToken) {
await updateUserData({ newUserData: { microsoftToken: idToken } });
}
} catch (error) {
console.log(error);
}
};
return ( const authRequest = new AuthSession.AuthRequest({
<View marginH-30> clientId: microsoftConfig.clientId,
<TouchableOpacity onPress={() => props.setSelectedPage(0)}> scopes: microsoftConfig.scopes,
<View row marginT-20 marginB-35 centerV> redirectUri: microsoftConfig.redirectUri,
<Ionicons name="chevron-back" size={22} color="#979797" /> responseType: AuthSession.ResponseType.Code,
<Text text70 color="#979797"> usePKCE: true, // Enable PKCE
Return to main settings });
</Text>
</View> console.log("Auth request created:", authRequest);
</TouchableOpacity>
<Text text60R>Calendar settings</Text> const authResult = await authRequest.promptAsync({
<View style={styles.card}> authorizationEndpoint: microsoftConfig.authorizationEndpoint,
<Text text70 marginB-14> });
Event Color Preference
</Text> console.log("Auth result:", authResult);
<View row spread>
<TouchableOpacity onPress={() => setSelectedColor(colorMap.pink)}> if (authResult.type === "success" && authResult.params?.code) {
<View style={styles.colorBox} backgroundColor={colorMap.pink}> const code = authResult.params.code;
{selectedColor == colorMap.pink && ( console.log("Authorization code received:", code);
<AntDesign name="check" size={30} color="white" />
)} // Exchange authorization code for tokens
</View> const tokenResponse = await fetch(microsoftConfig.tokenEndpoint, {
</TouchableOpacity> method: "POST",
<TouchableOpacity onPress={() => setSelectedColor(colorMap.orange)}> headers: {
<View style={styles.colorBox} backgroundColor={colorMap.orange}> "Content-Type": "application/x-www-form-urlencoded",
{selectedColor == colorMap.orange && ( },
<AntDesign name="check" size={30} color="white" /> body: `client_id=${microsoftConfig.clientId}&redirect_uri=${encodeURIComponent(
)} microsoftConfig.redirectUri
</View> )}&grant_type=authorization_code&code=${code}&code_verifier=${
</TouchableOpacity> authRequest.codeVerifier
<TouchableOpacity onPress={() => setSelectedColor(colorMap.green)}> }&scope=${encodeURIComponent("https://graph.microsoft.com/Calendars.ReadWrite offline_access")}`,
<View style={styles.colorBox} backgroundColor={colorMap.green}> });
{selectedColor == colorMap.green && (
<AntDesign name="check" size={30} color="white" />
)} console.log("Token response status:", tokenResponse.status);
</View>
</TouchableOpacity> if (!tokenResponse.ok) {
<TouchableOpacity onPress={() => setSelectedColor(colorMap.teal)}> console.error("Token exchange failed:", await tokenResponse.text());
<View style={styles.colorBox} backgroundColor={colorMap.teal}> return;
{selectedColor == colorMap.teal && ( }
<AntDesign name="check" size={30} color="white" />
)} const tokenData = await tokenResponse.json();
</View> console.log("Token data received:", tokenData);
</TouchableOpacity>
<TouchableOpacity onPress={() => setSelectedColor(colorMap.purple)}> if (tokenData?.id_token) {
<View style={styles.colorBox} backgroundColor={colorMap.purple}> console.log("ID token received, updating user data...");
{selectedColor == colorMap.purple && ( await updateUserData({newUserData: {microsoftToken: tokenData.access_token}});
<AntDesign name="check" size={30} color="white" /> console.log("User data updated successfully.");
)} }
</View> } else {
</TouchableOpacity> console.warn("Authentication was not successful:", authResult);
</View> }
</View> } catch (error) {
<View style={styles.card}> console.error("Error during Microsoft sign-in:", error);
<Text text70>Weekly Start Date</Text> }
<View row marginV-5 marginT-20> };
<Checkbox
value={startDate} return (
style={styles.checkbox} <ScrollView>
color="#ea156d" <View marginH-30>
onValueChange={() => setStartDate(true)} <TouchableOpacity onPress={() => props.setSelectedPage(0)}>
/> <View row marginT-20 marginB-35 centerV>
<View row marginL-8> <Ionicons name="chevron-back" size={22} color="#979797"/>
<Text text70>Sundays</Text> <Text text70 color="#979797">
<Text text70 color="gray"> Return to main settings
{" "} </Text>
(default) </View>
</Text> </TouchableOpacity>
</View> <Text text60R>Calendar settings</Text>
</View> <View style={styles.card}>
<View row marginV-5> <Text text70 marginB-14>
<Checkbox Event Color Preference
value={!startDate} </Text>
style={styles.checkbox} <View row spread>
color="#ea156d" <TouchableOpacity onPress={() => setSelectedColor(colorMap.pink)}>
onValueChange={() => setStartDate(false)} <View style={styles.colorBox} backgroundColor={colorMap.pink}>
/> {selectedColor == colorMap.pink && (
<Text text70 marginL-8> <AntDesign name="check" size={30} color="white"/>
Mondays )}
</Text> </View>
</View> </TouchableOpacity>
</View> <TouchableOpacity onPress={() => setSelectedColor(colorMap.orange)}>
<View style={styles.card}> <View style={styles.colorBox} backgroundColor={colorMap.orange}>
<Text text70>Add Calendar</Text> {selectedColor == colorMap.orange && (
<View style={{ marginTop: 20 }}> <AntDesign name="check" size={30} color="white"/>
<Button )}
label={"Connect Google"} </View>
iconSource={() => ( </TouchableOpacity>
<View <TouchableOpacity onPress={() => setSelectedColor(colorMap.green)}>
backgroundColor="#ededed" <View style={styles.colorBox} backgroundColor={colorMap.green}>
width={40} {selectedColor == colorMap.green && (
height={40} <AntDesign name="check" size={30} color="white"/>
style={{ borderRadius: 50 }} )}
marginR-10 </View>
centerV </TouchableOpacity>
centerH <TouchableOpacity onPress={() => setSelectedColor(colorMap.teal)}>
> <View style={styles.colorBox} backgroundColor={colorMap.teal}>
<Ionicons name="logo-google" size={22} color="#979797" /> {selectedColor == colorMap.teal && (
</View> <AntDesign name="check" size={30} color="white"/>
)} )}
backgroundColor="white" </View>
color="#464039" </TouchableOpacity>
borderRadius={15} <TouchableOpacity onPress={() => setSelectedColor(colorMap.purple)}>
onPress={handleGoogleLogin} <View style={styles.colorBox} backgroundColor={colorMap.purple}>
/> {selectedColor == colorMap.purple && (
<Button <AntDesign name="check" size={30} color="white"/>
label={"Connect Microsoft"} )}
iconSource={() => ( </View>
<View </TouchableOpacity>
backgroundColor="#ededed" </View>
width={40}
height={40}
style={{ borderRadius: 50 }}
marginR-10
centerV
centerH
>
<Ionicons name="logo-microsoft" size={22} color="#979797" />
</View> </View>
)} <View style={styles.card}>
backgroundColor="white" <Text text70>Weekly Start Date</Text>
color="#464039" <View row marginV-5 marginT-20>
borderRadius={15} <Checkbox
onPress={handleMicrosoftSignIn} value={startDate}
/> style={styles.checkbox}
</View> color="#ea156d"
</View> onValueChange={() => setStartDate(true)}
<View style={styles.card}> />
<Text text70>Calendars</Text> <View row marginL-8>
<View style={{ marginTop: 20 }}> <Text text70>Sundays</Text>
<Button <Text text70 color="gray">
label={"Sync Outlook"} {" "}
iconSource={() => ( (default)
<View </Text>
backgroundColor="#ededed" </View>
width={40} </View>
height={40} <View row marginV-5>
style={{ borderRadius: 50 }} <Checkbox
marginR-10 value={!startDate}
centerV style={styles.checkbox}
centerH color="#ea156d"
> onValueChange={() => setStartDate(false)}
<Ionicons name="logo-microsoft" size={22} color="#979797" /> />
</View> <Text text70 marginL-8>
)} Mondays
backgroundColor="white" </Text>
color="#464039" </View>
borderRadius={15}
onPress={fetchAndSaveMicrosoftEvents}
/>
{profileData?.googleToken !== undefined && (
<Button
label={"Sync Google"}
iconSource={() => (
<View
backgroundColor="#ededed"
width={40}
height={40}
style={{ borderRadius: 50 }}
marginR-10
centerV
centerH
>
<Ionicons name="logo-google" size={22} color="#979797" />
</View> </View>
)} <View style={styles.card}>
backgroundColor="white" <Text text70>Add Calendar</Text>
color="#464039" <View style={{marginTop: 20}}>
borderRadius={15} <Button
onPress={fetchAndSaveGoogleEvents} label={"Connect Google"}
/> iconSource={() => (
)} <View
</View> backgroundColor="#ededed"
</View> width={40}
</View> height={40}
); style={{borderRadius: 50}}
marginR-10
centerV
centerH
>
<Ionicons name="logo-google" size={22} color="#979797"/>
</View>
)}
backgroundColor="white"
color="#464039"
borderRadius={15}
onPress={handleGoogleLogin}
/>
<Button
label={"Connect Microsoft"}
iconSource={() => (
<View
backgroundColor="#ededed"
width={40}
height={40}
style={{borderRadius: 50}}
marginR-10
centerV
centerH
>
<Ionicons name="logo-microsoft" size={22} color="#979797"/>
</View>
)}
backgroundColor="white"
color="#464039"
borderRadius={15}
onPress={handleMicrosoftSignIn}
/>
</View>
</View>
<View style={styles.card}>
<Text text70>Calendars</Text>
<View style={{marginTop: 20}}>
<Button
label={"Sync Outlook"}
iconSource={() => (
<View
backgroundColor="#ededed"
width={40}
height={40}
style={{borderRadius: 50}}
marginR-10
centerV
centerH
>
<Ionicons name="logo-microsoft" size={22} color="#979797"/>
</View>
)}
backgroundColor="white"
color="#464039"
borderRadius={15}
onPress={fetchAndSaveMicrosoftEvents}
/>
{profileData?.googleToken !== undefined && (
<Button
label={"Sync Google"}
iconSource={() => (
<View
backgroundColor="#ededed"
width={40}
height={40}
style={{borderRadius: 50}}
marginR-10
centerV
centerH
>
<Ionicons name="logo-google" size={22} color="#979797"/>
</View>
)}
backgroundColor="white"
color="#464039"
borderRadius={15}
onPress={fetchAndSaveGoogleEvents}
/>
)}
</View>
</View>
</View>
</ScrollView>
);
}; };
const styles = StyleSheet.create({ const styles = StyleSheet.create({
backBtn: { backBtn: {
backgroundColor: "red", backgroundColor: "red",
marginLeft: -2, marginLeft: -2,
justifyContent: "flex-start", justifyContent: "flex-start",
}, },
card: { card: {
backgroundColor: "white", backgroundColor: "white",
width: "100%", width: "100%",
padding: 20, padding: 20,
paddingBottom: 30, paddingBottom: 30,
marginTop: 20, marginTop: 20,
borderRadius: 20, borderRadius: 20,
}, },
colorBox: { colorBox: {
aspectRatio: 1, aspectRatio: 1,
justifyContent: "center", justifyContent: "center",
alignItems: "center", alignItems: "center",
width: 50, width: 50,
borderRadius: 12, borderRadius: 12,
}, },
checkbox: { checkbox: {
borderRadius: 50, borderRadius: 50,
}, },
}); });
export default CalendarSettingsPage; export default CalendarSettingsPage;

View File

@ -14,8 +14,9 @@ export enum ProfileType {
interface IAuthContext { interface IAuthContext {
user: FirebaseAuthTypes.User | null, user: FirebaseAuthTypes.User | null,
profileType?: ProfileType, profileType?: ProfileType,
profileData?: UserProfile profileData?: UserProfile,
setProfileData: (profileData: UserProfile) => void setProfileData: (profileData: UserProfile) => void,
refreshProfileData: () => Promise<void>
} }
const AuthContext = createContext<IAuthContext>(undefined!) const AuthContext = createContext<IAuthContext>(undefined!)
@ -32,8 +33,14 @@ export const AuthContextProvider: FC<{ children: ReactNode }> = ({children}) =>
const onAuthStateChanged = async (user: FirebaseAuthTypes.User | null) => { const onAuthStateChanged = async (user: FirebaseAuthTypes.User | null) => {
setUser(user); setUser(user);
console.log(user) if (user) {
await refreshProfileData();
}
if (initializing) setInitializing(false);
}
const refreshProfileData = async () => {
if (user) { if (user) {
try { try {
const documentSnapshot = await firestore() const documentSnapshot = await firestore()
@ -42,17 +49,15 @@ export const AuthContextProvider: FC<{ children: ReactNode }> = ({children}) =>
.get(); .get();
if (documentSnapshot.exists) { if (documentSnapshot.exists) {
setProfileType(documentSnapshot.data()?.userType); setProfileType(documentSnapshot.data()?.userType);
setProfileData(documentSnapshot.data() as UserProfile) setProfileData(documentSnapshot.data() as UserProfile);
} }
} catch (error) { } catch (error) {
console.error("Error fetching user profile type:", error); console.error("Error fetching user profile data:", error);
setProfileType(undefined); setProfileType(undefined);
setProfileData(undefined);
} }
} }
};
if (initializing) setInitializing(false);
}
useEffect(() => { useEffect(() => {
const subscriber = auth().onAuthStateChanged(onAuthStateChanged); const subscriber = auth().onAuthStateChanged(onAuthStateChanged);
@ -78,10 +83,10 @@ export const AuthContextProvider: FC<{ children: ReactNode }> = ({children}) =>
} }
return ( return (
<AuthContext.Provider value={{user, profileType, profileData, setProfileData}}> <AuthContext.Provider value={{user, profileType, profileData, setProfileData, refreshProfileData}}>
{children} {children}
</AuthContext.Provider> </AuthContext.Provider>
) )
} }
export const useAuthContext = () => useContext(AuthContext)!; export const useAuthContext = () => useContext(AuthContext)!;

View File

@ -5,26 +5,36 @@ import {UserProfile} from "@/hooks/firebase/types/profileTypes";
import {FirebaseAuthTypes} from "@react-native-firebase/auth"; import {FirebaseAuthTypes} from "@react-native-firebase/auth";
export const useUpdateUserData = () => { export const useUpdateUserData = () => {
const {user: currentUser, setProfileData} = useAuthContext() const {user: currentUser, setProfileData, refreshProfileData} = useAuthContext();
return useMutation({ return useMutation({
mutationKey: ["updateUserData"], mutationKey: ["updateUserData"],
mutationFn: async ({newUserData, customUser}: {newUserData: Partial<UserProfile>, customUser?: FirebaseAuthTypes.User }) => { mutationFn: async ({newUserData, customUser}: {newUserData: Partial<UserProfile>, customUser?: FirebaseAuthTypes.User }) => {
const user = currentUser ?? customUser console.log("Mutation function called with data:", { newUserData, customUser });
const user = currentUser ?? customUser;
if (user) { if (user) {
console.log("Updating user data for UID:", user.uid);
try { try {
console.log("New user data:", newUserData);
await firestore() await firestore()
.collection("Profiles") .collection("Profiles")
.doc(user.uid) .doc(user.uid)
.update(newUserData); .update(newUserData);
const profileData = await firestore().collection("Profiles").doc(user?.uid!).get() console.log("User data updated successfully, fetching updated profile...");
setProfileData(profileData.data() as UserProfile)
await refreshProfileData()
console.log("Profile data updated in context.");
} catch (e) { } catch (e) {
console.error(e) console.error("Error updating user data:", e);
} }
} else {
console.warn("No user found: currentUser and customUser are both undefined.");
} }
} }
}) });
} };

View File

@ -946,6 +946,12 @@ PODS:
- abseil/meta/type_traits - abseil/meta/type_traits
- abseil/xcprivacy - abseil/xcprivacy
- abseil/xcprivacy (1.20240116.2) - abseil/xcprivacy (1.20240116.2)
- AppAuth (1.7.5):
- AppAuth/Core (= 1.7.5)
- AppAuth/ExternalUserAgent (= 1.7.5)
- AppAuth/Core (1.7.5)
- AppAuth/ExternalUserAgent (1.7.5):
- AppAuth/Core
- boost (1.83.0) - boost (1.83.0)
- BoringSSL-GRPC (0.0.32): - BoringSSL-GRPC (0.0.32):
- BoringSSL-GRPC/Implementation (= 0.0.32) - BoringSSL-GRPC/Implementation (= 0.0.32)
@ -956,6 +962,8 @@ PODS:
- BVLinearGradient (2.8.3): - BVLinearGradient (2.8.3):
- React-Core - React-Core
- DoubleConversion (1.1.6) - DoubleConversion (1.1.6)
- EXApplication (5.9.1):
- ExpoModulesCore
- EXBarCodeScanner (13.0.1): - EXBarCodeScanner (13.0.1):
- EXImageLoader - EXImageLoader
- ExpoModulesCore - ExpoModulesCore
@ -1178,18 +1186,26 @@ PODS:
- ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core - ReactCommon/turbomodule/core
- Yoga - Yoga
- ExpoAdapterGoogleSignIn (13.1.0):
- ExpoModulesCore
- GoogleSignIn (~> 7.1)
- React-Core
- ExpoAsset (10.0.10): - ExpoAsset (10.0.10):
- ExpoModulesCore - ExpoModulesCore
- ExpoCamera (15.0.16): - ExpoCamera (15.0.16):
- ExpoModulesCore - ExpoModulesCore
- ZXingObjC/OneD - ZXingObjC/OneD
- ZXingObjC/PDF417 - ZXingObjC/PDF417
- ExpoCrypto (13.0.2):
- ExpoModulesCore
- ExpoFileSystem (17.0.1): - ExpoFileSystem (17.0.1):
- ExpoModulesCore - ExpoModulesCore
- ExpoFont (12.0.10): - ExpoFont (12.0.10):
- ExpoModulesCore - ExpoModulesCore
- ExpoHead (3.5.23): - ExpoHead (3.5.23):
- ExpoModulesCore - ExpoModulesCore
- ExpoImagePicker (15.0.7):
- ExpoModulesCore
- ExpoKeepAwake (13.0.2): - ExpoKeepAwake (13.0.2):
- ExpoModulesCore - ExpoModulesCore
- ExpoModulesCore (1.12.24): - ExpoModulesCore (1.12.24):
@ -1335,6 +1351,10 @@ PODS:
- GoogleUtilities/Environment (~> 7.7) - GoogleUtilities/Environment (~> 7.7)
- nanopb (< 2.30911.0, >= 2.30908.0) - nanopb (< 2.30911.0, >= 2.30908.0)
- PromisesObjC (< 3.0, >= 1.2) - PromisesObjC (< 3.0, >= 1.2)
- GoogleSignIn (7.1.0):
- AppAuth (< 2.0, >= 1.7.3)
- GTMAppAuth (< 5.0, >= 4.1.1)
- GTMSessionFetcher/Core (~> 3.3)
- GoogleUtilities/AppDelegateSwizzler (7.13.3): - GoogleUtilities/AppDelegateSwizzler (7.13.3):
- GoogleUtilities/Environment - GoogleUtilities/Environment
- GoogleUtilities/Logger - GoogleUtilities/Logger
@ -1438,6 +1458,9 @@ PODS:
- gRPC-Core/Privacy (= 1.62.5) - gRPC-Core/Privacy (= 1.62.5)
- gRPC-Core/Interface (1.62.5) - gRPC-Core/Interface (1.62.5)
- gRPC-Core/Privacy (1.62.5) - gRPC-Core/Privacy (1.62.5)
- GTMAppAuth (4.1.1):
- AppAuth/Core (~> 1.7)
- GTMSessionFetcher/Core (< 4.0, >= 3.3)
- GTMSessionFetcher/Core (3.5.0) - GTMSessionFetcher/Core (3.5.0)
- hermes-engine (0.74.3): - hermes-engine (0.74.3):
- hermes-engine/Pre-built (= 0.74.3) - hermes-engine/Pre-built (= 0.74.3)
@ -2379,6 +2402,9 @@ PODS:
- React-Mapbuffer (0.74.3): - React-Mapbuffer (0.74.3):
- glog - glog
- React-debug - React-debug
- react-native-app-auth (8.0.0):
- AppAuth (>= 1.7.3)
- React-Core
- react-native-blur (4.4.0): - react-native-blur (4.4.0):
- DoubleConversion - DoubleConversion
- glog - glog
@ -2678,6 +2704,9 @@ PODS:
- ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core - ReactCommon/turbomodule/core
- Yoga - Yoga
- RNGoogleSignin (13.1.0):
- GoogleSignIn (~> 7.1)
- React-Core
- RNReanimated (3.10.1): - RNReanimated (3.10.1):
- DoubleConversion - DoubleConversion
- glog - glog
@ -2735,6 +2764,7 @@ DEPENDENCIES:
- boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`) - boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`)
- BVLinearGradient (from `../node_modules/react-native-linear-gradient`) - BVLinearGradient (from `../node_modules/react-native-linear-gradient`)
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
- EXApplication (from `../node_modules/expo-application/ios`)
- EXBarCodeScanner (from `../node_modules/expo-barcode-scanner/ios`) - EXBarCodeScanner (from `../node_modules/expo-barcode-scanner/ios`)
- EXConstants (from `../node_modules/expo-constants/ios`) - EXConstants (from `../node_modules/expo-constants/ios`)
- EXImageLoader (from `../node_modules/expo-image-loader/ios`) - EXImageLoader (from `../node_modules/expo-image-loader/ios`)
@ -2745,11 +2775,14 @@ DEPENDENCIES:
- expo-dev-launcher (from `../node_modules/expo-dev-launcher`) - expo-dev-launcher (from `../node_modules/expo-dev-launcher`)
- expo-dev-menu (from `../node_modules/expo-dev-menu`) - expo-dev-menu (from `../node_modules/expo-dev-menu`)
- expo-dev-menu-interface (from `../node_modules/expo-dev-menu-interface/ios`) - expo-dev-menu-interface (from `../node_modules/expo-dev-menu-interface/ios`)
- "ExpoAdapterGoogleSignIn (from `../node_modules/@react-native-google-signin/google-signin/expo/ios`)"
- ExpoAsset (from `../node_modules/expo-asset/ios`) - ExpoAsset (from `../node_modules/expo-asset/ios`)
- ExpoCamera (from `../node_modules/expo-camera/ios`) - ExpoCamera (from `../node_modules/expo-camera/ios`)
- ExpoCrypto (from `../node_modules/expo-crypto/ios`)
- ExpoFileSystem (from `../node_modules/expo-file-system/ios`) - ExpoFileSystem (from `../node_modules/expo-file-system/ios`)
- ExpoFont (from `../node_modules/expo-font/ios`) - ExpoFont (from `../node_modules/expo-font/ios`)
- ExpoHead (from `../node_modules/expo-router/ios`) - ExpoHead (from `../node_modules/expo-router/ios`)
- ExpoImagePicker (from `../node_modules/expo-image-picker/ios`)
- ExpoKeepAwake (from `../node_modules/expo-keep-awake/ios`) - ExpoKeepAwake (from `../node_modules/expo-keep-awake/ios`)
- ExpoModulesCore (from `../node_modules/expo-modules-core`) - ExpoModulesCore (from `../node_modules/expo-modules-core`)
- ExpoSystemUI (from `../node_modules/expo-system-ui/ios`) - ExpoSystemUI (from `../node_modules/expo-system-ui/ios`)
@ -2786,6 +2819,7 @@ DEPENDENCIES:
- React-jsitracing (from `../node_modules/react-native/ReactCommon/hermes/executor/`) - React-jsitracing (from `../node_modules/react-native/ReactCommon/hermes/executor/`)
- React-logger (from `../node_modules/react-native/ReactCommon/logger`) - React-logger (from `../node_modules/react-native/ReactCommon/logger`)
- React-Mapbuffer (from `../node_modules/react-native/ReactCommon`) - React-Mapbuffer (from `../node_modules/react-native/ReactCommon`)
- react-native-app-auth (from `../node_modules/react-native-app-auth`)
- "react-native-blur (from `../node_modules/@react-native-community/blur`)" - "react-native-blur (from `../node_modules/@react-native-community/blur`)"
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`) - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
- React-nativeconfig (from `../node_modules/react-native/ReactCommon`) - React-nativeconfig (from `../node_modules/react-native/ReactCommon`)
@ -2819,6 +2853,7 @@ DEPENDENCIES:
- "RNFBFirestore (from `../node_modules/@react-native-firebase/firestore`)" - "RNFBFirestore (from `../node_modules/@react-native-firebase/firestore`)"
- "RNFBFunctions (from `../node_modules/@react-native-firebase/functions`)" - "RNFBFunctions (from `../node_modules/@react-native-firebase/functions`)"
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`) - RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
- "RNGoogleSignin (from `../node_modules/@react-native-google-signin/google-signin`)"
- RNReanimated (from `../node_modules/react-native-reanimated`) - RNReanimated (from `../node_modules/react-native-reanimated`)
- RNScreens (from `../node_modules/react-native-screens`) - RNScreens (from `../node_modules/react-native-screens`)
- RNSVG (from `../node_modules/react-native-svg`) - RNSVG (from `../node_modules/react-native-svg`)
@ -2827,6 +2862,7 @@ DEPENDENCIES:
SPEC REPOS: SPEC REPOS:
trunk: trunk:
- abseil - abseil
- AppAuth
- BoringSSL-GRPC - BoringSSL-GRPC
- Firebase - Firebase
- FirebaseAppCheckInterop - FirebaseAppCheckInterop
@ -2845,9 +2881,11 @@ SPEC REPOS:
- FirebaseSessions - FirebaseSessions
- FirebaseSharedSwift - FirebaseSharedSwift
- GoogleDataTransport - GoogleDataTransport
- GoogleSignIn
- GoogleUtilities - GoogleUtilities
- "gRPC-C++" - "gRPC-C++"
- gRPC-Core - gRPC-Core
- GTMAppAuth
- GTMSessionFetcher - GTMSessionFetcher
- leveldb-library - leveldb-library
- nanopb - nanopb
@ -2864,6 +2902,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-linear-gradient" :path: "../node_modules/react-native-linear-gradient"
DoubleConversion: DoubleConversion:
:podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec" :podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec"
EXApplication:
:path: "../node_modules/expo-application/ios"
EXBarCodeScanner: EXBarCodeScanner:
:path: "../node_modules/expo-barcode-scanner/ios" :path: "../node_modules/expo-barcode-scanner/ios"
EXConstants: EXConstants:
@ -2884,16 +2924,22 @@ EXTERNAL SOURCES:
:path: "../node_modules/expo-dev-menu" :path: "../node_modules/expo-dev-menu"
expo-dev-menu-interface: expo-dev-menu-interface:
:path: "../node_modules/expo-dev-menu-interface/ios" :path: "../node_modules/expo-dev-menu-interface/ios"
ExpoAdapterGoogleSignIn:
:path: "../node_modules/@react-native-google-signin/google-signin/expo/ios"
ExpoAsset: ExpoAsset:
:path: "../node_modules/expo-asset/ios" :path: "../node_modules/expo-asset/ios"
ExpoCamera: ExpoCamera:
:path: "../node_modules/expo-camera/ios" :path: "../node_modules/expo-camera/ios"
ExpoCrypto:
:path: "../node_modules/expo-crypto/ios"
ExpoFileSystem: ExpoFileSystem:
:path: "../node_modules/expo-file-system/ios" :path: "../node_modules/expo-file-system/ios"
ExpoFont: ExpoFont:
:path: "../node_modules/expo-font/ios" :path: "../node_modules/expo-font/ios"
ExpoHead: ExpoHead:
:path: "../node_modules/expo-router/ios" :path: "../node_modules/expo-router/ios"
ExpoImagePicker:
:path: "../node_modules/expo-image-picker/ios"
ExpoKeepAwake: ExpoKeepAwake:
:path: "../node_modules/expo-keep-awake/ios" :path: "../node_modules/expo-keep-awake/ios"
ExpoModulesCore: ExpoModulesCore:
@ -2963,6 +3009,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/logger" :path: "../node_modules/react-native/ReactCommon/logger"
React-Mapbuffer: React-Mapbuffer:
:path: "../node_modules/react-native/ReactCommon" :path: "../node_modules/react-native/ReactCommon"
react-native-app-auth:
:path: "../node_modules/react-native-app-auth"
react-native-blur: react-native-blur:
:path: "../node_modules/@react-native-community/blur" :path: "../node_modules/@react-native-community/blur"
react-native-safe-area-context: react-native-safe-area-context:
@ -3029,6 +3077,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/@react-native-firebase/functions" :path: "../node_modules/@react-native-firebase/functions"
RNGestureHandler: RNGestureHandler:
:path: "../node_modules/react-native-gesture-handler" :path: "../node_modules/react-native-gesture-handler"
RNGoogleSignin:
:path: "../node_modules/@react-native-google-signin/google-signin"
RNReanimated: RNReanimated:
:path: "../node_modules/react-native-reanimated" :path: "../node_modules/react-native-reanimated"
RNScreens: RNScreens:
@ -3040,10 +3090,12 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS: SPEC CHECKSUMS:
abseil: d121da9ef7e2ff4cab7666e76c5a3e0915ae08c3 abseil: d121da9ef7e2ff4cab7666e76c5a3e0915ae08c3
AppAuth: 501c04eda8a8d11f179dbe8637b7a91bb7e5d2fa
boost: d3f49c53809116a5d38da093a8aa78bf551aed09 boost: d3f49c53809116a5d38da093a8aa78bf551aed09
BoringSSL-GRPC: 1e2348957acdbcad360b80a264a90799984b2ba6 BoringSSL-GRPC: 1e2348957acdbcad360b80a264a90799984b2ba6
BVLinearGradient: 880f91a7854faff2df62518f0281afb1c60d49a3 BVLinearGradient: 880f91a7854faff2df62518f0281afb1c60d49a3
DoubleConversion: 76ab83afb40bddeeee456813d9c04f67f78771b5 DoubleConversion: 76ab83afb40bddeeee456813d9c04f67f78771b5
EXApplication: c08200c34daca7af7fd76ac4b9d606077410e8ad
EXBarCodeScanner: e2dd9b42c1b522a2adc9202b1dfbc64cb34456d1 EXBarCodeScanner: e2dd9b42c1b522a2adc9202b1dfbc64cb34456d1
EXConstants: 409690fbfd5afea964e5e9d6c4eb2c2b59222c59 EXConstants: 409690fbfd5afea964e5e9d6c4eb2c2b59222c59
EXImageLoader: ab589d67d6c5f2c33572afea9917304418566334 EXImageLoader: ab589d67d6c5f2c33572afea9917304418566334
@ -3054,11 +3106,14 @@ SPEC CHECKSUMS:
expo-dev-launcher: fe4f2c0a0aa627449eeaec5f9f11e04090f97c40 expo-dev-launcher: fe4f2c0a0aa627449eeaec5f9f11e04090f97c40
expo-dev-menu: 5b14897ecce3a8cf9e9cf9109344c2c192a3766a expo-dev-menu: 5b14897ecce3a8cf9e9cf9109344c2c192a3766a
expo-dev-menu-interface: be32c09f1e03833050f0ee290dcc86b3ad0e73e4 expo-dev-menu-interface: be32c09f1e03833050f0ee290dcc86b3ad0e73e4
ExpoAdapterGoogleSignIn: da10ae7e7c1d73a10c2facebcdfe5ebea8e073ce
ExpoAsset: 323700f291684f110fb55f0d4022a3362ea9f875 ExpoAsset: 323700f291684f110fb55f0d4022a3362ea9f875
ExpoCamera: 929be541d1c1319fcf32f9f5d9df8b97804346b5 ExpoCamera: 929be541d1c1319fcf32f9f5d9df8b97804346b5
ExpoCrypto: 156078f266bf28f80ecf5e2a9c3a0d6ffce07a1c
ExpoFileSystem: 80bfe850b1f9922c16905822ecbf97acd711dc51 ExpoFileSystem: 80bfe850b1f9922c16905822ecbf97acd711dc51
ExpoFont: 00756e6c796d8f7ee8d211e29c8b619e75cbf238 ExpoFont: 00756e6c796d8f7ee8d211e29c8b619e75cbf238
ExpoHead: fcb28a68ed4ba28f177394d2dfb8a0a8824cd103 ExpoHead: fcb28a68ed4ba28f177394d2dfb8a0a8824cd103
ExpoImagePicker: 12a420923383ae38dccb069847218f27a3b87816
ExpoKeepAwake: 3b8815d9dd1d419ee474df004021c69fdd316d08 ExpoKeepAwake: 3b8815d9dd1d419ee474df004021c69fdd316d08
ExpoModulesCore: db3e31e694684f08223d713e89f7648c6d3e04d0 ExpoModulesCore: db3e31e694684f08223d713e89f7648c6d3e04d0
ExpoSystemUI: d4f065a016cae6721b324eb659cdee4d4cf0cb26 ExpoSystemUI: d4f065a016cae6721b324eb659cdee4d4cf0cb26
@ -3085,9 +3140,11 @@ SPEC CHECKSUMS:
fmt: 4c2741a687cc09f0634a2e2c72a838b99f1ff120 fmt: 4c2741a687cc09f0634a2e2c72a838b99f1ff120
glog: fdfdfe5479092de0c4bdbebedd9056951f092c4f glog: fdfdfe5479092de0c4bdbebedd9056951f092c4f
GoogleDataTransport: 6c09b596d841063d76d4288cc2d2f42cc36e1e2a GoogleDataTransport: 6c09b596d841063d76d4288cc2d2f42cc36e1e2a
GoogleSignIn: d4281ab6cf21542b1cfaff85c191f230b399d2db
GoogleUtilities: ea963c370a38a8069cc5f7ba4ca849a60b6d7d15 GoogleUtilities: ea963c370a38a8069cc5f7ba4ca849a60b6d7d15
"gRPC-C++": e725ef63c4475d7cdb7e2cf16eb0fde84bd9ee51 "gRPC-C++": e725ef63c4475d7cdb7e2cf16eb0fde84bd9ee51
gRPC-Core: eee4be35df218649fe66d721a05a7f27a28f069b gRPC-Core: eee4be35df218649fe66d721a05a7f27a28f069b
GTMAppAuth: f69bd07d68cd3b766125f7e072c45d7340dea0de
GTMSessionFetcher: 5aea5ba6bd522a239e236100971f10cb71b96ab6 GTMSessionFetcher: 5aea5ba6bd522a239e236100971f10cb71b96ab6
hermes-engine: 1f547997900dd0752dc0cc0ae6dd16173c49e09b hermes-engine: 1f547997900dd0752dc0cc0ae6dd16173c49e09b
leveldb-library: e8eadf9008a61f9e1dde3978c086d2b6d9b9dc28 leveldb-library: e8eadf9008a61f9e1dde3978c086d2b6d9b9dc28
@ -3118,6 +3175,7 @@ SPEC CHECKSUMS:
React-jsitracing: 1aa5681c353b41573b03e0e480a5adf5fa1c56d8 React-jsitracing: 1aa5681c353b41573b03e0e480a5adf5fa1c56d8
React-logger: fa92ba4d3a5d39ac450f59be2a3cec7b099f0304 React-logger: fa92ba4d3a5d39ac450f59be2a3cec7b099f0304
React-Mapbuffer: 70da5955150a58732e9336a0c7e71cd49e909f25 React-Mapbuffer: 70da5955150a58732e9336a0c7e71cd49e909f25
react-native-app-auth: c4a3b4edc11100070d8d7bc48d55fb66668cead9
react-native-blur: b58f3155f534d975b7647593d93a2e907513addd react-native-blur: b58f3155f534d975b7647593d93a2e907513addd
react-native-safe-area-context: a240ad4b683349e48b1d51fed1611138d1bdad97 react-native-safe-area-context: a240ad4b683349e48b1d51fed1611138d1bdad97
React-nativeconfig: 84806b820491db30175afbf027e99e8415dc63f0 React-nativeconfig: 84806b820491db30175afbf027e99e8415dc63f0
@ -3152,6 +3210,7 @@ SPEC CHECKSUMS:
RNFBFirestore: e47cdde04ea3d9e73e58e037e1aa1d0b1141c316 RNFBFirestore: e47cdde04ea3d9e73e58e037e1aa1d0b1141c316
RNFBFunctions: 738cc9e2177d060d29b5d143ef2f9ed0eda4bb1f RNFBFunctions: 738cc9e2177d060d29b5d143ef2f9ed0eda4bb1f
RNGestureHandler: 20a4307fd21cbff339abfcfa68192f3f0a6a518b RNGestureHandler: 20a4307fd21cbff339abfcfa68192f3f0a6a518b
RNGoogleSignin: 9e68b9bcc3888219357924e32ee563624745647d
RNReanimated: d51431fd3597a8f8320319dce8e42cee82a5445f RNReanimated: d51431fd3597a8f8320319dce8e42cee82a5445f
RNScreens: 30249f9331c3b00ae7cb7922e11f58b3ed369c07 RNScreens: 30249f9331c3b00ae7cb7922e11f58b3ed369c07
RNSVG: 4590aa95758149fa27c5c83e54a6a466349a1688 RNSVG: 4590aa95758149fa27c5c83e54a6a466349a1688
@ -3161,4 +3220,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: 50f618790da7cbbfd5c5e988b7f9370bd45d34a6 PODFILE CHECKSUM: 50f618790da7cbbfd5c5e988b7f9370bd45d34a6
COCOAPODS: 1.14.3 COCOAPODS: 1.15.2

View File

@ -293,7 +293,9 @@
); );
inputPaths = ( inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-cally/Pods-cally-resources.sh", "${PODS_ROOT}/Target Support Files/Pods-cally/Pods-cally-resources.sh",
"${PODS_CONFIGURATION_BUILD_DIR}/AppAuth/AppAuthCore_Privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/BoringSSL-GRPC/openssl_grpc.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/BoringSSL-GRPC/openssl_grpc.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/EXApplication/ExpoApplication_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/EXConstants/EXConstants.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/EXConstants/EXConstants.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/EXConstants/ExpoConstants_privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/EXConstants/ExpoConstants_privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/ExpoFileSystem/ExpoFileSystem_privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/ExpoFileSystem/ExpoFileSystem_privacy.bundle",
@ -306,8 +308,10 @@
"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseFirestore/FirebaseFirestore_Privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseFirestore/FirebaseFirestore_Privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseFirestoreInternal/FirebaseFirestoreInternal_Privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseFirestoreInternal/FirebaseFirestoreInternal_Privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations/FirebaseInstallations_Privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations/FirebaseInstallations_Privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/GTMAppAuth/GTMAppAuth_Privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/GTMSessionFetcher/GTMSessionFetcher_Core_Privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/GTMSessionFetcher/GTMSessionFetcher_Core_Privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport/GoogleDataTransport_Privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport/GoogleDataTransport_Privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/GoogleSignIn/GoogleSignIn.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities/GoogleUtilities_Privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities/GoogleUtilities_Privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC/FBLPromises_Privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC/FBLPromises_Privacy.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/PromisesSwift/Promises_Privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/PromisesSwift/Promises_Privacy.bundle",
@ -322,7 +326,9 @@
); );
name = "[CP] Copy Pods Resources"; name = "[CP] Copy Pods Resources";
outputPaths = ( outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AppAuthCore_Privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/openssl_grpc.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/openssl_grpc.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoApplication_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EXConstants.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EXConstants.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoConstants_privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoConstants_privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoFileSystem_privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoFileSystem_privacy.bundle",
@ -335,8 +341,10 @@
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseFirestore_Privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseFirestore_Privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseFirestoreInternal_Privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseFirestoreInternal_Privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseInstallations_Privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseInstallations_Privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GTMAppAuth_Privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GTMSessionFetcher_Core_Privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GTMSessionFetcher_Core_Privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleDataTransport_Privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleDataTransport_Privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleSignIn.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleUtilities_Privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleUtilities_Privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FBLPromises_Privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FBLPromises_Privacy.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Promises_Privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Promises_Privacy.bundle",
@ -429,7 +437,7 @@
); );
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG"; OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
PRODUCT_BUNDLE_IDENTIFIER = com.cally.app; PRODUCT_BUNDLE_IDENTIFIER = com.cally.app;
PRODUCT_NAME = "KaliFamilyPlanner"; PRODUCT_NAME = KaliFamilyPlanner;
SWIFT_OBJC_BRIDGING_HEADER = "cally/cally-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "cally/cally-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
@ -460,7 +468,7 @@
); );
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE"; OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
PRODUCT_BUNDLE_IDENTIFIER = com.cally.app; PRODUCT_BUNDLE_IDENTIFIER = com.cally.app;
PRODUCT_NAME = "KaliFamilyPlanner"; PRODUCT_NAME = KaliFamilyPlanner;
SWIFT_OBJC_BRIDGING_HEADER = "cally/cally-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "cally/cally-Bridging-Header.h";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";

View File

@ -4,6 +4,7 @@
#import <React/RCTBundleURLProvider.h> #import <React/RCTBundleURLProvider.h>
#import <React/RCTLinkingManager.h> #import <React/RCTLinkingManager.h>
#import "RNAppAuthAuthorizationFlowManager.h"
@implementation AppDelegate @implementation AppDelegate

View File

@ -27,7 +27,7 @@
<dict> <dict>
<key>CFBundleURLSchemes</key> <key>CFBundleURLSchemes</key>
<array> <array>
<string>myapp</string> <string>callyplanner</string>
<string>com.cally.app</string> <string>com.cally.app</string>
</array> </array>
</dict> </dict>
@ -75,6 +75,8 @@
<string>$(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route</string> <string>$(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route</string>
<string>$(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route</string> <string>$(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route</string>
<string>$(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route</string> <string>$(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route</string>
<string>$(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route</string>
<string>$(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route</string>
</array> </array>
<key>UILaunchStoryboardName</key> <key>UILaunchStoryboardName</key>
<string>SplashScreen</string> <string>SplashScreen</string>

View File

@ -40,6 +40,7 @@
"@react-navigation/native": "^6.0.2", "@react-navigation/native": "^6.0.2",
"date-fns": "^3.6.0", "date-fns": "^3.6.0",
"expo": "~51.0.24", "expo": "~51.0.24",
"expo-auth-session": "^5.5.2",
"expo-barcode-scanner": "~13.0.1", "expo-barcode-scanner": "~13.0.1",
"expo-build-properties": "~0.12.4", "expo-build-properties": "~0.12.4",
"expo-camera": "~15.0.16", "expo-camera": "~15.0.16",

1373
yarn.lock

File diff suppressed because it is too large Load Diff