diff --git a/public/js/app_user-stat.js b/public/js/app_user-stat.js
index c4bbd0a..e290b8d 100644
--- a/public/js/app_user-stat.js
+++ b/public/js/app_user-stat.js
@@ -41,11 +41,15 @@ window.onload = async function () {
}
function renderWinners(winners) {
- const winnersList = document.getElementById('winners-list');
- if (!winnersList) return;
+ const tbody = document.getElementById('winners-table-body');
+ if (!tbody) return;
const list = Array.isArray(winners) ? winners : [];
if (!list.length) {
- winnersList.innerHTML = '
Aucun gagnant défini.
';
+ tbody.innerHTML = `
+
+ | Aucun gagnant défini. |
+
+ `;
return;
}
@@ -64,7 +68,7 @@ window.onload = async function () {
});
const years = Array.from(byYear.keys()).map(Number).sort((a, b) => b - a);
- winnersList.innerHTML = '';
+ tbody.innerHTML = '';
years.forEach((year) => {
const winnersForYear = byYear.get(String(year)) || [];
@@ -77,35 +81,56 @@ window.onload = async function () {
return String(a.name || '').localeCompare(String(b.name || ''), 'fr', { sensitivity: 'base' });
});
- const item = document.createElement('div');
- item.className = 'list-group-item';
- const tieLabel = sorted.length > 1 ? ' (égalité)' : '';
+ const tr = document.createElement('tr');
- const winnersHtml = sorted
- .map((w) => {
- const pts = w.points === null || Number.isNaN(w.points) ? null : w.points;
- const ptsLabel = pts === null ? '' : ` — ${pts} pts`;
- return `${w.name}${ptsLabel}
`;
- })
- .join('');
+ const tdYear = document.createElement('td');
+ tdYear.className = 'fw-semibold';
+ tdYear.textContent = String(year);
+ if (sorted.length > 1) {
+ const small = document.createElement('div');
+ small.className = 'text-muted small';
+ small.textContent = 'égalité';
+ tdYear.appendChild(document.createElement('br'));
+ tdYear.appendChild(small);
+ }
- item.innerHTML = `
-
-
${year}${tieLabel}
-
${sorted.length}
-
- ${winnersHtml}
- `;
- winnersList.appendChild(item);
+ const tdWinners = document.createElement('td');
+ sorted.forEach((w, idx) => {
+ const row = document.createElement('div');
+ if (idx > 0) row.classList.add('mt-1');
+
+ const name = document.createElement('span');
+ name.className = 'fw-semibold';
+ name.textContent = w?.name || '(utilisateur supprimé)';
+ row.appendChild(name);
+
+ const pts = w.points === null || Number.isNaN(w.points) ? null : w.points;
+ if (pts !== null) {
+ const ptsSpan = document.createElement('span');
+ ptsSpan.className = 'text-muted';
+ ptsSpan.textContent = ` — ${pts} pts`;
+ row.appendChild(ptsSpan);
+ }
+
+ tdWinners.appendChild(row);
+ });
+
+ tr.appendChild(tdYear);
+ tr.appendChild(tdWinners);
+ tbody.appendChild(tr);
});
}
function renderCompletions(completions) {
- const root = document.getElementById('completers-by-year');
- if (!root) return;
+ const tbody = document.getElementById('completers-table-body');
+ if (!tbody) return;
if (!completions || typeof completions !== 'object') {
- root.innerHTML = 'Impossible de charger les finisseurs 100%.
';
+ tbody.innerHTML = `
+
+ | Impossible de charger les finisseurs 100%. |
+
+ `;
return;
}
@@ -114,48 +139,62 @@ window.onload = async function () {
const byYear = completions?.completersByYear && typeof completions.completersByYear === 'object' ? completions.completersByYear : {};
if (!years.length) {
- root.innerHTML = 'Aucune année trouvée.
';
+ tbody.innerHTML = `
+
+ | Aucune année trouvée. |
+
+ `;
return;
}
- // Build a simple accordion
- const accordionId = 'completersAccordion';
- root.innerHTML = ``;
- const acc = root.querySelector('.accordion');
+ const sortedYears = years
+ .map((y) => Number(y))
+ .filter((y) => Number.isInteger(y))
+ .sort((a, b) => b - a);
- years.forEach((y, idx) => {
+ tbody.innerHTML = '';
+ sortedYears.forEach((y) => {
const yearStr = String(y);
const total = Number(totals?.[yearStr] ?? 0);
const completers = Array.isArray(byYear?.[yearStr]) ? byYear[yearStr] : [];
const count = completers.length;
- const collapseId = `completers-${yearStr}`;
- const headingId = `heading-${yearStr}`;
- const show = idx === 0 ? 'show' : '';
- const collapsed = idx === 0 ? '' : 'collapsed';
- const expanded = idx === 0 ? 'true' : 'false';
+ const tr = document.createElement('tr');
- const bodyHtml = count
- ? `
- ${completers.map((u) => `- ${u?.name || '(sans nom)'}
`).join('')}
-
`
- : `Aucun utilisateur à 100%.
`;
+ const tdYear = document.createElement('td');
+ tdYear.className = 'fw-semibold';
+ tdYear.textContent = yearStr;
- const item = document.createElement('div');
- item.className = 'accordion-item';
- item.innerHTML = `
-
-
- `;
- acc.appendChild(item);
+ const tdCount = document.createElement('td');
+ const badge = document.createElement('span');
+ badge.className = 'badge bg-secondary';
+ badge.textContent = String(count);
+ tdCount.appendChild(badge);
+
+ const tdTotal = document.createElement('td');
+ tdTotal.textContent = String(Number.isFinite(total) ? total : 0);
+
+ const tdNames = document.createElement('td');
+ if (!count) {
+ tdNames.className = 'text-muted';
+ tdNames.textContent = '—';
+ } else {
+ const wrap = document.createElement('div');
+ wrap.className = 'd-flex flex-wrap gap-1';
+ completers.forEach((u) => {
+ const name = document.createElement('span');
+ name.className = 'badge bg-light text-dark border';
+ name.textContent = u?.name || '(sans nom)';
+ wrap.appendChild(name);
+ });
+ tdNames.appendChild(wrap);
+ }
+
+ tr.appendChild(tdYear);
+ tr.appendChild(tdCount);
+ tr.appendChild(tdTotal);
+ tr.appendChild(tdNames);
+ tbody.appendChild(tr);
});
}
@@ -241,8 +280,8 @@ window.onload = async function () {
});
// Hide spinner and show table after loading
- spinner.style.display = 'none';
- table.style.display = 'table';
+ if (spinner) spinner.classList.add('d-none');
+ if (table) table.classList.remove('d-none');
if (statsError) statsError.classList.add('d-none');
// Add event listener for user links
@@ -275,8 +314,8 @@ window.onload = async function () {
const spinner = document.getElementById('loading-spinner');
const table = document.querySelector('.user-table');
const statsError = document.getElementById('stats-error');
- if (spinner) spinner.style.display = 'none';
- if (table) table.style.display = 'none';
+ if (spinner) spinner.classList.add('d-none');
+ if (table) table.classList.add('d-none');
if (statsError) {
statsError.textContent = "Impossible de charger le classement pour le moment.";
statsError.classList.remove('d-none');
diff --git a/public/user-stat.html b/public/user-stat.html
index d76b403..0de9db8 100644
--- a/public/user-stat.html
+++ b/public/user-stat.html
@@ -20,10 +20,6 @@
.user-table {
margin-top: 20px;
}
- .ratio {
- font-weight: bold;
- margin-top: 10px;
- }
.navbar-toggler {
border-color: white; /* Make the border white */
}
@@ -100,7 +96,7 @@
-
+
| Nom |
@@ -117,9 +113,20 @@
Gagnants
-
Définis dans l’admin (optionnel).
-
-
Chargement…
+
+
+
+
+ | Année |
+ Gagnant(s) |
+
+
+
+
+ | Chargement… |
+
+
+
@@ -127,8 +134,22 @@
Utilisateurs ayant terminé 100% (par année)
Completion = 100% pour l’année (tous les films de l’année vus).
-
-
Chargement…
+
+
+
+
+ | Année |
+ Finisseur(s) |
+ Total films |
+ Noms |
+
+
+
+
+ | Chargement… |
+
+
+