[#1] added base calendar and started to tweak ui

This commit is contained in:
Camille Moussu
2025-06-27 18:11:23 +02:00
parent cceb83519f
commit 624c1b43ca
19 changed files with 1593 additions and 238 deletions
+137
View File
@@ -0,0 +1,137 @@
// components/EventModal.tsx
import React, { useEffect, useState } from "react";
import { addEvent } from "./EventsSlice";
import { CalendarEvent } from "./EventsTypes";
import { DateSelectArg } from "@fullcalendar/core";
import { useAppDispatch } from "../../app/hooks";
import { Popover, TextField, Button, Box, Typography } from "@mui/material";
function EventPopover({
anchorEl,
open,
onClose,
selectedRange,
}: {
anchorEl: HTMLElement | null;
open: boolean;
onClose: (event: {}, reason: "backdropClick" | "escapeKeyDown") => void;
selectedRange: any;
}) {
const dispatch = useAppDispatch();
const [title, setTitle] = useState("");
const [description, setDescription] = useState("");
const [location, setLocation] = useState("");
const [calendar, setCalendar] = useState("");
const [start, setStart] = useState("");
const [end, setEnd] = useState("");
useEffect(() => {
if (selectedRange) {
setStart(selectedRange.startStr);
setEnd(selectedRange.endStr ?? "");
}
}, [selectedRange]);
const handleSave = () => {
const newEvent: CalendarEvent = {
title,
start,
end,
calendar,
extendedProps: {
description,
location,
},
};
dispatch(addEvent(newEvent));
console.log(newEvent)
onClose({}, "backdropClick");
// Reset
setTitle("");
setDescription("");
setLocation("");
};
return (
<Popover
open={open}
anchorEl={anchorEl}
onClose={onClose}
anchorOrigin={{
vertical: "top",
horizontal: "left",
}}
transformOrigin={{
vertical: "top",
horizontal: "left",
}}
>
<Box p={2} width={300}>
<Typography variant="h6" gutterBottom>
Create Event
</Typography>
<TextField
fullWidth
label="Title"
value={title}
onChange={(e) => setTitle(e.target.value)}
size="small"
margin="dense"
/>
<TextField
fullWidth
label="Start"
type="datetime-local"
value={start}
onChange={(e) => setStart(e.target.value)}
size="small"
margin="dense"
InputLabelProps={{ shrink: true }}
/>
<TextField
fullWidth
label="End"
type="datetime-local"
value={end}
onChange={(e) => setEnd(e.target.value)}
size="small"
margin="dense"
InputLabelProps={{ shrink: true }}
/>
<TextField
fullWidth
label="Description"
value={description}
onChange={(e) => setDescription(e.target.value)}
size="small"
margin="dense"
multiline
rows={2}
/>
<TextField
fullWidth
label="Location"
value={location}
onChange={(e) => setLocation(e.target.value)}
size="small"
margin="dense"
/>
<Box mt={2} display="flex" justifyContent="flex-end" gap={1}>
<Button
variant="outlined"
onClick={() => onClose({}, "backdropClick")}
>
Cancel
</Button>
<Button variant="contained" onClick={handleSave}>
Save
</Button>
</Box>
</Box>
</Popover>
);
}
export default EventPopover;
+17
View File
@@ -0,0 +1,17 @@
// store/eventsSlice.ts
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { CalendarEvent } from "./EventsTypes";
const eventsSlice = createSlice({
name: "events",
initialState: [] as CalendarEvent[],
reducers: {
addEvent: (state, action: PayloadAction<CalendarEvent>) => {
state.push(action.payload);
},
},
});
export const { addEvent } = eventsSlice.actions;
export default eventsSlice.reducer;
+11
View File
@@ -0,0 +1,11 @@
// types/Event.ts
export interface CalendarEvent {
title: string;
start: string; // ISO date
end?: string;
calendar:string;
extendedProps?: {
description?: string;
location?: string;
};
}
+38
View File
@@ -0,0 +1,38 @@
import React, { useEffect } from "react";
import { useAppDispatch, useAppSelector } from "../../app/hooks";
import { Auth } from "./oidcAuth";
import { Loading } from "../../components/Loading/Loading";
import { Error } from "../../components/Error/Error";
import { push } from "redux-first-history";
export function HandleLogin() {
const userData = useAppSelector((state) => state.user.userData);
const dispatch = useAppDispatch();
useEffect(() => {
const initiateLogin = async () => {
if (!userData) {
const loginurl = await Auth();
sessionStorage.setItem(
"redirectState",
JSON.stringify({
code_verifier: loginurl.code_verifier,
state: loginurl.state,
})
);
window.location.assign(loginurl.redirectTo);
}
};
initiateLogin();
}, [userData]);
if (!userData) {
return <Error />;
}
dispatch(push("/calendar"));
return <Loading />;
}
export default HandleLogin;
+2 -19
View File
@@ -4,6 +4,7 @@ import { Callback } from "./oidcAuth";
import { useAppDispatch, useAppSelector } from "../../app/hooks";
import { push } from "redux-first-history";
import { setUserData } from "./userSlice";
import { Loading } from "../../components/Loading/Loading";
export function CallbackResume() {
const dispatch = useAppDispatch();
@@ -43,23 +44,5 @@ export function CallbackResume() {
}
}, [dispatch, saved]);
return (
<div>
<p>Processing OIDC callback...</p>
{/* Optionally show loading or debug info */}
{tokens && (
<ul>
<li>
ID_Token: <pre>{JSON.stringify(tokens?.id_token)}</pre>
</li>
<li>
Access_Token: <pre>{JSON.stringify(tokens?.access_token)}</pre>
</li>
<li>
User info: <pre>{JSON.stringify(userInfo, null, 2)}</pre>
</li>
</ul>
)}
</div>
);
return <Loading />;
}