let allSongs = []; let concerts = []; let historyViewMode = 'timeline'; function formatDate(dateStr) { const d = new Date(dateStr); return d.toLocaleDateString('fr-FR', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }); } function formatDateShort(dateStr) { const d = new Date(dateStr); return d.toLocaleDateString('fr-FR', { year: 'numeric', month: 'long', day: 'numeric' }); } function showError(message) { document.getElementById('error').innerHTML = `
${escapeHtml(message)}
`; } // ---------- Tabs ---------- function switchTab(tab) { document.getElementById('next-view').style.display = tab === 'next' ? '' : 'none'; document.getElementById('history-view').style.display = tab === 'history' ? '' : 'none'; document.getElementById('tab-next').classList.toggle('active', tab === 'next'); document.getElementById('tab-history').classList.toggle('active', tab === 'history'); } // ---------- Historique: liste (timeline / compact) ---------- function timelineSongRow(song) { const embed = youtubeEmbedUrl(song.youtube_url); return `
${song.position}
${escapeHtml(song.title)}
${escapeHtml(song.artist)}
${song.note ? `

${escapeHtml(song.note)}

` : ''} ${song.spotify_url ? `` : ''}
${embed ? `
` : `

Pas de lien YouTube

`}
`; } function timelineConcertBlock(concert) { const main = concert.songs.filter((s) => !s.is_encore); const encore = concert.songs.filter((s) => s.is_encore); const playlistUrl = youtubePlaylistUrl(concert.songs.map((s) => s.youtube_url).filter(Boolean)); return `
${escapeHtml(concert.name || 'Concert')}
${escapeHtml(concert.venue || '')} · ${formatDate(concert.concert_date)}
${playlistUrl ? `` : ''}

Setlist

${main.length ? `
${main.map(timelineSongRow).join('')}
` : '

Aucun morceau enregistré.

'}
${encore.length ? `

Rappel

${encore.map(timelineSongRow).join('')}
` : ''} Voir / modifier ce concert →
`; } function concertCardTemplate(c) { return `
${escapeHtml(c.name || 'Concert')}
${escapeHtml(c.venue || '')} · ${formatDateShort(c.concert_date)}
`; } function bindConcertLinks(container) { container.querySelectorAll('[data-concert-id]').forEach((el) => { el.addEventListener('click', (e) => { e.preventDefault(); showHistoryDetail(el.dataset.concertId); }); }); } function renderTimeline() { const container = document.getElementById('timeline-view'); if (!concerts.length) { container.innerHTML = '

Aucun concert passé enregistré.

'; return; } container.innerHTML = concerts.map(timelineConcertBlock).join(''); bindConcertLinks(container); } function renderCompact() { const container = document.getElementById('compact-view'); renderList(container, concerts, concertCardTemplate, 'Aucun concert passé enregistré.'); bindConcertLinks(container); } function applyHistoryViewMode() { const timelineEl = document.getElementById('timeline-view'); const compactEl = document.getElementById('compact-view'); const btn = document.getElementById('toggle-history-mode-btn'); if (historyViewMode === 'timeline') { timelineEl.style.display = 'block'; compactEl.style.display = 'none'; btn.textContent = 'Vue réduite'; } else { timelineEl.style.display = 'none'; compactEl.style.display = 'grid'; btn.textContent = 'Vue chronologique'; } } async function loadHistory() { concerts = await api.get('/api/setlists/history?full=1'); renderTimeline(); renderCompact(); applyHistoryViewMode(); } // ---------- Historique: détail d'un concert ---------- function showHistoryList() { document.getElementById('history-detail-view').style.display = 'none'; document.getElementById('history-list-view').style.display = 'block'; history.pushState({}, '', '/concerts.html?tab=history'); } function showHistoryDetail(id) { document.getElementById('history-list-view').style.display = 'none'; document.getElementById('history-detail-view').style.display = 'block'; history.pushState({}, '', `/concerts.html?tab=history&id=${id}`); const editor = createSetlistEditor({ containerId: 'history-detail-content', allSongs, getSetlist: async () => { try { return await api.get(`/api/setlists/${id}`); } catch (err) { return null; } }, emptyMessage: 'Concert introuvable.', allowDelete: true, onDeleted: async () => { showHistoryList(); await loadHistory(); }, }); editor.load(); } (async function init() { await initNav('concerts'); allSongs = await api.get('/api/songs'); const nextEditor = createSetlistEditor({ containerId: 'next-content', allSongs, getSetlist: () => api.get('/api/setlists/next'), createSetlist: (data) => api.post('/api/setlists', data), emptyMessage: 'Aucun concert à venir pour le moment.', }); document.getElementById('tab-next').addEventListener('click', () => switchTab('next')); document.getElementById('tab-history').addEventListener('click', () => switchTab('history')); document.getElementById('toggle-history-mode-btn').addEventListener('click', () => { historyViewMode = historyViewMode === 'timeline' ? 'compact' : 'timeline'; applyHistoryViewMode(); }); document.getElementById('back-to-history-link').addEventListener('click', (e) => { e.preventDefault(); showHistoryList(); }); try { await nextEditor.load(); await loadHistory(); const params = new URLSearchParams(window.location.search); const deepId = params.get('id'); if (deepId) { switchTab('history'); showHistoryDetail(deepId); } else if (params.get('tab') === 'history') { switchTab('history'); } } catch (err) { showError(err.message); } })();