[#4] attendance now change event display

This commit is contained in:
Camille Moussu
2025-08-01 17:41:13 +02:00
parent a71d1f12fb
commit cd829703e9
6 changed files with 111 additions and 3 deletions
@@ -30,6 +30,7 @@ describe("MiniCalendar", () => {
"667037022b752d0026472254/cal1": {
name: "Calendar 1",
color: "#FF0000",
ownerEmails: ["test@test.com"],
events: {
event1: {
calId: "667037022b752d0026472254/cal1",
@@ -139,6 +140,7 @@ describe("Found Bugs", () => {
"667037022b752d0026472254/cal1": {
name: "Calendar 1",
color: "#FF0000",
ownerEmails: ["test.test@test.com"],
events: {
event1: {
calId: "667037022b752d0026472254/cal1",
+12
View File
@@ -27,6 +27,18 @@ main {
position: relative;
}
.declined-event {
opacity: 0.7;
}
.tentative-event {
}
.needs-action-event {
opacity: 0.7;
border: dashed 1px #ffffff;
}
.fc .fc-timegrid-slot {
height: 30px !important;
min-height: 30px !important;
+81
View File
@@ -27,12 +27,17 @@ import { Calendars } from "../../features/Calendars/CalendarTypes";
import { push } from "redux-first-history";
import EventDisplayModal from "../../features/Events/EventDisplay";
import { createSelector } from "@reduxjs/toolkit";
import HelpOutlineIcon from "@mui/icons-material/HelpOutline";
import ClearIcon from "@mui/icons-material/Clear";
import AccessTimeIcon from "@mui/icons-material/AccessTime";
import { userAttendee } from "../../features/User/userDataTypes";
export default function CalendarApp() {
const calendarRef = useRef<CalendarApi | null>(null);
const [selectedDate, setSelectedDate] = useState(new Date());
const [selectedMiniDate, setSelectedMiniDate] = useState(new Date());
const tokens = useAppSelector((state) => state.user.tokens);
const user = useAppSelector((state) => state.user.userData);
const dispatch = useAppDispatch();
if (!tokens) {
@@ -372,6 +377,82 @@ export default function CalendarApp() {
center: "prev,today,next",
right: "dayGridMonth,timeGridWeek,timeGridDay",
}}
eventContent={(arg) => {
const event = arg.event;
if (!calendars[arg.event._def.extendedProps.calId]) return;
const attendees = event._def.extendedProps.attendee || [];
let Icon = null;
let titleStyle: React.CSSProperties = {};
const ownerEmails = new Set(
calendars[arg.event._def.extendedProps.calId].ownerEmails?.map(
(email) => email.toLowerCase()
)
);
const showSpecialDisplay = attendees.filter((att: userAttendee) =>
ownerEmails.has(att.cal_address.toLowerCase())
);
if (!showSpecialDisplay[0]) return;
switch (showSpecialDisplay[0].partstat) {
case "DECLINED":
Icon = null;
titleStyle.textDecoration = "line-through";
break;
case "TENTATIVE":
Icon = HelpOutlineIcon;
break;
case "NEEDS-ACTION":
Icon = AccessTimeIcon;
break;
case "ACCEPTED":
Icon = null;
break;
default:
break;
}
return (
<div>
{Icon && <Icon fontSize="small" />}
<span style={titleStyle}>{event.title}</span>
</div>
);
}}
eventDidMount={(arg) => {
const attendees = arg.event._def.extendedProps.attendee || [];
if (!calendars[arg.event._def.extendedProps.calId]) return;
const ownerEmails = new Set(
calendars[arg.event._def.extendedProps.calId].ownerEmails?.map(
(email) => email.toLowerCase()
)
);
const showSpecialDisplay = attendees.filter((att: userAttendee) =>
ownerEmails.has(att.cal_address.toLowerCase())
);
if (!showSpecialDisplay[0]) return;
// Clear previously applied classes
arg.el.classList.remove(
"declined-event",
"tentative-event",
"needs-action-event"
);
switch (showSpecialDisplay[0].partstat) {
case "DECLINED":
arg.el.classList.add("declined-event");
break;
case "TENTATIVE":
arg.el.classList.add("tentative-event");
break;
case "NEEDS-ACTION":
arg.el.classList.add("needs-action-event");
break;
default:
break;
}
}}
/>
<EventPopover
anchorEl={anchorEl}
+10 -3
View File
@@ -2,7 +2,7 @@ import { createAsyncThunk, createSlice, PayloadAction } from "@reduxjs/toolkit";
import { Calendars } from "./CalendarTypes";
import { CalendarEvent } from "../Events/EventsTypes";
import { getCalendar, getCalendars } from "./CalendarApi";
import getOpenPaasUser from "../User/userAPI";
import getOpenPaasUser, { getUserDetails } from "../User/userAPI";
import { parseCalendarEvent } from "../Events/eventUtils";
import { deleteEvent, putEvent } from "../Events/EventApi";
import { formatDateToYYYYMMDDTHHMMSS } from "../../utils/dateUtils";
@@ -24,9 +24,16 @@ export const getCalendarsListAsync = createAsyncThunk<
.replace("/calendars/", "")
.replace(".json", "")
: cal._links.self.href.replace("/calendars/", "").replace(".json", "");
const ownerData: any = await getUserDetails(id.split("/")[0]);
const color = cal["apple:color"];
importedCalendars[id] = { id, name, description, color, events: {} };
importedCalendars[id] = {
id,
name,
ownerEmails: ownerData.emails,
description,
color,
events: {},
};
}
return importedCalendars;
+1
View File
@@ -5,6 +5,7 @@ export interface Calendars {
name: string;
prodid?: string;
color?: string;
ownerEmails?: string[];
description?: string;
calscale?: string;
version?: string;
+5
View File
@@ -25,3 +25,8 @@ export async function searchUsers(query: string) {
avatarUrl: user.photos?.[0]?.url || "",
}));
}
export async function getUserDetails(id: string) {
const user = await api.get(`api/users/${id}`).json();
return user;
}