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 nextWeek = add(now, { days: 7 });
|
||||
|
||||
|
||||
@ -169,18 +169,49 @@ export async function GET(req: NextRequest) {
|
||||
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', {
|
||||
userId: session.user.id,
|
||||
personalCount: filteredPersonalCalendars.length,
|
||||
missionCount: missionCalendars.length,
|
||||
totalCount: uniqueCalendars.length,
|
||||
totalCount: sortedCalendars.length,
|
||||
filteredOut: personalCalendars.length - filteredPersonalCalendars.length,
|
||||
});
|
||||
|
||||
// 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) {
|
||||
logger.error('[CALENDAR] Erreur lors de la récupération des calendriers', {
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
|
||||
@ -255,15 +255,16 @@ function CalendarDialog({ open, onClose, onSave, onDelete, onSyncSetup, initialD
|
||||
setIsSubmitting(true);
|
||||
|
||||
try {
|
||||
// Only update color, preserve name and description from initialData
|
||||
await onSave({
|
||||
id: initialData?.id,
|
||||
name,
|
||||
color,
|
||||
description
|
||||
name: initialData?.name || name, // Keep original name
|
||||
color, // Only color can be changed
|
||||
description: initialData?.description || description // Keep original description
|
||||
});
|
||||
resetForm();
|
||||
} 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 {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
@ -301,24 +302,36 @@ function CalendarDialog({ open, onClose, onSave, onDelete, onSyncSetup, initialD
|
||||
<DialogHeader>
|
||||
<DialogTitle className="flex items-center text-xl font-semibold text-gray-900">
|
||||
<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>
|
||||
</DialogHeader>
|
||||
|
||||
<form onSubmit={handleSubmit}>
|
||||
<div className="space-y-5 py-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="calendar-name" className="text-gray-700">Nom</Label>
|
||||
<Input
|
||||
id="calendar-name"
|
||||
value={name}
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
placeholder="Nom du calendrier"
|
||||
required
|
||||
disabled={isMainCalendar || isMissionOrGroupCalendar}
|
||||
className="rounded-lg border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 bg-white text-gray-900"
|
||||
/>
|
||||
</div>
|
||||
{/* 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">
|
||||
<Label htmlFor="calendar-name" className="text-gray-700">Nom</Label>
|
||||
<Input
|
||||
id="calendar-name"
|
||||
value={name}
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
placeholder="Nom du calendrier"
|
||||
required
|
||||
className="rounded-lg border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 bg-white text-gray-900"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="space-y-3">
|
||||
<Label className="text-gray-700">Couleur</Label>
|
||||
@ -384,20 +397,32 @@ function CalendarDialog({ open, onClose, onSave, onDelete, onSyncSetup, initialD
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="calendar-description" className="text-gray-700">
|
||||
Description (optionnelle)
|
||||
</Label>
|
||||
<Textarea
|
||||
id="calendar-description"
|
||||
value={description}
|
||||
onChange={(e) => setDescription(e.target.value)}
|
||||
placeholder="Description du calendrier"
|
||||
rows={3}
|
||||
disabled={isMissionOrGroupCalendar}
|
||||
className="rounded-lg border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 bg-white text-gray-900"
|
||||
/>
|
||||
</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">
|
||||
<Label htmlFor="calendar-description" className="text-gray-700">
|
||||
Description (optionnelle)
|
||||
</Label>
|
||||
<Textarea
|
||||
id="calendar-description"
|
||||
value={description}
|
||||
onChange={(e) => setDescription(e.target.value)}
|
||||
placeholder="Description du calendrier"
|
||||
rows={3}
|
||||
className="rounded-lg border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 bg-white text-gray-900"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Sync Section for Private Calendars */}
|
||||
{isPrivateCalendar && initialData?.id && (
|
||||
@ -532,18 +557,7 @@ function CalendarDialog({ open, onClose, onSave, onDelete, onSyncSetup, initialD
|
||||
</div>
|
||||
|
||||
<DialogFooter className="mt-6 border-t border-gray-100 pt-4">
|
||||
<div className="flex justify-between 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 justify-end w-full">
|
||||
<div className="flex gap-3">
|
||||
<Button
|
||||
type="button"
|
||||
@ -556,13 +570,13 @@ function CalendarDialog({ open, onClose, onSave, onDelete, onSyncSetup, initialD
|
||||
</Button>
|
||||
<Button
|
||||
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"
|
||||
>
|
||||
{isSubmitting
|
||||
? "Enregistrement..."
|
||||
: initialData?.id
|
||||
? "Mettre à jour"
|
||||
? "Mettre à jour la couleur"
|
||||
: "Créer"
|
||||
}
|
||||
</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 filtered = filterCalendars(cals);
|
||||
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 bIsSynced = b.syncConfig?.syncEnabled && b.syncConfig?.mailCredential;
|
||||
const aIsGroup = a.name?.startsWith("Groupe:");
|
||||
@ -731,7 +747,11 @@ export function CalendarClient({ initialCalendars, userId, userProfile }: Calend
|
||||
const aIsMission = a.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;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user