[#31] added repetition and all day to events to be sent

This commit is contained in:
Camille Moussu
2025-07-23 12:12:56 +02:00
parent 08789cb6f3
commit a150db82cd
4 changed files with 65 additions and 14 deletions
+10
View File
@@ -16,3 +16,13 @@ export async function putEvent(cal: Calendars, event: CalendarEvent) {
).json();
return response;
}
export async function deleteEvent(calId: string, eventId: string) {
const response = await api(
`dav/calendars/${calId}/${eventId.split(".")[0]}.isc`,
{
method: "DELETE",
}
).json();
return response;
}
+39 -10
View File
@@ -18,6 +18,7 @@ import {
import { Calendars } from "../Calendars/CalendarTypes";
import { putEvent } from "./EventApi";
import { TIMEZONES } from "../../utils/timezone-data";
import { CheckBox, Repeat } from "@mui/icons-material";
function EventPopover({
anchorEl,
@@ -50,6 +51,8 @@ function EventPopover({
const [start, setStart] = useState("");
const [end, setEnd] = useState("");
const [calendarid, setCalendarid] = useState(0);
const [allday, setAllDay] = useState(false);
const [repetition, setRepetition] = useState("");
const [timezone, setTimezone] = useState(
Intl.DateTimeFormat().resolvedOptions().timeZone
);
@@ -66,9 +69,11 @@ function EventPopover({
title,
start: new Date(start),
end: new Date(end),
allday,
uid: crypto.randomUUID(),
description,
location,
repetition,
organizer,
timezone,
attendee: [
@@ -113,6 +118,14 @@ function EventPopover({
Create Event
</Typography>
<TextField
fullWidth
label="Title"
value={title}
onChange={(e) => setTitle(e.target.value)}
size="small"
margin="dense"
/>
<FormControl fullWidth margin="dense" size="small">
<InputLabel id="calendar-select-label">Calendar</InputLabel>
<Select
@@ -131,18 +144,10 @@ function EventPopover({
</Select>
</FormControl>
<TextField
fullWidth
label="Title"
value={title}
onChange={(e) => setTitle(e.target.value)}
size="small"
margin="dense"
/>
<TextField
fullWidth
label="Start"
type="datetime-local"
type={allday ? "date" : "datetime-local"}
value={start}
onChange={(e) => setStart(e.target.value)}
size="small"
@@ -152,13 +157,21 @@ function EventPopover({
<TextField
fullWidth
label="End"
type="datetime-local"
type={allday ? "date" : "datetime-local"}
value={end}
onChange={(e) => setEnd(e.target.value)}
size="small"
margin="dense"
InputLabelProps={{ shrink: true }}
/>
<label>
<input
type="checkbox"
checked={allday}
onChange={() => setAllDay(!allday)}
/>
All day
</label>
<TextField
fullWidth
label="Description"
@@ -178,6 +191,22 @@ function EventPopover({
margin="dense"
/>
<FormControl fullWidth margin="dense" size="small">
<InputLabel id="repeat">Repetition</InputLabel>
<Select
labelId="repeat"
value={repetition}
label="Time Zone"
onChange={(e: SelectChangeEvent) => setRepetition(e.target.value)}
>
<MenuItem value={""}>No Repetition</MenuItem>
<MenuItem value={"daily"}>Repeat daily</MenuItem>
<MenuItem value={"weekly"}>Repeat weekly</MenuItem>
<MenuItem value={"monthly"}>Repeat monthly</MenuItem>
<MenuItem value={"yearly"}>Repeat yearly</MenuItem>
</Select>
</FormControl>
<FormControl fullWidth margin="dense" size="small">
<InputLabel id="timezone-select-label">Time Zone</InputLabel>
<Select
+1
View File
@@ -19,4 +19,5 @@ export interface CalendarEvent {
error?: string;
status?: string;
timezone: string;
repetition?: string;
}
+15 -4
View File
@@ -94,7 +94,12 @@ export function calendarEventToJCal(event: CalendarEvent): any[] {
[
["uid", {}, "text", event.uid],
["transp", {}, "text", event.transp ?? "OPAQUE"],
["dtstart", { tzid }, "date-time", formatDateToICal(event.start)],
[
"dtstart",
{ tzid },
event.allday ? "date" : "date-time",
formatDateToICal(event.start, event.allday ?? false),
],
["class", {}, "text", event.class ?? "PUBLIC"],
[
"x-openpaas-videoconference",
@@ -111,8 +116,8 @@ export function calendarEventToJCal(event: CalendarEvent): any[] {
vevent[1].push([
"dtend",
{ tzid },
"date-time",
formatDateToICal(event.end),
event.allday ? "date" : "date-time",
formatDateToICal(event.end, event.allday ?? false),
]);
}
if (event.organizer) {
@@ -129,6 +134,9 @@ export function calendarEventToJCal(event: CalendarEvent): any[] {
if (event.description) {
vevent[1].push(["description", {}, "text", event.description]);
}
if (event.repetition) {
vevent[1].push(["rrule", {}, "recur", { freq: event.repetition }]);
}
event.attendee.forEach((att) => {
vevent[1].push([
@@ -151,7 +159,7 @@ export function calendarEventToJCal(event: CalendarEvent): any[] {
});
return ["vcalendar", [], [vevent, vtimezone.component.jCal]];
}
function formatDateToICal(date: Date) {
function formatDateToICal(date: Date, allday: Boolean) {
// Format date like: 20250214T110000 (local time)
const pad = (n: number) => n.toString().padStart(2, "0");
@@ -161,5 +169,8 @@ function formatDateToICal(date: Date) {
const hours = pad(date.getHours());
const minutes = pad(date.getMinutes());
const seconds = pad(date.getSeconds());
if (allday) {
return `${year}-${month}-${day}`;
}
return `${year}${month}${day}T${hours}${minutes}${seconds}`;
}