Agenda refactor

This commit is contained in:
alma 2026-01-15 18:36:33 +01:00
parent 9d5a8d6d2f
commit 82070fa033

View File

@ -994,32 +994,26 @@ export function CalendarClient({ initialCalendars, userId, userProfile }: Calend
const endDate = new Date(startDate);
endDate.setHours(startDate.getHours() + 1);
// If no calendar is selected, use the first available calendar
if (!selectedCalendarId && calendars.length > 0) {
const firstCalendar = calendars[0];
setSelectedCalendarId(firstCalendar.id);
setEventForm({
title: "",
description: null,
start: startDate.toISOString(),
end: endDate.toISOString(),
allDay: false,
location: null,
calendarId: firstCalendar.id
});
} else {
setEventForm({
title: "",
description: null,
start: startDate.toISOString(),
end: endDate.toISOString(),
allDay: false,
location: null,
calendarId: selectedCalendarId
});
// Get available calendars and use the first one if needed
const availableCalendarsList = getAvailableCalendars();
const calendarToUse = selectedCalendarId && availableCalendarsList.some(cal => cal.id === selectedCalendarId)
? selectedCalendarId
: (availableCalendarsList[0]?.id || calendars[0]?.id);
if (calendarToUse && calendarToUse !== selectedCalendarId) {
setSelectedCalendarId(calendarToUse);
}
setEventForm({
title: "",
description: null,
start: startDate.toISOString(),
end: endDate.toISOString(),
allDay: false,
location: null,
calendarId: calendarToUse
});
setIsEventModalOpen(true);
lastClickDateRef.current = null;
} else {
@ -1050,33 +1044,26 @@ export function CalendarClient({ initialCalendars, userId, userProfile }: Calend
selectDate.setHours(0, 0, 0, 0);
setSelectedDate(selectDate);
// If no calendar is selected, use the first available calendar
if (!selectedCalendarId && calendars.length > 0) {
const firstCalendar = calendars[0];
console.log("No calendar selected, selecting first calendar:", firstCalendar);
setSelectedCalendarId(firstCalendar.id);
setEventForm({
title: "",
description: null,
start: startDate.toISOString(),
end: endDate.toISOString(),
allDay: selectInfo.allDay,
location: null,
calendarId: firstCalendar.id
});
} else {
setEventForm({
title: "",
description: null,
start: startDate.toISOString(),
end: endDate.toISOString(),
allDay: selectInfo.allDay,
location: null,
calendarId: selectedCalendarId
});
// Get available calendars and use the first one if needed
const availableCalendarsList = getAvailableCalendars();
const calendarToUse = selectedCalendarId && availableCalendarsList.some(cal => cal.id === selectedCalendarId)
? selectedCalendarId
: (availableCalendarsList[0]?.id || calendars[0]?.id);
if (calendarToUse && calendarToUse !== selectedCalendarId) {
setSelectedCalendarId(calendarToUse);
}
setEventForm({
title: "",
description: null,
start: startDate.toISOString(),
end: endDate.toISOString(),
allDay: selectInfo.allDay || false,
location: null,
calendarId: calendarToUse
});
setIsEventModalOpen(true);
};
@ -1085,6 +1072,15 @@ export function CalendarClient({ initialCalendars, userId, userProfile }: Calend
const startDate = new Date(event.start);
const endDate = new Date(event.end || event.start);
const eventCalendarId = event.extendedProps.calendarId;
const availableCalendars = getAvailableCalendars();
// Check if the event's calendar is still available for editing
const canEditEventCalendar = availableCalendars.some(cal => cal.id === eventCalendarId);
// If not available, use the first available calendar instead
const calendarIdToUse = canEditEventCalendar ? eventCalendarId : (availableCalendars[0]?.id || eventCalendarId);
setSelectedEvent(event.extendedProps.originalEvent);
setEventForm({
title: event.title,
@ -1093,7 +1089,7 @@ export function CalendarClient({ initialCalendars, userId, userProfile }: Calend
end: endDate.toISOString().slice(0, 16),
allDay: event.isAllDay,
location: event.extendedProps.location,
calendarId: event.extendedProps.calendarId,
calendarId: calendarIdToUse,
});
setIsEventModalOpen(true);
};
@ -1248,6 +1244,59 @@ export function CalendarClient({ initialCalendars, userId, userProfile }: Calend
return calendar.name;
};
// Check if user can create/edit events in a mission calendar
const canEditMissionCalendar = (calendar: CalendarWithMission): boolean => {
// If not a mission calendar, allow
if (!calendar.missionId || !calendar.mission) {
return true;
}
const mission = calendar.mission;
// Check if user is the creator
if (mission.creatorId === userId) {
return true;
}
// Check if user has one of the guardian roles
const guardianRoles = ['gardien-temps', 'gardien-parole', 'gardien-memoire'];
const userMissionRole = mission.missionUsers?.find(
mu => mu.userId === userId && guardianRoles.includes(mu.role)
);
return !!userMissionRole;
};
// Get available calendars for event creation/editing
const getAvailableCalendars = (): CalendarWithMission[] => {
return calendars.filter(cal => {
const calWithMission = cal as CalendarWithMission;
// Always allow "Mon Calendrier"
if (cal.name === "Mon Calendrier") {
return true;
}
// Always allow Microsoft synced calendars
if (calWithMission.syncConfig?.syncEnabled && calWithMission.syncConfig?.mailCredential) {
return true;
}
// Always allow group calendars
if (cal.name?.startsWith("Groupe:")) {
return true;
}
// For mission calendars, check permissions
if (cal.name?.startsWith("Mission:")) {
return canEditMissionCalendar(calWithMission);
}
// Allow other calendars by default
return true;
});
};
// Update CalendarSelector to handle visibility - displayed as a left column
const CalendarSelector = () => (
<div className="flex flex-col gap-2 mb-4">
@ -1892,45 +1941,51 @@ export function CalendarClient({ initialCalendars, userId, userProfile }: Calend
<div className="space-y-2">
<Label className="text-base font-semibold text-gray-800">Calendrier</Label>
<div className="grid grid-cols-2 gap-2">
{calendars.map((cal) => {
const calWithMission = cal as CalendarWithMission;
const label = getCalendarDisplayName(calWithMission);
return (
<button
key={cal.id}
type="button"
onClick={() => {
setEventForm(prev => ({
...prev,
calendarId: cal.id
}));
}}
className={`flex items-center gap-2 px-3 py-2 rounded-lg transition-all ${
eventForm.calendarId === cal.id
? 'bg-white ring-2 ring-primary'
: 'bg-white hover:bg-gray-50 border border-gray-200'
}`}
>
<div
className="w-3 h-3 rounded-full"
style={{ backgroundColor: cal.color }}
/>
<span className={`text-sm ${
eventForm.calendarId === cal.id
? 'font-medium text-gray-900'
: 'text-gray-700'
}`}>
{label}
</span>
{calWithMission.syncConfig?.syncEnabled && (
<Badge variant="outline" className="ml-auto text-[10px] px-1 py-0.5 border-blue-400 text-blue-600">
Sync
</Badge>
)}
</button>
);})}
</div>
<ScrollArea className="max-h-64 border border-gray-200 rounded-lg">
<div className="space-y-1 p-2">
{getAvailableCalendars().map((cal) => {
const calWithMission = cal as CalendarWithMission;
const label = getCalendarDisplayName(calWithMission);
return (
<button
key={cal.id}
type="button"
onClick={() => {
setEventForm(prev => ({
...prev,
calendarId: cal.id
}));
}}
className={`w-full flex items-center gap-3 px-3 py-2.5 rounded-lg transition-all text-left ${
eventForm.calendarId === cal.id
? 'bg-blue-50 ring-2 ring-blue-500 border border-blue-200'
: 'bg-white hover:bg-gray-50 border border-gray-200'
}`}
>
<div
className="w-4 h-4 rounded-full flex-shrink-0"
style={{ backgroundColor: cal.color }}
/>
<span className={`text-sm flex-1 ${
eventForm.calendarId === cal.id
? 'font-medium text-gray-900'
: 'text-gray-700'
}`}>
{label}
</span>
{calWithMission.syncConfig?.syncEnabled && (
<Badge variant="outline" className="text-[10px] px-1.5 py-0.5 border-blue-400 text-blue-600 flex-shrink-0">
Sync
</Badge>
)}
{eventForm.calendarId === cal.id && (
<Check className="w-4 h-4 text-blue-600 flex-shrink-0" />
)}
</button>
);
})}
</div>
</ScrollArea>
</div>
<div className="grid grid-cols-2 gap-4">