diff --git a/ajax_promoteur_hub.php b/ajax_promoteur_hub.php index cb93e67..14c8583 100644 --- a/ajax_promoteur_hub.php +++ b/ajax_promoteur_hub.php @@ -16,22 +16,36 @@ if (empty($_SESSION['com_id'])) { exit; } -if ($strAction !== 'event_stats' || $intEveId <= 0) { +$intComId = intval($_SESSION['com_id']); + +if (!in_array($strAction, array('event_stats', 'event_links'), true) || $intEveId <= 0) { echo json_encode(array('ok' => false, 'msg' => 'Requête invalide')); exit; } -$intComId = intval($_SESSION['com_id']); - if (!fxPromoteurHubComHasEvent($intComId, $intEveId)) { echo json_encode(array('ok' => false, 'msg' => 'Accès refusé')); exit; } -$arrBundle = fxPromoteurHubRenderEventStatsBundle($intEveId, $strLangue); +if ($strAction === 'event_stats') { + $arrBundle = fxPromoteurHubRenderEventStatsBundle($intEveId, $strLangue); + + echo json_encode(array( + 'ok' => true, + 'flash' => $arrBundle['flash'], + 'html' => $arrBundle['html'], + )); + exit; +} + +$arrItem = fxPromoteurHubGetEventItemForLinks($intComId, $intEveId); +if ($arrItem === null) { + echo json_encode(array('ok' => false, 'msg' => 'Événement introuvable')); + exit; +} echo json_encode(array( 'ok' => true, - 'flash' => $arrBundle['flash'], - 'html' => $arrBundle['html'], + 'html' => fxPromoteurHubRenderEventPanelContent($arrItem, $strLangue), )); diff --git a/js/v2/promoteur-hub.js b/js/v2/promoteur-hub.js new file mode 100644 index 0000000..5c409ea --- /dev/null +++ b/js/v2/promoteur-hub.js @@ -0,0 +1,111 @@ +/** + * Hub promoteur — chargement AJAX stats + menu fonctionnalités. + * Chargé uniquement sur compte_promoteur_hub. + */ +(function () { + 'use strict'; + + var cfg = window.MS1_V2_PROMOTEUR_HUB || {}; + var $ = window.jQuery; + + if (!$) { + return; + } + + var strAjaxUrl = cfg.ajaxUrl || ''; + var strWaitMsg = cfg.preloaderWait || 'Chargement…'; + var intHubLoaderPending = 0; + + function fxHubShowLoader() { + intHubLoaderPending++; + if (intHubLoaderPending !== 1) { + return; + } + if (window.Ms1Loader) { + Ms1Loader.show(strWaitMsg); + return; + } + var $preloader = $('#preloader'); + if ($preloader.length) { + $('#preloader_text').html(strWaitMsg); + $preloader.show(); + } + } + + function fxHubHideLoader() { + intHubLoaderPending = Math.max(0, intHubLoaderPending - 1); + if (intHubLoaderPending !== 0) { + return; + } + if (window.Ms1Loader) { + Ms1Loader.hide(); + return; + } + $('#preloader').fadeOut('slow'); + } + + function fxHubLoadStats($collapse) { + if ($collapse.data('hub-loaded') || !strAjaxUrl) { + return; + } + var intEve = $collapse.data('hub-eve-id'); + var strLang = $collapse.data('hub-lang') || 'fr'; + + fxHubShowLoader(); + $.getJSON(strAjaxUrl, { a: 'event_stats', eve_id: intEve, lang: strLang }) + .done(function (r) { + if (!r || !r.ok) { + $collapse.find('.promoteur-hub-stats-placeholder').text(r && r.msg ? r.msg : 'Erreur'); + return; + } + $collapse.find('.promoteur-hub-stats-placeholder').replaceWith(r.html || ''); + if (r.flash) { + $collapse.closest('.promoteur-hub-card').find('.promoteur-hub-card-flash-wrap').html(r.flash); + } + $collapse.data('hub-loaded', 1); + }) + .fail(function () { + $collapse.find('.promoteur-hub-stats-placeholder').text('Erreur chargement'); + }) + .always(function () { + fxHubHideLoader(); + }); + } + + function fxHubLoadLinks($collapse) { + if ($collapse.data('hub-links-loaded') || !strAjaxUrl) { + return; + } + var intEve = $collapse.data('hub-eve-id'); + var strLang = $collapse.data('hub-lang') || 'fr'; + + fxHubShowLoader(); + $.getJSON(strAjaxUrl, { a: 'event_links', eve_id: intEve, lang: strLang }) + .done(function (r) { + if (!r || !r.ok) { + $collapse.find('.promoteur-hub-links-placeholder').text(r && r.msg ? r.msg : 'Erreur'); + return; + } + $collapse.find('.promoteur-hub-links-placeholder').replaceWith(r.html || ''); + $collapse.data('hub-links-loaded', 1); + }) + .fail(function () { + $collapse.find('.promoteur-hub-links-placeholder').text('Erreur chargement'); + }) + .always(function () { + fxHubHideLoader(); + }); + } + + $(document).on('show.bs.collapse', '.promoteur-hub-epreuves-collapse', function () { + var $card = $(this).closest('.promoteur-hub-card'); + $card.find('.promoteur-hub-epreuves-collapse.show, .promoteur-hub-functions.show').not(this).collapse('hide'); + fxHubLoadStats($(this)); + }); + + $(document).on('show.bs.collapse', '.promoteur-hub-functions', function () { + var $card = $(this).closest('.promoteur-hub-card'); + $card.find('.promoteur-hub-epreuves-collapse.show, .promoteur-hub-functions.show').not(this).collapse('hide'); + fxHubLoadLinks($(this)); + }); +})(); diff --git a/php/inc_fx_promoteur_hub.php b/php/inc_fx_promoteur_hub.php index 94d0b60..1966bcb 100644 --- a/php/inc_fx_promoteur_hub.php +++ b/php/inc_fx_promoteur_hub.php @@ -130,6 +130,33 @@ function fxPromoteurHubCanAccessPromoteurWeb($intComId, $intEveId, $arrLegacyFli return fxEveAccesHasAnyPermission(intval($intComId), intval($intEveId), fxPromoteurHubPermKeysWeb()); } +/** + * Contrôle d'accès promoteur web en lot (évite N requêtes eve_acces par carte). + * Prérequis : $arrLegacyFlip, $arrV2EventFlip, $arrWebPermFlip préchargés. + */ +function fxPromoteurHubCanAccessPromoteurWebBatch($intComId, $intEveId, $arrLegacyFlip, $arrV2EventFlip, $arrWebPermFlip) +{ + $intEveId = intval($intEveId); + + if (isset($arrLegacyFlip[$intEveId])) { + return true; + } + + if (!function_exists('fxIsPromoteur')) { + require_once __DIR__ . '/inc_fonctions.php'; + } + + if (fxIsPromoteur(intval($intComId), $intEveId)) { + return true; + } + + if (!isset($arrV2EventFlip[$intEveId])) { + return false; + } + + return isset($arrWebPermFlip[$intEveId]); +} + function fxPromoteurHubParseDateTs($strDate) { $strDate = trim((string)$strDate); @@ -248,10 +275,9 @@ function fxPromoteurHubGetEvents($intComId, $strLangue = 'fr') $arrArchived = array(); // Union : evenements legacy (com_eve_promoteur) + acces v2 - $arrEventIds = array_merge( - fxPromoteurHubGetLegacyEventIds(intval($intComId)), - fxEveAccesGetEventIds(intval($intComId)) - ); + $arrLegacyIds = fxPromoteurHubGetLegacyEventIds(intval($intComId)); + $arrV2EventIds = fxEveAccesGetEventIds(intval($intComId)); + $arrEventIds = array_merge($arrLegacyIds, $arrV2EventIds); if (empty($arrEventIds)) { return array('highlight' => $arrHighlight, 'archived' => $arrArchived); @@ -269,7 +295,9 @@ function fxPromoteurHubGetEvents($intComId, $strLangue = 'fr') $strAlt = ($strLang === 'fr') ? 'en' : 'fr'; $arrRoles = fxPromoteurHubGetRoleLabelsByEvent(intval($intComId)); $intToday = strtotime(date('Y-m-d')); - $arrLegacyFlip = array_flip(array_map('intval', fxPromoteurHubGetLegacyEventIds(intval($intComId)))); + $arrLegacyFlip = array_flip(array_map('intval', $arrLegacyIds)); + $arrV2EventFlip = array_flip(array_map('intval', $arrV2EventIds)); + $arrWebPermFlip = array_flip(fxEveAccesGetEventIdsWithAnyPermission(intval($intComId), fxPromoteurHubPermKeysWeb())); if (!function_exists('fxInscrGestionGetPromoteurEveIds')) { require_once __DIR__ . '/inc_fx_inscriptions_gestion.php'; @@ -328,7 +356,7 @@ function fxPromoteurHubGetEvents($intComId, $strLangue = 'fr') 'qte_modifiable' => intval($row['eve_qte_modifiable'] ?? 0), 'rapport_capitaines' => intval($row['eve_rapport_finances_capitaines'] ?? 0), 'com_id' => intval($intComId), - 'url_promoteur' => fxPromoteurHubCanAccessPromoteurWeb($intComId, $intEveId, $arrLegacyFlip) + 'url_promoteur' => fxPromoteurHubCanAccessPromoteurWebBatch($intComId, $intEveId, $arrLegacyFlip, $arrV2EventFlip, $arrWebPermFlip) ? fxPromoteurHubPromoteurTableUrl($intEveId, $strLang) : '', 'url_mobile' => '', @@ -492,13 +520,11 @@ function fxPromoteurHubRenderLinkList($arrLinks, $strDefaultIcon) return $html; } -function fxPromoteurHubRenderEventPanel($arrItem, $strLangue) +function fxPromoteurHubRenderEventPanelContent($arrItem, $strLangue) { - $strPanelId = 'hub-fn-' . intval($arrItem['eve_id']); $arrLinks = fxPromoteurHubGetEventLinks($arrItem, $strLangue); - $html = '