81 lines
2.8 KiB
JavaScript
81 lines
2.8 KiB
JavaScript
// Dates du jeu-concours affichées au public. Elles viennent de l'API (date de
|
|
// début fixée par l'admin) ; en attendant la réponse, ou si le jeu n'est pas
|
|
// configuré, on affiche les dates prévues par le règlement : 2 → 31 octobre 2026.
|
|
|
|
const TIME_ZONE = 'Europe/Paris'
|
|
const DAY_MS = 24 * 60 * 60 * 1000
|
|
|
|
// Mêmes durées que backend/src/utils/gameWindow.js.
|
|
const GAME_DURATION_DAYS = 30
|
|
const CLAIM_EXTENSION_DAYS = 30
|
|
|
|
export const DEFAULT_START_DATE = '2026-10-02T00:00:00+02:00'
|
|
|
|
function windowFromStart(startDate) {
|
|
const start = new Date(startDate)
|
|
return {
|
|
start,
|
|
participationDeadline: new Date(start.getTime() + GAME_DURATION_DAYS * DAY_MS),
|
|
claimDeadline: new Date(start.getTime() + (GAME_DURATION_DAYS + CLAIM_EXTENSION_DAYS) * DAY_MS),
|
|
}
|
|
}
|
|
|
|
// Les échéances sont des instants exclusifs (début + 30 j) : le dernier jour
|
|
// affiché est celui qui précède immédiatement l'échéance.
|
|
function lastDayBefore(deadline) {
|
|
return new Date(deadline.getTime() - 1)
|
|
}
|
|
|
|
export function toGameDates(gameWindow) {
|
|
const source = gameWindow?.configured && gameWindow.startDate
|
|
? {
|
|
start: new Date(gameWindow.startDate),
|
|
participationDeadline: new Date(gameWindow.participationDeadline),
|
|
claimDeadline: new Date(gameWindow.claimDeadline),
|
|
}
|
|
: windowFromStart(DEFAULT_START_DATE)
|
|
|
|
return {
|
|
start: source.start,
|
|
lastPlayDay: lastDayBefore(source.participationDeadline),
|
|
lastClaimDay: lastDayBefore(source.claimDeadline),
|
|
}
|
|
}
|
|
|
|
// Même calcul à partir d'une date de début seule (aperçu dans l'admin).
|
|
export function gameDatesFromStart(startDate) {
|
|
return toGameDates({ configured: true, startDate, ...windowFromStart(startDate) })
|
|
}
|
|
|
|
function parts(date) {
|
|
const values = {}
|
|
new Intl.DateTimeFormat('fr-FR', { timeZone: TIME_ZONE, day: 'numeric', month: 'long', year: 'numeric' })
|
|
.formatToParts(date)
|
|
.forEach(({ type, value }) => { values[type] = value })
|
|
return values
|
|
}
|
|
|
|
// « 30 novembre 2026 »
|
|
export function formatDay(date) {
|
|
const { day, month, year } = parts(date)
|
|
return `${day} ${month} ${year}`
|
|
}
|
|
|
|
// « 2 au 31 octobre 2026 », « 15 octobre au 13 novembre 2026 »,
|
|
// « 20 décembre 2026 au 18 janvier 2027 ». Sans « du » : l'appelant choisit
|
|
// la majuscule. `padDay` écrit « 02 », `withYear: false` omet l'année.
|
|
export function formatRange(start, end, { padDay = false, withYear = true } = {}) {
|
|
const a = parts(start)
|
|
const b = parts(end)
|
|
const startDay = padDay ? a.day.padStart(2, '0') : a.day
|
|
const year = withYear ? ` ${b.year}` : ''
|
|
|
|
if (a.year !== b.year) {
|
|
return `${startDay} ${a.month}${withYear ? ` ${a.year}` : ''} au ${b.day} ${b.month}${year}`
|
|
}
|
|
if (a.month !== b.month) {
|
|
return `${startDay} ${a.month} au ${b.day} ${b.month}${year}`
|
|
}
|
|
return `${startDay} au ${b.day} ${b.month}${year}`
|
|
}
|