fix: show all upcomming concerts in calendar add url to export the slot

This commit is contained in:
Nathan FONTEYNE 2026-07-10 15:27:07 +02:00
parent fea5c30d69
commit 16110d8ad3
10 changed files with 227 additions and 89 deletions

View file

@ -0,0 +1,2 @@
ALTER TABLE calendar_settings ADD COLUMN IF NOT EXISTS concert_start TIME NOT NULL DEFAULT '19:00';
ALTER TABLE calendar_settings ADD COLUMN IF NOT EXISTS concert_end TIME NOT NULL DEFAULT '22:00';

View file

@ -205,27 +205,31 @@ function parseTime(hhmmss) {
async function getSlotSettings() {
const { rows } = await pool.query(
'SELECT weekday_start, weekday_end, weekend_start, weekend_end, margin_minutes FROM calendar_settings WHERE id = 1'
'SELECT weekday_start, weekday_end, weekend_start, weekend_end, margin_minutes, concert_start, concert_end FROM calendar_settings WHERE id = 1'
);
const row = rows[0];
const weekdayStart = parseTime(row.weekday_start);
const weekdayEnd = parseTime(row.weekday_end);
const weekendStart = parseTime(row.weekend_start);
const weekendEnd = parseTime(row.weekend_end);
const concertStart = parseTime(row.concert_start);
const concertEnd = parseTime(row.concert_end);
return {
weekday: { startHour: weekdayStart.hour, startMinute: weekdayStart.minute, endHour: weekdayEnd.hour, endMinute: weekdayEnd.minute },
weekend: { startHour: weekendStart.hour, startMinute: weekendStart.minute, endHour: weekendEnd.hour, endMinute: weekendEnd.minute },
marginMinutes: row.margin_minutes,
concert: { startHour: concertStart.hour, startMinute: concertStart.minute, endHour: concertEnd.hour, endMinute: concertEnd.minute },
};
}
async function updateSlotSettings({ weekdayStart, weekdayEnd, weekendStart, weekendEnd, marginMinutes }) {
async function updateSlotSettings({ weekdayStart, weekdayEnd, weekendStart, weekendEnd, marginMinutes, concertStart, concertEnd }) {
const { rows } = await pool.query(
`UPDATE calendar_settings
SET weekday_start = $1, weekday_end = $2, weekend_start = $3, weekend_end = $4, margin_minutes = $5
SET weekday_start = $1, weekday_end = $2, weekend_start = $3, weekend_end = $4, margin_minutes = $5,
concert_start = $6, concert_end = $7
WHERE id = 1
RETURNING weekday_start, weekday_end, weekend_start, weekend_end, margin_minutes`,
[weekdayStart, weekdayEnd, weekendStart, weekendEnd, marginMinutes]
RETURNING weekday_start, weekday_end, weekend_start, weekend_end, margin_minutes, concert_start, concert_end`,
[weekdayStart, weekdayEnd, weekendStart, weekendEnd, marginMinutes, concertStart, concertEnd]
);
return rows[0];
}

View file

@ -184,6 +184,22 @@ router.get(
weekendStart: formatTime(settings.weekend.startHour, settings.weekend.startMinute),
weekendEnd: formatTime(settings.weekend.endHour, settings.weekend.endMinute),
marginMinutes: settings.marginMinutes,
concertStart: formatTime(settings.concert.startHour, settings.concert.startMinute),
concertEnd: formatTime(settings.concert.endHour, settings.concert.endMinute),
});
})
);
// Public (any authenticated user): the default concert start/end times are
// needed client-side on calendar.html and concerts.html to build "add to my
// calendar" links, but only an admin may change them (see PATCH /settings).
router.get(
'/concert-hours',
asyncHandler(async (req, res) => {
const settings = await calendarRepo.getSlotSettings();
res.json({
start: formatTime(settings.concert.startHour, settings.concert.startMinute),
end: formatTime(settings.concert.endHour, settings.concert.endMinute),
});
})
);
@ -196,8 +212,8 @@ router.patch(
'/settings',
requireAdmin,
asyncHandler(async (req, res) => {
const { weekdayStart, weekdayEnd, weekendStart, weekendEnd, marginMinutes } = req.body || {};
const times = { weekdayStart, weekdayEnd, weekendStart, weekendEnd };
const { weekdayStart, weekdayEnd, weekendStart, weekendEnd, marginMinutes, concertStart, concertEnd } = req.body || {};
const times = { weekdayStart, weekdayEnd, weekendStart, weekendEnd, concertStart, concertEnd };
for (const [key, value] of Object.entries(times)) {
if (!TIME_RE.test(value || '')) {
return res.status(400).json({ error: 'invalid_time', field: key });
@ -209,6 +225,9 @@ router.patch(
if (weekendStart >= weekendEnd) {
return res.status(400).json({ error: 'weekend_start_must_be_before_end' });
}
if (concertStart >= concertEnd) {
return res.status(400).json({ error: 'concert_start_must_be_before_end' });
}
const margin = Number(marginMinutes);
if (!Number.isInteger(margin) || margin < 0 || margin > 180) {
return res.status(400).json({ error: 'invalid_margin_minutes' });