Add event deletion

This commit is contained in:
Milan Paunovic
2024-10-31 12:01:01 +01:00
parent fff113de65
commit 1b6a241bbe
2 changed files with 670 additions and 615 deletions

View File

@ -14,40 +14,36 @@ import {
TouchableOpacity, TouchableOpacity,
View, View,
} from "react-native-ui-lib"; } from "react-native-ui-lib";
import { ScrollView } from "react-native-gesture-handler"; import {ScrollView} from "react-native-gesture-handler";
import { useSafeAreaInsets } from "react-native-safe-area-context"; import {useSafeAreaInsets} from "react-native-safe-area-context";
import { useEffect, useRef, useState } from "react"; import {useEffect, useRef, useState} from "react";
import { AntDesign, Feather, Ionicons } from "@expo/vector-icons"; import {AntDesign, Feather, Ionicons} from "@expo/vector-icons";
import { PickerMultiValue } from "react-native-ui-lib/src/components/picker/types"; import {PickerMultiValue} from "react-native-ui-lib/src/components/picker/types";
import { useCreateEvent } from "@/hooks/firebase/useCreateEvent"; import {useCreateEvent} from "@/hooks/firebase/useCreateEvent";
import { EventData } from "@/hooks/firebase/types/eventData"; import {EventData} from "@/hooks/firebase/types/eventData";
import { addHours } from "date-fns"; import {addHours} from "date-fns";
import DropModalIcon from "@/assets/svgs/DropModalIcon"; import DropModalIcon from "@/assets/svgs/DropModalIcon";
import { StyleSheet } from "react-native"; import {StyleSheet} from "react-native";
import ClockIcon from "@/assets/svgs/ClockIcon"; import ClockIcon from "@/assets/svgs/ClockIcon";
import LockIcon from "@/assets/svgs/LockIcon"; import LockIcon from "@/assets/svgs/LockIcon";
import MenuIcon from "@/assets/svgs/MenuIcon"; import MenuIcon from "@/assets/svgs/MenuIcon";
import CameraIcon from "@/assets/svgs/CameraIcon"; import CameraIcon from "@/assets/svgs/CameraIcon";
import AssigneesDisplay from "@/components/shared/AssigneesDisplay"; import AssigneesDisplay from "@/components/shared/AssigneesDisplay";
import { useAtom } from "jotai"; import {useAtom} from "jotai";
import { import {eventForEditAtom, selectedNewEventDateAtom,} from "@/components/pages/calendar/atoms";
eventForEditAtom, import {useGetFamilyMembers} from "@/hooks/firebase/useGetFamilyMembers";
selectedNewEventDateAtom,
} from "@/components/pages/calendar/atoms";
import { useGetFamilyMembers } from "@/hooks/firebase/useGetFamilyMembers";
import BinIcon from "@/assets/svgs/BinIcon"; import BinIcon from "@/assets/svgs/BinIcon";
import CloseXIcon from "@/assets/svgs/CloseXIcon";
import PenIcon from "@/assets/svgs/PenIcon";
import DeleteEventDialog from "./DeleteEventDialog"; import DeleteEventDialog from "./DeleteEventDialog";
import {useDeleteEvent} from "@/hooks/firebase/useDeleteEvent";
const daysOfWeek = [ const daysOfWeek = [
{ label: "Monday", value: "monday" }, {label: "Monday", value: "monday"},
{ label: "Tuesday", value: "tuesday" }, {label: "Tuesday", value: "tuesday"},
{ label: "Wednesday", value: "wednesday" }, {label: "Wednesday", value: "wednesday"},
{ label: "Thursday", value: "thursday" }, {label: "Thursday", value: "thursday"},
{ label: "Friday", value: "friday" }, {label: "Friday", value: "friday"},
{ label: "Saturday", value: "saturday" }, {label: "Saturday", value: "saturday"},
{ label: "Sunday", value: "sunday" }, {label: "Sunday", value: "sunday"},
]; ];
export const ManuallyAddEventModal = () => { export const ManuallyAddEventModal = () => {
@ -58,20 +54,12 @@ export const ManuallyAddEventModal = () => {
); );
const [editEvent, setEditEvent] = useAtom(eventForEditAtom); const [editEvent, setEditEvent] = useAtom(eventForEditAtom);
const [deleteModalVisible, setDeleteModalVisible] = useState<boolean>(false); const [deleteModalVisible, setDeleteModalVisible] = useState<boolean>(false);
const {mutateAsync: deleteEvent, isLoading: isDeleting} = useDeleteEvent()
const showDeleteEventModal = () => { const {show, close, initialDate} = {
setDeleteModalVisible(true);
};
const handleDeleteEvent = () => {};
const hideDeleteEventModal = () => {
setDeleteModalVisible(false);
};
const { show, close, initialDate } = {
show: !!selectedNewEventDate || !!editEvent, show: !!selectedNewEventDate || !!editEvent,
close: () => { close: () => {
setDeleteModalVisible(false);
setSelectedNewEndDate(undefined); setSelectedNewEndDate(undefined);
setEditEvent(undefined); setEditEvent(undefined);
}, },
@ -113,8 +101,10 @@ export const ManuallyAddEventModal = () => {
); );
const [repeatInterval, setRepeatInterval] = useState<PickerMultiValue>([]); const [repeatInterval, setRepeatInterval] = useState<PickerMultiValue>([]);
const { mutateAsync: createEvent, isLoading, isError } = useCreateEvent(); const {mutateAsync: createEvent, isLoading: isAdding, isError} = useCreateEvent();
const { data: members } = useGetFamilyMembers(true); const {data: members} = useGetFamilyMembers(true);
const isLoading = isDeleting || isAdding
useEffect(() => { useEffect(() => {
setTitle(editEvent?.title || ""); setTitle(editEvent?.title || "");
@ -156,6 +146,19 @@ export const ManuallyAddEventModal = () => {
}); });
}; };
const showDeleteEventModal = () => {
setDeleteModalVisible(true);
};
const handleDeleteEvent = async () => {
await deleteEvent({eventId: `${editEvent?.id}`})
close()
};
const hideDeleteEventModal = () => {
setDeleteModalVisible(false);
};
const combineDateAndTime = (date: Date, time: Date): Date => { const combineDateAndTime = (date: Date, time: Date): Date => {
const combined = new Date(date); const combined = new Date(date);
combined.setHours(time.getHours()); combined.setHours(time.getHours());
@ -234,7 +237,7 @@ export const ManuallyAddEventModal = () => {
onRequestClose={close} onRequestClose={close}
transparent={false} transparent={false}
> >
<LoaderScreen message={"Saving event..."} color={Colors.grey40} /> <LoaderScreen message={isDeleting ? "Deleting event..." : "Saving event..."} color={Colors.grey40}/>
</Modal> </Modal>
); );
} }
@ -256,39 +259,39 @@ export const ManuallyAddEventModal = () => {
paddingRight: insets.right, // Safe area inset for right paddingRight: insets.right, // Safe area inset for right
}} }}
> >
{editEvent ? ( {/*{editEvent ? (*/}
<> {/* <>*/}
<View center paddingT-8> {/* <View center paddingT-8>*/}
<TouchableOpacity onPress={close}> {/* <TouchableOpacity onPress={close}>*/}
<DropModalIcon /> {/* <DropModalIcon />*/}
</TouchableOpacity> {/* </TouchableOpacity>*/}
</View> {/* </View>*/}
<View row spread paddingH-10 paddingB-15> {/* <View row spread paddingH-10 paddingB-15>*/}
<Button {/* <Button*/}
color="#05a8b6" {/* color="#05a8b6"*/}
style={styles.topBtn} {/* style={styles.topBtn}*/}
iconSource={() => <CloseXIcon />} {/* iconSource={() => <CloseXIcon />}*/}
onPress={close} {/* onPress={close}*/}
/> {/* />*/}
<View row> {/* <View row>*/}
<Button {/* <Button*/}
style={styles.topBtn} {/* style={styles.topBtn}*/}
marginR-10 {/* marginR-10*/}
iconSource={() => <PenIcon />} {/* iconSource={() => <PenIcon />}*/}
onPress={handleSave} {/* onPress={handleSave}*/}
/> {/* />*/}
<Button {/* <Button*/}
style={styles.topBtn} {/* style={styles.topBtn}*/}
marginL-5 {/* marginL-5*/}
iconSource={() => <BinIcon />} {/* iconSource={() => <BinIcon />}*/}
onPress={() => { {/* onPress={() => {*/}
showDeleteEventModal(); {/* showDeleteEventModal();*/}
}} {/* }}*/}
/> {/* />*/}
</View> {/* </View>*/}
</View> {/* </View>*/}
</> {/* </>*/}
) : ( {/*) : (*/}
<View <View
style={{ style={{
flexDirection: "row", flexDirection: "row",
@ -308,7 +311,10 @@ export const ManuallyAddEventModal = () => {
Cancel Cancel
</Text> </Text>
</TouchableOpacity> </TouchableOpacity>
<DropModalIcon onPress={close} /> <View row center>
<DropModalIcon onPress={close}/>
</View>
<View flexS row gap-10>
<TouchableOpacity onPress={handleSave}> <TouchableOpacity onPress={handleSave}>
<Text <Text
style={{ style={{
@ -321,9 +327,19 @@ export const ManuallyAddEventModal = () => {
Save Save
</Text> </Text>
</TouchableOpacity> </TouchableOpacity>
</View> {editEvent && (
<Button
style={styles.topBtn}
marginL-5
iconSource={() => <BinIcon/>}
onPress={showDeleteEventModal}
/>
)} )}
<ScrollView style={{ minHeight: "85%" }}> </View>
</View>
{/*)}*/}
<ScrollView style={{minHeight: "85%"}}>
<TextField <TextField
placeholder="Add event title" placeholder="Add event title"
value={title} value={title}
@ -332,16 +348,16 @@ export const ManuallyAddEventModal = () => {
setTitle(text); setTitle(text);
}} }}
placeholderTextColor="#2d2d30" placeholderTextColor="#2d2d30"
style={{ fontFamily: "Manrope_500Medium", fontSize: 22 }} style={{fontFamily: "Manrope_500Medium", fontSize: 22}}
paddingT-15 paddingT-15
paddingL-30 paddingL-30
returnKeyType="next" returnKeyType="next"
/> />
<View style={styles.divider} marginT-8 /> <View style={styles.divider} marginT-8/>
<View marginL-30 centerV> <View marginL-30 centerV>
<View row spread marginB-10 centerV> <View row spread marginB-10 centerV>
<View row> <View row>
<AntDesign name="clockcircleo" size={24} color="#919191" /> <AntDesign name="clockcircleo" size={24} color="#919191"/>
<Text <Text
style={{ style={{
fontFamily: "PlusJakartaSans_500Medium", fontFamily: "PlusJakartaSans_500Medium",
@ -364,7 +380,7 @@ export const ManuallyAddEventModal = () => {
</View> </View>
<View row marginB-10 spread> <View row marginB-10 spread>
<View row centerV> <View row centerV>
<Feather name="calendar" size={25} color="#919191" /> <Feather name="calendar" size={25} color="#919191"/>
<DateTimePicker <DateTimePicker
value={startDate} value={startDate}
onChange={(date) => { onChange={(date) => {
@ -404,7 +420,7 @@ export const ManuallyAddEventModal = () => {
{!isAllDay && ( {!isAllDay && (
<View row marginB-10 spread> <View row marginB-10 spread>
<View row centerV> <View row centerV>
<Feather name="calendar" size={25} color="#919191" /> <Feather name="calendar" size={25} color="#919191"/>
<DateTimePicker <DateTimePicker
value={endDate} value={endDate}
minimumDate={startDate} minimumDate={startDate}
@ -445,30 +461,30 @@ export const ManuallyAddEventModal = () => {
)} )}
</View> </View>
<View style={styles.divider} /> <View style={styles.divider}/>
<View marginH-30 marginB-10 row centerV> <View marginH-30 marginB-10 row centerV>
<Ionicons name="person-circle-outline" size={28} color="#919191" /> <Ionicons name="person-circle-outline" size={28} color="#919191"/>
<Text <Text
style={{ fontFamily: "Manrope_600SemiBold", fontSize: 18 }} style={{fontFamily: "Manrope_600SemiBold", fontSize: 18}}
marginL-10 marginL-10
> >
Attendees Attendees
</Text> </Text>
<View flex-1 /> <View flex-1/>
<Picker <Picker
value={selectedAttendees} value={selectedAttendees}
onChange={(value) => onChange={(value) =>
setSelectedAttendees((value as string[]) ?? []) setSelectedAttendees((value as string[]) ?? [])
} }
style={{ marginLeft: "auto" }} style={{marginLeft: "auto"}}
mode={PickerModes.MULTI} mode={PickerModes.MULTI}
renderInput={() => ( renderInput={() => (
<Button <Button
size={ButtonSize.small} size={ButtonSize.small}
paddingH-8 paddingH-8
iconSource={() => ( iconSource={() => (
<Ionicons name="add-outline" size={20} color="#ea156c" /> <Ionicons name="add-outline" size={20} color="#ea156c"/>
)} )}
style={{ style={{
marginLeft: "auto", marginLeft: "auto",
@ -503,10 +519,10 @@ export const ManuallyAddEventModal = () => {
/> />
</View> </View>
<View style={styles.divider} /> <View style={styles.divider}/>
<View marginH-30 marginB-0 row spread centerV> <View marginH-30 marginB-0 row spread centerV>
<View row centerV> <View row centerV>
<ClockIcon /> <ClockIcon/>
<Text <Text
style={{ style={{
fontFamily: "Manrope_600SemiBold", fontFamily: "Manrope_600SemiBold",
@ -522,7 +538,7 @@ export const ManuallyAddEventModal = () => {
size={ButtonSize.small} size={ButtonSize.small}
paddingH-8 paddingH-8
iconSource={() => ( iconSource={() => (
<Ionicons name="add-outline" size={20} color="#ea156c" /> <Ionicons name="add-outline" size={20} color="#ea156c"/>
)} )}
style={{ style={{
marginLeft: "auto", marginLeft: "auto",
@ -531,16 +547,16 @@ export const ManuallyAddEventModal = () => {
borderColor: "#ea156c", borderColor: "#ea156c",
borderWidth: 1, borderWidth: 1,
}} }}
labelStyle={{ fontFamily: "Manrope_600SemiBold", fontSize: 14 }} labelStyle={{fontFamily: "Manrope_600SemiBold", fontSize: 14}}
color="#ea156c" color="#ea156c"
label="Set Reminder" label="Set Reminder"
/> />
</View> </View>
</View> </View>
<View style={styles.divider} /> <View style={styles.divider}/>
<View marginH-30 marginB-0 row spread centerV> <View marginH-30 marginB-0 row spread centerV>
<View row centerH> <View row centerH>
<LockIcon /> <LockIcon/>
<Text <Text
style={{ style={{
fontFamily: "PlusJakartaSans_500Medium", fontFamily: "PlusJakartaSans_500Medium",
@ -561,11 +577,11 @@ export const ManuallyAddEventModal = () => {
/> />
</View> </View>
</View> </View>
<View style={styles.divider} /> <View style={styles.divider}/>
<View marginH-30 marginB-0 spread centerV flex-1> <View marginH-30 marginB-0 spread centerV flex-1>
<TouchableOpacity onPress={() => detailsRef?.current?.focus()}> <TouchableOpacity onPress={() => detailsRef?.current?.focus()}>
<View row centerV> <View row centerV>
<MenuIcon /> <MenuIcon/>
<Text <Text
style={{ style={{
fontFamily: "PlusJakartaSans_500Medium", fontFamily: "PlusJakartaSans_500Medium",
@ -586,7 +602,7 @@ export const ManuallyAddEventModal = () => {
multiline multiline
numberOfLines={10} numberOfLines={10}
marginT-10 marginT-10
style={{ flex: 1, minHeight: 180 }} style={{flex: 1, minHeight: 180}}
/> />
</View> </View>
</ScrollView> </ScrollView>
@ -596,12 +612,12 @@ export const ManuallyAddEventModal = () => {
marginB-15 marginB-15
label="Create event from image" label="Create event from image"
text70 text70
style={{ height: 47 }} style={{height: 47}}
labelStyle={{ fontFamily: "PlusJakartaSans_500Medium", fontSize: 15 }} labelStyle={{fontFamily: "PlusJakartaSans_500Medium", fontSize: 15}}
backgroundColor="#05a8b6" backgroundColor="#05a8b6"
iconSource={() => ( iconSource={() => (
<View marginR-5> <View marginR-5>
<CameraIcon color="white" /> <CameraIcon color="white"/>
</View> </View>
)} )}
/> />
@ -619,7 +635,7 @@ export const ManuallyAddEventModal = () => {
}; };
const styles = StyleSheet.create({ const styles = StyleSheet.create({
divider: { height: 1, backgroundColor: "#e4e4e4", marginVertical: 15 }, divider: {height: 1, backgroundColor: "#e4e4e4", marginVertical: 15},
gradient: { gradient: {
height: "25%", height: "25%",
position: "absolute", position: "absolute",

View File

@ -0,0 +1,39 @@
import {useMutation, useQueryClient} from "react-query";
import firestore from "@react-native-firebase/firestore";
export const useDeleteEvent = () => {
const queryClient = useQueryClient();
return useMutation({
mutationKey: ["deleteEvent"],
mutationFn: async ({eventId, docId}: { eventId?: string; docId?: string }) => {
try {
if (docId) {
await firestore()
.collection("Events")
.doc(docId)
.delete();
} else if (eventId) {
const snapshot = await firestore()
.collection("Events")
.where("id", "==", eventId)
.get();
const doc = snapshot.docs[0];
if (doc) {
await doc.ref.delete();
} else {
console.warn("Event not found");
}
} else {
console.warn("No identifier provided");
}
} catch (e) {
console.error(e);
}
},
onSuccess: () => {
queryClient.invalidateQueries("events");
}
});
};