From cc2bd156582556151159e3113cdf30250640b458 Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 13 Jul 2026 17:32:09 -0400 Subject: [PATCH] Refactor inscription management UI to eliminate hardcoded language strings, replacing them with dynamic keys for better localization. Update CSS for improved grid layout and visual consistency, including responsive adjustments for mobile views. Increment version code to 4.72.811 to reflect these changes. --- .cursor/rules/ms1-documentation.mdc | 9 +- css/style.css | 132 +++++++++++++++++++--- php/inc_fx_inscriptions_gestion.php | 70 +++++++----- php/inc_settings.php | 2 +- sql/MSIN-4401-inscr-gestion-list-i18n.sql | 31 +++++ 5 files changed, 196 insertions(+), 48 deletions(-) create mode 100644 sql/MSIN-4401-inscr-gestion-list-i18n.sql diff --git a/.cursor/rules/ms1-documentation.mdc b/.cursor/rules/ms1-documentation.mdc index ed92e45..e28399d 100644 --- a/.cursor/rules/ms1-documentation.mdc +++ b/.cursor/rules/ms1-documentation.mdc @@ -14,10 +14,13 @@ alwaysApply: true ## Libellés UI (table `info`) -- Tout texte affiché à l’utilisateur (FR/EN) passe par **Info** (`afficheTexte` / clés `info_clef`), **jamais** codé en dur dans le PHP/JS. -- Nouvelle clé = script SQL `sql/MSIN-xxxx-….sql` (INSERT dans `info`, fr + en), exécutable en pilote/prod. -- Les fallbacks PHP FR/EN ne remplacent pas ce script : ce sont un filet de secours uniquement. +- Tout texte affiché à l’utilisateur (FR/EN) passe par **Info** (`afficheTexte` / `fxInscrGestionT` / clés `info_clef`), **jamais** codé en dur dans le PHP/JS. +- Ça inclut aussi : en-têtes de colonnes, compteurs (« 12 inscriptions »), pastilles, `title`/`aria-label`, messages d’invite — **même si `aria-hidden`**. +- Interdit : `if ($strLangue === 'fr') { echo '…'; } else { echo '…'; }`, ternaires FR/EN, chaînes collées dans un `echo` HTML. +- Nouvelle clé = script SQL `sql/MSIN-xxxx-….sql` (INSERT dans `info`, fr + en) **dans le même lot** que le PHP. +- Les fallbacks PHP FR/EN (`fxInscrGestionFallbackTexte`, etc.) = filet de secours uniquement ; **pas** la source de vérité, et ne remplacent **pas** le script SQL. +Avant de terminer une tâche UI : rechercher dans les fichiers touchés les motifs `=== 'fr'`, `=== 'en'`, `$blnFr ?`, et les libellés français littéraux hors commentaires. ## AJAX multi-pages (Info) Tout endpoint AJAX qui lit/écrit des libellés Info et peut être appelé depuis plusieurs pages (compte, hub, `/mobile`) doit **forcer le contexte `compte.php`** avant les includes utiles : diff --git a/css/style.css b/css/style.css index b0b9978..d4df28e 100644 --- a/css/style.css +++ b/css/style.css @@ -3817,6 +3817,13 @@ a.ms1-trad-link.btn-aide-trad{ } .inscr-gestion-list{ + --ig-list-cols: + minmax(9.5rem, 1.15fr) + minmax(11rem, 1.9fr) + minmax(6.75rem, 0.7fr) + minmax(3.75rem, 5rem) + 2.5rem + 1.15rem; border:1px solid #c5d8f0; border-radius:6px; background:#fff; @@ -3826,7 +3833,7 @@ a.ms1-trad-link.btn-aide-trad{ .inscr-gestion-list-item{ display:grid; - grid-template-columns:minmax(120px,1.4fr) minmax(100px,1.2fr) minmax(80px,.8fr) 56px minmax(72px,.9fr) 20px; + grid-template-columns:var(--ig-list-cols); gap:8px 12px; align-items:center; padding:10px 12px; @@ -3839,42 +3846,50 @@ a.ms1-trad-link.btn-aide-trad{ /* En-tete de colonnes : meme grille que les lignes pour un alignement parfait. */ .inscr-gestion-list-cols{ display:grid; - grid-template-columns:minmax(120px,1.4fr) minmax(100px,1.2fr) minmax(80px,.8fr) 56px minmax(72px,.9fr) 20px; + grid-template-columns:var(--ig-list-cols); gap:8px 12px; align-items:center; padding:8px 12px; - background:#f5f9ff; - border-bottom:1px solid #d6e4f5; + background:#e7f1ff; + border-bottom:1px solid #c5d8f0; font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:.03em; - color:#6c757d; + color:#004085; } .inscr-gestion-list-cols__bib, .inscr-gestion-list-cols__check{ - text-align:right; + text-align:center; } .inscr-gestion-list-item:last-child{ border-bottom:none; } +.inscr-gestion-list > a.inscr-gestion-list-item:nth-of-type(even){ + background:#f7faff; +} + .inscr-gestion-list-item:hover, .inscr-gestion-list-item:focus{ color:inherit; text-decoration:none; - background:#f0f6ff; + background:#eaf3ff; } -.inscr-gestion-list-item--cancelled{ +.inscr-gestion-list-item--cancellation{ background:#fff5f5; border-color:#f1b0b7; } -.inscr-gestion-list-item--cancelled:hover, -.inscr-gestion-list-item--cancelled:focus{ +.inscr-gestion-list-item--cancellation:nth-of-type(even){ + background:#fff0f0; +} + +.inscr-gestion-list-item--cancellation:hover, +.inscr-gestion-list-item--cancellation:focus{ background:#ffecec; } @@ -3923,11 +3938,19 @@ a.ms1-trad-link.btn-aide-trad{ font-size:13px; color:#495057; min-width:0; + overflow:hidden; + text-overflow:ellipsis; + white-space:nowrap; } .inscr-gestion-list-item__order{ font-size:12px; color:#6c757d; + font-variant-numeric:tabular-nums; + min-width:0; + overflow:hidden; + text-overflow:ellipsis; + white-space:nowrap; } .inscr-gestion-list-item__meta{ @@ -3935,19 +3958,81 @@ a.ms1-trad-link.btn-aide-trad{ } .inscr-gestion-list-item__bib{ + text-align:center; + min-width:0; +} + +.inscr-gestion-bib-pill{ + display:inline-block; + max-width:100%; + padding:2px 9px; + border-radius:999px; + background:#e7f1ff; + border:1px solid #b8daff; + color:#004085; + font-weight:700; + font-size:12px; + font-variant-numeric:tabular-nums; + line-height:1.35; + overflow:hidden; + text-overflow:ellipsis; + white-space:nowrap; + vertical-align:middle; +} + +.inscr-gestion-bib-pill--empty{ + background:#f1f3f5; + border-color:#dee2e6; + color:#adb5bd; font-weight:600; - font-size:13px; - color:#007bff; - text-align:right; } .inscr-gestion-list-item__check{ - text-align:right; + text-align:center; +} + +.inscr-gestion-remis{ + display:inline-flex; + align-items:center; + justify-content:center; + width:1.35rem; + height:1.35rem; + border-radius:50%; + line-height:1; +} + +.inscr-gestion-remis--yes{ + color:#28a745; + background:#e8f5e9; + font-size:14px; +} + +.inscr-gestion-remis--no{ + background:#eef1f4; + border:1px solid #dee2e6; } .inscr-gestion-list-item__arrow{ - color:#adb5bd; + color:#8aa8d4; flex-shrink:0; + justify-self:end; +} + +/* Tablette : cacher Commande, garder le punch utile (nom / épreuve / dossard / remis). */ +@media (max-width:1099px) and (min-width:768px){ + .inscr-gestion-list{ + --ig-list-cols: + minmax(8.5rem, 1.2fr) + minmax(10rem, 2fr) + minmax(3.5rem, 4.75rem) + 2.5rem + 1.15rem; + } + + .inscr-gestion-list-cols__order, + .inscr-gestion-list-item__order{ + display:none; + } } .inscr-gestion-badge{ @@ -4577,12 +4662,25 @@ a.ms1-trad-link.btn-aide-trad{ "race race" "order bib" "check check"; - gap:4px 8px; + gap:6px 10px; padding:12px; + border-left:3px solid #c5d8f0; + margin:0; + border-radius:0; + } + + .inscr-gestion-list > a.inscr-gestion-list-item:nth-of-type(even){ + background:#f7faff; } .inscr-gestion-list-item__name{ grid-area:name; } - .inscr-gestion-list-item__race{ grid-area:race; } + .inscr-gestion-list-item__race{ + grid-area:race; + white-space:normal; + display:-webkit-box; + -webkit-line-clamp:2; + -webkit-box-orient:vertical; + } .inscr-gestion-list-item__order{ grid-area:order; } .inscr-gestion-list-item__bib{ grid-area:bib; text-align:left; } .inscr-gestion-list-item__check{ grid-area:check; text-align:left; } diff --git a/php/inc_fx_inscriptions_gestion.php b/php/inc_fx_inscriptions_gestion.php index e01ef87..5fc2fa7 100644 --- a/php/inc_fx_inscriptions_gestion.php +++ b/php/inc_fx_inscriptions_gestion.php @@ -452,6 +452,13 @@ function fxInscrGestionFallbackTexte($strClef, $strLangue) { 'inscr_gestion_refund_cancel_hint' => $blnFr ? 'Votre transaction a été remboursée. Si vous voulez aussi l\'annuler dans le système d\'inscription :' : 'Your transaction has been refunded. If you also want to cancel it in the registration system:', + 'inscr_gestion_col_participant' => $blnFr ? 'Participant' : 'Participant', + 'inscr_gestion_col_commande' => $blnFr ? 'Commande' : 'Order', + 'inscr_gestion_col_dossard' => $blnFr ? 'Dossard' : 'Bib', + 'inscr_gestion_col_remis' => $blnFr ? 'Remis' : 'Issued', + 'inscr_gestion_list_count_one' => $blnFr ? '%d inscription' : '%d registration', + 'inscr_gestion_list_count_many' => $blnFr ? '%d inscriptions' : '%d registrations', + 'inscr_gestion_list_page' => $blnFr ? 'Page %d / %d' : 'Page %d / %d', ); } @@ -1853,38 +1860,33 @@ function fxInscrGestionRenderList($intEveId, $strLangue, $strBaseUrl, $arrReq) { } echo '
'; - if ($strLangue === 'fr') { - echo '' . (int)$intNbTotal . ' inscription' . ($intNbTotal > 1 ? 's' : '') . ''; - } else { - echo '' . (int)$intNbTotal . ' registration' . ($intNbTotal !== 1 ? 's' : '') . ''; - } + $strCountKey = ($intNbTotal === 1) ? 'inscr_gestion_list_count_one' : 'inscr_gestion_list_count_many'; + echo '' . fxInscrGestionEsc(sprintf(fxInscrGestionT($strCountKey), $intNbTotal)) . ''; if ($intNbTotal > $intNbItemsParPage) { $intNbPages = (int)ceil($intNbTotal / $intNbItemsParPage); - echo '' . ($strLangue === 'fr' ? 'Page ' : 'Page ') . $intPage . ' / ' . $intNbPages . ''; + echo '' + . fxInscrGestionEsc(sprintf(fxInscrGestionT('inscr_gestion_list_page'), $intPage, $intNbPages)) + . ''; } echo '
'; if ($intNbTotal > 0) { echo '
'; - // En-tete de colonnes (memes colonnes que les lignes ; masque en vue cellulaire, - // ou la liste passe en cartes). aria-hidden : purement visuel, redondant pour les - // lecteurs d'ecran car chaque valeur de ligne porte deja son sens. + // En-tete de colonnes (memes colonnes que les lignes ; masque en vue cellulaire). + // aria-hidden : purement visuel — libellés Info (pas de FR/EN en dur). echo ''; for ($j = $intStart; $j <= $intEnd; $j++) { @@ -1907,16 +1909,30 @@ function fxInscrGestionRenderList($intEveId, $strLangue, $strBaseUrl, $arrReq) { . fxInscrGestionEsc(fxInscrGestionT('inscr_gestion_statut_' . $strCause)) . ''; } + $strRemisLabel = fxInscrGestionT('promoteur_bib_enregistre'); + $blnRemis = (intval($row['no_bib_remis']) === 1); + echo ''; echo '' . fxInscrGestionEsc($strName) . $strCancelBadge . ''; - echo '' . fxInscrGestionEsc($strRace) . ''; + echo '' + . fxInscrGestionEsc($strRace) . ''; echo '' . fxInscrGestionEsc($row['no_commande']) . ''; echo ''; - echo trim($strBib) !== '' ? fxInscrGestionEsc($strBib) : '—'; + if (trim($strBib) !== '') { + echo '' . fxInscrGestionEsc($strBib) . ''; + } else { + echo ''; + } echo ''; echo ''; - if ($row['no_bib_remis'] == 1) { - echo '' . fxInscrGestionEsc(fxInscrGestionT('promoteur_bib_enregistre')) . ''; + if ($blnRemis) { + echo ''; + echo ''; + echo '' . fxInscrGestionEsc($strRemisLabel) . ''; + echo ''; + } else { + echo ''; } echo ''; echo ''; diff --git a/php/inc_settings.php b/php/inc_settings.php index 52627d2..de11cf1 100644 --- a/php/inc_settings.php +++ b/php/inc_settings.php @@ -7,7 +7,7 @@ * Constantes * * **************/ -define('_VERSION_CODE', '4.72.809'); +define('_VERSION_CODE', '4.72.811'); define('_DATE_CODE', '2026-07-13'); //MSIN-4290 define('QR_SECRET_KEY', 'ms1_qr_2026_cle_secrete_longue_et_fixe'); diff --git a/sql/MSIN-4401-inscr-gestion-list-i18n.sql b/sql/MSIN-4401-inscr-gestion-list-i18n.sql new file mode 100644 index 0000000..702f3ed --- /dev/null +++ b/sql/MSIN-4401-inscr-gestion-list-i18n.sql @@ -0,0 +1,31 @@ +-- MSIN-4401 — Libellés Info liste résultats (gestion inscriptions V2) +-- Prérequis : aucun +-- Idempotent (DELETE + INSERT). Jamais de FR/EN en dur dans le PHP de la liste. + +DELETE FROM info +WHERE info_prg = 'compte.php' + AND info_clef IN ( + 'inscr_gestion_col_participant', + 'inscr_gestion_col_commande', + 'inscr_gestion_col_dossard', + 'inscr_gestion_col_remis', + 'inscr_gestion_list_count_one', + 'inscr_gestion_list_count_many', + 'inscr_gestion_list_page' + ); + +INSERT INTO info (info_clef, info_langue, info_texte, info_aide, info_prg, info_description, info_trie, info_actif, info_option1, info_option2, info_option3, info_creation) VALUES +('inscr_gestion_col_participant', 'fr', 'Participant', '', 'compte.php', '', 0, 1, '', '', '', NOW()), +('inscr_gestion_col_participant', 'en', 'Participant', '', 'compte.php', '', 0, 1, '', '', '', NOW()), +('inscr_gestion_col_commande', 'fr', 'Commande', '', 'compte.php', '', 0, 1, '', '', '', NOW()), +('inscr_gestion_col_commande', 'en', 'Order', '', 'compte.php', '', 0, 1, '', '', '', NOW()), +('inscr_gestion_col_dossard', 'fr', 'Dossard', '', 'compte.php', '', 0, 1, '', '', '', NOW()), +('inscr_gestion_col_dossard', 'en', 'Bib', '', 'compte.php', '', 0, 1, '', '', '', NOW()), +('inscr_gestion_col_remis', 'fr', 'Remis', '', 'compte.php', '', 0, 1, '', '', '', NOW()), +('inscr_gestion_col_remis', 'en', 'Issued', '', 'compte.php', '', 0, 1, '', '', '', NOW()), +('inscr_gestion_list_count_one', 'fr', '%d inscription', '', 'compte.php', '', 0, 1, '', '', '', NOW()), +('inscr_gestion_list_count_one', 'en', '%d registration', '', 'compte.php', '', 0, 1, '', '', '', NOW()), +('inscr_gestion_list_count_many', 'fr', '%d inscriptions', '', 'compte.php', '', 0, 1, '', '', '', NOW()), +('inscr_gestion_list_count_many', 'en', '%d registrations', '', 'compte.php', '', 0, 1, '', '', '', NOW()), +('inscr_gestion_list_page', 'fr', 'Page %d / %d', '', 'compte.php', '', 0, 1, '', '', '', NOW()), +('inscr_gestion_list_page', 'en', 'Page %d / %d', '', 'compte.php', '', 0, 1, '', '', '', NOW());