Merge remote-tracking branch 'origin/dev' into dev

# Conflicts:
#	components/pages/settings/CalendarSettingsPage.tsx
This commit is contained in:
Milan Paunovic
2024-11-01 03:20:51 +01:00
4 changed files with 306 additions and 200 deletions

View File

@ -74,7 +74,7 @@ const GroceryList = ({onInputFocus}: {onInputFocus: (y: number) => void}) => {
}, [groceries]); }, [groceries]);
return ( return (
<View marginH-20 marginB-20> <View marginH-20 marginB-45>
<HeaderTemplate <HeaderTemplate
message={"Welcome to your grocery list"} message={"Welcome to your grocery list"}
isWelcome={false} isWelcome={false}

View File

@ -16,6 +16,7 @@ import {settingsPageIndex} from "../calendar/atoms";
import CalendarSettingsDialog from "./calendar_components/CalendarSettingsDialog"; import CalendarSettingsDialog from "./calendar_components/CalendarSettingsDialog";
import {useClearTokens} from "@/hooks/firebase/useClearTokens"; import {useClearTokens} from "@/hooks/firebase/useClearTokens";
import {useCalSync} from "@/hooks/useCalSync"; import {useCalSync} from "@/hooks/useCalSync";
import Feather from "@expo/vector-icons/Feather";
const CalendarSettingsPage = () => { const CalendarSettingsPage = () => {
@ -234,34 +235,6 @@ const CalendarSettingsPage = () => {
color="black" color="black"
text70BL text70BL
/> />
{profileData?.googleAccounts
? Object.keys(profileData?.googleAccounts)?.map((googleMail) => {
const googleToken = profileData?.googleAccounts?.[googleMail]?.accessToken;
return (
googleToken && (
<Button
key={googleMail}
onPress={() => {
showConfirmationDialog("google", googleMail);
}}
label={`Disconnect ${googleMail}`}
labelStyle={styles.addCalLbl}
labelProps={{
numberOfLines: 2,
}}
iconSource={() => (
<View marginR-15>
<GoogleIcon/>
</View>
)}
style={styles.addCalBtn}
color="black"
text70BL
/>
)
);
})
: null}
{!profileData?.appleAccounts && ( {!profileData?.appleAccounts && (
<Button <Button
@ -282,33 +255,6 @@ const CalendarSettingsPage = () => {
/> />
)} )}
{profileData?.appleAccounts
? Object.keys(profileData?.appleAccounts)?.map((appleEmail) => {
const appleToken = profileData?.appleAccounts?.[appleEmail!];
return (
appleToken && (
<Button
key={appleEmail}
onPress={() => showConfirmationDialog("apple", appleEmail)}
label={`Disconnect Apple`}
labelStyle={styles.addCalLbl}
labelProps={{
numberOfLines: 2,
}}
iconSource={() => (
<View marginR-15>
<AppleIcon/>
</View>
)}
style={styles.addCalBtn}
color="black"
text70BL
/>
)
);
})
: null}
<Button <Button
onPress={() => handleMicrosoftSignIn()} onPress={() => handleMicrosoftSignIn()}
label={profileData?.microsoftAccounts ? "Connect another Outlook account" : "Connect Outlook"} label={profileData?.microsoftAccounts ? "Connect another Outlook account" : "Connect Outlook"}
@ -325,37 +271,6 @@ const CalendarSettingsPage = () => {
color="black" color="black"
text70BL text70BL
/> />
{profileData?.microsoftAccounts
? Object.keys(profileData?.microsoftAccounts)?.map(
(microsoftEmail) => {
const microsoftToken =
profileData?.microsoftAccounts?.[microsoftEmail];
return (
microsoftToken && (
<Button
key={microsoftEmail}
onPress={() => {
showConfirmationDialog("outlook", microsoftEmail);
}}
label={`Disconnect ${microsoftEmail}`}
labelStyle={styles.addCalLbl}
labelProps={{
numberOfLines: 2,
}}
iconSource={() => (
<View marginR-15>
<OutlookIcon/>
</View>
)}
style={styles.addCalBtn}
color="black"
text70BL
/>
)
);
}
)
: null}
{(isConnectedToGoogle || {(isConnectedToGoogle ||
isConnectedToMicrosoft || isConnectedToMicrosoft ||
@ -371,50 +286,62 @@ const CalendarSettingsPage = () => {
Object.keys(profileData?.googleAccounts)?.map( Object.keys(profileData?.googleAccounts)?.map(
(googleEmail) => { (googleEmail) => {
const googleToken = const googleToken =
profileData?.googleAccounts?.[googleEmail]; profileData?.googleAccounts?.[googleEmail]?.accessToken;
return ( return (
googleToken && ( googleToken && (
<TouchableOpacity <View row paddingR-5 center>
onPress={() => <View
fetchAndSaveGoogleEvents({ style={{
token: googleToken, backgroundColor: "#ffffff",
email: googleEmail, marginBottom: 15,
}) paddingLeft: 15,
} }}
> color="black"
<View row paddingR-20 center> text70BL
<Button row
disabled={isSyncingGoogle} centerV
onPress={() => width="100%"
fetchAndSaveGoogleEvents({ spread
token: googleToken, >
email: googleEmail,
})
}
label={`Sync ${googleEmail}`}
labelStyle={styles.addCalLbl}
labelProps={{numberOfLines: 3}}
iconSource={() => (
<View marginR-15>
<GoogleIcon/>
</View>
)}
style={styles.addCalBtn}
color="black"
text70BL
/>
{isSyncingGoogle ? ( {isSyncingGoogle ? (
<ActivityIndicator/> <View marginR-5>
<ActivityIndicator/>
</View>
) : ( ) : (
<Ionicons <View marginR-5>
name={"refresh"} <Button
size={20} style={{backgroundColor: "#ffffff"}}
color={"#000000"} color="black"
/> onPress={() =>
fetchAndSaveGoogleEvents({
token: googleToken,
email: googleEmail,
})
}
iconSource={() => <Ionicons
name={"refresh"}
size={20}
color={"#000000"}
/>}
/>
</View>
)} )}
<View marginR-5>
<GoogleIcon/>
</View>
<Text style={styles.addCalLbl}>
{googleEmail}
</Text>
<Button
style={{backgroundColor: "#ffffff", marginRight: 5}}
color="black"
onPress={
() => showConfirmationDialog("google", googleEmail)
}
iconSource={() => <Feather name="x" size={24} />}
/>
</View> </View>
</TouchableOpacity> </View>
) )
); );
} }
@ -427,46 +354,57 @@ const CalendarSettingsPage = () => {
const appleToken = profileData?.appleAccounts?.[appleEmail]; const appleToken = profileData?.appleAccounts?.[appleEmail];
return ( return (
appleToken && ( appleToken && (
<TouchableOpacity <View row paddingR-5 center>
onPress={() => <View
fetchAndSaveAppleEvents({ style={{
email: appleEmail, backgroundColor: "#ffffff",
token: appleToken, marginBottom: 15,
}) paddingLeft: 15,
} }}
> color="black"
<View row paddingR-20 center> text70BL
<Button row
disabled={isSyncingApple} centerV
onPress={() => width="100%"
fetchAndSaveAppleEvents({ spread
email: appleEmail, >
token: appleToken, <View marginR-5>
}) <AppleIcon/>
} </View>
label={isSyncingApple ? "Syncing Events from the Apple calendar..." : `Sync Apple`} <Text style={styles.addCalLbl}>
labelStyle={styles.addCalLbl} {appleEmail}
labelProps={{numberOfLines: 3}} </Text>
iconSource={() => (
<View marginR-15>
<AppleIcon/>
</View>
)}
style={styles.addCalBtn}
color="black"
text70BL
/>
{isSyncingApple ? ( {isSyncingApple ? (
<ActivityIndicator/> <View marginR-5>
<ActivityIndicator/>
</View>
) : ( ) : (
<Ionicons <View marginR-5>
name={"refresh"} <Button
size={20} style={{backgroundColor: "#ffffff"}}
color={"#000000"} color="black"
/> onPress={() =>
fetchAndSaveAppleEvents({
email: appleEmail,
token: appleToken,
})
}
iconSource={() => <Ionicons
name={"refresh"}
size={20}
color={"#000000"}
/>}
/>
</View>
)} )}
<Button
style={{backgroundColor: "#ffffff", marginRight: 5}}
color="black"
onPress={() => showConfirmationDialog("apple", appleEmail)}
iconSource={() => <Feather name="x" size={24} />}
/>
</View> </View>
</TouchableOpacity> </View>
) )
); );
})} })}
@ -478,46 +416,59 @@ const CalendarSettingsPage = () => {
profileData?.microsoftAccounts?.[microsoftEmail]; profileData?.microsoftAccounts?.[microsoftEmail];
return ( return (
microsoftToken && ( microsoftToken && (
<TouchableOpacity <View row paddingR-5 center>
onPress={() => <View
fetchAndSaveOutlookEvents({ style={{
token: microsoftToken, backgroundColor: "#ffffff",
email: microsoftEmail, marginBottom: 15,
}) paddingLeft: 15,
} }}
> color="black"
<View row paddingR-20 center> text70BL
<Button row
disabled={isSyncingOutlook} centerV
onPress={() => width="100%"
fetchAndSaveOutlookEvents({ spread
token: microsoftToken, >
email: microsoftEmail,
})
}
label={`Sync ${microsoftEmail}`}
labelStyle={styles.addCalLbl}
labelProps={{numberOfLines: 3}}
iconSource={() => (
<View marginR-15>
<OutlookIcon/>
</View>
)}
style={styles.addCalBtn}
color="black"
text70BL
/>
{isSyncingOutlook ? ( {isSyncingOutlook ? (
<ActivityIndicator/> <View marginR-5>
<ActivityIndicator/>
</View>
) : ( ) : (
<Ionicons <View marginR-5>
name={"refresh"} <Button
size={20} style={{backgroundColor: "#ffffff"}}
color={"#000000"} color="black"
/> onPress={() =>
fetchAndSaveOutlookEvents({
token: microsoftToken,
email: microsoftEmail,
})
}
iconSource={() => <Ionicons
name={"refresh"}
size={20}
color={"#000000"}
/>}
/>
</View>
)} )}
<View marginR-5>
<OutlookIcon/>
</View>
<Text style={styles.addCalLbl}>
{microsoftEmail}
</Text>
<Button
style={{backgroundColor: "#ffffff", marginRight: 5}}
color="black"
onPress={
() => showConfirmationDialog("outlook", microsoftEmail)
}
iconSource={() => <Feather name="x" size={24} />}
/>
</View> </View>
</TouchableOpacity> </View>
) )
); );
} }
@ -578,10 +529,10 @@ const styles = StyleSheet.create({
fontSize: 16, fontSize: 16,
fontFamily: "PlusJakartaSan_500Medium", fontFamily: "PlusJakartaSan_500Medium",
flexWrap: "wrap", flexWrap: "wrap",
width: "75%", width: "70%",
textAlign: "left", textAlign: "left",
lineHeight: 20, lineHeight: 20,
overflow: "visible", overflow: "hidden",
}, },
subTitle: { subTitle: {
fontFamily: "Manrope_600SemiBold", fontFamily: "Manrope_600SemiBold",

View File

@ -0,0 +1,128 @@
import React, { useState } from "react";
import { Dialog, Button, Text, View } from "react-native-ui-lib";
import { StyleSheet } from "react-native";
import { Feather } from "@expo/vector-icons";
interface ConfirmationDialogProps {
visible: boolean;
onDismiss: () => void;
onFirstYes: () => void;
onConfirm: () => void;
}
const DeleteProfileDialogs: React.FC<ConfirmationDialogProps> = ({
visible,
onDismiss,
onFirstYes,
onConfirm,
}) => {
const [confirmationDialog, setConfirmationDialog] = useState<boolean>(false);
return (
<>
<Dialog
visible={visible}
onDismiss={onDismiss}
containerStyle={styles.dialog}
>
<View centerH>
<Feather name="alert-triangle" size={70} color="#FF5449" />
</View>
<Text center style={styles.title}>
Are you sure?
</Text>
<Text
style={{
fontSize: 18,
fontFamily: "PlusJakartaSans_700Bold",
color: "#979797",
marginBottom: 20,
}}
center
>
This action will permanently delete all your data, you won't be able
to recover it!
</Text>
<View centerV></View>
<View row right gap-8>
<Button
label="Cancel"
onPress={onDismiss}
style={styles.cancelBtn}
color="#999999"
labelStyle={{ fontFamily: "Poppins_500Medium", fontSize: 13.53 }}
/>
<Button
label="Yes"
onPress={() => {
setTimeout(() => setConfirmationDialog(true), 300);
onFirstYes();
}}
style={styles.confirmBtn}
labelStyle={{ fontFamily: "PlusJakartaSans_500Medium" }}
/>
</View>
</Dialog>
<Dialog
visible={confirmationDialog}
onDismiss={() => setConfirmationDialog(false)}
containerStyle={styles.dialog}
>
<View center paddingH-10 paddingT-15 paddingB-5>
<Text style={styles.title}>
We're sorry to see you go, are you really sure you want to delete
everything?
</Text>
<View row right gap-8 marginT-15>
<Button
label="Cancel"
onPress={() => {
setConfirmationDialog(false);
}}
style={styles.cancelBtn}
color="#999999"
labelStyle={{ fontFamily: "Poppins_500Medium", fontSize: 13.53 }}
/>
<Button
label="Yes"
onPress={() => {
onConfirm();
setConfirmationDialog(false);
}}
style={styles.confirmBtn}
labelStyle={{ fontFamily: "PlusJakartaSans_500Medium" }}
/>
</View>
</View>
</Dialog>
</>
);
};
// Empty stylesheet for future styles
const styles = StyleSheet.create({
confirmBtn: {
backgroundColor: "#FF5449",
},
cancelBtn: {
backgroundColor: "white",
},
dialog: {
backgroundColor: "white",
paddingHorizontal: 25,
paddingTop: 25,
paddingBottom: 17,
borderRadius: 20,
},
title: {
fontFamily: "Manrope_600SemiBold",
fontSize: 22,
marginBottom: 5,
},
text: {
fontFamily: "PlusJakartaSans_400Regular",
fontSize: 16,
marginBottom: 0,
},
});
export default DeleteProfileDialogs;

View File

@ -3,6 +3,7 @@ import { StyleSheet, TouchableOpacity } from "react-native";
import { ScrollView } from "react-native-gesture-handler"; import { ScrollView } from "react-native-gesture-handler";
import * as ImagePicker from "expo-image-picker"; import * as ImagePicker from "expo-image-picker";
import { import {
Button,
Colors, Colors,
Image, Image,
Picker, Picker,
@ -18,6 +19,7 @@ import { useAuthContext } from "@/contexts/AuthContext";
import { useUpdateUserData } from "@/hooks/firebase/useUpdateUserData"; import { useUpdateUserData } from "@/hooks/firebase/useUpdateUserData";
import { useChangeProfilePicture } from "@/hooks/firebase/useChangeProfilePicture"; import { useChangeProfilePicture } from "@/hooks/firebase/useChangeProfilePicture";
import { colorMap } from "@/constants/colorMap"; import { colorMap } from "@/constants/colorMap";
import DeleteProfileDialogs from "../user_components/DeleteProfileDialogs";
const MyProfile = () => { const MyProfile = () => {
const { user, profileData } = useAuthContext(); const { user, profileData } = useAuthContext();
@ -32,6 +34,15 @@ const MyProfile = () => {
string | ImagePicker.ImagePickerAsset | null string | ImagePicker.ImagePickerAsset | null
>(profileData?.pfp || null); >(profileData?.pfp || null);
const [showDeleteDialog, setShowDeleteDialog] = useState<boolean>(false);
const handleHideDeleteDialog = () => {
setShowDeleteDialog(false);
};
const handleShowDeleteDialog = () => {
setShowDeleteDialog(true);
};
const { mutateAsync: updateUserData } = useUpdateUserData(); const { mutateAsync: updateUserData } = useUpdateUserData();
const { mutateAsync: changeProfilePicture } = useChangeProfilePicture(); const { mutateAsync: changeProfilePicture } = useChangeProfilePicture();
const isFirstRender = useRef(true); const isFirstRender = useRef(true);
@ -93,7 +104,7 @@ const MyProfile = () => {
: profileImage; : profileImage;
return ( return (
<ScrollView style={{ paddingBottom: 100, flex: 1 }}> <ScrollView style={{ paddingBottom: 20, flex: 1 }}>
<View style={styles.card}> <View style={styles.card}>
<Text style={styles.subTit}>Your Profile</Text> <Text style={styles.subTit}>Your Profile</Text>
<View row spread paddingH-15 centerV marginV-15> <View row spread paddingH-15 centerV marginV-15>
@ -205,6 +216,22 @@ const MyProfile = () => {
</Picker> </Picker>
</View> </View>
</View> </View>
<Button
size="large"
backgroundColor="#FF5449"
label="Delete Profile"
style={{ marginTop: 10 }}
labelStyle={{ fontFamily: "PlusJakartaSans_500Medium", fontSize: 15 }}
onPress={handleShowDeleteDialog}
/>
<DeleteProfileDialogs
onFirstYes={() => {
setShowDeleteDialog(false);
}}
visible={showDeleteDialog}
onDismiss={handleHideDeleteDialog}
onConfirm={() => {console.log('delete account here')}}
/>
</ScrollView> </ScrollView>
); );
}; };