Enhance multi-page AJAX handling by enforcing context for translations in ajax_inscr_gestion and ajax_promoteur_hub. Introduce new language keys for improved user feedback and error messages. Increment version code to 4.72.806 to reflect these changes.
This commit is contained in:
@ -48,9 +48,17 @@ function fxEveAccesPromoteurT($strClef, $strLangue = 'fr')
|
||||
'fr' => '0 = sans expiration. Utilisé surtout pour les nouveaux accès.',
|
||||
'en' => '0 = no expiration. Mainly for new access grants.',
|
||||
),
|
||||
'eve_acces_promoteur_invite_courriel_help' => array(
|
||||
'fr' => 'Saisissez d\'abord le courriel : on vérifie s\'il existe déjà un compte MS1 avant de demander le nom.',
|
||||
'en' => 'Enter the email first: we check if an MS1 account already exists before asking for a name.',
|
||||
),
|
||||
'eve_acces_promoteur_btn_invite' => array('fr' => 'Assigner l\'accès', 'en' => 'Grant access'),
|
||||
'eve_acces_promoteur_btn_resend' => array('fr' => 'Renvoyer le mail', 'en' => 'Resend email'),
|
||||
'eve_acces_promoteur_btn_revoke' => array('fr' => 'Retirer', 'en' => 'Revoke'),
|
||||
'eve_acces_promoteur_confirm_revoke' => array(
|
||||
'fr' => 'Retirer cet accès ?',
|
||||
'en' => 'Revoke this access?',
|
||||
),
|
||||
'eve_acces_promoteur_no_kits' => array(
|
||||
'fr' => 'Aucun kit délégable disponible. Demandez à un super admin d\'activer « délégable » sur un kit.',
|
||||
'en' => 'No delegable kit available. Ask a super admin to mark a kit as delegable.',
|
||||
@ -100,6 +108,29 @@ function fxEveAccesPromoteurT($strClef, $strLangue = 'fr')
|
||||
'fr' => 'Courriel invalide.',
|
||||
'en' => 'Invalid email.',
|
||||
),
|
||||
'eve_acces_promoteur_access_denied' => array('fr' => 'Accès refusé.', 'en' => 'Access denied.'),
|
||||
'eve_acces_promoteur_btn_back' => array('fr' => 'Retour', 'en' => 'Back'),
|
||||
'eve_acces_promoteur_mail_new_subject' => array(
|
||||
'fr' => 'Accès promoteur — créez votre mot de passe',
|
||||
'en' => 'Promoter access — set your password',
|
||||
),
|
||||
'eve_acces_promoteur_mail_new_body' => array(
|
||||
'fr' => 'Bonjour %prenom%,<br><br>Un accès vous a été accordé pour <strong>%eve_nom%</strong> (kit : %kit%).<br><br>Un compte a été créé avec le courriel <strong>%login%</strong>.<br>Cliquez ci-dessous pour choisir votre mot de passe.<br><br>Ensuite, connectez-vous ici pour travailler sur le terrain :<br><a href="%mobile_url%">%mobile_url%</a>',
|
||||
'en' => 'Hello %prenom%,<br><br>You were granted access to <strong>%eve_nom%</strong> (kit: %kit%).<br><br>An account was created with <strong>%login%</strong>.<br>Click below to set your password.<br><br>Then sign in here for field use:<br><a href="%mobile_url%">%mobile_url%</a>',
|
||||
),
|
||||
'eve_acces_promoteur_mail_new_cta' => array('fr' => 'Choisir mon mot de passe', 'en' => 'Set my password'),
|
||||
'eve_acces_promoteur_mail_existing_subject' => array(
|
||||
'fr' => 'Nouvel accès — %eve_nom%',
|
||||
'en' => 'New access — %eve_nom%',
|
||||
),
|
||||
'eve_acces_promoteur_mail_existing_body' => array(
|
||||
'fr' => 'Bonjour %prenom%,<br><br>Un accès vous a été accordé pour <strong>%eve_nom%</strong> (kit : %kit%).<br><br>Ouvrez le lien ci-dessous et connectez-vous avec le compte <strong>%login%</strong> (si un autre compte est déjà ouvert, vous serez invité à vous déconnecter).',
|
||||
'en' => 'Hello %prenom%,<br><br>You were granted access to <strong>%eve_nom%</strong> (kit: %kit%).<br><br>Open the link below and sign in as <strong>%login%</strong> (if another account is already open, you will be asked to sign out).',
|
||||
),
|
||||
'eve_acces_promoteur_mail_existing_cta' => array(
|
||||
'fr' => 'Ouvrir l\'accès (mobile)',
|
||||
'en' => 'Open access (mobile)',
|
||||
),
|
||||
);
|
||||
$strLang = ($strLangue === 'en') ? 'en' : 'fr';
|
||||
if (isset($arrFallback[$strClef][$strLang])) {
|
||||
@ -294,53 +325,26 @@ function fxEveAccesPromoteurSendInviteMail($arrCompte, $arrEve, $arrRole, $strLa
|
||||
}
|
||||
$strMobileUrl = fxEveAccesPromoteurAppendInviteParams($strMobileUrl, $intComId, $intEveId);
|
||||
|
||||
// Placeholders Info (contenu HTML géré dans table info).
|
||||
$arrMailVars = array(
|
||||
'%prenom%' => htmlspecialchars($strPrenom, ENT_QUOTES, 'UTF-8'),
|
||||
'%eve_nom%' => htmlspecialchars($strEveNom, ENT_QUOTES, 'UTF-8'),
|
||||
'%kit%' => htmlspecialchars($strKit, ENT_QUOTES, 'UTF-8'),
|
||||
'%login%' => htmlspecialchars((string)$strLogin, ENT_QUOTES, 'UTF-8'),
|
||||
'%mobile_url%' => htmlspecialchars($strMobileUrl, ENT_QUOTES, 'UTF-8'),
|
||||
);
|
||||
|
||||
if ($blnNewAccount && $strResetToken !== '') {
|
||||
if ($strLangue === 'fr') {
|
||||
$subject = 'Accès promoteur — créez votre mot de passe';
|
||||
$message = 'Bonjour ' . $strPrenom . ',<br><br>'
|
||||
. 'Un accès vous a été accordé pour <strong>' . htmlspecialchars($strEveNom, ENT_QUOTES, 'UTF-8') . '</strong>'
|
||||
. ' (kit : ' . htmlspecialchars($strKit, ENT_QUOTES, 'UTF-8') . ').<br><br>'
|
||||
. 'Un compte a été créé avec le courriel <strong>' . htmlspecialchars($strLogin, ENT_QUOTES, 'UTF-8') . '</strong>.<br>'
|
||||
. 'Cliquez ci-dessous pour choisir votre mot de passe.<br><br>'
|
||||
. 'Ensuite, connectez-vous ici pour travailler sur le terrain :<br>'
|
||||
. '<a href="' . htmlspecialchars($strMobileUrl, ENT_QUOTES, 'UTF-8') . '">'
|
||||
. htmlspecialchars($strMobileUrl, ENT_QUOTES, 'UTF-8') . '</a>';
|
||||
$attachment_label = 'Choisir mon mot de passe';
|
||||
} else {
|
||||
$subject = 'Promoter access — set your password';
|
||||
$message = 'Hello ' . $strPrenom . ',<br><br>'
|
||||
. 'You were granted access to <strong>' . htmlspecialchars($strEveNom, ENT_QUOTES, 'UTF-8') . '</strong>'
|
||||
. ' (kit: ' . htmlspecialchars($strKit, ENT_QUOTES, 'UTF-8') . ').<br><br>'
|
||||
. 'An account was created with <strong>' . htmlspecialchars($strLogin, ENT_QUOTES, 'UTF-8') . '</strong>.<br>'
|
||||
. 'Click below to set your password.<br><br>'
|
||||
. 'Then sign in here for field use:<br>'
|
||||
. '<a href="' . htmlspecialchars($strMobileUrl, ENT_QUOTES, 'UTF-8') . '">'
|
||||
. htmlspecialchars($strMobileUrl, ENT_QUOTES, 'UTF-8') . '</a>';
|
||||
$attachment_label = 'Set my password';
|
||||
}
|
||||
$subject = strtr(fxEveAccesPromoteurT('eve_acces_promoteur_mail_new_subject', $strLangue), $arrMailVars);
|
||||
$message = strtr(fxEveAccesPromoteurT('eve_acces_promoteur_mail_new_body', $strLangue), $arrMailVars);
|
||||
$attachment_label = fxEveAccesPromoteurT('eve_acces_promoteur_mail_new_cta', $strLangue);
|
||||
$attachment_url = $vDomaine . $strComptePath . '/reset?t=' . urlencode($strResetToken)
|
||||
. '&m=' . urlencode($arrCompte['com_courriel'])
|
||||
. '&id=' . intval($arrCompte['com_id']);
|
||||
} else {
|
||||
if ($strLangue === 'fr') {
|
||||
$subject = 'Nouvel accès — ' . $strEveNom;
|
||||
$message = 'Bonjour ' . $strPrenom . ',<br><br>'
|
||||
. 'Un accès vous a été accordé pour <strong>' . htmlspecialchars($strEveNom, ENT_QUOTES, 'UTF-8') . '</strong>'
|
||||
. ' (kit : ' . htmlspecialchars($strKit, ENT_QUOTES, 'UTF-8') . ').<br><br>'
|
||||
. 'Ouvrez le lien ci-dessous et connectez-vous avec le compte '
|
||||
. '<strong>' . htmlspecialchars($strLogin, ENT_QUOTES, 'UTF-8') . '</strong> '
|
||||
. '(si un autre compte est déjà ouvert, vous serez invité à vous déconnecter).';
|
||||
$attachment_label = 'Ouvrir l\'accès (mobile)';
|
||||
} else {
|
||||
$subject = 'New access — ' . $strEveNom;
|
||||
$message = 'Hello ' . $strPrenom . ',<br><br>'
|
||||
. 'You were granted access to <strong>' . htmlspecialchars($strEveNom, ENT_QUOTES, 'UTF-8') . '</strong>'
|
||||
. ' (kit: ' . htmlspecialchars($strKit, ENT_QUOTES, 'UTF-8') . ').<br><br>'
|
||||
. 'Open the link below and sign in as '
|
||||
. '<strong>' . htmlspecialchars($strLogin, ENT_QUOTES, 'UTF-8') . '</strong> '
|
||||
. '(if another account is already open, you will be asked to sign out).';
|
||||
$attachment_label = 'Open access (mobile)';
|
||||
}
|
||||
$subject = strtr(fxEveAccesPromoteurT('eve_acces_promoteur_mail_existing_subject', $strLangue), $arrMailVars);
|
||||
$message = strtr(fxEveAccesPromoteurT('eve_acces_promoteur_mail_existing_body', $strLangue), $arrMailVars);
|
||||
$attachment_label = fxEveAccesPromoteurT('eve_acces_promoteur_mail_existing_cta', $strLangue);
|
||||
$attachment_url = $strMobileUrl;
|
||||
}
|
||||
|
||||
@ -739,11 +743,7 @@ function fxEveAccesPromoteurRenderPage($intEveId, $strLangue = 'fr', $strFlash =
|
||||
echo '</div>';
|
||||
echo '</div>';
|
||||
echo '<p class="small text-muted mb-0">'
|
||||
. fxEveAccesPromoteurEsc(
|
||||
$strLangue === 'en'
|
||||
? 'Enter the email first: we check if an MS1 account already exists before asking for a name.'
|
||||
: 'Saisissez d\'abord le courriel : on vérifie s\'il existe déjà un compte MS1 avant de demander le nom.'
|
||||
)
|
||||
. fxEveAccesPromoteurEsc(fxEveAccesPromoteurT('eve_acces_promoteur_invite_courriel_help', $strLangue))
|
||||
. '</p>';
|
||||
echo '</form>';
|
||||
fxEveAccesPromoteurRenderInviteScript();
|
||||
@ -825,7 +825,7 @@ function fxEveAccesPromoteurRenderPage($intEveId, $strLangue = 'fr', $strFlash =
|
||||
echo '</button></form>';
|
||||
echo '<form method="post" action="' . fxEveAccesPromoteurEsc($strFormAction) . '" class="d-inline"';
|
||||
echo ' onsubmit="return confirm(\'' . fxEveAccesPromoteurEsc(
|
||||
$strLangue === 'en' ? 'Revoke this access?' : 'Retirer cet accès ?'
|
||||
fxEveAccesPromoteurT('eve_acces_promoteur_confirm_revoke', $strLangue)
|
||||
) . '\');">';
|
||||
echo '<input type="hidden" name="eve_acces_action" value="revoke">';
|
||||
echo '<input type="hidden" name="ea_id" value="' . intval($arrRow['ea_id']) . '">';
|
||||
|
||||
@ -71,6 +71,11 @@ function fxInscrGestionCanDo($intComId, $intEveId, $strActionPerm) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// MSIN-4401 — kit propriétaire / total (grants_all) = toutes les actions, sans cocher chaque droit.
|
||||
if (fxEveAccesComEventHasGrantsAllKit(intval($intComId), intval($intEveId))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (fxEveAccesHasPermission(intval($intComId), intval($intEveId), $strActionPerm)) {
|
||||
return true;
|
||||
}
|
||||
@ -400,6 +405,53 @@ function fxInscrGestionFallbackTexte($strClef, $strLangue) {
|
||||
'inscr_gestion_rech_statut' => $blnFr ? 'Statut de course' : 'Race status',
|
||||
'inscr_gestion_rech_statut_all' => $blnFr ? 'Tous les statuts' : 'All statuses',
|
||||
'inscr_gestion_rech_statut_n' => $blnFr ? '%d sélectionnés' : '%d selected',
|
||||
'inscr_gestion_mobile_title' => $blnFr ? 'Inscriptions mobile' : 'Mobile registrations',
|
||||
'inscr_gestion_login_user' => $blnFr ? 'Nom d\'utilisateur' : 'Username',
|
||||
'inscr_gestion_login_pass' => $blnFr ? 'Mot de passe' : 'Password',
|
||||
'inscr_gestion_login_btn' => $blnFr ? 'Connexion' : 'Sign in',
|
||||
'inscr_gestion_login_intro' => $blnFr
|
||||
? 'Connectez-vous pour accéder aux inscriptions mobile.'
|
||||
: 'Sign in to access mobile registrations.',
|
||||
'inscr_gestion_login_err_user' => $blnFr
|
||||
? 'Veuillez entrer votre nom d\'usager'
|
||||
: 'Please enter your username',
|
||||
'inscr_gestion_login_err_pass' => $blnFr
|
||||
? 'Veuillez entrer votre mot de passe'
|
||||
: 'Please enter your password',
|
||||
'inscr_gestion_choose_event' => $blnFr ? 'Choisir un événement' : 'Choose an event',
|
||||
'inscr_gestion_back_events' => $blnFr ? 'Événements' : 'Events',
|
||||
'tableau_promoteur_menueinscription_v2' => $blnFr ? 'Inscriptions V2' : 'Registrations V2',
|
||||
'mobile_no_acces_v2' => $blnFr
|
||||
? 'Aucun accès inscriptions mobile (v2) n\'est actif pour ce compte.'
|
||||
: 'No active mobile registration access (v2) for this account.',
|
||||
'mobile_invite_conflict_signed_as' => $blnFr
|
||||
? 'Vous êtes actuellement connecté en tant que %name%.'
|
||||
: 'You are currently signed in as %name%.',
|
||||
'mobile_invite_conflict_for' => $blnFr
|
||||
? 'Cette invitation concerne le compte %name%%mail_part%. Déconnectez-vous d\'abord, puis reconnectez-vous avec ce compte.'
|
||||
: 'This invitation is for %name%%mail_part%. Sign out first, then sign in with that account.',
|
||||
'mobile_invite_conflict_btn_logout' => $blnFr
|
||||
? 'Se déconnecter et continuer'
|
||||
: 'Sign out and continue',
|
||||
'mobile_invite_conflict_btn_stay' => $blnFr
|
||||
? 'Rester sur mon compte actuel'
|
||||
: 'Stay on my current account',
|
||||
'inscr_gestion_bib_scan_found_search' => $blnFr
|
||||
? 'Numéro %s détecté — recherche...'
|
||||
: 'Number %s detected — searching...',
|
||||
'inscr_gestion_bib_ocr_not_configured' => $blnFr
|
||||
? 'OCR non configuré (clé Vision absente sur le serveur).'
|
||||
: 'OCR not configured (Vision API key missing on server).',
|
||||
'inscr_gestion_bib_ocr_vision_prefix' => $blnFr ? 'Erreur Vision : ' : 'Vision error: ',
|
||||
'inscr_gestion_bib_ocr_image_invalid' => $blnFr ? 'Image invalide.' : 'Invalid image capture.',
|
||||
'inscr_gestion_bib_ocr_network' => $blnFr ? 'Erreur réseau ou capture.' : 'Network or capture error.',
|
||||
'inscr_gestion_err_load' => $blnFr ? 'Erreur de chargement.' : 'Loading error.',
|
||||
'inscr_gestion_err_network' => $blnFr ? 'Erreur réseau.' : 'Network error.',
|
||||
'inscr_gestion_err_refund' => $blnFr ? 'Erreur remboursement.' : 'Refund error.',
|
||||
'inscr_gestion_refund_ok' => $blnFr ? 'Remboursement effectué.' : 'Refund completed.',
|
||||
'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:',
|
||||
);
|
||||
}
|
||||
|
||||
@ -476,37 +528,33 @@ function fxInscrGestionLoginActionUrl($strLangue) {
|
||||
|
||||
function fxInscrGestionRenderLoginPage($strLangue) {
|
||||
$strActionUrl = fxInscrGestionLoginActionUrl($strLangue);
|
||||
$strLblUser = ($strLangue === 'fr') ? 'Nom d\'utilisateur' : 'Username';
|
||||
$strLblPass = ($strLangue === 'fr') ? 'Mot de passe' : 'Password';
|
||||
$strBtn = ($strLangue === 'fr') ? 'Connexion' : 'Sign in';
|
||||
$strIntro = ($strLangue === 'fr')
|
||||
? 'Connectez-vous pour accéder aux inscriptions mobile.'
|
||||
: 'Sign in to access mobile registrations.';
|
||||
|
||||
echo '<div class="inscr-gestion-page inscr-gestion-login-wrap">';
|
||||
echo '<div id="module-inscr-gestion" class="inscr-gestion-shell inscr-gestion-shell--login">';
|
||||
fxInscrGestionRenderPageHead(
|
||||
($strLangue === 'fr') ? 'Inscriptions mobile' : 'Mobile registrations'
|
||||
);
|
||||
echo '<p class="inscr-gestion-login-intro text-muted">' . fxInscrGestionEsc($strIntro) . '</p>';
|
||||
fxInscrGestionRenderPageHead(fxInscrGestionT('inscr_gestion_mobile_title'));
|
||||
echo '<p class="inscr-gestion-login-intro text-muted">'
|
||||
. fxInscrGestionEsc(fxInscrGestionT('inscr_gestion_login_intro')) . '</p>';
|
||||
echo '<form action="' . fxInscrGestionEsc($strActionUrl) . '" id="frm_inscr_gestion_login" method="post" class="inscr-gestion-login-form">';
|
||||
echo '<input type="hidden" name="form_action" value="' . fxInscrGestionEsc(urlencode(base64_encode('login'))) . '">';
|
||||
echo '<label class="inscr-gestion-label" for="txt_login_mobile">' . fxInscrGestionEsc($strLblUser) . '</label>';
|
||||
echo '<label class="inscr-gestion-label" for="txt_login_mobile">'
|
||||
. fxInscrGestionEsc(fxInscrGestionT('inscr_gestion_login_user')) . '</label>';
|
||||
echo '<input class="form-control form-control-sm rounded-0" type="text" id="txt_login_mobile" name="txt_login" required autofocus>';
|
||||
echo '<label class="inscr-gestion-label" for="txt_password_mobile">' . fxInscrGestionEsc($strLblPass) . '</label>';
|
||||
echo '<label class="inscr-gestion-label" for="txt_password_mobile">'
|
||||
. fxInscrGestionEsc(fxInscrGestionT('inscr_gestion_login_pass')) . '</label>';
|
||||
echo '<input class="form-control form-control-sm rounded-0" type="password" id="txt_password_mobile" name="txt_password" required>';
|
||||
echo '<button class="btn btn-primary btn-sm rounded-0 btn-block mt-3" type="submit" id="btn_login_mobile" name="btn_login">' . fxInscrGestionEsc($strBtn) . '</button>';
|
||||
echo '<button class="btn btn-primary btn-sm rounded-0 btn-block mt-3" type="submit" id="btn_login_mobile" name="btn_login">'
|
||||
. fxInscrGestionEsc(fxInscrGestionT('inscr_gestion_login_btn')) . '</button>';
|
||||
echo '</form></div></div>';
|
||||
}
|
||||
|
||||
/** Libellé menu promoteur V2 (même texte que l'ancien + suffixe V2). */
|
||||
/** Libellé menu promoteur V2 (Info). */
|
||||
function fxInscrGestionPromoteurMenuLabel() {
|
||||
return afficheTexte('tableau_promoteur_menueinscription', 0) . ' V2';
|
||||
return fxInscrGestionT('tableau_promoteur_menueinscription_v2');
|
||||
}
|
||||
|
||||
function fxInscrGestionListBackLabel($strLangue) {
|
||||
if (fxInscrGestionIsEntry()) {
|
||||
return ($strLangue === 'fr') ? 'Événements' : 'Events';
|
||||
return fxInscrGestionT('inscr_gestion_back_events');
|
||||
}
|
||||
|
||||
return fxInscrGestionT('promoteur_back');
|
||||
@ -1437,7 +1485,7 @@ function fxInscrGestionResolveQrScan($strRaw, $intEveId, $strLangue) {
|
||||
function fxInscrGestionRenderEventPicker($tabEveIds, $strLangue, $strBaseUrl) {
|
||||
global $objDatabase;
|
||||
|
||||
$strTitle = ($strLangue === 'fr') ? 'Choisir un événement' : 'Choose an event';
|
||||
$strTitle = fxInscrGestionT('inscr_gestion_choose_event');
|
||||
|
||||
echo '<div id="module-inscr-gestion" class="inscr-gestion-shell">';
|
||||
fxInscrGestionRenderPageHead($strTitle);
|
||||
@ -1629,23 +1677,24 @@ function fxInscrGestionVisionReadBibNumber($strImageBase64) {
|
||||
function fxInscrGestionRenderBibScanBlock($strBibInputId, $strLangue) {
|
||||
echo '<div class="inscr-gestion-bib-scan-panel" hidden';
|
||||
echo ' data-bib-input-id="' . fxInscrGestionEsc($strBibInputId) . '"';
|
||||
echo ' data-msg-scanning="' . fxInscrGestionEsc(fxInscrGestionFallbackTexte('inscr_gestion_bib_scan_scanning', $strLangue)) . '"';
|
||||
echo ' data-msg-loading="' . fxInscrGestionEsc(fxInscrGestionFallbackTexte('inscr_gestion_bib_scan_loading', $strLangue)) . '"';
|
||||
echo ' data-msg-ready="' . fxInscrGestionEsc(fxInscrGestionFallbackTexte('inscr_gestion_bib_scan_ready', $strLangue)) . '"';
|
||||
echo ' data-msg-found="' . fxInscrGestionEsc(fxInscrGestionFallbackTexte('inscr_gestion_bib_scan_found', $strLangue)) . '"';
|
||||
echo ' data-msg-invalid="' . fxInscrGestionEsc(fxInscrGestionFallbackTexte('inscr_gestion_bib_scan_invalid', $strLangue)) . '"';
|
||||
echo ' data-msg-camera="' . fxInscrGestionEsc(fxInscrGestionFallbackTexte('inscr_gestion_qr_camera_error', $strLangue)) . '">';
|
||||
echo ' data-msg-scanning="' . fxInscrGestionEsc(fxInscrGestionT('inscr_gestion_bib_scan_scanning')) . '"';
|
||||
echo ' data-msg-loading="' . fxInscrGestionEsc(fxInscrGestionT('inscr_gestion_bib_scan_loading')) . '"';
|
||||
echo ' data-msg-ready="' . fxInscrGestionEsc(fxInscrGestionT('inscr_gestion_bib_scan_ready')) . '"';
|
||||
echo ' data-msg-found="' . fxInscrGestionEsc(fxInscrGestionT('inscr_gestion_bib_scan_found')) . '"';
|
||||
echo ' data-msg-found-search="' . fxInscrGestionEsc(fxInscrGestionT('inscr_gestion_bib_scan_found_search')) . '"';
|
||||
echo ' data-msg-invalid="' . fxInscrGestionEsc(fxInscrGestionT('inscr_gestion_bib_scan_invalid')) . '"';
|
||||
echo ' data-msg-camera="' . fxInscrGestionEsc(fxInscrGestionT('inscr_gestion_qr_camera_error')) . '">';
|
||||
echo '<p class="inscr-gestion-bib-scan-hint text-muted small mb-1">'
|
||||
. fxInscrGestionEsc(fxInscrGestionFallbackTexte('inscr_gestion_bib_scan_hint', $strLangue)) . '</p>';
|
||||
. fxInscrGestionEsc(fxInscrGestionT('inscr_gestion_bib_scan_hint')) . '</p>';
|
||||
echo '<div class="inscr-gestion-bib-scan-status small mb-1" aria-live="polite"></div>';
|
||||
echo '<div class="inscr-gestion-bib-scan-capture" role="button" tabindex="0">';
|
||||
echo '<div class="inscr-gestion-bib-scan-video"></div>';
|
||||
// Zone-cible centrale (eclaircie) : aligne le repere visuel sur la region
|
||||
// reellement lue par l'OCR (captureCenterFrame : ~55% largeur x 30% hauteur).
|
||||
echo '<div class="inscr-gestion-bib-scan-target" aria-hidden="true"></div>';
|
||||
// Pastille courte (fallback integre) — evite un long texte info qui masque le viseur.
|
||||
// Pastille courte — texte Info (inscr_gestion_bib_scan_tap).
|
||||
echo '<span class="inscr-gestion-bib-scan-capture-label">'
|
||||
. fxInscrGestionEsc(fxInscrGestionFallbackTexte('inscr_gestion_bib_scan_tap', $strLangue)) . '</span>';
|
||||
. fxInscrGestionEsc(fxInscrGestionT('inscr_gestion_bib_scan_tap')) . '</span>';
|
||||
echo '</div>';
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
@ -463,9 +463,14 @@ function fxPromoteurHubStaticFallback($clef, $strLangParam = '')
|
||||
$strLangParam = !empty($strLangue) ? $strLangue : 'fr';
|
||||
}
|
||||
$lng = ($strLangParam === 'en') ? 'en' : 'fr';
|
||||
// MSIN-4401 — filet si Info absente (jamais la source de vérité).
|
||||
$tab = array(
|
||||
'promoteur_hub_section_gestion' => array('fr' => 'Gestion', 'en' => 'Management'),
|
||||
'promoteur_hub_link_dashboard' => array('fr' => 'Tableau de bord V2', 'en' => 'V2 dashboard'),
|
||||
'promoteur_hub_no_features' => array(
|
||||
'fr' => 'Aucune fonctionnalité disponible avec vos droits actuels.',
|
||||
'en' => 'No features available with your current permissions.',
|
||||
),
|
||||
'promoteur_hub_menu' => array('fr' => 'Tableau de bord V2', 'en' => 'V2 dashboard'),
|
||||
'tableau_promoteur_menurapports' => array('fr' => 'Rapports', 'en' => 'Reports'),
|
||||
'tableau_promoteur_menudossard' => array('fr' => 'Dossards', 'en' => 'Bibs'),
|
||||
@ -474,6 +479,48 @@ function fxPromoteurHubStaticFallback($clef, $strLangParam = '')
|
||||
'tableau_promoteur_menueinscription' => array('fr' => 'Inscriptions', 'en' => 'Registrations'),
|
||||
'tableau_promoteur_rabais' => array('fr' => 'Rabais', 'en' => 'Discounts'),
|
||||
'tableau_promoteur_envoie_email_questions' => array('fr' => 'Envoi courriel questions', 'en' => 'Send question emails'),
|
||||
'promoteur_hub_load_menu' => array('fr' => 'Chargement du menu…', 'en' => 'Loading menu…'),
|
||||
'promoteur_hub_load_dashboard' => array('fr' => 'Chargement du tableau de bord…', 'en' => 'Loading dashboard…'),
|
||||
'promoteur_hub_epreuves_title' => array('fr' => 'Épreuves en vente', 'en' => 'Events for sale'),
|
||||
'promoteur_hub_produits_title' => array('fr' => 'Produits en vente', 'en' => 'Products for sale'),
|
||||
'promoteur_hub_bibs_sold' => array('fr' => 'dossards vendus', 'en' => 'bibs sold'),
|
||||
'promoteur_hub_restant' => array('fr' => 'restant', 'en' => 'left'),
|
||||
'promoteur_hub_unlimited' => array('fr' => 'illimité', 'en' => 'unlimited'),
|
||||
'promoteur_hub_prix_courant' => array('fr' => 'Prix courant', 'en' => 'Current price'),
|
||||
'promoteur_hub_prochain_prix' => array('fr' => 'Prochain prix', 'en' => 'Next price'),
|
||||
'promoteur_hub_des' => array('fr' => 'dès', 'en' => 'on'),
|
||||
'promoteur_hub_dossards_remis' => array('fr' => 'Dossards remis', 'en' => 'Bibs handed out'),
|
||||
'promoteur_hub_liste_active' => array('fr' => 'liste active', 'en' => 'list active'),
|
||||
'promoteur_hub_waiting_n' => array('fr' => 'en attente', 'en' => 'waiting'),
|
||||
'promoteur_hub_waiting_list' => array('fr' => 'Liste d\'attente', 'en' => 'Waiting list'),
|
||||
'promoteur_hub_disponible' => array('fr' => 'disponible(s)', 'en' => 'available'),
|
||||
'promoteur_hub_vendus_title' => array('fr' => 'Vendus', 'en' => 'Sold'),
|
||||
'promoteur_hub_vendus_lbl' => array('fr' => 'vendu(s)', 'en' => 'sold'),
|
||||
'promoteur_hub_paniers_title' => array('fr' => 'Dans des paniers incomplets', 'en' => 'In incomplete carts'),
|
||||
'promoteur_hub_paniers_lbl' => array('fr' => 'panier(s)', 'en' => 'cart(s)'),
|
||||
'promoteur_hub_menu_features' => array('fr' => 'Menu des fonctionnalités', 'en' => 'Features menu'),
|
||||
'promoteur_hub_flash_inscrits' => array('fr' => 'inscrits', 'en' => 'registered'),
|
||||
'promoteur_hub_flash_rempli' => array('fr' => 'rempli', 'en' => 'filled'),
|
||||
'promoteur_hub_flash_places' => array('fr' => 'places restantes', 'en' => 'spots left'),
|
||||
'promoteur_hub_flash_revenus' => array('fr' => 'revenus est.', 'en' => 'est. revenue'),
|
||||
'promoteur_hub_badge_completes' => array('fr' => 'complète(s)', 'en' => 'sold out'),
|
||||
'promoteur_hub_badge_presque' => array('fr' => 'presque pleine(s)', 'en' => 'almost full'),
|
||||
'promoteur_hub_badge_attente' => array('fr' => 'en attente', 'en' => 'waiting'),
|
||||
'promoteur_hub_badge_limite' => array('fr' => 'limite', 'en' => 'deadline'),
|
||||
'promoteur_hub_ajax_session' => array('fr' => 'Session expirée', 'en' => 'Session expired'),
|
||||
'promoteur_hub_ajax_invalid' => array('fr' => 'Requête invalide', 'en' => 'Invalid request'),
|
||||
'promoteur_hub_ajax_denied' => array('fr' => 'Accès refusé', 'en' => 'Access denied'),
|
||||
'promoteur_hub_ajax_not_found' => array('fr' => 'Événement introuvable', 'en' => 'Event not found'),
|
||||
'promoteur_hub_ajax_error' => array('fr' => 'Erreur', 'en' => 'Error'),
|
||||
'promoteur_hub_rapport_chrono' => array('fr' => 'chrono + questions', 'en' => 'chrono + questions'),
|
||||
'promoteur_hub_rapport_finances' => array('fr' => 'Transactions-Finances', 'en' => 'Transactions-Finances'),
|
||||
'promoteur_hub_rapport_finances_all' => array('fr' => 'Transactions-Finances-Tout', 'en' => 'Transactions-Finances-All'),
|
||||
'promoteur_hub_rapport_finances_adh' => array('fr' => 'Transactions-Finances-Adhésions Seul', 'en' => 'Transactions-Finances-Memberships only'),
|
||||
'promoteur_hub_rapport_finances_eve' => array('fr' => 'Transactions-Finances-Événements Seul', 'en' => 'Transactions-Finances-Events only'),
|
||||
'promoteur_hub_rapport_adhesions' => array('fr' => 'adhésions actives', 'en' => 'active memberships'),
|
||||
'promoteur_hub_rapport_adhesions_annuelles' => array('fr' => 'liste d\'adhésions annuelles', 'en' => 'annual memberships list'),
|
||||
'promoteur_hub_rapport_finances_capitaines' => array('fr' => 'Transactions-Finances (capitaines seulement)', 'en' => 'Transactions-Finances (captains only)'),
|
||||
'promoteur_hub_rapport_paiements' => array('fr' => 'Paiements', 'en' => 'Payments'),
|
||||
);
|
||||
|
||||
return $tab[$clef][$lng] ?? '';
|
||||
@ -555,38 +602,74 @@ function fxPromoteurHubGetEventLinks($arrItem, $strLangue)
|
||||
|
||||
// ---- Rapports (niveau 1 V2 : chrono / finances / paiements) ----
|
||||
if ($intTeId != 9 && $fnCan(array('reports.chrono'))) {
|
||||
$arrRapports[] = array('label' => 'chrono + questions', 'url' => $strRapport . 'chrono&e=' . $strE . '&lng=' . $strLangue, 'target' => '_blank');
|
||||
$arrRapports[] = array(
|
||||
'label' => fxPromoteurHubTexte('promoteur_hub_rapport_chrono', 0),
|
||||
'url' => $strRapport . 'chrono&e=' . $strE . '&lng=' . $strLangue,
|
||||
'target' => '_blank',
|
||||
);
|
||||
}
|
||||
|
||||
if ($fnCan(array('reports.finances', 'reports.finances_membership', 'reports.finances_events'))) {
|
||||
if ($intTeId == 13) {
|
||||
$arrRapports[] = array('label' => 'Transactions-Finances-Tout', 'url' => $strRapport . 'finances-membership&e=' . $strE . '&lng=' . $strLangue . '&a-ach_maj_from=' . urlencode($strDateTq) . '&btn_search=', 'target' => '_blank');
|
||||
$arrRapports[] = array(
|
||||
'label' => fxPromoteurHubTexte('promoteur_hub_rapport_finances_all', 0),
|
||||
'url' => $strRapport . 'finances-membership&e=' . $strE . '&lng=' . $strLangue . '&a-ach_maj_from=' . urlencode($strDateTq) . '&btn_search=',
|
||||
'target' => '_blank',
|
||||
);
|
||||
} else {
|
||||
$arrRapports[] = array('label' => 'Transactions-Finances', 'url' => $strRapport . 'finances&e=' . $strE . '&lng=' . $strLangue, 'target' => '_blank');
|
||||
$arrRapports[] = array(
|
||||
'label' => fxPromoteurHubTexte('promoteur_hub_rapport_finances', 0),
|
||||
'url' => $strRapport . 'finances&e=' . $strE . '&lng=' . $strLangue,
|
||||
'target' => '_blank',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ($intTeId == 13 && $fnCan(array('reports.finances_membership', 'reports.finances_events', 'reports.adhesions', 'reports.adhesions_sales'))) {
|
||||
if ($fnCan(array('reports.finances_membership'))) {
|
||||
$arrRapports[] = array('label' => 'Transactions-Finances-Adhésions Seul', 'url' => $strRapport . 'finances-membership-tq&e=' . $strE . '&lng=' . $strLangue . '&a-ach_maj_from=' . urlencode($strDateTq) . '&btn_search=', 'target' => '_blank');
|
||||
$arrRapports[] = array(
|
||||
'label' => fxPromoteurHubTexte('promoteur_hub_rapport_finances_adh', 0),
|
||||
'url' => $strRapport . 'finances-membership-tq&e=' . $strE . '&lng=' . $strLangue . '&a-ach_maj_from=' . urlencode($strDateTq) . '&btn_search=',
|
||||
'target' => '_blank',
|
||||
);
|
||||
}
|
||||
if ($fnCan(array('reports.finances_events'))) {
|
||||
$arrRapports[] = array('label' => 'Transactions-Finances-Événements Seul', 'url' => $strRapport . 'finances-membership-autre&e=' . $strE . '&lng=' . $strLangue . '&a-ach_maj_from=' . urlencode($strDateTq) . '&btn_search=', 'target' => '_blank');
|
||||
$arrRapports[] = array(
|
||||
'label' => fxPromoteurHubTexte('promoteur_hub_rapport_finances_eve', 0),
|
||||
'url' => $strRapport . 'finances-membership-autre&e=' . $strE . '&lng=' . $strLangue . '&a-ach_maj_from=' . urlencode($strDateTq) . '&btn_search=',
|
||||
'target' => '_blank',
|
||||
);
|
||||
}
|
||||
if ($fnCan(array('reports.adhesions'))) {
|
||||
$arrRapports[] = array('label' => 'adhésions actives', 'url' => $strRapport . 'adhesions&e=' . $strE . '&lng=' . $strLangue, 'target' => '_blank');
|
||||
$arrRapports[] = array(
|
||||
'label' => fxPromoteurHubTexte('promoteur_hub_rapport_adhesions', 0),
|
||||
'url' => $strRapport . 'adhesions&e=' . $strE . '&lng=' . $strLangue,
|
||||
'target' => '_blank',
|
||||
);
|
||||
}
|
||||
if ($fnCan(array('reports.adhesions_sales'))) {
|
||||
$arrRapports[] = array('label' => "liste d'adhésions annuelles", 'url' => $strRapport . 'adhesions-ventes&e=' . $strE . '&lng=' . $strLangue, 'target' => '_blank');
|
||||
$arrRapports[] = array(
|
||||
'label' => fxPromoteurHubTexte('promoteur_hub_rapport_adhesions_annuelles', 0),
|
||||
'url' => $strRapport . 'adhesions-ventes&e=' . $strE . '&lng=' . $strLangue,
|
||||
'target' => '_blank',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (intval($arrItem['rapport_capitaines'] ?? 0) == 1 && $fnCan(array('reports.finances_captains'))) {
|
||||
$arrRapports[] = array('label' => 'Transactions-Finances (capitaines seulement)', 'url' => $strRapport . 'finances-pnq&e=' . $strE . '&lng=' . $strLangue, 'target' => '_blank');
|
||||
$arrRapports[] = array(
|
||||
'label' => fxPromoteurHubTexte('promoteur_hub_rapport_finances_capitaines', 0),
|
||||
'url' => $strRapport . 'finances-pnq&e=' . $strE . '&lng=' . $strLangue,
|
||||
'target' => '_blank',
|
||||
);
|
||||
}
|
||||
|
||||
if ($fnCan(array('reports.payments'))) {
|
||||
$arrRapports[] = array('label' => ($strLangue === 'fr' ? 'Paiements' : 'Payments'), 'url' => $strRapport . 'remboursements&e=' . $strE . '&lng=' . $strLangue, 'target' => '_blank');
|
||||
$arrRapports[] = array(
|
||||
'label' => fxPromoteurHubTexte('promoteur_hub_rapport_paiements', 0),
|
||||
'url' => $strRapport . 'remboursements&e=' . $strE . '&lng=' . $strLangue,
|
||||
'target' => '_blank',
|
||||
);
|
||||
}
|
||||
|
||||
if (($blnLegacyMenus || $blnGrantsAll || $blnSuper || $fnCan(array('reports.custom'))) && function_exists('fxGetMenussuperadm')) {
|
||||
@ -694,11 +777,8 @@ function fxPromoteurHubRenderEventPanelContent($arrItem, $strLangue)
|
||||
|
||||
// MSIN-4401 — pas d'en-têtes vides si aucun droit dans la section
|
||||
if (!$blnGestion && !$blnRapports) {
|
||||
$blnFr = ($strLangue !== 'en');
|
||||
return '<p class="text-muted small mb-0">'
|
||||
. fxPromoteurHubEsc($blnFr
|
||||
? 'Aucune fonctionnalité disponible avec vos droits actuels.'
|
||||
: 'No features available with your current permissions.')
|
||||
. fxPromoteurHubEsc(fxPromoteurHubTexte('promoteur_hub_no_features', 0))
|
||||
. '</p>';
|
||||
}
|
||||
|
||||
@ -732,8 +812,7 @@ function fxPromoteurHubRenderEventPanelShell($arrItem, $strLangue)
|
||||
{
|
||||
$strPanelId = 'hub-fn-' . intval($arrItem['eve_id']);
|
||||
$intEveId = intval($arrItem['eve_id']);
|
||||
$blnFr = ($strLangue !== 'en');
|
||||
$strLoadMsg = $blnFr ? 'Chargement du menu…' : 'Loading menu…';
|
||||
$strLoadMsg = fxPromoteurHubTexte('promoteur_hub_load_menu', 0);
|
||||
|
||||
global $vDomaine;
|
||||
$strRunnerSrc = $vDomaine . '/images/ms1-runner-loader.gif?v=' . _VERSION_CODE;
|
||||
@ -1074,13 +1153,8 @@ function fxPromoteurHubRenderFlash($arrStats, $strLangue = 'fr')
|
||||
return '';
|
||||
}
|
||||
|
||||
$blnFr = ($strLangue !== 'en');
|
||||
$arrFlash = $arrStats['flash'];
|
||||
|
||||
$lbl = function ($fr, $en) use ($blnFr) {
|
||||
return $blnFr ? $fr : $en;
|
||||
};
|
||||
|
||||
$html = '';
|
||||
|
||||
// ---- Bande flash ----
|
||||
@ -1088,25 +1162,25 @@ function fxPromoteurHubRenderFlash($arrStats, $strLangue = 'fr')
|
||||
|
||||
$html .= '<div class="phub-flash-item phub-flash-main">';
|
||||
$html .= '<span class="phub-flash-num">' . intval($arrFlash['total_vendus']) . '</span>';
|
||||
$html .= '<span class="phub-flash-lbl">' . fxPromoteurHubEsc($lbl('inscrits', 'registered')) . '</span>';
|
||||
$html .= '<span class="phub-flash-lbl">' . fxPromoteurHubEsc(fxPromoteurHubTexte('promoteur_hub_flash_inscrits', 0)) . '</span>';
|
||||
$html .= '</div>';
|
||||
|
||||
if (intval($arrFlash['total_max']) > 0) {
|
||||
$html .= '<div class="phub-flash-item">';
|
||||
$html .= '<span class="phub-flash-num">' . intval($arrFlash['pct_global']) . '%</span>';
|
||||
$html .= '<span class="phub-flash-lbl">' . fxPromoteurHubEsc($lbl('rempli', 'filled')) . '</span>';
|
||||
$html .= '<span class="phub-flash-lbl">' . fxPromoteurHubEsc(fxPromoteurHubTexte('promoteur_hub_flash_rempli', 0)) . '</span>';
|
||||
$html .= '</div>';
|
||||
|
||||
$html .= '<div class="phub-flash-item">';
|
||||
$html .= '<span class="phub-flash-num">' . intval($arrFlash['total_restant']) . '</span>';
|
||||
$html .= '<span class="phub-flash-lbl">' . fxPromoteurHubEsc($lbl('places restantes', 'spots left')) . '</span>';
|
||||
$html .= '<span class="phub-flash-lbl">' . fxPromoteurHubEsc(fxPromoteurHubTexte('promoteur_hub_flash_places', 0)) . '</span>';
|
||||
$html .= '</div>';
|
||||
}
|
||||
|
||||
if (floatval($arrFlash['revenus']) > 0) {
|
||||
$html .= '<div class="phub-flash-item">';
|
||||
$html .= '<span class="phub-flash-num">' . fxPromoteurHubEsc(fxShowPrix($arrFlash['revenus'], $strLangue)) . '</span>';
|
||||
$html .= '<span class="phub-flash-lbl">' . fxPromoteurHubEsc($lbl('revenus est.', 'est. revenue')) . '</span>';
|
||||
$html .= '<span class="phub-flash-lbl">' . fxPromoteurHubEsc(fxPromoteurHubTexte('promoteur_hub_flash_revenus', 0)) . '</span>';
|
||||
$html .= '</div>';
|
||||
}
|
||||
|
||||
@ -1116,19 +1190,19 @@ function fxPromoteurHubRenderFlash($arrStats, $strLangue = 'fr')
|
||||
$arrBadges = array();
|
||||
if (intval($arrFlash['nb_completes']) > 0) {
|
||||
$arrBadges[] = array('cls' => 'phub-badge-danger', 'icon' => 'fa-ban',
|
||||
'txt' => intval($arrFlash['nb_completes']) . ' ' . $lbl('complète(s)', 'sold out'));
|
||||
'txt' => intval($arrFlash['nb_completes']) . ' ' . fxPromoteurHubTexte('promoteur_hub_badge_completes', 0));
|
||||
}
|
||||
if (intval($arrFlash['nb_presque']) > 0) {
|
||||
$arrBadges[] = array('cls' => 'phub-badge-warn', 'icon' => 'fa-exclamation-triangle',
|
||||
'txt' => intval($arrFlash['nb_presque']) . ' ' . $lbl('presque pleine(s)', 'almost full'));
|
||||
'txt' => intval($arrFlash['nb_presque']) . ' ' . fxPromoteurHubTexte('promoteur_hub_badge_presque', 0));
|
||||
}
|
||||
if (intval($arrFlash['total_attente']) > 0) {
|
||||
$arrBadges[] = array('cls' => 'phub-badge-info', 'icon' => 'fa-hourglass-half',
|
||||
'txt' => intval($arrFlash['total_attente']) . ' ' . $lbl('en attente', 'waiting'));
|
||||
'txt' => intval($arrFlash['total_attente']) . ' ' . fxPromoteurHubTexte('promoteur_hub_badge_attente', 0));
|
||||
}
|
||||
if ($arrFlash['prochaine_date_limite'] !== '') {
|
||||
$arrBadges[] = array('cls' => 'phub-badge-soft', 'icon' => 'fa-clock-o',
|
||||
'txt' => $lbl('limite', 'deadline') . ' ' . fxShowDate($arrFlash['prochaine_date_limite'], $strLangue, 1));
|
||||
'txt' => fxPromoteurHubTexte('promoteur_hub_badge_limite', 0) . ' ' . fxShowDate($arrFlash['prochaine_date_limite'], $strLangue, 1));
|
||||
}
|
||||
if (!empty($arrBadges)) {
|
||||
$html .= '<div class="promoteur-hub-badges">';
|
||||
@ -1151,12 +1225,10 @@ function fxPromoteurHubRenderEpreuvesGrid($arrStats, $strLangue = 'fr')
|
||||
return '';
|
||||
}
|
||||
|
||||
$blnFr = ($strLangue !== 'en');
|
||||
|
||||
// ---- Titre de section ----
|
||||
$html = '<h6 class="promoteur-hub-produits-title text-uppercase text-muted">'
|
||||
. '<i class="fa fa-flag-checkered mr-2" aria-hidden="true"></i>'
|
||||
. fxPromoteurHubEsc($blnFr ? 'Épreuves en vente' : 'Events for sale') . '</h6>';
|
||||
. fxPromoteurHubEsc(fxPromoteurHubTexte('promoteur_hub_epreuves_title', 0)) . '</h6>';
|
||||
|
||||
// ---- Tuiles par epreuve ----
|
||||
$html .= '<div class="promoteur-hub-epreuves-grid">';
|
||||
@ -1182,45 +1254,45 @@ function fxPromoteurHubRenderEpreuvesGrid($arrStats, $strLangue = 'fr')
|
||||
if (!$arrEpr['illimitee']) {
|
||||
$html .= '<span class="phub-epr-max">/ ' . intval($arrEpr['max']) . '</span>';
|
||||
}
|
||||
$html .= '<span class="phub-epr-biglbl">' . fxPromoteurHubEsc($blnFr ? 'dossards vendus' : 'bibs sold') . '</span>';
|
||||
$html .= '<span class="phub-epr-biglbl">' . fxPromoteurHubEsc(fxPromoteurHubTexte('promoteur_hub_bibs_sold', 0)) . '</span>';
|
||||
$html .= '</div>';
|
||||
|
||||
// Barre de progression
|
||||
if (!$arrEpr['illimitee'] && intval($arrEpr['max']) > 0) {
|
||||
$html .= '<div class="phub-epr-bar"><span style="width:' . intval($arrEpr['pct']) . '%"></span></div>';
|
||||
$html .= '<div class="phub-epr-barlbl">' . intval($arrEpr['pct']) . '% · '
|
||||
. intval($arrEpr['restant']) . ' ' . fxPromoteurHubEsc($blnFr ? 'restant' : 'left') . '</div>';
|
||||
. intval($arrEpr['restant']) . ' ' . fxPromoteurHubEsc(fxPromoteurHubTexte('promoteur_hub_restant', 0)) . '</div>';
|
||||
} else {
|
||||
$html .= '<div class="phub-epr-barlbl phub-epr-illimite"><span class="phub-infini mr-1" aria-hidden="true">∞</span>'
|
||||
. fxPromoteurHubEsc($blnFr ? 'illimité' : 'unlimited') . '</div>';
|
||||
. fxPromoteurHubEsc(fxPromoteurHubTexte('promoteur_hub_unlimited', 0)) . '</div>';
|
||||
}
|
||||
|
||||
// Pastilles secondaires
|
||||
$html .= '<div class="phub-epr-chips">';
|
||||
|
||||
if ($arrEpr['prix_courant'] !== null) {
|
||||
$html .= '<span class="phub-chip phub-chip-prix" title="' . fxPromoteurHubEsc($blnFr ? 'Prix courant' : 'Current price') . '">'
|
||||
$html .= '<span class="phub-chip phub-chip-prix" title="' . fxPromoteurHubEsc(fxPromoteurHubTexte('promoteur_hub_prix_courant', 0)) . '">'
|
||||
. '<i class="fa fa-tag mr-1" aria-hidden="true"></i>' . fxPromoteurHubEsc(fxShowPrix($arrEpr['prix_courant'], $strLangue)) . '</span>';
|
||||
|
||||
if ($arrEpr['prix_prochain'] !== null && $arrEpr['prix_date_fin'] !== '' && $arrEpr['prix_date_fin'] >= date('Y-m-d')) {
|
||||
$html .= '<span class="phub-chip phub-chip-next" title="' . fxPromoteurHubEsc($blnFr ? 'Prochain prix' : 'Next price') . '">'
|
||||
$html .= '<span class="phub-chip phub-chip-next" title="' . fxPromoteurHubEsc(fxPromoteurHubTexte('promoteur_hub_prochain_prix', 0)) . '">'
|
||||
. '<i class="fa fa-arrow-up mr-1" aria-hidden="true"></i>'
|
||||
. fxPromoteurHubEsc(fxShowPrix($arrEpr['prix_prochain'], $strLangue))
|
||||
. ' ' . fxPromoteurHubEsc($blnFr ? 'dès' : 'on') . ' '
|
||||
. ' ' . fxPromoteurHubEsc(fxPromoteurHubTexte('promoteur_hub_des', 0)) . ' '
|
||||
. fxShowDate($arrEpr['prix_date_fin'], $strLangue, 1) . '</span>';
|
||||
}
|
||||
}
|
||||
|
||||
if (intval($arrEpr['checkin']) > 0) {
|
||||
$html .= '<span class="phub-chip phub-chip-checkin" title="' . fxPromoteurHubEsc($blnFr ? 'Dossards remis' : 'Bibs handed out') . '">'
|
||||
$html .= '<span class="phub-chip phub-chip-checkin" title="' . fxPromoteurHubEsc(fxPromoteurHubTexte('promoteur_hub_dossards_remis', 0)) . '">'
|
||||
. '<i class="fa fa-check mr-1" aria-hidden="true"></i>' . intval($arrEpr['checkin']) . '</span>';
|
||||
}
|
||||
|
||||
if (intval($arrEpr['attente_nb']) > 0 || $arrEpr['attente_active']) {
|
||||
$strAtt = $arrEpr['attente_active'] && intval($arrEpr['attente_nb']) === 0
|
||||
? ($blnFr ? 'liste active' : 'list active')
|
||||
: intval($arrEpr['attente_nb']) . ' ' . ($blnFr ? 'en attente' : 'waiting');
|
||||
$html .= '<span class="phub-chip phub-chip-attente" title="' . fxPromoteurHubEsc($blnFr ? 'Liste d\'attente' : 'Waiting list') . '">'
|
||||
? fxPromoteurHubTexte('promoteur_hub_liste_active', 0)
|
||||
: intval($arrEpr['attente_nb']) . ' ' . fxPromoteurHubTexte('promoteur_hub_waiting_n', 0);
|
||||
$html .= '<span class="phub-chip phub-chip-attente" title="' . fxPromoteurHubEsc(fxPromoteurHubTexte('promoteur_hub_waiting_list', 0)) . '">'
|
||||
. '<i class="fa fa-hourglass-half mr-1" aria-hidden="true"></i>' . fxPromoteurHubEsc($strAtt) . '</span>';
|
||||
}
|
||||
|
||||
@ -1335,12 +1407,10 @@ function fxPromoteurHubRenderProduits($arrProduits, $strLangue = 'fr')
|
||||
return '';
|
||||
}
|
||||
|
||||
$blnFr = ($strLangue !== 'en');
|
||||
|
||||
$html = '<div class="promoteur-hub-produits">';
|
||||
$html .= '<h6 class="promoteur-hub-produits-title text-uppercase text-muted">'
|
||||
. '<i class="fa fa-shopping-bag mr-2" aria-hidden="true"></i>'
|
||||
. fxPromoteurHubEsc($blnFr ? 'Produits en vente' : 'Products for sale') . '</h6>';
|
||||
. fxPromoteurHubEsc(fxPromoteurHubTexte('promoteur_hub_produits_title', 0)) . '</h6>';
|
||||
$html .= '<div class="promoteur-hub-produits-grid">';
|
||||
|
||||
foreach ($arrProduits as $arrProd) {
|
||||
@ -1359,17 +1429,17 @@ function fxPromoteurHubRenderProduits($arrProduits, $strLangue = 'fr')
|
||||
$html .= '<span class="phub-prod-num">' . intval($arrProd['restant']) . '</span>';
|
||||
$html .= '<span class="phub-prod-tot">/ ' . intval($arrProd['total']) . '</span>';
|
||||
}
|
||||
$html .= '<span class="phub-prod-lbl">' . fxPromoteurHubEsc($blnFr ? 'disponible(s)' : 'available') . '</span>';
|
||||
$html .= '<span class="phub-prod-lbl">' . fxPromoteurHubEsc(fxPromoteurHubTexte('promoteur_hub_disponible', 0)) . '</span>';
|
||||
$html .= '</div>';
|
||||
|
||||
$html .= '<div class="phub-epr-chips">';
|
||||
$html .= '<span class="phub-chip phub-chip-checkin" title="' . fxPromoteurHubEsc($blnFr ? 'Vendus' : 'Sold') . '">'
|
||||
$html .= '<span class="phub-chip phub-chip-checkin" title="' . fxPromoteurHubEsc(fxPromoteurHubTexte('promoteur_hub_vendus_title', 0)) . '">'
|
||||
. '<i class="fa fa-check mr-1" aria-hidden="true"></i>' . intval($arrProd['vendus']) . ' '
|
||||
. fxPromoteurHubEsc($blnFr ? 'vendu(s)' : 'sold') . '</span>';
|
||||
. fxPromoteurHubEsc(fxPromoteurHubTexte('promoteur_hub_vendus_lbl', 0)) . '</span>';
|
||||
if (intval($arrProd['panier']) > 0) {
|
||||
$html .= '<span class="phub-chip phub-chip-attente" title="' . fxPromoteurHubEsc($blnFr ? 'Dans des paniers incomplets' : 'In incomplete carts') . '">'
|
||||
$html .= '<span class="phub-chip phub-chip-attente" title="' . fxPromoteurHubEsc(fxPromoteurHubTexte('promoteur_hub_paniers_title', 0)) . '">'
|
||||
. '<i class="fa fa-shopping-cart mr-1" aria-hidden="true"></i>' . intval($arrProd['panier']) . ' '
|
||||
. fxPromoteurHubEsc($blnFr ? 'panier(s)' : 'cart(s)') . '</span>';
|
||||
. fxPromoteurHubEsc(fxPromoteurHubTexte('promoteur_hub_paniers_lbl', 0)) . '</span>';
|
||||
}
|
||||
$html .= '</div>'; // .phub-epr-chips
|
||||
|
||||
@ -1445,7 +1515,6 @@ function fxPromoteurHubRenderEventCard($arrItem, $strLangue, $blnArchived = fals
|
||||
{
|
||||
$strCardClass = 'card promoteur-hub-card mb-3' . ($blnArchived ? ' promoteur-hub-card-archived' : '');
|
||||
|
||||
$blnFr = ($strLangue !== 'en');
|
||||
$intEveId = intval($arrItem['eve_id']);
|
||||
$intComId = intval($arrItem['com_id'] ?? ($_SESSION['com_id'] ?? 0));
|
||||
|
||||
@ -1506,7 +1575,7 @@ function fxPromoteurHubRenderEventCard($arrItem, $strLangue, $blnArchived = fals
|
||||
|
||||
if ($blnFonctions) {
|
||||
$html .= '<button type="button" class="btn btn-outline-primary rounded-pill mb-2 promoteur-hub-toggle collapsed" data-toggle="collapse" data-target="#' . fxPromoteurHubEsc($strFnId) . '" aria-expanded="false" aria-controls="' . fxPromoteurHubEsc($strFnId) . '">';
|
||||
$html .= '<i class="fa fa-bars mr-2" aria-hidden="true"></i>' . fxPromoteurHubEsc($blnFr ? 'Menu des fonctionnalités' : 'Features menu');
|
||||
$html .= '<i class="fa fa-bars mr-2" aria-hidden="true"></i>' . fxPromoteurHubEsc(fxPromoteurHubTexte('promoteur_hub_menu_features', 0));
|
||||
$html .= '<i class="fa fa-chevron-down ml-2 promoteur-hub-toggle-caret" aria-hidden="true"></i>';
|
||||
$html .= '</button>';
|
||||
}
|
||||
@ -1517,7 +1586,7 @@ function fxPromoteurHubRenderEventCard($arrItem, $strLangue, $blnArchived = fals
|
||||
// ---- Collapse : stats chargées au clic (ajax_promoteur_hub.php) ----
|
||||
if ($blnHasStats) {
|
||||
global $vDomaine;
|
||||
$strLoadMsg = $blnFr ? 'Chargement du tableau de bord…' : 'Loading dashboard…';
|
||||
$strLoadMsg = fxPromoteurHubTexte('promoteur_hub_load_dashboard', 0);
|
||||
$strRunnerSrc = $vDomaine . '/images/ms1-runner-loader.gif?v=' . _VERSION_CODE;
|
||||
$html .= '<div class="collapse promoteur-hub-epreuves-collapse mt-2" id="' . fxPromoteurHubEsc($strEprId) . '"'
|
||||
. ' data-hub-eve-id="' . $intEveId . '" data-hub-lang="' . fxPromoteurHubEsc($strLangue) . '">';
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
* Constantes *
|
||||
*
|
||||
**************/
|
||||
define('_VERSION_CODE', '4.72.804');
|
||||
define('_VERSION_CODE', '4.72.806');
|
||||
define('_DATE_CODE', '2026-07-13');
|
||||
//MSIN-4290
|
||||
define('QR_SECRET_KEY', 'ms1_qr_2026_cle_secrete_longue_et_fixe');
|
||||
|
||||
@ -23,13 +23,23 @@ if (!function_exists('fxV2RegisterScript')) {
|
||||
|
||||
$strLangue = ($strLangue === 'en') ? 'en' : 'fr';
|
||||
$strWait = afficheTexte('preloader_wait', 0, 0, 1);
|
||||
if (trim((string)$strWait) === '' || $strWait === 'preloader_wait') {
|
||||
$strWait = ($strLangue === 'en') ? 'Loading…' : 'Chargement…';
|
||||
if (trim((string)$strWait) === '' || $strWait === 'preloader_wait' || $strWait === '*preloader_wait*') {
|
||||
$strWait = function_exists('fxPromoteurHubTexte')
|
||||
? fxPromoteurHubTexte('promoteur_hub_load_dashboard', 0)
|
||||
: '';
|
||||
}
|
||||
|
||||
// MSIN-4401 — libellés Info injectés (pas de FR/EN en dur dans promoteur-hub.js).
|
||||
$strAjaxError = function_exists('fxPromoteurHubTexte')
|
||||
? fxPromoteurHubTexte('promoteur_hub_ajax_error', 0)
|
||||
: afficheTexte('promoteur_hub_ajax_error', 0, 0, 1);
|
||||
|
||||
return [
|
||||
'ajaxUrl' => $vDomaine . '/ajax_promoteur_hub.php',
|
||||
'preloaderWait' => $strWait,
|
||||
'i18n' => [
|
||||
'ajaxError' => $strAjaxError,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
@ -47,17 +57,29 @@ if (!function_exists('fxV2RegisterScript')) {
|
||||
? (bool)fxInscrGestionBibOcrCloudEnabled()
|
||||
: false,
|
||||
'preloaderWait' => afficheTexte('preloader_wait', 0, 0, 1),
|
||||
'refundCancelHint' => ($strLangue === 'en')
|
||||
? 'Your transaction has been refunded. If you also want to cancel it in the registration system:'
|
||||
: "Votre transaction a été remboursée. Si vous voulez aussi l'annuler dans le système d'inscription :",
|
||||
'refundCancelHint' => function_exists('fxInscrGestionT')
|
||||
? fxInscrGestionT('inscr_gestion_refund_cancel_hint')
|
||||
: '',
|
||||
'loginMessages' => [
|
||||
'txt_login' => ($strLangue === 'fr')
|
||||
? "Veuillez entrer votre nom d'usager"
|
||||
: 'Please enter your username',
|
||||
'txt_password' => ($strLangue === 'fr')
|
||||
? 'Veuillez entrer votre mot de passe'
|
||||
: 'Please enter your password',
|
||||
'txt_login' => function_exists('fxInscrGestionT')
|
||||
? fxInscrGestionT('inscr_gestion_login_err_user')
|
||||
: '',
|
||||
'txt_password' => function_exists('fxInscrGestionT')
|
||||
? fxInscrGestionT('inscr_gestion_login_err_pass')
|
||||
: '',
|
||||
],
|
||||
// MSIN-4401 — libellés Info injectés (pas de FR/EN en dur dans le JS).
|
||||
'i18n' => function_exists('fxInscrGestionT') ? [
|
||||
'errLoad' => fxInscrGestionT('inscr_gestion_err_load'),
|
||||
'errNetwork' => fxInscrGestionT('inscr_gestion_err_network'),
|
||||
'errRefund' => fxInscrGestionT('inscr_gestion_err_refund'),
|
||||
'refundOk' => fxInscrGestionT('inscr_gestion_refund_ok'),
|
||||
'bibOcrNotConfigured' => fxInscrGestionT('inscr_gestion_bib_ocr_not_configured'),
|
||||
'bibOcrVisionPrefix' => fxInscrGestionT('inscr_gestion_bib_ocr_vision_prefix'),
|
||||
'bibOcrImageInvalid' => fxInscrGestionT('inscr_gestion_bib_ocr_image_invalid'),
|
||||
'bibOcrNetwork' => fxInscrGestionT('inscr_gestion_bib_ocr_network'),
|
||||
'bibOcrUnreadable' => fxInscrGestionT('inscr_gestion_bib_scan_invalid'),
|
||||
] : [],
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user