From 9868d2c39a020e20d7f9d8db85a502fac6e117a7 Mon Sep 17 00:00:00 2001 From: Mathieu Moran Date: Tue, 27 Jan 2026 02:45:49 -0500 Subject: [PATCH] Refine admin control layout and stats tabs Tighten admin tab layout/styling and simplify control UI while aligning stats tab spacing and labels. --- public/control.html | 800 +++++++++++++++++---------------------- public/css/app.css | 81 ++++ public/js/app_control.js | 145 +++---- public/user-stat.html | 16 +- 4 files changed, 496 insertions(+), 546 deletions(-) diff --git a/public/control.html b/public/control.html index f0f2b8e..33dc6af 100644 --- a/public/control.html +++ b/public/control.html @@ -27,6 +27,185 @@ .navbar-toggler-icon { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3E%3Cpath stroke='white' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E"); } + + .admin-tabs-content { + font-size: 0.95rem; + } + + .admin-tabs-content .info-line { + display: flex; + align-items: center; + gap: 0.5rem; + line-height: 1; + align-self: center; + transform: translateY(-2px); + } + + .admin-tabs-content .info-line .badge { + display: inline-flex; + align-items: center; + justify-content: center; + line-height: 1; + width: 1.2em; + height: 1.2em; + padding: 0; + } + + .admin-tabs-content .info-line .info-text { + display: inline-flex; + align-items: center; + line-height: 1; + } + + .admin-tabs-content .btn-compact { + padding: 0.2rem 0.5rem; + font-size: 0.85rem; + line-height: 1.2; + } + + .admin-tabs-content .btn-check-compact { + padding-left: 0.35rem; + padding-right: 0.35rem; + } + + .admin-tabs-content .app-version-create { + font-size: 0.95rem; + } + + .admin-tabs-content .app-version-create .fw-semibold { + font-size: 0.95rem; + } + + .admin-tabs-content .backup-restore-panel { + font-size: 0.95rem; + } + + .admin-tabs-content .backup-restore-panel .form-label, + .admin-tabs-content .backup-restore-panel .form-check-label { + font-size: 0.95rem; + } + + .admin-tabs-content .backup-restore-panel .alert { + font-size: 0.9rem; + padding: 0.5rem 0.75rem; + } + + .admin-tabs-content .btn-check-small { + height: 1.9rem; + } + + .admin-tabs-content .oscar-date-year-select { + max-width: 220px; + width: 220px; + margin-right: 0; + } + + .admin-tabs-content .manage-year-select { + max-width: 110px; + width: 110px; + } + + .admin-tabs-content .oscar-date-input { + max-width: 220px; + width: 220px; + } + + .admin-tabs-content .points-input-half { + max-width: 110px; + width: 110px; + } + + .admin-tabs-content .oscar-date-layout { + display: flex; + align-items: flex-start; + gap: 0.75rem; + } + + .admin-tabs-content .oscar-date-fields { + display: flex; + flex-direction: column; + gap: 0.5rem; + } + + .admin-tabs-content .oscar-date-fields .form-text { + margin-top: 0.2rem; + } + + .admin-tabs-content .oscar-date-current { + display: inline-block; + width: fit-content; + max-width: 100%; + padding: 0.4rem 0.65rem; + min-width: 220px; + } + + .admin-tabs-content .btn-check-wide { + padding-left: 0.55rem; + padding-right: 0.55rem; + } + + .admin-tabs-content h4, + .admin-tabs-content h5 { + font-size: 1rem; + font-weight: 600; + letter-spacing: 0.01em; + } + + .admin-subtabs .nav-link { + padding: 0.3rem 0.7rem; + font-size: 0.9rem; + line-height: 1.2; + } + + + html[data-theme="dark"] #adminAddMovieAccordion .accordion-item { + background-color: var(--app-surface-alt); + border-color: var(--app-border); + } + + html[data-theme="dark"] #adminAddMovieAccordion .accordion-button { + background-color: var(--app-surface-alt); + color: var(--app-text); + box-shadow: none; + } + + html[data-theme="dark"] #adminAddMovieAccordion .accordion-button::after { + filter: invert(1); + } + + html[data-theme="dark"] #adminAddMovieAccordion .accordion-button:not(.collapsed) { + background-color: var(--app-surface); + color: var(--app-text); + box-shadow: none; + } + + html[data-theme="dark"] #adminAddMovieAccordion .accordion-body { + background-color: var(--app-surface); + color: var(--app-text); + } + + .admin-movies-add { + margin-top: 0.5rem; + } + + .admin-movies-separator { + border-top: 1px solid var(--app-border); + margin: 0.75rem 0; + } + + .admin-movies-meta { + margin: 0 0 0.5rem; + } + + .admin-subtabs-tight { + margin-top: 0; + } + + .admin-tabs-content .table, + .admin-tabs-content .table th, + .admin-tabs-content .table td { + font-size: 0.95rem; + } @@ -46,7 +225,7 @@ Checklist Statistiques - Admin + Admin -
+
-
+
-
-

Réglages

-
Paramètres globaux du site (année, dates, options du lecteur).
+
+ + Paramètres globaux du site (année, dates, options du lecteur).
- -
-
-
- Pilote tout le site (films, checklist, statistiques). -
- -
-
- - -
-
-
Basé sur les années présentes dans les films.
-
-
+ +
+
+
+
+
+ Configure la date de cérémonie pour le compte à rebours (Films & Checklist). Défaut: 15 mars. +
- -
-
-
- Configure la date de cérémonie pour le compte à rebours (Films & Checklist). Défaut: 15 mars. -
+
+
+
+ +
+ + +
+
Basé sur les années présentes dans les films.
+
+
+ +
+ + +
+
Format: YYYY-MM-DD.
+
+
+
-
-
- - -
Basé sur les années présentes dans les films.
-
-
- - -
Format: YYYY-MM-DD.
-
-
- - +
+
Dates configurées
+
—
+
-
-
Dates configurées
-
—
-
-
-
+
+
+
+ Configure les points attribués pour les films regardés et les bonnes réponses aux Oscars. +
- -
-
-
- Configure les points attribués pour les films regardés et les bonnes réponses aux Oscars. -
+ - +
+
+ + +
Points attribués pour chaque film complété.
+
+
+ + +
Points attribués pour chaque bonne réponse aux Oscars.
+
+
-
-
- - -
Points attribués pour chaque film complété.
-
-
- - -
Points attribués pour chaque bonne réponse aux Oscars.
-
-
+
+
+ + +
+
-
-
- - -
-
- -
-
Calcul des points
-
-
- Total = (Films regardés × 1) + (Bonnes réponses × 1) +
+
Calcul des points
+
+
+ Total = (Films regardés × 1) + (Bonnes réponses × 1) +
+
@@ -267,8 +426,7 @@
- - +
@@ -279,125 +437,46 @@
-
-

Version

-
Contrôle la version affichée dans le footer (stockée en DB).
+
+ + Contrôle la version affichée dans le footer (stockée en DB). Clique sur ✓ pour activer une version, puis vérifie l’aperçu.
- - -
- -
+
-
-
Version active
-
- Met à jour ce que les utilisateurs voient dans le footer. -
- - -
-
- -
La liste vient de l’historique stocké en DB.
-
-
- - -
-
- -
-
Aperçu (footer)
-
—
-
-
+
—
-
-
Bon à savoir
-
    -
  • “Recharger” relit l’historique depuis l’API.
  • -
  • “Activer” change la version active en DB.
  • -
  • Le footer lit ensuite la version via /api/version.
  • -
-
-
-
-
- - -
-
-
-
Historique
-
Supprime les entrées obsolètes si besoin.
-
-
-
—
-
- - -
-
-
-
+
Créer une nouvelle version
Ajoute une entrée dans l’historique (tu peux l’activer immédiatement).
-
+
Ex: 1.2.3
-
+
Court & lisible (affiché dans le footer).
- - + +
- -
-
-
Astuce
-
- Après création, va dans l’onglet “Active” pour vérifier l’aperçu du footer. -
-
-
-
@@ -405,28 +484,15 @@
-
-

Modal 100%

-
Contenu affiché quand un utilisateur a vu 100% des films.
+
+ + Contenu affiché quand un utilisateur a vu 100% des films.
- - -
+
-
+
@@ -461,56 +527,32 @@
- - +
-
-
-
Aperçu
-
-
Aperçu live (non sauvegardé).
- -
-
-
—
-
-
-
- -
- -
-
-
-
-
-
- - -
-
-
-
-
Règles
-
    -
  • Texte: affiché tel quel (safe), retours à la ligne conservés.
  • -
  • HTML: le serveur retire les <script> et les attributs on*.
  • -
  • Vidéo: accepte un chemin relatif (ex: video/reward.mp4) ou une URL complète.
  • -
-
-
-
-
Astuce
-
- Si tu utilises du HTML, préfère des tags simples (<p>, <a>, <strong>) pour éviter des surprises d’affichage. +
+
—
+
+
+
+ +
+ +
+ +
+
    +
  • Texte: affiché tel quel (safe), retours à la ligne conservés.
  • +
  • HTML: le serveur retire les <script> et les attributs on*.
  • +
  • Vidéo: accepte un chemin relatif (ex: video/reward.mp4) ou une URL complète.
  • +
@@ -525,15 +567,13 @@
-
-

Liste des utilisateurs

-
- — utilisateur(s) -
+
+ + — utilisateur(s)
- - + +
@@ -559,63 +599,53 @@
-
-
-

Films

-
Gestion et ajout des films (par année).
+
+
+ + Ajout de films : cette section récupère automatiquement les infos du film via l’imdb_id (OMDb). +
+ +
+
+
+ + +
Sépare films & stats par année.
+
+
+ + +
+
+ + +
+
+ +
+
+
+
+ +
+ +
+
+
- - -
- -
-
-
-
Gérer les films
-
Filtre, sélection et suppression en lot.
-
-
- — -
-
- -
+
- -
-
- -
- - -
-
- -
- - +
+ +
@@ -647,149 +677,15 @@
-
- - -
-
Ajouter un film
-
- Le serveur récupère automatiquement titre/plot/poster via OMDb avec l’imdb_id. -
- -
-
-
- - -
Sépare films & stats par année.
-
-
- - -
-
- - -
-
-
- - -
-
- -
-
-
-

- -

-
-
-
-
- - -
Auto = video_src → embed_src → vod_link.
-
-
- - -
Si video_file est fourni et que ce champ est vide, la lecture utilisera /api/video/<movieId>.
-
-
- - -
Chemin relatif sous VIDEO_FILES_DIR (défaut: public/video).
-
-
- - -
Chemin relatif sous VIDEO_FILES_DIR. Ex: LOW/123.LOW.mp4.
-
-
- - -
Upload d'un fichier .srt (converti en VTT serveur, interne uniquement).
-
-
- - -
-
- - -
-
-
- - -
-
-
- - -
-
- - -
Compat. Préfère video_src / embed_src.
-
-
-
-
-
-
-
- -
- - -
-
-
-
- - -
-
-
-
-
Notes rapides
-
    -
  • Auto: utilise video_src → embed_src → vod_link.
  • -
  • Server file: mets video_file (chemin relatif sous public/video).
  • -
  • Low quality: mets video_file_low (ex: LOW/mon_film.LOW.mp4).
  • -
  • Édition: le bouton “Éditer” ouvre une modale avec des onglets Info / Player.
  • -
-
-
-
-
-
Astuce
-
- Dans “Gérer”, la recherche filtre la table localement (sans requête API). Le “Tout sélectionner” ne coche que les lignes visibles. -
-
-
-
-
-
-
-

Backup / Restore

-
Sauvegarde et restauration de la base MongoDB.
+
+ + Sauvegarde et restauration de la base MongoDB.
@@ -820,8 +716,8 @@
Format .ndjson.gz, stocké sur le serveur.
- - + +
@@ -869,7 +765,7 @@
- +
@@ -917,9 +813,9 @@
-
-

Catégories Oscars

-
Créez et gérez les catégories manuellement.
+
+ + Créez et gérez les catégories manuellement.
@@ -1024,9 +920,9 @@
-
-

Gagnants

-
Définis un ou plusieurs gagnants par année (égalité possible).
+
+ + Définis un ou plusieurs gagnants par année (égalité possible).
@@ -1075,9 +971,9 @@
- - - + + +
@@ -1156,8 +1052,8 @@
@@ -1193,8 +1089,8 @@
diff --git a/public/css/app.css b/public/css/app.css index 7b57f14..7b24d65 100644 --- a/public/css/app.css +++ b/public/css/app.css @@ -580,6 +580,75 @@ footer { color: #111827; } + /* Admin tabs: visually connect tabs with their content */ + #adminTabs { + border-bottom: 0; + gap: 0.35rem; + padding-bottom: 0; + } + + #adminTabs .nav-link { + background-color: var(--app-surface); + border: 1px solid var(--app-border); + } + + #adminTabs .nav-link:hover { + background-color: var(--app-surface); + } + + #adminTabs .nav-link.active { + background-color: var(--app-surface); + border-color: var(--app-border); + border-bottom-color: transparent; + position: relative; + top: 1px; + z-index: 2; + } + + #adminTabs .nav-link.active::after { + content: ""; + position: absolute; + left: 1px; + right: 1px; + bottom: -3px; + height: 3px; + background: var(--app-surface); + } + + #adminTabs .nav-link:not(.active) { + border-color: var(--app-border); + } + + #adminTabs + .admin-tabs-content { + background-color: transparent; + border: 0; + border-radius: 0; + padding: 0; + margin-top: -1px; + padding-top: 0 !important; + } + + /* Hide top border under the active admin tab */ + #adminTabs + .admin-tabs-content > .tab-pane.active { + position: relative; + } + + #adminTabs + .admin-tabs-content > .tab-pane.active::before { + content: ""; + position: absolute; + top: 0; + left: 0; + height: 1px; + width: calc(100% + 2px); + margin-left: -1px; + background: transparent; + pointer-events: none; + } + + #adminTabs + .admin-tabs-content .tab-pane .card:first-of-type { + border-top-color: transparent; + } + body.bg-light { background-color: var(--app-bg) !important; @@ -1083,6 +1152,18 @@ footer { color: #fff; background: rgba(79, 124, 255, 0.18); border-color: rgba(79, 124, 255, 0.4); + border-bottom-color: transparent; + } + + html[data-theme="dark"] #adminTabs .nav-link:not(.active) { + border-color: var(--app-border); + } + + html[data-theme="dark"] #adminTabs .nav-link.active::after, + html[data-theme="dark"] #editMovieTabs .nav-link.active::after { + background: var(--app-surface); + bottom: -3px; + height: 3px; } html[data-theme="dark"] #adminTabsContent .table, diff --git a/public/js/app_control.js b/public/js/app_control.js index 11c1eb9..df5271c 100644 --- a/public/js/app_control.js +++ b/public/js/app_control.js @@ -1,5 +1,6 @@ window.onload = async function () { const token = localStorage.getItem('auth_token'); + if (!token) { window.location.href = '/'; return; @@ -38,7 +39,7 @@ window.onload = async function () { const form = document.getElementById('add-movie-form'); const yearInput = document.getElementById('oscar_year'); - const activeYearInput = document.getElementById('active_oscar_year'); + const activeYearInput = document.getElementById('active_oscar_year') || document.getElementById('oscar_date_year'); const saveActiveYearBtn = document.getElementById('save-active-year'); // Player UI (settings tab): show/hide admin status blocks in player.html @@ -49,9 +50,6 @@ window.onload = async function () { // Version control tab elements const adminVersionTabBtn = document.getElementById('admin-version-tab'); const appVersionAlertEl = document.getElementById('app_version_alert'); - const appVersionActiveSelectEl = document.getElementById('app_version_active_select'); - const appVersionReloadBtn = document.getElementById('app_version_reload'); - const appVersionSetActiveBtn = document.getElementById('app_version_set_active'); const appVersionPreviewEl = document.getElementById('app_version_preview'); const appVersionNewVersionEl = document.getElementById('app_version_new_version'); const appVersionNewMessageEl = document.getElementById('app_version_new_message'); @@ -419,40 +417,10 @@ window.onload = async function () { } function renderAppVersionUI() { - if (!appVersionActiveSelectEl || !appVersionListEl) return; + if (!appVersionListEl) return; const versions = Array.isArray(appVersionState.versions) ? appVersionState.versions : []; const activeId = appVersionState?.active?.id ? String(appVersionState.active.id) : ''; - const previous = String(appVersionActiveSelectEl.value || ''); - appVersionActiveSelectEl.innerHTML = ''; - - if (!versions.length) { - const opt = document.createElement('option'); - opt.value = ''; - opt.textContent = 'Aucune version (crée-en une)'; - opt.disabled = true; - opt.selected = true; - appVersionActiveSelectEl.appendChild(opt); - appVersionActiveSelectEl.disabled = true; - if (appVersionSetActiveBtn) appVersionSetActiveBtn.disabled = true; - } else { - versions.forEach((v) => { - const opt = document.createElement('option'); - opt.value = String(v?.id || ''); - const dateLabel = v?.dateISO ? formatDateTime(v.dateISO) : '—'; - const msg = String(v?.message || '').trim(); - const shortMsg = msg.length > 80 ? `${msg.slice(0, 77)}...` : msg; - opt.textContent = `${v?.version || '—'} — ${dateLabel}${shortMsg ? ` — ${shortMsg}` : ''}`; - appVersionActiveSelectEl.appendChild(opt); - }); - - const stillExists = versions.map((v) => String(v?.id || '')).includes(previous); - const desired = activeId || (stillExists ? previous : String(versions[0]?.id || '')); - appVersionActiveSelectEl.value = desired; - appVersionActiveSelectEl.disabled = false; - if (appVersionSetActiveBtn) appVersionSetActiveBtn.disabled = false; - } - if (!versions.length) { appVersionListEl.textContent = '—'; return; @@ -465,6 +433,9 @@ window.onload = async function () { const msg = escapeHtml(String(v?.message || '').trim()); const versionLabel = escapeHtml(String(v?.version || '—')); const activeBadge = isActive ? 'Active' : ''; + const activateBtn = isActive + ? '' + : ``; // IMPORTANT: keep markup compact (no preserved whitespace surprises). return ( @@ -476,8 +447,9 @@ window.onload = async function () { `
` + `
${escapeHtml(dateLabel)}${msg ? ` — ${msg}` : ''}
` + `
` + - `
` + - `` + + `
` + + `${activateBtn}` + + `` + `
` + `
` ); @@ -485,6 +457,29 @@ window.onload = async function () { appVersionListEl.innerHTML = `
${rows}
`; + appVersionListEl.querySelectorAll('button[data-app-version-activate]').forEach((btn) => { + btn.addEventListener('click', async () => { + const id = btn.getAttribute('data-app-version-activate'); + if (!id) return; + btn.disabled = true; + const old = btn.textContent; + btn.textContent = '...'; + try { + hideAppVersionAlert(); + appVersionState = await setActiveAppVersion(id); + appVersionLoadedOnce = true; + renderAppVersionUI(); + await refreshAppVersionPreview(); + setAppVersionAlert('success', 'Version active mise à jour.'); + } catch (err) { + setAppVersionAlert('danger', err.message || 'Erreur réseau'); + } finally { + btn.disabled = false; + btn.textContent = old; + } + }); + }); + appVersionListEl.querySelectorAll('button[data-app-version-delete]').forEach((btn) => { btn.addEventListener('click', async () => { const id = btn.getAttribute('data-app-version-delete'); @@ -513,7 +508,7 @@ window.onload = async function () { async function loadAppVersionTab(options = {}) { const force = !!options.force; - if (!appVersionActiveSelectEl || !appVersionListEl) return; + if (!appVersionListEl) return; if (appVersionLoadedOnce && !force) return; try { hideAppVersionAlert(); @@ -1103,7 +1098,7 @@ window.onload = async function () { return ( `
` + `
${name}${ptsLabel}
` + - `` + + `` + `
` ); }).join(''); @@ -1235,7 +1230,7 @@ window.onload = async function () { return /^tt\d{5,}$/.test(String(value || '').trim()); } - document.getElementById('reset-form').addEventListener('click', function () { + document.getElementById('reset-form')?.addEventListener('click', function () { form.reset(); responseEl.classList.add('d-none'); }); @@ -1632,8 +1627,8 @@ window.onload = async function () { ${formatBytes(b?.sizeBytes)} ${formatDateTime(b?.mtime)} - - + + `; dbBackupListBody.appendChild(tr); @@ -1802,42 +1797,7 @@ window.onload = async function () { if (adminVersionTabBtn) { adminVersionTabBtn.addEventListener('shown.bs.tab', () => loadAppVersionTab({ force: false })); } - if (appVersionReloadBtn) { - appVersionReloadBtn.addEventListener('click', async () => { - appVersionReloadBtn.disabled = true; - const old = appVersionReloadBtn.textContent; - appVersionReloadBtn.textContent = 'Chargement...'; - try { - await loadAppVersionTab({ force: true }); - setAppVersionAlert('success', 'Rechargé.'); - } finally { - appVersionReloadBtn.disabled = false; - appVersionReloadBtn.textContent = old; - } - }); - } - if (appVersionSetActiveBtn && appVersionActiveSelectEl) { - appVersionSetActiveBtn.addEventListener('click', async () => { - const id = String(appVersionActiveSelectEl.value || '').trim(); - if (!id) return; - appVersionSetActiveBtn.disabled = true; - const old = appVersionSetActiveBtn.textContent; - appVersionSetActiveBtn.textContent = '...'; - try { - hideAppVersionAlert(); - appVersionState = await setActiveAppVersion(id); - appVersionLoadedOnce = true; - renderAppVersionUI(); - await refreshAppVersionPreview(); - setAppVersionAlert('success', 'Version active mise à jour.'); - } catch (err) { - setAppVersionAlert('danger', err.message || 'Erreur réseau'); - } finally { - appVersionSetActiveBtn.disabled = false; - appVersionSetActiveBtn.textContent = old; - } - }); - } + // Active version is handled inside the history list (✓). async function handleCreateAppVersion(activate) { const version = String(appVersionNewVersionEl?.value || '').trim(); @@ -1990,18 +1950,17 @@ window.onload = async function () { const year = parseYear(yearInput.value); const imdb_id = document.getElementById('imdb_id').value.trim(); const category = document.getElementById('category').value.trim(); - const cam = !!document.getElementById('cam_flag')?.checked; - const vod_link = document.getElementById('vod_link').value.trim(); - const player_mode = (document.getElementById('player_mode')?.value || 'auto').trim(); - const video_src = document.getElementById('video_src')?.value?.trim() || ''; - const video_file = document.getElementById('video_file')?.value?.trim() || ''; - const video_file_low = document.getElementById('video_file_low')?.value?.trim() || ''; - const embed_src = document.getElementById('embed_src')?.value?.trim() || ''; - const subtitleFileInput = document.getElementById('subtitle_file'); - const subtitleFile = subtitleFileInput?.files?.[0] || null; - const subtitle_lang = normalizeSubtitleText(document.getElementById('subtitle_lang')?.value, 24); - const subtitle_label = normalizeSubtitleText(document.getElementById('subtitle_label')?.value, 80); - const subtitle_default = !!document.getElementById('subtitle_default')?.checked; + const cam = false; + const vod_link = ''; + const player_mode = 'auto'; + const video_src = ''; + const video_file = ''; + const video_file_low = ''; + const embed_src = ''; + const subtitleFile = null; + const subtitle_lang = ''; + const subtitle_label = ''; + const subtitle_default = false; if (!year) { showResponse('warning', 'Année invalide. Exemple attendu: 2026'); @@ -2158,7 +2117,7 @@ window.onload = async function () { } // Oscar date year dropdown (settings tab) - if (oscarDateYearSelect && oscarDateValueInput && saveOscarDateBtn && clearOscarDateBtn) { + if (oscarDateYearSelect && oscarDateValueInput && saveOscarDateBtn) { const previousOscarYearSelection = String(oscarDateYearSelect.value || ''); oscarDateYearSelect.innerHTML = ''; @@ -2172,7 +2131,7 @@ window.onload = async function () { oscarDateYearSelect.disabled = true; oscarDateValueInput.disabled = true; saveOscarDateBtn.disabled = true; - clearOscarDateBtn.disabled = true; + if (clearOscarDateBtn) clearOscarDateBtn.disabled = true; } else { cleanedYears.forEach((y) => { const opt = document.createElement('option'); @@ -2191,7 +2150,7 @@ window.onload = async function () { oscarDateYearSelect.disabled = false; oscarDateValueInput.disabled = false; saveOscarDateBtn.disabled = false; - clearOscarDateBtn.disabled = false; + if (clearOscarDateBtn) clearOscarDateBtn.disabled = false; oscarDateYearSelect.value = desired; } } diff --git a/public/user-stat.html b/public/user-stat.html index fd056ec..7058692 100644 --- a/public/user-stat.html +++ b/public/user-stat.html @@ -35,9 +35,23 @@ .stats-tabs .nav-link { font-weight: 400; } + .stats-tabs { + border-bottom: 0; + } .stats-tab-panel { + padding-top: 0; + } + .stats-tab-panel > .tab-pane:not(#pane-ranking) { padding-top: 1rem; } + #pane-ranking .user-table { + margin-top: 0.25rem; + } + .stats-tab-panel .table, + .stats-tab-panel .table th, + .stats-tab-panel .table td { + font-size: 0.9rem; + } @@ -111,7 +125,7 @@