feat: améliorer inscription et export apprenants
Some checks failed
Validation applicative / TypeScript, tests et build (push) Failing after 2m21s
Some checks failed
Validation applicative / TypeScript, tests et build (push) Failing after 2m21s
This commit is contained in:
55
shared/registration.ts
Normal file
55
shared/registration.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* 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" });
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user