Agenda refactor
This commit is contained in:
parent
986f66ac92
commit
d8846524f0
@ -647,6 +647,37 @@ export default async function CalendarPage() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Sort calendars: "Mon Calendrier" first, then synced, then groups, then missions
|
||||||
|
calendars = calendars.sort((a, b) => {
|
||||||
|
const aIsMonCalendrier = a.name === "Mon Calendrier";
|
||||||
|
const bIsMonCalendrier = b.name === "Mon Calendrier";
|
||||||
|
const aIsSynced = a.syncConfig?.syncEnabled && a.syncConfig?.mailCredential;
|
||||||
|
const bIsSynced = b.syncConfig?.syncEnabled && b.syncConfig?.mailCredential;
|
||||||
|
const aIsGroup = a.name?.startsWith("Groupe:");
|
||||||
|
const bIsGroup = b.name?.startsWith("Groupe:");
|
||||||
|
const aIsMission = a.name?.startsWith("Mission:");
|
||||||
|
const bIsMission = b.name?.startsWith("Mission:");
|
||||||
|
|
||||||
|
// "Mon Calendrier" always first
|
||||||
|
if (aIsMonCalendrier && !bIsMonCalendrier) return -1;
|
||||||
|
if (!aIsMonCalendrier && bIsMonCalendrier) return 1;
|
||||||
|
|
||||||
|
// Synced calendars second
|
||||||
|
if (aIsSynced && !bIsSynced) return -1;
|
||||||
|
if (!aIsSynced && bIsSynced) return 1;
|
||||||
|
|
||||||
|
// Groups third
|
||||||
|
if (aIsGroup && !bIsGroup && !bIsSynced) return -1;
|
||||||
|
if (!aIsGroup && bIsGroup && !aIsSynced) return 1;
|
||||||
|
|
||||||
|
// Missions fourth
|
||||||
|
if (aIsMission && !bIsMission && !bIsGroup && !bIsSynced) return -1;
|
||||||
|
if (!aIsMission && bIsMission && !aIsGroup && !aIsSynced) return 1;
|
||||||
|
|
||||||
|
// Same type, sort by name
|
||||||
|
return (a.name || '').localeCompare(b.name || '');
|
||||||
|
});
|
||||||
|
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
const nextWeek = add(now, { days: 7 });
|
const nextWeek = add(now, { days: 7 });
|
||||||
|
|
||||||
|
|||||||
@ -169,18 +169,49 @@ export async function GET(req: NextRequest) {
|
|||||||
new Map(calendars.map(cal => [cal.id, cal])).values()
|
new Map(calendars.map(cal => [cal.id, cal])).values()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Sort calendars: "Mon Calendrier" first, then synced, then groups, then missions
|
||||||
|
const sortedCalendars = uniqueCalendars.sort((a, b) => {
|
||||||
|
const aIsMonCalendrier = a.name === "Mon Calendrier";
|
||||||
|
const bIsMonCalendrier = b.name === "Mon Calendrier";
|
||||||
|
const aIsSynced = a.syncConfig?.syncEnabled && a.syncConfig?.mailCredential;
|
||||||
|
const bIsSynced = b.syncConfig?.syncEnabled && b.syncConfig?.mailCredential;
|
||||||
|
const aIsGroup = a.name?.startsWith("Groupe:");
|
||||||
|
const bIsGroup = b.name?.startsWith("Groupe:");
|
||||||
|
const aIsMission = a.name?.startsWith("Mission:");
|
||||||
|
const bIsMission = b.name?.startsWith("Mission:");
|
||||||
|
|
||||||
|
// "Mon Calendrier" always first
|
||||||
|
if (aIsMonCalendrier && !bIsMonCalendrier) return -1;
|
||||||
|
if (!aIsMonCalendrier && bIsMonCalendrier) return 1;
|
||||||
|
|
||||||
|
// Synced calendars second
|
||||||
|
if (aIsSynced && !bIsSynced) return -1;
|
||||||
|
if (!aIsSynced && bIsSynced) return 1;
|
||||||
|
|
||||||
|
// Groups third
|
||||||
|
if (aIsGroup && !bIsGroup && !bIsSynced) return -1;
|
||||||
|
if (!aIsGroup && bIsGroup && !aIsSynced) return 1;
|
||||||
|
|
||||||
|
// Missions fourth
|
||||||
|
if (aIsMission && !bIsMission && !bIsGroup && !bIsSynced) return -1;
|
||||||
|
if (!aIsMission && bIsMission && !aIsGroup && !aIsSynced) return 1;
|
||||||
|
|
||||||
|
// Same type, sort by name
|
||||||
|
return (a.name || '').localeCompare(b.name || '');
|
||||||
|
});
|
||||||
|
|
||||||
logger.debug('[CALENDAR] Fetched calendars with events', {
|
logger.debug('[CALENDAR] Fetched calendars with events', {
|
||||||
userId: session.user.id,
|
userId: session.user.id,
|
||||||
personalCount: filteredPersonalCalendars.length,
|
personalCount: filteredPersonalCalendars.length,
|
||||||
missionCount: missionCalendars.length,
|
missionCount: missionCalendars.length,
|
||||||
totalCount: uniqueCalendars.length,
|
totalCount: sortedCalendars.length,
|
||||||
filteredOut: personalCalendars.length - filteredPersonalCalendars.length,
|
filteredOut: personalCalendars.length - filteredPersonalCalendars.length,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Cache the results
|
// Cache the results
|
||||||
await cacheCalendarData(session.user.id, uniqueCalendars);
|
await cacheCalendarData(session.user.id, sortedCalendars);
|
||||||
|
|
||||||
return NextResponse.json(uniqueCalendars);
|
return NextResponse.json(sortedCalendars);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('[CALENDAR] Erreur lors de la récupération des calendriers', {
|
logger.error('[CALENDAR] Erreur lors de la récupération des calendriers', {
|
||||||
error: error instanceof Error ? error.message : String(error),
|
error: error instanceof Error ? error.message : String(error),
|
||||||
|
|||||||
@ -255,15 +255,16 @@ function CalendarDialog({ open, onClose, onSave, onDelete, onSyncSetup, initialD
|
|||||||
setIsSubmitting(true);
|
setIsSubmitting(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Only update color, preserve name and description from initialData
|
||||||
await onSave({
|
await onSave({
|
||||||
id: initialData?.id,
|
id: initialData?.id,
|
||||||
name,
|
name: initialData?.name || name, // Keep original name
|
||||||
color,
|
color, // Only color can be changed
|
||||||
description
|
description: initialData?.description || description // Keep original description
|
||||||
});
|
});
|
||||||
resetForm();
|
resetForm();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Erreur lors de la création du calendrier:", error);
|
console.error("Erreur lors de la mise à jour du calendrier:", error);
|
||||||
} finally {
|
} finally {
|
||||||
setIsSubmitting(false);
|
setIsSubmitting(false);
|
||||||
}
|
}
|
||||||
@ -301,12 +302,24 @@ function CalendarDialog({ open, onClose, onSave, onDelete, onSyncSetup, initialD
|
|||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle className="flex items-center text-xl font-semibold text-gray-900">
|
<DialogTitle className="flex items-center text-xl font-semibold text-gray-900">
|
||||||
<CalendarIcon className="w-5 h-5 mr-2 text-indigo-600" />
|
<CalendarIcon className="w-5 h-5 mr-2 text-indigo-600" />
|
||||||
{initialData?.id ? "Modifier le calendrier" : "Créer un nouveau calendrier"}
|
{initialData?.id ? "Paramètres du calendrier" : "Créer un nouveau calendrier"}
|
||||||
</DialogTitle>
|
</DialogTitle>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
|
|
||||||
<form onSubmit={handleSubmit}>
|
<form onSubmit={handleSubmit}>
|
||||||
<div className="space-y-5 py-4">
|
<div className="space-y-5 py-4">
|
||||||
|
{/* Display calendar name (read-only) */}
|
||||||
|
{initialData?.id && (
|
||||||
|
<div className="space-y-2">
|
||||||
|
<Label className="text-gray-700">Nom</Label>
|
||||||
|
<div className="px-3 py-2 bg-gray-50 rounded-lg text-gray-900 border border-gray-200">
|
||||||
|
{initialData?.name || name}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Name input only for new calendars */}
|
||||||
|
{!initialData?.id && (
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="calendar-name" className="text-gray-700">Nom</Label>
|
<Label htmlFor="calendar-name" className="text-gray-700">Nom</Label>
|
||||||
<Input
|
<Input
|
||||||
@ -315,10 +328,10 @@ function CalendarDialog({ open, onClose, onSave, onDelete, onSyncSetup, initialD
|
|||||||
onChange={(e) => setName(e.target.value)}
|
onChange={(e) => setName(e.target.value)}
|
||||||
placeholder="Nom du calendrier"
|
placeholder="Nom du calendrier"
|
||||||
required
|
required
|
||||||
disabled={isMainCalendar || isMissionOrGroupCalendar}
|
|
||||||
className="rounded-lg border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 bg-white text-gray-900"
|
className="rounded-lg border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 bg-white text-gray-900"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<Label className="text-gray-700">Couleur</Label>
|
<Label className="text-gray-700">Couleur</Label>
|
||||||
@ -384,6 +397,18 @@ function CalendarDialog({ open, onClose, onSave, onDelete, onSyncSetup, initialD
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Display description (read-only) for existing calendars */}
|
||||||
|
{initialData?.id && initialData?.description && (
|
||||||
|
<div className="space-y-2">
|
||||||
|
<Label className="text-gray-700">Description</Label>
|
||||||
|
<div className="px-3 py-2 bg-gray-50 rounded-lg text-gray-700 border border-gray-200 text-sm">
|
||||||
|
{initialData?.description || description}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Description input only for new calendars */}
|
||||||
|
{!initialData?.id && (
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="calendar-description" className="text-gray-700">
|
<Label htmlFor="calendar-description" className="text-gray-700">
|
||||||
Description (optionnelle)
|
Description (optionnelle)
|
||||||
@ -394,10 +419,10 @@ function CalendarDialog({ open, onClose, onSave, onDelete, onSyncSetup, initialD
|
|||||||
onChange={(e) => setDescription(e.target.value)}
|
onChange={(e) => setDescription(e.target.value)}
|
||||||
placeholder="Description du calendrier"
|
placeholder="Description du calendrier"
|
||||||
rows={3}
|
rows={3}
|
||||||
disabled={isMissionOrGroupCalendar}
|
|
||||||
className="rounded-lg border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 bg-white text-gray-900"
|
className="rounded-lg border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 bg-white text-gray-900"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Sync Section for Private Calendars */}
|
{/* Sync Section for Private Calendars */}
|
||||||
{isPrivateCalendar && initialData?.id && (
|
{isPrivateCalendar && initialData?.id && (
|
||||||
@ -532,18 +557,7 @@ function CalendarDialog({ open, onClose, onSave, onDelete, onSyncSetup, initialD
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<DialogFooter className="mt-6 border-t border-gray-100 pt-4">
|
<DialogFooter className="mt-6 border-t border-gray-100 pt-4">
|
||||||
<div className="flex justify-between w-full">
|
<div className="flex justify-end w-full">
|
||||||
{initialData?.id && !isMainCalendar && !isMissionOrGroupCalendar && (
|
|
||||||
<Button
|
|
||||||
type="button"
|
|
||||||
variant="destructive"
|
|
||||||
onClick={handleDelete}
|
|
||||||
disabled={isSubmitting || isMainCalendar || isMissionOrGroupCalendar}
|
|
||||||
>
|
|
||||||
<X className="w-4 h-4 mr-2" />
|
|
||||||
Supprimer
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
<div className="flex gap-3">
|
<div className="flex gap-3">
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
@ -556,13 +570,13 @@ function CalendarDialog({ open, onClose, onSave, onDelete, onSyncSetup, initialD
|
|||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
disabled={!name || isSubmitting || isMainCalendar || isMissionOrGroupCalendar}
|
disabled={isSubmitting || (initialData?.id ? false : !name)}
|
||||||
className="rounded-lg bg-indigo-600 hover:bg-indigo-700 text-white"
|
className="rounded-lg bg-indigo-600 hover:bg-indigo-700 text-white"
|
||||||
>
|
>
|
||||||
{isSubmitting
|
{isSubmitting
|
||||||
? "Enregistrement..."
|
? "Enregistrement..."
|
||||||
: initialData?.id
|
: initialData?.id
|
||||||
? "Mettre à jour"
|
? "Mettre à jour la couleur"
|
||||||
: "Créer"
|
: "Créer"
|
||||||
}
|
}
|
||||||
</Button>
|
</Button>
|
||||||
@ -720,10 +734,12 @@ export function CalendarClient({ initialCalendars, userId, userProfile }: Calend
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// Sort calendars: synced (courrier) first, then groups, then missions
|
// Sort calendars: "Mon Calendrier" first, then synced (courrier), then groups, then missions
|
||||||
const sortCalendars = (cals: typeof initialCalendars) => {
|
const sortCalendars = (cals: typeof initialCalendars) => {
|
||||||
const filtered = filterCalendars(cals);
|
const filtered = filterCalendars(cals);
|
||||||
return [...filtered].sort((a, b) => {
|
return [...filtered].sort((a, b) => {
|
||||||
|
const aIsMonCalendrier = a.name === "Mon Calendrier";
|
||||||
|
const bIsMonCalendrier = b.name === "Mon Calendrier";
|
||||||
const aIsSynced = a.syncConfig?.syncEnabled && a.syncConfig?.mailCredential;
|
const aIsSynced = a.syncConfig?.syncEnabled && a.syncConfig?.mailCredential;
|
||||||
const bIsSynced = b.syncConfig?.syncEnabled && b.syncConfig?.mailCredential;
|
const bIsSynced = b.syncConfig?.syncEnabled && b.syncConfig?.mailCredential;
|
||||||
const aIsGroup = a.name?.startsWith("Groupe:");
|
const aIsGroup = a.name?.startsWith("Groupe:");
|
||||||
@ -731,7 +747,11 @@ export function CalendarClient({ initialCalendars, userId, userProfile }: Calend
|
|||||||
const aIsMission = a.name?.startsWith("Mission:");
|
const aIsMission = a.name?.startsWith("Mission:");
|
||||||
const bIsMission = b.name?.startsWith("Mission:");
|
const bIsMission = b.name?.startsWith("Mission:");
|
||||||
|
|
||||||
// Synced calendars first
|
// "Mon Calendrier" always first
|
||||||
|
if (aIsMonCalendrier && !bIsMonCalendrier) return -1;
|
||||||
|
if (!aIsMonCalendrier && bIsMonCalendrier) return 1;
|
||||||
|
|
||||||
|
// Synced calendars second
|
||||||
if (aIsSynced && !bIsSynced) return -1;
|
if (aIsSynced && !bIsSynced) return -1;
|
||||||
if (!aIsSynced && bIsSynced) return 1;
|
if (!aIsSynced && bIsSynced) return 1;
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user