Some checks failed
Validation applicative / TypeScript, tests et build (push) Failing after 2m21s
56 lines
2.0 KiB
TypeScript
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" });
|
|
});
|
|
}
|