- arte_api.py : GENRE_PAGES devient une liste de (nom, url), chaque concert reçoit un champ "categories" avec ses genres d'appartenance - main.py : endpoint /api/categories + param ?category= sur /api/concerts - index.html : barre de pills catégories (Tout + 10 genres) - style.css : styles .cat-bar / .cat-pill avec pill active en or - app.js : chargement dynamique des pills, filtre catégorie dans le state Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+28
-1
@@ -4,6 +4,7 @@
|
||||
const state = {
|
||||
page: 1,
|
||||
search: '',
|
||||
category: '',
|
||||
pageSize: 24,
|
||||
totalPages: 1,
|
||||
current: null, // concert object shown in modal
|
||||
@@ -21,6 +22,7 @@ const modalOverlay = $('modal-overlay');
|
||||
const dlPanel = $('dl-panel');
|
||||
const dlPanelBody = $('dl-panel-body');
|
||||
const dlBadge = $('dl-badge');
|
||||
const catBar = $('cat-bar');
|
||||
|
||||
// ── Helpers ──────────────────────────────────────────────────────────────────
|
||||
function fmtDuration(secs) {
|
||||
@@ -45,12 +47,37 @@ function debounce(fn, ms) {
|
||||
let t; return (...a) => { clearTimeout(t); t = setTimeout(() => fn(...a), ms); };
|
||||
}
|
||||
|
||||
// ── Categories ───────────────────────────────────────────────────────────────
|
||||
async function loadCategories() {
|
||||
try {
|
||||
const cats = await fetch('/api/categories').then(r => r.json());
|
||||
cats.forEach(cat => {
|
||||
const btn = document.createElement('button');
|
||||
btn.className = 'cat-pill';
|
||||
btn.dataset.cat = cat;
|
||||
btn.textContent = cat;
|
||||
catBar.appendChild(btn);
|
||||
});
|
||||
} catch {}
|
||||
}
|
||||
|
||||
catBar.addEventListener('click', e => {
|
||||
const pill = e.target.closest('.cat-pill');
|
||||
if (!pill) return;
|
||||
catBar.querySelectorAll('.cat-pill').forEach(p => p.classList.remove('active'));
|
||||
pill.classList.add('active');
|
||||
state.category = pill.dataset.cat;
|
||||
state.page = 1;
|
||||
refresh();
|
||||
});
|
||||
|
||||
// ── Concerts ─────────────────────────────────────────────────────────────────
|
||||
async function loadConcerts() {
|
||||
const params = new URLSearchParams({
|
||||
page: state.page,
|
||||
search: state.search,
|
||||
page_size: state.pageSize,
|
||||
category: state.category,
|
||||
});
|
||||
const res = await fetch(`/api/concerts?${params}`);
|
||||
if (!res.ok) throw new Error(res.statusText);
|
||||
@@ -359,6 +386,6 @@ document.addEventListener('keydown', e => {
|
||||
|
||||
// ── Init ─────────────────────────────────────────────────────────────────────
|
||||
(async () => {
|
||||
await refreshDlHistory();
|
||||
await Promise.all([loadCategories(), refreshDlHistory()]);
|
||||
await refresh();
|
||||
})();
|
||||
|
||||
@@ -195,6 +195,45 @@ body {
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
|
||||
/* ══ CATEGORY BAR ══════════════════════════════════════════════════════════ */
|
||||
.cat-bar {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin-bottom: 20px;
|
||||
overflow-x: auto;
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
|
||||
.cat-bar::-webkit-scrollbar { display: none; }
|
||||
|
||||
.cat-pill {
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 20px;
|
||||
color: var(--text-dim);
|
||||
cursor: pointer;
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-size: 13px;
|
||||
padding: 6px 16px;
|
||||
white-space: nowrap;
|
||||
transition: color var(--transition), border-color var(--transition), background var(--transition);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.cat-pill:hover {
|
||||
color: var(--text);
|
||||
border-color: rgba(255,255,255,0.15);
|
||||
}
|
||||
|
||||
.cat-pill.active {
|
||||
background: var(--gold);
|
||||
border-color: var(--gold);
|
||||
color: #000;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* ══ GRID ══════════════════════════════════════════════════════════════════ */
|
||||
.grid {
|
||||
display: grid;
|
||||
|
||||
Reference in New Issue
Block a user