Files
formation-manager-itinova/shared/registration.ts
manus-admin a7845f5b06
Some checks failed
Validation applicative / TypeScript, tests et build (push) Failing after 2m21s
feat: améliorer inscription et export apprenants
2026-10-02 11:11:50 +02:00

56 lines
2.0 KiB
TypeScript

/**
* Détermine l'ordre d'affichage des séquences sur le lien d'inscription public.
* Les sessions ouvertes avec des places disponibles sont toujours proposées en premier.
*/
export type RegistrationSequence = {
id: number;
nom: string;
statut: string;
dateBlocage?: Date | string | null;
capaciteMax: number;
nbInscrits?: number | null;
dates?: ReadonlyArray<{ dateDebut: Date | string }>;
};
export type RegistrationSequenceWithAvailability<T extends RegistrationSequence> = T & {
isBloquee: boolean;
placesRestantes: number;
};
function firstDateTimestamp(sequence: RegistrationSequence): number {
const firstDate = sequence.dates?.[0]?.dateDebut;
if (!firstDate) return Number.MAX_SAFE_INTEGER;
const timestamp = new Date(firstDate).getTime();
return Number.isFinite(timestamp) ? timestamp : Number.MAX_SAFE_INTEGER;
}
function displayPriority(sequence: RegistrationSequenceWithAvailability<RegistrationSequence>): number {
if (sequence.isBloquee) return 2;
return sequence.placesRestantes > 0 ? 0 : 1;
}
export function sortSequencesForRegistration<T extends RegistrationSequence>(
sequences: readonly T[],
now = new Date(),
): RegistrationSequenceWithAvailability<T>[] {
return sequences
.map((sequence) => {
const dateBlocage = sequence.dateBlocage ? new Date(sequence.dateBlocage) : null;
const hasReachedBlockingDate = dateBlocage !== null && now >= dateBlocage;
const isBloquee = sequence.statut !== "ouverte" || hasReachedBlockingDate;
const placesRestantes = Math.max(0, sequence.capaciteMax - (sequence.nbInscrits ?? 0));
return { ...sequence, isBloquee, placesRestantes };
})
.sort((left, right) => {
const priorityDifference = displayPriority(left) - displayPriority(right);
if (priorityDifference !== 0) return priorityDifference;
const dateDifference = firstDateTimestamp(left) - firstDateTimestamp(right);
if (dateDifference !== 0) return dateDifference;
return left.nom.localeCompare(right.nom, "fr", { sensitivity: "base" });
});
}