diff --git a/public/css/style.css b/public/css/style.css index 287b81a..e77936a 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -1422,12 +1422,15 @@ a.back-link:hover { color: var(--accent); } flex-wrap: wrap; } -.cell-rehearsal-badge { +.cell-badges { position: absolute; top: 0.3rem; right: 0.4rem; + display: flex; + gap: 0.2rem; font-size: 0.85rem; line-height: 1; } .cal-cell.has-rehearsal { border-color: var(--accent); } +.cal-cell.has-concert { border-color: var(--success); } diff --git a/public/js/calendar.js b/public/js/calendar.js index 0913dc2..5a6aa1e 100644 --- a/public/js/calendar.js +++ b/public/js/calendar.js @@ -3,6 +3,7 @@ let state = { slots: [], personIds: [], rehearsals: [], + nextConcert: null, }; let me = null; let currentModalDate = null; @@ -23,6 +24,11 @@ async function loadRehearsals() { renderCalendar(); } +async function loadNextConcert() { + state.nextConcert = await api.get('/api/setlists/next'); + renderCalendar(); +} + async function loadLastChecked() { const { last_checked } = await api.get('/api/calendar/last-checked'); const el = document.getElementById('last-checked'); @@ -64,6 +70,8 @@ function renderCalendar() { const rehearsalsByDate = new Map(); for (const r of state.rehearsals) rehearsalsByDate.set(isoDate(new Date(r.startsAt)), r); + const nextConcertDate = state.nextConcert ? isoDate(new Date(state.nextConcert.concert_date)) : null; + // Grid starts on the Monday of the current week so columns align Mon->Sun. const start = new Date(today); const dow = start.getDay(); @@ -95,16 +103,28 @@ function renderCalendar() { dateLabel.innerHTML = `${date.getDate()}${shortMonth(date)}`; cell.appendChild(dateLabel); + const badges = document.createElement('div'); + badges.className = 'cell-badges'; + const rehearsal = rehearsalsByDate.get(isoDate(date)); if (rehearsal) { cell.classList.add('has-rehearsal'); - const badge = document.createElement('div'); - badge.className = 'cell-rehearsal-badge'; + const badge = document.createElement('span'); badge.title = 'Répétition proposée'; badge.textContent = '🎸'; - cell.appendChild(badge); + badges.appendChild(badge); } + if (nextConcertDate && isoDate(date) === nextConcertDate) { + cell.classList.add('has-concert'); + const badge = document.createElement('span'); + badge.title = `Prochain concert${state.nextConcert.name ? ' : ' + state.nextConcert.name : ''}${state.nextConcert.venue ? ' (' + state.nextConcert.venue + ')' : ''}`; + badge.textContent = '🎤'; + badges.appendChild(badge); + } + + if (badges.childElementCount) cell.appendChild(badges); + if (isPastDay) { cell.classList.add('empty'); const lbl = document.createElement('div'); @@ -565,6 +585,7 @@ async function onRemoveMyFeed(feedId) { await loadPeople(); buildFilters(); await loadRehearsals(); + await loadNextConcert(); await loadSlots(); await loadLastChecked(); await loadMyFeeds();