Added attendees

This commit is contained in:
Milan Paunovic
2024-10-20 00:53:09 +02:00
parent 478341cce4
commit d87d67eae5
5 changed files with 120 additions and 37 deletions

View File

@ -5,6 +5,8 @@ import {
DateTimePicker, DateTimePicker,
LoaderScreen, LoaderScreen,
Modal, Modal,
Picker,
PickerModes,
Switch, Switch,
Text, Text,
TextField, TextField,
@ -28,6 +30,7 @@ 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 {selectedNewEventDateAtom} from "@/components/pages/calendar/atoms";
import {useGetFamilyMembers} from "@/hooks/firebase/useGetFamilyMembers";
const daysOfWeek = [ const daysOfWeek = [
{label: "Monday", value: "monday"}, {label: "Monday", value: "monday"},
@ -70,9 +73,13 @@ export const ManuallyAddEventModal = () => {
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(initialDate ?? new Date());
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)
if (!selectedNewEventDate) return null; if (!selectedNewEventDate) return null;
@ -111,6 +118,7 @@ export const ManuallyAddEventModal = () => {
startDate: finalStartDate, startDate: finalStartDate,
endDate: finalEndDate, endDate: finalEndDate,
allDay: isAllDay, allDay: isAllDay,
attendees: selectedAttendees,
}; };
await createEvent(eventData); await createEvent(eventData);
@ -338,27 +346,45 @@ export const ManuallyAddEventModal = () => {
> >
Attendees Attendees
</Text> </Text>
<Button <View flex-1/>
size={ButtonSize.small} <Picker
paddingH-8 value={selectedAttendees}
iconSource={() => ( onChange={(value) => setSelectedAttendees(value as string[] ?? [])}
<Ionicons name="add-outline" size={20} color="#ea156c"/> style={{marginLeft: "auto"}}
)} mode={PickerModes.MULTI}
style={{ renderInput={() =>
marginLeft: "auto", <Button
borderRadius: 8, size={ButtonSize.small}
backgroundColor: "#ffe8f1", paddingH-8
borderColor: "#ea156c", iconSource={() => (
borderWidth: 1, <Ionicons name="add-outline" size={20} color="#ea156c"/>
}} )}
color="#ea156c" style={{
label="Add" marginLeft: "auto",
labelStyle={{fontFamily: "Manrope_600SemiBold", fontSize: 14}} borderRadius: 8,
/> backgroundColor: "#ffe8f1",
borderColor: "#ea156c",
borderWidth: 1,
}}
color="#ea156c"
label="Add"
labelStyle={{fontFamily: "Manrope_600SemiBold", fontSize: 14}}
/>
}>
{members?.map((member) => (
<Picker.Item
key={member?.uid}
value={member?.uid!}
label={member?.firstName + " " + member?.lastName}
/>
))}
</Picker>
</View> </View>
<View marginL-35> <View marginL-35>
<AssigneesDisplay/> <AssigneesDisplay setSlectedAttendees={setSelectedAttendees} selectedAttendees={selectedAttendees}/>
</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>

View File

@ -1,23 +1,77 @@
import React from "react"; import React from "react";
import { ImageBackground, StyleSheet } from "react-native"; import {ImageBackground, StyleSheet} from "react-native";
import { View } from "react-native-ui-lib"; import {Text, TouchableOpacity, View} from "react-native-ui-lib";
import RemoveAssigneeBtn from "./RemoveAssigneeBtn"; import RemoveAssigneeBtn from "./RemoveAssigneeBtn";
import {useGetFamilyMembers} from "@/hooks/firebase/useGetFamilyMembers";
const AssigneesDisplay = () => { const AssigneesDisplay = ({selectedAttendees, setSlectedAttendees}: {
return ( selectedAttendees: string[],
<View row marginH-13 marginT-13 gap-20> setSlectedAttendees: (value: React.SetStateAction<string[]>) => void
<ImageBackground }) => {
source={require("../../assets/images/child-picture.png")} const {data: members} = useGetFamilyMembers(true);
style={{ aspectRatio: 1, width: 58.08, overflow: "hidden" }}
children={<RemoveAssigneeBtn />} const selectedMembers = members?.filter((x) => selectedAttendees.includes(x?.uid!));
/>
<ImageBackground const getInitials = (firstName: string, lastName: string) => {
source={require("../../assets/images/child1-picture.png")} return `${firstName.charAt(0)}${lastName.charAt(0)}`;
style={{ aspectRatio: 1, width: 58.08, overflow: "hidden" }} };
children={<RemoveAssigneeBtn />}
/> const removeAttendee = (uid: string) => {
</View> setSlectedAttendees((prev) => prev.filter((x) => x !== uid));
); }
return (
<View row marginH-13 marginT-13 gap-20>
{selectedMembers?.map((member) => (
<TouchableOpacity key={member.uid} style={styles.assigneeWrapper}
onPress={() => removeAttendee(member.uid!)}>
{member?.pfp ? (
<ImageBackground
source={{uri: member?.pfp}}
style={styles.image}
children={<RemoveAssigneeBtn/>}
/>
) : (
<View style={styles.initialsCircle}>
<Text style={styles.initialsText}>
{getInitials(member.firstName, member.lastName)}
</Text>
</View>
)}
<RemoveAssigneeBtn/>
</TouchableOpacity>
))}
{selectedAttendees.length === 0 && <Text>No attendees added</Text>}
</View>
);
}; };
const styles = StyleSheet.create({
assigneeWrapper: {
position: 'relative',
width: 58.08,
aspectRatio: 1,
},
image: {
aspectRatio: 1,
width: '100%',
borderRadius: 100, // Makes the image circular
overflow: 'hidden',
},
initialsCircle: {
backgroundColor: '#ccc',
justifyContent: 'center',
alignItems: 'center',
borderRadius: 100, // Circular shape
width: '100%',
height: '100%',
},
initialsText: {
color: '#fff',
fontSize: 24,
fontWeight: 'bold',
},
});
export default AssigneesDisplay; export default AssigneesDisplay;

View File

@ -11,4 +11,5 @@ export interface EventData {
notes?: string, notes?: string,
reminders?: string[] reminders?: string[]
id?: string | number, id?: string | number,
attendees?: string[]
} }

View File

@ -17,6 +17,7 @@ export interface UserProfile {
password: string; password: string;
familyId?: string; familyId?: string;
uid?: string; uid?: string;
pfp?: string;
googleToken?: string | null; googleToken?: string | null;
microsoftToken?: string | null; microsoftToken?: string | null;
appleToken?: string | null; appleToken?: string | null;

View File

@ -14,7 +14,8 @@ export const useGetEvents = () => {
queryFn: async () => { queryFn: async () => {
const eventsQuery = firestore() const eventsQuery = firestore()
.collection("Events") .collection("Events")
.where("creatorId", "==", user?.uid); .where("creatorId", "==", user?.uid)
.where("attendees", "array-contains", user?.uid);
if (isFamilyView) { if (isFamilyView) {
eventsQuery.where("familyID", "==", profileData?.familyId); eventsQuery.where("familyID", "==", profileData?.familyId);