diff --git a/src/components/Event/EventRepeat.tsx b/src/components/Event/EventRepeat.tsx index 433fc2f..37a6e67 100644 --- a/src/components/Event/EventRepeat.tsx +++ b/src/components/Event/EventRepeat.tsx @@ -6,18 +6,15 @@ import { MenuItem, Box, Stack, - Paper, Typography, TextField, Checkbox, - List, - ListItem, FormControlLabel, FormGroup, Radio, RadioGroup, } from "@mui/material"; -import { useState } from "react"; +import { useEffect, useState } from "react"; import { RepetitionObject } from "../../features/Events/EventsTypes"; export default function RepeatEvent({ @@ -29,23 +26,31 @@ export default function RepeatEvent({ setRepetition: Function; isOwn?: boolean; }) { - console.log(JSON.stringify(repetition)); - const repetitionValues = ["day", "week", "month", "year"]; - const [interval, setInterval] = useState(repetition.interval ?? 0); - const [selectedDays, setSelectedDays] = useState( - repetition.selectedDays ?? [] - ); - const [endOption, setEndOption] = useState(""); - const [occurrences, setOccurrences] = useState(repetition.occurrences) ?? 0; - const [endDate, setEndDate] = useState(repetition.endDate ?? ""); const days = ["MO", "TU", "WE", "TH", "FR", "SA", "SU"]; - const handleDayChange = (day: string) => { - setSelectedDays((prev: string[]) => - prev.includes(day) ? prev.filter((d) => d !== day) : [...prev, day] - ); + // derive endOption based on repetition + const getEndOption = () => { + if (repetition.occurrences && repetition.occurrences > 0) return "after"; + if (repetition.endDate) return "on"; + return "never"; }; + + const [endOption, setEndOption] = useState(getEndOption()); + + // keep endOption in sync if repetition changes from parent + useEffect(() => { + setEndOption(getEndOption()); + }, [repetition.occurrences, repetition.endDate]); + + const handleDayChange = (day: string) => { + const updatedDays = repetition.selectedDays?.includes(day) + ? repetition.selectedDays.filter((d) => d !== day) + : [...(repetition.selectedDays ?? []), day]; + + setRepetition({ ...repetition, selectedDays: updatedDays }); + }; + return ( Repetition @@ -64,18 +69,24 @@ export default function RepeatEvent({ Repeat monthly Repeat yearly + {repetition.freq && ( + {/* Interval */} Interval: setInterval(Number(e.target.value))} + value={repetition.interval ?? 0} + onChange={(e) => + setRepetition({ + ...repetition, + interval: Number(e.target.value), + }) + } size="small" sx={{ width: 80 }} /> - { repetitionValues[ @@ -84,6 +95,8 @@ export default function RepeatEvent({ } + + {/* Weekly selection */} {repetition.freq === "weekly" && ( @@ -95,7 +108,9 @@ export default function RepeatEvent({ key={day} control={ handleDayChange(day)} /> } @@ -105,13 +120,38 @@ export default function RepeatEvent({ )} + + {/* End options */} End: setEndOption(e.target.value)} + onChange={(e) => { + const value = e.target.value; + setEndOption(value); + + if (value === "never") { + setRepetition({ ...repetition, occurrences: 0, endDate: "" }); + } + if (value === "after") { + setRepetition({ + freq: repetition.freq, + interval: repetition.interval, + occurence: Number(e.target.value), + }); + } + if (value === "on") { + setRepetition({ + freq: repetition.freq, + interval: repetition.interval, + endDate: new Date(e.target.value) + .toISOString() + .slice(0, 16), + }); + } + }} > setOccurrences(Number(e.target.value))} + value={repetition.occurrences ?? 0} + onChange={(e) => + setRepetition({ + freq: repetition.freq, + interval: repetition.interval, + occurence: Number(e.target.value), + }) + } sx={{ width: 100 }} inputProps={{ min: 1 }} disabled={endOption !== "after"} @@ -148,8 +194,14 @@ export default function RepeatEvent({ setEndDate(e.target.value)} + value={repetition.endDate ?? ""} + onChange={(e) => + setRepetition({ + freq: repetition.freq, + interval: repetition.interval, + endDate: e.target.value, + }) + } disabled={endOption !== "on"} /> diff --git a/src/features/Events/EventDisplay.tsx b/src/features/Events/EventDisplay.tsx index d716b34..40343f3 100644 --- a/src/features/Events/EventDisplay.tsx +++ b/src/features/Events/EventDisplay.tsx @@ -124,7 +124,8 @@ export default function EventDisplayModal({ if (!event || !calendar) { onClose({}, "backdropClick"); } - }, [open, eventId, dispatch, onClose]); + setRepetition(event.repetition ?? ({} as RepetitionObject)); + }, [open, eventId, dispatch, onClose, event]); if (!event || !calendar) return null; @@ -224,315 +225,331 @@ export default function EventDisplayModal({ return ( - - {/* Close button */} - - onClose({}, "backdropClick")}> - - - - - - - - {/* Title */} - setTitle(e.target.value)} - size="small" - margin="dense" - /> - - {/* RSVP */} - {currentUserAttendee && isOwnCal && ( - - - - - - - - - )} - - {/* Calendar selector */} - - Calendar - - + + + - {/* Dates */} - - setStart(formatLocalDateTime(new Date(e.target.value))) - } - size="small" - margin="dense" - InputLabelProps={{ shrink: true }} - /> + - - setEnd(formatLocalDateTime(new Date(e.target.value))) - } - size="small" - margin="dense" - InputLabelProps={{ shrink: true }} - /> + + {/* Title */} + setTitle(e.target.value)} + size="small" + margin="dense" + /> - + + + + + + + + )} + + {/* Calendar selector */} + + Calendar + setAlarm(e.target.value)} - > - No Alarm - 1 minute - 2 minutes - 10 minutes - 15 minutes - 30 minutes - 1 hours - 2 hours - 5 hours - 12 hours - 1 day - 2 days - 1 week - - - - - Visibility - - - {/* Error */} - {event.error && ( - - } - text={event.error} - error - /> - )} - - )} - - - - - {isOwn && ( - { - onClose({}, "backdropClick"); - dispatch( - deleteEventAsync({ calId, eventId, eventURL: event.URL }) - ); + labelId="calendar-select-label" + value={calendarid.toString()} + label="Calendar" + onChange={(e: SelectChangeEvent) => { + const newId = Number(e.target.value); + setCalendarid(newId); + setNewCalId(userPersonnalCalendars[newId].id); }} > - - - )} - + {calList} + + + + {/* Dates */} + + setStart(formatLocalDateTime(new Date(e.target.value))) + } + size="small" + margin="dense" + InputLabelProps={{ shrink: true }} + /> + + + setEnd(formatLocalDateTime(new Date(e.target.value))) + } + size="small" + margin="dense" + InputLabelProps={{ shrink: true }} + /> + + { + const endDate = new Date(end); + const startDate = new Date(start); + setAllDay(!allday); + if (endDate.getDate() === startDate.getDate()) { + endDate.setDate(startDate.getDate() + 1); + setEnd(formatLocalDateTime(endDate)); + } + }} + /> + } + label="All day" + /> + + {/* Description & Location */} + setDescription(e.target.value)} + size="small" + margin="dense" + multiline + rows={2} + /> {isOwn && ( - + { + const newAttendeeList = attendees.concat(value); + setAttendees(newAttendeeList); + }} + /> )} - - - + + setLocation(e.target.value)} + size="small" + margin="dense" + /> + + {/* Video */} + {event.x_openpass_videoconference && ( + } + text="Video conference available" + data={event.x_openpass_videoconference} + /> + )} + + {/* Attendees */} + {event.attendee?.length > 0 && ( + + Attendees: + {organizer.cal_address && + renderAttendeeBadge(organizer, "org", true)} + {(showAllAttendees + ? attendees + : attendees.slice(0, attendeeDisplayLimit) + ).map((a, idx) => ( + + {renderAttendeeBadge(a, idx.toString())} + {isOwn && ( + { + const newAttendeesList = [...attendees]; + newAttendeesList.splice(idx, 1); + setAttendees(newAttendeesList); + }} + > + + + )} + + ))} + {attendees.length > attendeeDisplayLimit && ( + setShowAllAttendees(!showAllAttendees)} + > + {showAllAttendees + ? "Show less" + : `Show more (${ + attendees.length - attendeeDisplayLimit + } more)`} + + )} + + )} + + + + {/* Extended options */} + {showMore && ( + <> + + + + Alarm + + + + + Visibility + + + {/* Error */} + {event.error && ( + + } + text={event.error} + error + /> + )} + + )} + + + + + {isOwn && ( + { + onClose({}, "backdropClick"); + dispatch( + deleteEventAsync({ calId, eventId, eventURL: event.URL }) + ); + }} + > + + + )} + + + {isOwn && ( + + )} + + + + ); } diff --git a/src/features/Events/eventUtils.ts b/src/features/Events/eventUtils.ts index 088eb0f..f76fd6b 100644 --- a/src/features/Events/eventUtils.ts +++ b/src/features/Events/eventUtils.ts @@ -84,18 +84,21 @@ export function parseCalendarEvent( break; case "rrule": event.repetition = { freq: value.freq.toLowerCase() }; + console.log(value); if (value.byday) { + console.log(value.byday); event.repetition.selectedDays = value.byday; } if (value.until) { - event.repetition.selectedDays = value.endDate; + event.repetition.endDate = value.until; } if (value.count) { - event.repetition.selectedDays = value.occurrences; + event.repetition.occurrences = value.count; } if (value.interval) { event.repetition.interval = value.interval; } + console.log(event.repetition); break; } }