MSIN-4459 — Implement team member display under captain in participant list. Update CSS for layout adjustments and add new SQL query to fetch team members. Increment version code to 4.72.836.

This commit is contained in:
2026-07-20 12:01:41 -04:00
parent da4de58b08
commit 39fd110388
4 changed files with 189 additions and 6 deletions

View File

@ -4048,6 +4048,15 @@ a.ms1-trad-link.btn-aide-trad{
display:contents; display:contents;
} }
/* MSIN-4459 — cellule participant : capitaine + nom d'équipe + coéquipiers */
.inscr-gestion-list-item__who{
min-width:0;
display:flex;
flex-direction:column;
align-items:stretch;
gap:3px;
}
.inscr-gestion-list-item__name{ .inscr-gestion-list-item__name{
font-weight:700; font-weight:700;
font-size:14px; font-size:14px;
@ -4059,6 +4068,46 @@ a.ms1-trad-link.btn-aide-trad{
gap:8px; gap:8px;
} }
.inscr-gestion-list-item__team{
font-size:12px;
font-weight:500;
color:#495057;
line-height:1.35;
}
.inscr-gestion-list-mates{
list-style:none;
margin:2px 0 0;
padding:2px 0 0 10px;
border-left:3px solid #c5d8f0;
width:100%;
}
.inscr-gestion-list-mates__item{
font-size:12px;
font-weight:500;
color:#495057;
line-height:1.4;
padding:1px 0;
}
.inscr-gestion-list-mates__link{
color:inherit;
text-decoration:none;
display:inline-block;
max-width:100%;
}
.inscr-gestion-list-mates__link:hover{
color:#004085;
text-decoration:underline;
}
.inscr-gestion-list-mates__role{
color:#6c757d;
font-weight:400;
}
/* MSIN-4405 — la pastille de cause se colle au bord droit de la cellule du nom */ /* MSIN-4405 — la pastille de cause se colle au bord droit de la cellule du nom */
.inscr-gestion-list-item__name .inscr-gestion-cancel-badge{ .inscr-gestion-list-item__name .inscr-gestion-cancel-badge{
margin-left:auto; margin-left:auto;
@ -5037,7 +5086,8 @@ button.inscr-gestion-list-remis:hover{
background:#f7faff; background:#f7faff;
} }
.inscr-gestion-list-item__name{ grid-area:name; } .inscr-gestion-list-item__who{ grid-area:name; }
.inscr-gestion-list-item__name{ display:flex; }
.inscr-gestion-list-item__race{ .inscr-gestion-list-item__race{
grid-area:race; grid-area:race;
white-space:normal; white-space:normal;

View File

@ -542,6 +542,9 @@ function fxInscrGestionFallbackTexte($strClef, $strLangue) {
: 'Bib search mode', : 'Bib search mode',
'chk_bib' => $blnFr ? 'Sans numéro de dossard' : 'Without bib number', 'chk_bib' => $blnFr ? 'Sans numéro de dossard' : 'Without bib number',
'inscr_gestion_reset_search' => $blnFr ? 'Réinitialiser la recherche' : 'Reset search', 'inscr_gestion_reset_search' => $blnFr ? 'Réinitialiser la recherche' : 'Reset search',
// MSIN-4459 — Nom d'équipe + coéquipiers sous le capitaine en liste.
'inscr_gestion_list_team_name' => $blnFr ? 'Nom d\'équipe : %s' : 'Team name: %s',
'inscr_gestion_list_teammate' => $blnFr ? 'Coéquipier' : 'Teammate',
); );
} }
@ -979,9 +982,10 @@ function fxInscrGestionFetchRows($intEveId, $arrReq) {
global $objDatabase; global $objDatabase;
$strWhere = fxInscrGestionBuildWhere($intEveId, $arrReq); $strWhere = fxInscrGestionBuildWhere($intEveId, $arrReq);
// MSIN-4459 — pec_nom_equipe pour affichage du nom d'équipe en liste (1 ligne = 1 commande).
$sql = 'SELECT p.no_bib, p.no_bib_remis, p.no_bib_remis_date, p.no_bib_remis_par, p.par_statut_course, p.par_id, p.par_equipe,' $sql = 'SELECT p.no_bib, p.no_bib_remis, p.no_bib_remis_date, p.no_bib_remis_par, p.par_statut_course, p.par_id, p.par_equipe,'
. ' p.par_prenom, p.par_nom, e.pec_id_original, e.epr_id, e.eve_id, e.pec_id, e.is_cancelled, e.pec_actif, p.rol_id,' . ' p.par_prenom, p.par_nom, e.pec_id_original, e.epr_id, e.eve_id, e.pec_id, e.is_cancelled, e.pec_actif, p.rol_id,'
. ' e.no_commande, e.no_panier, e.no_equipe, e.pec_equipe' . ' e.no_commande, e.no_panier, e.no_equipe, e.pec_equipe, e.pec_nom_equipe'
. ' FROM resultats_epreuves_commandees e, resultats_participants p' . ' FROM resultats_epreuves_commandees e, resultats_participants p'
. ' WHERE ' . $strWhere . ' AND p.pec_id = e.pec_id_original' . ' WHERE ' . $strWhere . ' AND p.pec_id = e.pec_id_original'
. ' GROUP BY e.pec_id_original' . ' GROUP BY e.pec_id_original'
@ -990,6 +994,53 @@ function fxInscrGestionFetchRows($intEveId, $arrReq) {
return $objDatabase->fxGetResults($sql); return $objDatabase->fxGetResults($sql);
} }
/**
* MSIN-4459 — Membres d'équipe pour enrichir la liste (sous le capitaine).
* Une requête batch par page ; exclut rol_id 3/4 (comme promoteur).
*
* @param array $arrPecIds pec_id_original
* @return array map pec_id => liste de participants (capitaine en premier si present)
*/
function fxInscrGestionFetchTeamMembersByPecs($arrPecIds) {
global $objDatabase;
$arrIds = array();
if (is_array($arrPecIds)) {
foreach ($arrPecIds as $intPec) {
$intPec = intval($intPec);
if ($intPec > 0) {
$arrIds[$intPec] = $intPec;
}
}
}
if (count($arrIds) === 0) {
return array();
}
$sql = 'SELECT pec_id, par_id, par_nom, par_prenom, rol_id, no_bib_remis, par_statut_course'
. ' FROM resultats_participants'
. ' WHERE pec_id IN (' . implode(',', $arrIds) . ')'
. ' AND rol_id NOT IN (3, 4)'
. ' ORDER BY pec_id, CASE WHEN rol_id = 1 THEN 0 ELSE 1 END, par_nom, par_prenom';
$tab = $objDatabase->fxGetResults($sql);
$map = array();
if (!is_array($tab) || count($tab) === 0) {
return $map;
}
$intNb = count($tab);
for ($i = 1; $i <= $intNb; $i++) {
$intPec = intval($tab[$i]['pec_id']);
if (!isset($map[$intPec])) {
$map[$intPec] = array();
}
$map[$intPec][] = $tab[$i];
}
return $map;
}
function fxInscrGestionFetchRowByPec($intPecId, $intEveId) { function fxInscrGestionFetchRowByPec($intPecId, $intEveId) {
global $objDatabase; global $objDatabase;
@ -2133,6 +2184,16 @@ function fxInscrGestionRenderList($intEveId, $strLangue, $strBaseUrl, $arrReq) {
$strRemisLabel = fxInscrGestionT('promoteur_bib_enregistre'); $strRemisLabel = fxInscrGestionT('promoteur_bib_enregistre');
$strBibOkLabel = fxInscrGestionT('inscr_gestion_bib_ok'); $strBibOkLabel = fxInscrGestionT('inscr_gestion_bib_ok');
$strTeammateLabel = fxInscrGestionT('inscr_gestion_list_teammate');
// MSIN-4459 — Membres d'équipe de la page courante (1 requête batch).
$arrTeamPecs = array();
for ($jTeam = $intStart; $jTeam <= $intEnd; $jTeam++) {
if (!empty($tabRows[$jTeam]) && intval($tabRows[$jTeam]['pec_equipe']) === 1) {
$arrTeamPecs[] = (int)$tabRows[$jTeam]['pec_id_original'];
}
}
$tabTeamMembersByPec = fxInscrGestionFetchTeamMembersByPecs($arrTeamPecs);
for ($j = $intStart; $j <= $intEnd; $j++) { for ($j = $intStart; $j <= $intEnd; $j++) {
$row = $tabRows[$j]; $row = $tabRows[$j];
@ -2142,6 +2203,42 @@ function fxInscrGestionRenderList($intEveId, $strLangue, $strBaseUrl, $arrReq) {
)); ));
$strFicheHref = fxInscrGestionEsc($strFicheUrl); $strFicheHref = fxInscrGestionEsc($strFicheUrl);
$blnEquipe = (intval($row['pec_equipe']) === 1);
$intPecId = (int)$row['pec_id_original'];
$tabMates = array();
$strTeamName = '';
// MSIN-4459 — Ligne parente = capitaine ; coéquipiers en sous-liste.
if ($blnEquipe) {
$strTeamName = trim(fxUnescape(isset($row['pec_nom_equipe']) ? $row['pec_nom_equipe'] : ''));
$tabMembers = isset($tabTeamMembersByPec[$intPecId]) ? $tabTeamMembersByPec[$intPecId] : array();
$arrCaptain = null;
foreach ($tabMembers as $arrMem) {
if ((int)$arrMem['rol_id'] === 1 && $arrCaptain === null) {
$arrCaptain = $arrMem;
} else {
$tabMates[] = $arrMem;
}
}
if ($arrCaptain !== null) {
$row['par_nom'] = $arrCaptain['par_nom'];
$row['par_prenom'] = $arrCaptain['par_prenom'];
$row['par_id'] = $arrCaptain['par_id'];
$row['no_bib_remis'] = $arrCaptain['no_bib_remis'];
$row['par_statut_course'] = $arrCaptain['par_statut_course'];
$row['rol_id'] = 1;
} else {
// Pas de capitaine : garder la ligne GROUP BY ; exclure ce par_id des mates.
$intMainPar = (int)$row['par_id'];
$tabMates = array();
foreach ($tabMembers as $arrMem) {
if ((int)$arrMem['par_id'] !== $intMainPar) {
$tabMates[] = $arrMem;
}
}
}
}
$strBib = fxInscrGestionBibDisplay($row); $strBib = fxInscrGestionBibDisplay($row);
$strName = fxUnescape($row['par_nom']) . ', ' . fxUnescape($row['par_prenom']); $strName = fxUnescape($row['par_nom']) . ', ' . fxUnescape($row['par_prenom']);
$strRace = fxInscrGestionEpreuveLabel($row['epr_id'], $strLangue); $strRace = fxInscrGestionEpreuveLabel($row['epr_id'], $strLangue);
@ -2157,19 +2254,39 @@ function fxInscrGestionRenderList($intEveId, $strLangue, $strBaseUrl, $arrReq) {
if ($row['is_cancelled'] == '1') { if ($row['is_cancelled'] == '1') {
// MSIN-4405 — Cause derivee en lecture seule (aucune ecriture en base). // MSIN-4405 — Cause derivee en lecture seule (aucune ecriture en base).
$strCause = fxGetAnnulationCause($row['pec_id_original'], $row['pec_actif']); $strCause = fxGetAnnulationCause($row['pec_id_original'], $row['pec_actif']);
$strCardClass .= ' inscr-gestion-list-item--cancelled inscr-gestion-list-item--' . $strCause; $strCardClass .= ' inscr-gestion-list-item--cancellation inscr-gestion-list-item--' . $strCause;
$strCancelBadge = ' <span class="inscr-gestion-cancel-badge inscr-gestion-cancel-badge--' . $strCause . '">' $strCancelBadge = ' <span class="inscr-gestion-cancel-badge inscr-gestion-cancel-badge--' . $strCause . '">'
. fxInscrGestionEsc(fxInscrGestionT('inscr_gestion_statut_' . $strCause)) . '</span>'; . fxInscrGestionEsc(fxInscrGestionT('inscr_gestion_statut_' . $strCause)) . '</span>';
} }
$blnRemis = (intval($row['no_bib_remis']) === 1); $blnRemis = (intval($row['no_bib_remis']) === 1);
$intParId = (int)$row['par_id']; $intParId = (int)$row['par_id'];
$blnEquipe = (intval($row['pec_equipe']) === 1);
// MSIN-4448 — Ligne en div : cellules nav (lien) vs dossard/remis editables. // MSIN-4448 — Ligne en div : cellules nav (lien) vs dossard/remis editables.
echo '<div class="' . $strCardClass . '">'; echo '<div class="' . $strCardClass . '">';
// MSIN-4459 — Bloc nom : capitaine + nom d'équipe + coéquipiers.
echo '<div class="inscr-gestion-list-item__who">';
echo '<a class="inscr-gestion-list-item__name" href="' . $strFicheHref . '">' echo '<a class="inscr-gestion-list-item__name" href="' . $strFicheHref . '">'
. fxInscrGestionEsc($strName) . $strCancelBadge . '</a>'; . fxInscrGestionEsc($strName) . $strCancelBadge . '</a>';
if ($blnEquipe && $strTeamName !== '') {
echo '<span class="inscr-gestion-list-item__team">'
. fxInscrGestionEsc(sprintf(fxInscrGestionT('inscr_gestion_list_team_name'), $strTeamName))
. '</span>';
}
if ($blnEquipe && count($tabMates) > 0) {
echo '<ul class="inscr-gestion-list-mates">';
foreach ($tabMates as $arrMate) {
$strMateName = fxUnescape($arrMate['par_nom']) . ', ' . fxUnescape($arrMate['par_prenom']);
echo '<li class="inscr-gestion-list-mates__item">';
echo '<a class="inscr-gestion-list-mates__link" href="' . $strFicheHref . '">';
echo '<span class="inscr-gestion-list-mates__role">'
. fxInscrGestionEsc($strTeammateLabel) . '</span> ';
echo fxInscrGestionEsc($strMateName);
echo '</a></li>';
}
echo '</ul>';
}
echo '</div>';
echo '<a class="inscr-gestion-list-item__race" href="' . $strFicheHref . '" title="' echo '<a class="inscr-gestion-list-item__race" href="' . $strFicheHref . '" title="'
. fxInscrGestionEsc($strRace) . '">' . fxInscrGestionEsc($strRace) . '</a>'; . fxInscrGestionEsc($strRace) . '">' . fxInscrGestionEsc($strRace) . '</a>';
echo '<a class="inscr-gestion-list-item__order" href="' . $strFicheHref . '">' echo '<a class="inscr-gestion-list-item__order" href="' . $strFicheHref . '">'

View File

@ -7,8 +7,8 @@
* Constantes * * Constantes *
* *
**************/ **************/
define('_VERSION_CODE', '4.72.835'); define('_VERSION_CODE', '4.72.836');
define('_DATE_CODE', '2026-07-16'); define('_DATE_CODE', '2026-07-20');
//MSIN-4290 //MSIN-4290
define('QR_SECRET_KEY', 'ms1_qr_2026_cle_secrete_longue_et_fixe'); define('QR_SECRET_KEY', 'ms1_qr_2026_cle_secrete_longue_et_fixe');

View File

@ -0,0 +1,16 @@
-- MSIN-4459 — Liste inscriptions : nom d'équipe + libellé coéquipier
-- Prérequis : aucun
-- Idempotent (DELETE + INSERT). Compte.php (contexte AJAX / fiche gestion).
DELETE FROM info
WHERE info_prg = 'compte.php'
AND info_clef IN (
'inscr_gestion_list_team_name',
'inscr_gestion_list_teammate'
);
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_list_team_name', 'fr', 'Nom d\'équipe : %s', '', 'compte.php', '', 0, 1, '', '', '', NOW()),
('inscr_gestion_list_team_name', 'en', 'Team name: %s', '', 'compte.php', '', 0, 1, '', '', '', NOW()),
('inscr_gestion_list_teammate', 'fr', 'Coéquipier', '', 'compte.php', '', 0, 1, '', '', '', NOW()),
('inscr_gestion_list_teammate', 'en', 'Teammate', '', 'compte.php', '', 0, 1, '', '', '', NOW());