Agenda refactor
This commit is contained in:
parent
9d5a8d6d2f
commit
82070fa033
@ -994,10 +994,15 @@ export function CalendarClient({ initialCalendars, userId, userProfile }: Calend
|
|||||||
const endDate = new Date(startDate);
|
const endDate = new Date(startDate);
|
||||||
endDate.setHours(startDate.getHours() + 1);
|
endDate.setHours(startDate.getHours() + 1);
|
||||||
|
|
||||||
// If no calendar is selected, use the first available calendar
|
// Get available calendars and use the first one if needed
|
||||||
if (!selectedCalendarId && calendars.length > 0) {
|
const availableCalendarsList = getAvailableCalendars();
|
||||||
const firstCalendar = calendars[0];
|
const calendarToUse = selectedCalendarId && availableCalendarsList.some(cal => cal.id === selectedCalendarId)
|
||||||
setSelectedCalendarId(firstCalendar.id);
|
? selectedCalendarId
|
||||||
|
: (availableCalendarsList[0]?.id || calendars[0]?.id);
|
||||||
|
|
||||||
|
if (calendarToUse && calendarToUse !== selectedCalendarId) {
|
||||||
|
setSelectedCalendarId(calendarToUse);
|
||||||
|
}
|
||||||
|
|
||||||
setEventForm({
|
setEventForm({
|
||||||
title: "",
|
title: "",
|
||||||
@ -1006,19 +1011,8 @@ export function CalendarClient({ initialCalendars, userId, userProfile }: Calend
|
|||||||
end: endDate.toISOString(),
|
end: endDate.toISOString(),
|
||||||
allDay: false,
|
allDay: false,
|
||||||
location: null,
|
location: null,
|
||||||
calendarId: firstCalendar.id
|
calendarId: calendarToUse
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
setEventForm({
|
|
||||||
title: "",
|
|
||||||
description: null,
|
|
||||||
start: startDate.toISOString(),
|
|
||||||
end: endDate.toISOString(),
|
|
||||||
allDay: false,
|
|
||||||
location: null,
|
|
||||||
calendarId: selectedCalendarId
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
setIsEventModalOpen(true);
|
setIsEventModalOpen(true);
|
||||||
lastClickDateRef.current = null;
|
lastClickDateRef.current = null;
|
||||||
@ -1050,32 +1044,25 @@ export function CalendarClient({ initialCalendars, userId, userProfile }: Calend
|
|||||||
selectDate.setHours(0, 0, 0, 0);
|
selectDate.setHours(0, 0, 0, 0);
|
||||||
setSelectedDate(selectDate);
|
setSelectedDate(selectDate);
|
||||||
|
|
||||||
// If no calendar is selected, use the first available calendar
|
// Get available calendars and use the first one if needed
|
||||||
if (!selectedCalendarId && calendars.length > 0) {
|
const availableCalendarsList = getAvailableCalendars();
|
||||||
const firstCalendar = calendars[0];
|
const calendarToUse = selectedCalendarId && availableCalendarsList.some(cal => cal.id === selectedCalendarId)
|
||||||
console.log("No calendar selected, selecting first calendar:", firstCalendar);
|
? selectedCalendarId
|
||||||
setSelectedCalendarId(firstCalendar.id);
|
: (availableCalendarsList[0]?.id || calendars[0]?.id);
|
||||||
|
|
||||||
|
if (calendarToUse && calendarToUse !== selectedCalendarId) {
|
||||||
|
setSelectedCalendarId(calendarToUse);
|
||||||
|
}
|
||||||
|
|
||||||
setEventForm({
|
setEventForm({
|
||||||
title: "",
|
title: "",
|
||||||
description: null,
|
description: null,
|
||||||
start: startDate.toISOString(),
|
start: startDate.toISOString(),
|
||||||
end: endDate.toISOString(),
|
end: endDate.toISOString(),
|
||||||
allDay: selectInfo.allDay,
|
allDay: selectInfo.allDay || false,
|
||||||
location: null,
|
location: null,
|
||||||
calendarId: firstCalendar.id
|
calendarId: calendarToUse
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
setEventForm({
|
|
||||||
title: "",
|
|
||||||
description: null,
|
|
||||||
start: startDate.toISOString(),
|
|
||||||
end: endDate.toISOString(),
|
|
||||||
allDay: selectInfo.allDay,
|
|
||||||
location: null,
|
|
||||||
calendarId: selectedCalendarId
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
setIsEventModalOpen(true);
|
setIsEventModalOpen(true);
|
||||||
};
|
};
|
||||||
@ -1085,6 +1072,15 @@ export function CalendarClient({ initialCalendars, userId, userProfile }: Calend
|
|||||||
const startDate = new Date(event.start);
|
const startDate = new Date(event.start);
|
||||||
const endDate = new Date(event.end || 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);
|
setSelectedEvent(event.extendedProps.originalEvent);
|
||||||
setEventForm({
|
setEventForm({
|
||||||
title: event.title,
|
title: event.title,
|
||||||
@ -1093,7 +1089,7 @@ export function CalendarClient({ initialCalendars, userId, userProfile }: Calend
|
|||||||
end: endDate.toISOString().slice(0, 16),
|
end: endDate.toISOString().slice(0, 16),
|
||||||
allDay: event.isAllDay,
|
allDay: event.isAllDay,
|
||||||
location: event.extendedProps.location,
|
location: event.extendedProps.location,
|
||||||
calendarId: event.extendedProps.calendarId,
|
calendarId: calendarIdToUse,
|
||||||
});
|
});
|
||||||
setIsEventModalOpen(true);
|
setIsEventModalOpen(true);
|
||||||
};
|
};
|
||||||
@ -1248,6 +1244,59 @@ export function CalendarClient({ initialCalendars, userId, userProfile }: Calend
|
|||||||
return calendar.name;
|
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
|
// Update CalendarSelector to handle visibility - displayed as a left column
|
||||||
const CalendarSelector = () => (
|
const CalendarSelector = () => (
|
||||||
<div className="flex flex-col gap-2 mb-4">
|
<div className="flex flex-col gap-2 mb-4">
|
||||||
@ -1892,8 +1941,9 @@ export function CalendarClient({ initialCalendars, userId, userProfile }: Calend
|
|||||||
|
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label className="text-base font-semibold text-gray-800">Calendrier</Label>
|
<Label className="text-base font-semibold text-gray-800">Calendrier</Label>
|
||||||
<div className="grid grid-cols-2 gap-2">
|
<ScrollArea className="max-h-64 border border-gray-200 rounded-lg">
|
||||||
{calendars.map((cal) => {
|
<div className="space-y-1 p-2">
|
||||||
|
{getAvailableCalendars().map((cal) => {
|
||||||
const calWithMission = cal as CalendarWithMission;
|
const calWithMission = cal as CalendarWithMission;
|
||||||
const label = getCalendarDisplayName(calWithMission);
|
const label = getCalendarDisplayName(calWithMission);
|
||||||
return (
|
return (
|
||||||
@ -1906,17 +1956,17 @@ export function CalendarClient({ initialCalendars, userId, userProfile }: Calend
|
|||||||
calendarId: cal.id
|
calendarId: cal.id
|
||||||
}));
|
}));
|
||||||
}}
|
}}
|
||||||
className={`flex items-center gap-2 px-3 py-2 rounded-lg transition-all ${
|
className={`w-full flex items-center gap-3 px-3 py-2.5 rounded-lg transition-all text-left ${
|
||||||
eventForm.calendarId === cal.id
|
eventForm.calendarId === cal.id
|
||||||
? 'bg-white ring-2 ring-primary'
|
? 'bg-blue-50 ring-2 ring-blue-500 border border-blue-200'
|
||||||
: 'bg-white hover:bg-gray-50 border border-gray-200'
|
: 'bg-white hover:bg-gray-50 border border-gray-200'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="w-3 h-3 rounded-full"
|
className="w-4 h-4 rounded-full flex-shrink-0"
|
||||||
style={{ backgroundColor: cal.color }}
|
style={{ backgroundColor: cal.color }}
|
||||||
/>
|
/>
|
||||||
<span className={`text-sm ${
|
<span className={`text-sm flex-1 ${
|
||||||
eventForm.calendarId === cal.id
|
eventForm.calendarId === cal.id
|
||||||
? 'font-medium text-gray-900'
|
? 'font-medium text-gray-900'
|
||||||
: 'text-gray-700'
|
: 'text-gray-700'
|
||||||
@ -1924,13 +1974,18 @@ export function CalendarClient({ initialCalendars, userId, userProfile }: Calend
|
|||||||
{label}
|
{label}
|
||||||
</span>
|
</span>
|
||||||
{calWithMission.syncConfig?.syncEnabled && (
|
{calWithMission.syncConfig?.syncEnabled && (
|
||||||
<Badge variant="outline" className="ml-auto text-[10px] px-1 py-0.5 border-blue-400 text-blue-600">
|
<Badge variant="outline" className="text-[10px] px-1.5 py-0.5 border-blue-400 text-blue-600 flex-shrink-0">
|
||||||
Sync
|
Sync
|
||||||
</Badge>
|
</Badge>
|
||||||
)}
|
)}
|
||||||
|
{eventForm.calendarId === cal.id && (
|
||||||
|
<Check className="w-4 h-4 text-blue-600 flex-shrink-0" />
|
||||||
|
)}
|
||||||
</button>
|
</button>
|
||||||
);})}
|
);
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
</ScrollArea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid grid-cols-2 gap-4">
|
<div className="grid grid-cols-2 gap-4">
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user