mirror of
https://github.com/urosran/cally.git
synced 2025-11-26 16:34:54 +00:00
Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
4
app.json
4
app.json
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"expo": {
|
"expo": {
|
||||||
"name": "Cally.",
|
"name": "Cally ",
|
||||||
"slug": "cally",
|
"slug": "cally",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"orientation": "portrait",
|
"orientation": "portrait",
|
||||||
@ -16,7 +16,7 @@
|
|||||||
"supportsTablet": true,
|
"supportsTablet": true,
|
||||||
"bundleIdentifier": "com.cally.app",
|
"bundleIdentifier": "com.cally.app",
|
||||||
"googleServicesFile": "./ios/GoogleService-Info.plist",
|
"googleServicesFile": "./ios/GoogleService-Info.plist",
|
||||||
"buildNumber": "31",
|
"buildNumber": "34",
|
||||||
"usesAppleSignIn": true
|
"usesAppleSignIn": true
|
||||||
},
|
},
|
||||||
"android": {
|
"android": {
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 29 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 29 KiB |
@ -72,12 +72,14 @@ export const AddEventDialog = () => {
|
|||||||
style={{marginTop: 20, alignItems: "center", width: "100%"}}
|
style={{marginTop: 20, alignItems: "center", width: "100%"}}
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
|
disabled
|
||||||
style={{
|
style={{
|
||||||
marginBottom: 10,
|
marginBottom: 10,
|
||||||
backgroundColor: "#ea156c",
|
// backgroundColor: "#ea156c",
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
width: "100%",
|
width: "100%",
|
||||||
paddingVertical: 13,
|
paddingVertical: 13,
|
||||||
|
opacity: 0.5
|
||||||
}}
|
}}
|
||||||
label="Scan Image"
|
label="Scan Image"
|
||||||
labelStyle={styles.btnLabel}
|
labelStyle={styles.btnLabel}
|
||||||
@ -104,12 +106,14 @@ export const AddEventDialog = () => {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
|
disabled
|
||||||
style={{
|
style={{
|
||||||
marginBottom: 10,
|
marginBottom: 10,
|
||||||
backgroundColor: "#05a8b6",
|
// backgroundColor: "#05a8b6",
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
width: "100%",
|
width: "100%",
|
||||||
paddingVertical: 13,
|
paddingVertical: 13,
|
||||||
|
opacity: 0.5
|
||||||
}}
|
}}
|
||||||
label="Add To Do"
|
label="Add To Do"
|
||||||
labelStyle={styles.btnLabel}
|
labelStyle={styles.btnLabel}
|
||||||
|
|||||||
@ -1,303 +0,0 @@
|
|||||||
import {Button, ButtonSize, DateTimePicker, Dialog, Switch, Text, TextField, View} from "react-native-ui-lib";
|
|
||||||
import React from "react";
|
|
||||||
import {AntDesign, Feather, Ionicons} from "@expo/vector-icons";
|
|
||||||
import {PanningDirectionsEnum} from "react-native-ui-lib/src/incubator/panView";
|
|
||||||
import {StyleSheet} from "react-native";
|
|
||||||
import DropModalIcon from "@/assets/svgs/DropModalIcon";
|
|
||||||
import ClockIcon from "@/assets/svgs/ClockIcon";
|
|
||||||
import LockIcon from "@/assets/svgs/LockIcon";
|
|
||||||
import MenuIcon from "@/assets/svgs/MenuIcon";
|
|
||||||
import {useUpdateEvent} from "@/hooks/firebase/useUpdateEvent";
|
|
||||||
import {editVisibleAtom, eventForEditAtom} from "@/components/pages/calendar/atoms";
|
|
||||||
import {useAtom} from "jotai";
|
|
||||||
|
|
||||||
|
|
||||||
const EditEventDialog = () => {
|
|
||||||
const [isVisible, setIsVisible] = useAtom(editVisibleAtom)
|
|
||||||
const [event, setEvent] = useAtom(eventForEditAtom)
|
|
||||||
|
|
||||||
const {mutateAsync: updateEvent} = useUpdateEvent();
|
|
||||||
|
|
||||||
if (!event) return null
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Dialog
|
|
||||||
bottom={true}
|
|
||||||
height={"90%"}
|
|
||||||
panDirection={PanningDirectionsEnum.DOWN}
|
|
||||||
onDismiss={() => setIsVisible(false)}
|
|
||||||
containerStyle={{
|
|
||||||
borderRadius: 10,
|
|
||||||
backgroundColor: "white",
|
|
||||||
width: "100%",
|
|
||||||
alignSelf: "stretch",
|
|
||||||
padding: 0,
|
|
||||||
paddingTop: 4,
|
|
||||||
margin: 0,
|
|
||||||
}}
|
|
||||||
visible={isVisible}
|
|
||||||
>
|
|
||||||
<View row spread>
|
|
||||||
<Button
|
|
||||||
color="#05a8b6"
|
|
||||||
style={styles.topBtn}
|
|
||||||
label="Cancel"
|
|
||||||
onPress={() => {
|
|
||||||
setIsVisible(false);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<View marginT-12>
|
|
||||||
<DropModalIcon
|
|
||||||
onPress={() => {
|
|
||||||
setIsVisible(false);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
<Button
|
|
||||||
color="#05a8b6"
|
|
||||||
style={styles.topBtn}
|
|
||||||
label="Save"
|
|
||||||
onPress={() => {
|
|
||||||
try {
|
|
||||||
if (event.id) {
|
|
||||||
updateEvent(event).then(() => setIsVisible(false));
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
<TextField
|
|
||||||
placeholder="Edit event title"
|
|
||||||
value={event.title}
|
|
||||||
onChangeText={(text) => {
|
|
||||||
setEvent((prevEvent) => ({
|
|
||||||
...prevEvent!,
|
|
||||||
title: text,
|
|
||||||
}));
|
|
||||||
}}
|
|
||||||
placeholderTextColor="#2d2d30"
|
|
||||||
text60R
|
|
||||||
marginT-15
|
|
||||||
marginL-30
|
|
||||||
/>
|
|
||||||
<View style={styles.divider} marginT-8/>
|
|
||||||
|
|
||||||
<View row spread marginB-10 marginL-30 centerV>
|
|
||||||
<View row>
|
|
||||||
<AntDesign name="clockcircleo" size={24} color="#919191"/>
|
|
||||||
<Text text70 marginL-10>
|
|
||||||
All day
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
<View right marginR-30>
|
|
||||||
<Switch
|
|
||||||
onColor={"#ea156c"}
|
|
||||||
offColor={"#e1e1e2"}
|
|
||||||
marginL-10
|
|
||||||
value={event.allDay}
|
|
||||||
onValueChange={(value) =>
|
|
||||||
setEvent((prev) => ({...prev!, allDay: value}))
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
<View marginL-30 centerV>
|
|
||||||
<View row marginB-10 spread>
|
|
||||||
<View row centerV>
|
|
||||||
<Feather name="calendar" size={25} color="#919191"/>
|
|
||||||
<DateTimePicker
|
|
||||||
value={event.start}
|
|
||||||
text70
|
|
||||||
marginL-8
|
|
||||||
maximumDate={event.end}
|
|
||||||
onChange={(date) => {
|
|
||||||
setEvent((prev) => ({...prev!, start: date}));
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
<DateTimePicker
|
|
||||||
text70
|
|
||||||
value={event.start}
|
|
||||||
onChange={(date) => {
|
|
||||||
setEvent((prev) => ({...prev!, start: date}));
|
|
||||||
}}
|
|
||||||
maximumDate={event.end}
|
|
||||||
dateTimeFormatter={(date) => date.toLocaleTimeString("en-us",
|
|
||||||
{
|
|
||||||
hour: "numeric",
|
|
||||||
minute: "numeric"
|
|
||||||
})}
|
|
||||||
mode="time"
|
|
||||||
marginR-30
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
{!event.allDay && (
|
|
||||||
<View row marginB-10 spread>
|
|
||||||
<View row centerV>
|
|
||||||
<Feather name="calendar" size={25} color="#919191"/>
|
|
||||||
<DateTimePicker
|
|
||||||
value={event.end}
|
|
||||||
minimumDate={event.start}
|
|
||||||
text70
|
|
||||||
marginL-8
|
|
||||||
onChange={(date) => {
|
|
||||||
setEvent((prev) => ({...prev!, end: date}));
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
<DateTimePicker
|
|
||||||
text70
|
|
||||||
value={event.end}
|
|
||||||
minimumDate={event.start}
|
|
||||||
onChange={(date) => {
|
|
||||||
setEvent((prev) => ({...prev!, end: date}));
|
|
||||||
}}
|
|
||||||
dateTimeFormatter={(date) => date.toLocaleTimeString("en-us",
|
|
||||||
{
|
|
||||||
hour: "numeric",
|
|
||||||
minute: "numeric"
|
|
||||||
})}
|
|
||||||
mode="time"
|
|
||||||
marginR-30
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
)}
|
|
||||||
</View>
|
|
||||||
<View style={styles.divider}/>
|
|
||||||
|
|
||||||
<View marginH-30 marginB-10 row centerV>
|
|
||||||
<Ionicons name="person-circle-outline" size={28} color="#919191"/>
|
|
||||||
<Text text70R marginL-10>
|
|
||||||
Assignees
|
|
||||||
</Text>
|
|
||||||
<Button
|
|
||||||
size={ButtonSize.small}
|
|
||||||
paddingH-8
|
|
||||||
iconSource={() => (
|
|
||||||
<Ionicons name="add-outline" size={20} color="#ea156c"/>
|
|
||||||
)}
|
|
||||||
style={{
|
|
||||||
marginLeft: "auto",
|
|
||||||
borderRadius: 8,
|
|
||||||
backgroundColor: "#ffe8f1",
|
|
||||||
borderColor: "#ea156c",
|
|
||||||
borderWidth: 1,
|
|
||||||
}}
|
|
||||||
color="#ea156c"
|
|
||||||
label="Assign"
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
<View row marginH-13 marginT-13>
|
|
||||||
<View
|
|
||||||
marginL-30
|
|
||||||
style={{
|
|
||||||
aspectRatio: 1,
|
|
||||||
width: 50,
|
|
||||||
backgroundColor: "red",
|
|
||||||
borderRadius: 50,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<View
|
|
||||||
marginL-30
|
|
||||||
style={{
|
|
||||||
aspectRatio: 1,
|
|
||||||
width: 50,
|
|
||||||
backgroundColor: "red",
|
|
||||||
borderRadius: 50,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
<View style={styles.divider}/>
|
|
||||||
<View marginH-30 marginB-0 row spread centerV>
|
|
||||||
<View row centerV>
|
|
||||||
<ClockIcon/>
|
|
||||||
<Text text70 marginL-10>
|
|
||||||
Reminder
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
<View>
|
|
||||||
<Button
|
|
||||||
size={ButtonSize.small}
|
|
||||||
paddingH-8
|
|
||||||
iconSource={() => (
|
|
||||||
<Ionicons name="add-outline" size={20} color="#ea156c"/>
|
|
||||||
)}
|
|
||||||
style={{
|
|
||||||
marginLeft: "auto",
|
|
||||||
borderRadius: 8,
|
|
||||||
backgroundColor: "#ffe8f1",
|
|
||||||
borderColor: "#ea156c",
|
|
||||||
borderWidth: 1,
|
|
||||||
}}
|
|
||||||
color="#ea156c"
|
|
||||||
label="Set Reminder"
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
<View style={styles.divider}/>
|
|
||||||
<View marginH-30 marginB-0 row spread centerV>
|
|
||||||
<View row>
|
|
||||||
<LockIcon/>
|
|
||||||
<Text text70 marginL-10>
|
|
||||||
Mark as Private
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
<View>
|
|
||||||
<Switch
|
|
||||||
onColor={"#ea156c"}
|
|
||||||
offColor={"#e1e1e2"}
|
|
||||||
marginL-10
|
|
||||||
value={event.private}
|
|
||||||
onValueChange={(value) =>
|
|
||||||
setEvent((prev) => ({...prev!, private: value}))
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
<View style={styles.divider}/>
|
|
||||||
<View marginH-30 marginB-0 row spread centerV>
|
|
||||||
<View row centerV>
|
|
||||||
<MenuIcon/>
|
|
||||||
<Text text70 marginL-10>
|
|
||||||
Add Details
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
<View></View>
|
|
||||||
</View>
|
|
||||||
</Dialog>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default EditEventDialog;
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
divider: {height: 1, backgroundColor: "#e4e4e4", marginVertical: 15},
|
|
||||||
gradient: {
|
|
||||||
height: "25%",
|
|
||||||
position: "absolute",
|
|
||||||
bottom: 0,
|
|
||||||
width: "100%",
|
|
||||||
},
|
|
||||||
buttonContainer: {
|
|
||||||
position: "absolute",
|
|
||||||
bottom: 25,
|
|
||||||
width: "100%",
|
|
||||||
},
|
|
||||||
button: {
|
|
||||||
backgroundColor: "rgb(253, 23, 117)",
|
|
||||||
paddingVertical: 20,
|
|
||||||
},
|
|
||||||
topBtn: {
|
|
||||||
backgroundColor: "white",
|
|
||||||
color: "#05a8b6",
|
|
||||||
},
|
|
||||||
rotateSwitch: {
|
|
||||||
marginLeft: 35,
|
|
||||||
marginBottom: 10,
|
|
||||||
marginTop: 25,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
@ -48,9 +48,15 @@ export const EventCalendar: React.FC<EventCalendarProps> = React.memo(({calendar
|
|||||||
}, [events, mode]);
|
}, [events, mode]);
|
||||||
|
|
||||||
const handlePressEvent = useCallback((event: CalendarEvent) => {
|
const handlePressEvent = useCallback((event: CalendarEvent) => {
|
||||||
setEditVisible(true);
|
if (mode === "day") {
|
||||||
setEventForEdit(event);
|
setEditVisible(true);
|
||||||
}, [setEditVisible, setEventForEdit]);
|
console.log({event})
|
||||||
|
setEventForEdit(event);
|
||||||
|
} else {
|
||||||
|
setMode("day")
|
||||||
|
setSelectedDate(event.start);
|
||||||
|
}
|
||||||
|
}, [setEditVisible, setEventForEdit, mode]);
|
||||||
|
|
||||||
const handlePressCell = useCallback(
|
const handlePressCell = useCallback(
|
||||||
(date: Date) => {
|
(date: Date) => {
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import React, {useRef, useState} from "react";
|
|||||||
import {LayoutChangeEvent} from "react-native";
|
import {LayoutChangeEvent} from "react-native";
|
||||||
import CalendarViewSwitch from "@/components/pages/calendar/CalendarViewSwitch";
|
import CalendarViewSwitch from "@/components/pages/calendar/CalendarViewSwitch";
|
||||||
import {AddEventDialog} from "@/components/pages/calendar/AddEventDialog";
|
import {AddEventDialog} from "@/components/pages/calendar/AddEventDialog";
|
||||||
import EditEventDialog from "@/components/pages/calendar/EditEventDialog";
|
|
||||||
import {ManuallyAddEventModal} from "@/components/pages/calendar/ManuallyAddEventModal";
|
import {ManuallyAddEventModal} from "@/components/pages/calendar/ManuallyAddEventModal";
|
||||||
import {CalendarHeader} from "@/components/pages/calendar/CalendarHeader";
|
import {CalendarHeader} from "@/components/pages/calendar/CalendarHeader";
|
||||||
import {EventCalendar} from "@/components/pages/calendar/EventCalendar";
|
import {EventCalendar} from "@/components/pages/calendar/EventCalendar";
|
||||||
@ -37,7 +36,6 @@ export const InnerCalendar = () => {
|
|||||||
<CalendarViewSwitch/>
|
<CalendarViewSwitch/>
|
||||||
|
|
||||||
<AddEventDialog/>
|
<AddEventDialog/>
|
||||||
<EditEventDialog/>
|
|
||||||
<ManuallyAddEventModal/>
|
<ManuallyAddEventModal/>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -10,12 +10,13 @@ import {
|
|||||||
Switch,
|
Switch,
|
||||||
Text,
|
Text,
|
||||||
TextField,
|
TextField,
|
||||||
|
TextFieldRef,
|
||||||
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 {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";
|
||||||
@ -29,7 +30,7 @@ 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 {selectedNewEventDateAtom} from "@/components/pages/calendar/atoms";
|
import {eventForEditAtom, selectedNewEventDateAtom} from "@/components/pages/calendar/atoms";
|
||||||
import {useGetFamilyMembers} from "@/hooks/firebase/useGetFamilyMembers";
|
import {useGetFamilyMembers} from "@/hooks/firebase/useGetFamilyMembers";
|
||||||
|
|
||||||
const daysOfWeek = [
|
const daysOfWeek = [
|
||||||
@ -46,42 +47,77 @@ export const ManuallyAddEventModal = () => {
|
|||||||
const insets = useSafeAreaInsets();
|
const insets = useSafeAreaInsets();
|
||||||
|
|
||||||
const [selectedNewEventDate, setSelectedNewEndDate] = useAtom(selectedNewEventDateAtom)
|
const [selectedNewEventDate, setSelectedNewEndDate] = useAtom(selectedNewEventDateAtom)
|
||||||
|
const [editEvent, setEditEvent] = useAtom(eventForEditAtom)
|
||||||
|
|
||||||
const {show, close, initialDate} = {
|
const {show, close, initialDate} = {
|
||||||
show: !!selectedNewEventDate,
|
show: !!selectedNewEventDate || !!editEvent,
|
||||||
close: () => setSelectedNewEndDate(undefined),
|
close: () => {
|
||||||
initialDate: selectedNewEventDate
|
setSelectedNewEndDate(undefined)
|
||||||
|
setEditEvent(undefined)
|
||||||
|
},
|
||||||
|
initialDate: selectedNewEventDate || editEvent?.start
|
||||||
}
|
}
|
||||||
|
|
||||||
const [title, setTitle] = useState<string>("");
|
const detailsRef = useRef<TextFieldRef>(null)
|
||||||
|
|
||||||
const [isAllDay, setIsAllDay] = useState(false);
|
const [title, setTitle] = useState<string>(editEvent?.title || "");
|
||||||
const [isPrivate, setIsPrivate] = useState<boolean>(false);
|
const [details, setDetails] = useState<string>(editEvent?.notes || "");
|
||||||
|
const [isAllDay, setIsAllDay] = useState(editEvent?.allDay || false);
|
||||||
|
const [isPrivate, setIsPrivate] = useState<boolean>(editEvent?.private || false);
|
||||||
const [startTime, setStartTime] = useState(() => {
|
const [startTime, setStartTime] = useState(() => {
|
||||||
const date = initialDate ?? new Date();
|
const date = initialDate ?? new Date();
|
||||||
date.setSeconds(0, 0);
|
date.setSeconds(0, 0);
|
||||||
return date;
|
return date;
|
||||||
});
|
});
|
||||||
const [endTime, setEndTime] = useState(() => {
|
const [endTime, setEndTime] = useState(() => {
|
||||||
const date = initialDate
|
if (editEvent?.end) {
|
||||||
? addHours(initialDate, 1)
|
const date = new Date(editEvent.end);
|
||||||
|
date.setSeconds(0, 0);
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
const date = (editEvent?.end ?? initialDate)
|
||||||
|
? addHours((editEvent?.end ?? initialDate!), 1)
|
||||||
: addHours(new Date(), 1);
|
: addHours(new Date(), 1);
|
||||||
date.setSeconds(0, 0);
|
date.setSeconds(0, 0);
|
||||||
return date;
|
return date;
|
||||||
});
|
});
|
||||||
|
|
||||||
const [startDate, setStartDate] = useState(initialDate ?? new Date());
|
const [startDate, setStartDate] = useState(initialDate ?? new Date());
|
||||||
const [endDate, setEndDate] = useState(initialDate ?? new Date());
|
const [endDate, setEndDate] = useState(editEvent?.end ?? initialDate ?? new Date());
|
||||||
|
const [selectedAttendees, setSelectedAttendees] = useState<string[]>(editEvent?.participants ?? []);
|
||||||
const [selectedAttendees, setSelectedAttendees] = useState<string[]>([]);
|
|
||||||
|
|
||||||
const [repeatInterval, setRepeatInterval] = useState<PickerMultiValue>([]);
|
const [repeatInterval, setRepeatInterval] = useState<PickerMultiValue>([]);
|
||||||
|
|
||||||
const {mutateAsync: createEvent, isLoading, isError} = useCreateEvent();
|
const {mutateAsync: createEvent, isLoading, isError} = useCreateEvent();
|
||||||
const {data: members} = useGetFamilyMembers(true)
|
const {data: members} = useGetFamilyMembers(true);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setTitle(editEvent?.title || "");
|
||||||
|
setDetails(editEvent?.notes || "");
|
||||||
|
setIsAllDay(editEvent?.allDay || false);
|
||||||
|
setIsPrivate(editEvent?.private || false);
|
||||||
|
setStartTime(() => {
|
||||||
|
const date = initialDate ?? new Date();
|
||||||
|
date.setSeconds(0, 0);
|
||||||
|
return date;
|
||||||
|
});
|
||||||
|
setEndTime(() => {
|
||||||
|
if (editEvent?.end) {
|
||||||
|
const date = new Date(editEvent.end);
|
||||||
|
date.setSeconds(0, 0);
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
const date = (editEvent?.end ?? initialDate)
|
||||||
|
? addHours((editEvent?.end ?? initialDate!), 1)
|
||||||
|
: addHours(new Date(), 1);
|
||||||
|
date.setSeconds(0, 0);
|
||||||
|
return date;
|
||||||
|
});
|
||||||
|
setStartDate(initialDate ?? new Date());
|
||||||
|
setEndDate(editEvent?.end ?? initialDate ?? new Date());
|
||||||
|
setSelectedAttendees(editEvent?.participants ?? []);
|
||||||
|
setRepeatInterval([]);
|
||||||
|
}, [editEvent, selectedNewEventDate]);
|
||||||
|
|
||||||
if (!selectedNewEventDate) return null;
|
if (!show) return null;
|
||||||
|
|
||||||
const formatDateTime = (date?: Date | string) => {
|
const formatDateTime = (date?: Date | string) => {
|
||||||
if (!date) return undefined;
|
if (!date) return undefined;
|
||||||
@ -119,8 +155,11 @@ export const ManuallyAddEventModal = () => {
|
|||||||
endDate: finalEndDate,
|
endDate: finalEndDate,
|
||||||
allDay: isAllDay,
|
allDay: isAllDay,
|
||||||
attendees: selectedAttendees,
|
attendees: selectedAttendees,
|
||||||
|
notes: details
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (editEvent?.id) eventData.id = editEvent?.id
|
||||||
|
|
||||||
await createEvent(eventData);
|
await createEvent(eventData);
|
||||||
|
|
||||||
close();
|
close();
|
||||||
@ -221,7 +260,7 @@ export const ManuallyAddEventModal = () => {
|
|||||||
</Text>
|
</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
<ScrollView>
|
<ScrollView style={{minHeight: "85%"}}>
|
||||||
<TextField
|
<TextField
|
||||||
placeholder="Add event title"
|
placeholder="Add event title"
|
||||||
value={title}
|
value={title}
|
||||||
@ -382,7 +421,8 @@ export const ManuallyAddEventModal = () => {
|
|||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View marginL-35>
|
<View marginL-35>
|
||||||
<AssigneesDisplay setSlectedAttendees={setSelectedAttendees} selectedAttendees={selectedAttendees}/>
|
<AssigneesDisplay setSlectedAttendees={setSelectedAttendees}
|
||||||
|
selectedAttendees={selectedAttendees}/>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={styles.divider}/>
|
<View style={styles.divider}/>
|
||||||
@ -421,7 +461,7 @@ 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>
|
<View row centerH>
|
||||||
<LockIcon/>
|
<LockIcon/>
|
||||||
<Text
|
<Text
|
||||||
style={{
|
style={{
|
||||||
@ -444,23 +484,28 @@ export const ManuallyAddEventModal = () => {
|
|||||||
</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 spread centerV flex-1>
|
||||||
<View row centerV>
|
<TouchableOpacity onPress={() => detailsRef?.current?.focus()}>
|
||||||
<MenuIcon/>
|
<View row centerV>
|
||||||
<Text
|
<MenuIcon/>
|
||||||
style={{
|
<Text
|
||||||
fontFamily: "PlusJakartaSans_500Medium",
|
style={{
|
||||||
fontSize: 16,
|
fontFamily: "PlusJakartaSans_500Medium",
|
||||||
}}
|
fontSize: 16,
|
||||||
marginL-10
|
}}
|
||||||
>
|
marginL-10
|
||||||
Add Details
|
>
|
||||||
</Text>
|
Add Details
|
||||||
</View>
|
</Text>
|
||||||
<View></View>
|
</View>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<TextField value={details} onChangeText={setDetails} ref={detailsRef} maxLength={2000} multiline
|
||||||
|
numberOfLines={10} marginT-10 style={{flex: 1, minHeight: 180}}/>
|
||||||
</View>
|
</View>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
<Button
|
<Button
|
||||||
|
disabled
|
||||||
marginH-30
|
marginH-30
|
||||||
marginB-15
|
marginB-15
|
||||||
label="Create event from image"
|
label="Create event from image"
|
||||||
|
|||||||
@ -10,4 +10,5 @@ export interface CalendarEvent {
|
|||||||
eventColor?: string; // Optional color to represent the event
|
eventColor?: string; // Optional color to represent the event
|
||||||
participants?: string[]; // Optional list of participants or attendees
|
participants?: string[]; // Optional list of participants or attendees
|
||||||
private?: boolean;
|
private?: boolean;
|
||||||
|
notes?: string
|
||||||
}
|
}
|
||||||
@ -11,11 +11,30 @@ export const useCreateEvent = () => {
|
|||||||
mutationKey: ["createEvent"],
|
mutationKey: ["createEvent"],
|
||||||
mutationFn: async (eventData: Partial<EventData>) => {
|
mutationFn: async (eventData: Partial<EventData>) => {
|
||||||
try {
|
try {
|
||||||
|
if (eventData.id) {
|
||||||
|
const snapshot = await firestore()
|
||||||
|
.collection("Events")
|
||||||
|
.where("id", "==", eventData.id)
|
||||||
|
.get();
|
||||||
|
|
||||||
|
if (!snapshot.empty) {
|
||||||
|
const docId = snapshot.docs[0].id;
|
||||||
|
await firestore()
|
||||||
|
.collection("Events")
|
||||||
|
.doc(docId)
|
||||||
|
.set({
|
||||||
|
...eventData,
|
||||||
|
creatorId: currentUser?.uid,
|
||||||
|
familyId: profileData?.familyId
|
||||||
|
}, {merge: true});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
await firestore()
|
await firestore()
|
||||||
.collection("Events")
|
.collection("Events")
|
||||||
.add({...eventData, creatorId: currentUser?.uid, familyId: profileData?.familyId})
|
.add({...eventData, creatorId: currentUser?.uid, familyId: profileData?.familyId});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
|
|||||||
@ -53,6 +53,13 @@ export const useGetEvents = () => {
|
|||||||
index === self.findIndex(e => e.id === event.id)
|
index === self.findIndex(e => e.id === event.id)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
allEvents = allEvents.filter(event => {
|
||||||
|
if (event.private) {
|
||||||
|
return event.creatorId === userId;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
return await Promise.all(
|
return await Promise.all(
|
||||||
allEvents.map(async (event) => {
|
allEvents.map(async (event) => {
|
||||||
const profileSnapshot = await db
|
const profileSnapshot = await db
|
||||||
@ -70,6 +77,7 @@ export const useGetEvents = () => {
|
|||||||
end: new Date(event.endDate.seconds * 1000),
|
end: new Date(event.endDate.seconds * 1000),
|
||||||
hideHours: event.allDay,
|
hideHours: event.allDay,
|
||||||
eventColor: eventColor,
|
eventColor: eventColor,
|
||||||
|
notes: event.notes
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|||||||
@ -450,7 +450,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 = Cally;
|
PRODUCT_NAME = "Cally";
|
||||||
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;
|
||||||
@ -484,7 +484,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 = Cally;
|
PRODUCT_NAME = "Cally";
|
||||||
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";
|
||||||
|
|||||||
@ -47,7 +47,7 @@
|
|||||||
</dict>
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>31</string>
|
<string>34</string>
|
||||||
<key>LSRequiresIPhoneOS</key>
|
<key>LSRequiresIPhoneOS</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>NSAppTransportSecurity</key>
|
<key>NSAppTransportSecurity</key>
|
||||||
@ -111,6 +111,7 @@
|
|||||||
<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>
|
||||||
|
|||||||
Reference in New Issue
Block a user