Agenda refactor
This commit is contained in:
parent
9d5a8d6d2f
commit
82070fa033
@ -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">
|
||||
|
||||
Loading…
Reference in New Issue
Block a user