[#64] added creation modal to list and api call

This commit is contained in:
Camille Moussu
2025-09-11 16:59:03 +02:00
committed by Benoit TELLIER
parent d1140a47b2
commit 9d43c15ee0
6 changed files with 152 additions and 93 deletions
+21
View File
@@ -30,3 +30,24 @@ export async function getCalendar(
const calendar = await response.json();
return calendar;
}
export async function postCalendar(
userId: string,
calId: string,
color: string,
name: string,
desc: string
) {
const response = await api.post(`dav/calendars/${userId}.json`, {
headers: {
Accept: "application/json, text/plain, */*",
},
body: JSON.stringify({
id: calId,
"dav:name": name,
"apple:color": color,
"caldav:description": desc,
}),
});
return response;
}
+9 -5
View File
@@ -1,6 +1,6 @@
import { useState } from "react";
import { createCalendar } from "./CalendarSlice";
import { useAppDispatch } from "../../app/hooks";
import { createCalendar, createCalendarAsync } from "./CalendarSlice";
import { useAppDispatch, useAppSelector } from "../../app/hooks";
import {
Popover,
TextField,
@@ -21,14 +21,18 @@ function CalendarPopover({
onClose: (Calendar: {}, reason: "backdropClick" | "escapeKeyDown") => void;
}) {
const dispatch = useAppDispatch();
const userId =
useAppSelector((state) => state.user.userData.openpaasId) ?? "";
const [name, setName] = useState("");
const [description, setDescription] = useState("");
const [color, setColor] = useState("");
const [timeZone, setTimeZone] = useState("");
const timezones = Intl.supportedValuesOf?.("timeZone") ?? [];
const handleSave = () => {
dispatch(createCalendar({ name, description, color }));
const calId = crypto.randomUUID();
dispatch(
createCalendarAsync({ name, desc: description, color, userId, calId })
);
onClose({}, "backdropClick");
// Reset
@@ -68,7 +72,7 @@ function CalendarPopover({
gutterBottom
style={{ backgroundColor: color }}
>
Create a Calendar
Calendar configuration
</Typography>
<TextField
fullWidth
+22 -4
View File
@@ -1,7 +1,7 @@
import { createAsyncThunk, createSlice, PayloadAction } from "@reduxjs/toolkit";
import { Calendars } from "./CalendarTypes";
import { CalendarEvent } from "../Events/EventsTypes";
import { getCalendar, getCalendars } from "./CalendarApi";
import { getCalendar, getCalendars, postCalendar } from "./CalendarApi";
import { getOpenPaasUser, getUserDetails } from "../User/userAPI";
import { parseCalendarEvent } from "../Events/eventUtils";
import { deleteEvent, getEvent, moveEvent, putEvent } from "../Events/EventApi";
@@ -157,6 +157,14 @@ export const deleteEventAsync = createAsyncThunk<
return { calId, eventId };
});
export const createCalendarAsync = createAsyncThunk<
{ userId: string; calId: string; color: string; name: string; desc: string }, // Return type
{ userId: string; calId: string; color: string; name: string; desc: string } // Arg type
>("calendars/createCalendar", async ({ userId, calId, color, name, desc }) => {
const response = await postCalendar(userId, calId, color, name, desc);
return { userId, calId, color, name, desc };
});
const CalendarSlice = createSlice({
name: "calendars",
initialState: { list: {} as Record<string, Calendars>, pending: false },
@@ -206,9 +214,7 @@ const CalendarSlice = createSlice({
getCalendarsListAsync.fulfilled,
(state, action: PayloadAction<Record<string, Calendars>>) => {
state.pending = false;
Object.keys(action.payload).forEach((id) => {
state.list[id] = action.payload[id];
});
state.list = action.payload;
}
)
.addCase(
@@ -324,6 +330,15 @@ const CalendarSlice = createSlice({
];
}
})
.addCase(createCalendarAsync.fulfilled, (state, action) => {
state.pending = false;
state.list[`${action.payload.userId}/${action.payload.calId}`] = {
color: action.payload.color,
id: `${action.payload.userId}/${action.payload.calId}`,
description: action.payload.desc,
name: action.payload.name,
} as unknown as Calendars;
})
.addCase(getCalendarDetailAsync.pending, (state) => {
state.pending = true;
})
@@ -341,6 +356,9 @@ const CalendarSlice = createSlice({
})
.addCase(deleteEventAsync.pending, (state) => {
state.pending = true;
})
.addCase(createCalendarAsync.pending, (state) => {
state.pending = true;
});
},
});
+23 -21
View File
@@ -18,28 +18,30 @@ export default function ImportAlert() {
return (
<>
{Object.keys(calendars).map((calendarId) =>
Object.keys(calendars[calendarId].events)
.filter((id) => calendars[calendarId].events[id].error)
.map((id) => {
const isVisible =
visibleAlerts[calendars[calendarId].events[id].uid] ?? true; // default to visible
calendars[calendarId]?.events
? Object.keys(calendars[calendarId]?.events)
.filter((id) => calendars[calendarId]?.events[id].error)
.map((id) => {
const isVisible =
visibleAlerts[calendars[calendarId].events[id].uid] ?? true; // default to visible
return (
<Collapse
in={isVisible}
key={calendars[calendarId].events[id].uid}
>
<Alert
severity="error"
onClose={() =>
toggleEventAlert(calendars[calendarId].events[id].uid)
}
>
{calendars[calendarId].events[id].error}
</Alert>
</Collapse>
);
})
return (
<Collapse
in={isVisible}
key={calendars[calendarId].events[id].uid}
>
<Alert
severity="error"
onClose={() =>
toggleEventAlert(calendars[calendarId].events[id].uid)
}
>
{calendars[calendarId].events[id].error}
</Alert>
</Collapse>
);
})
: []
)}
</>
);