495 lines
24 KiB
PHP
Executable File
495 lines
24 KiB
PHP
Executable File
<?php
|
|
require_once 'gabarit_queries.php';
|
|
$gabary = new Gabary();
|
|
|
|
// Active menu tracking
|
|
$_SESSION['firstLevelMenu'] = '';
|
|
$current_url = $_SERVER['REQUEST_URI'];
|
|
$elements = explode("/", $current_url);
|
|
$activeLink = $elements[1];
|
|
$fullPath = $gabary->get_full_path($activeLink);
|
|
$fullPath = explode("\ ", $fullPath);
|
|
|
|
$activeLevel1 = $activeLink;
|
|
$activeLevel2 = sizeof($fullPath) > 1 ? $fullPath[1] : '';
|
|
$activeLevel3 = sizeof($fullPath) > 2 ? $fullPath[2] : '';
|
|
$activeLevel4 = sizeof($fullPath) > 3 ? $fullPath[3] : '';
|
|
$activeLevel5 = sizeof($fullPath) > 4 ? $fullPath[4] : '';
|
|
|
|
$_SESSION['firstLevelMenu'] = $activeLink;
|
|
|
|
const MAX_COMPANY_NAME_LENGTH = 20;
|
|
|
|
$companyDisplayName = htmlspecialchars($_SESSION['nomSociete'], ENT_QUOTES);
|
|
$modeDev = $_SESSION['modeDev_C'];
|
|
$imgData = $_SESSION['photoAssureCrypte'];
|
|
|
|
// Get breadcrumb info
|
|
$infovue = $gabary->getInfosVue($_SESSION['vue']);
|
|
$descriptionVue = est_anglophone() ? $infovue['DescriptionEng'] : $infovue['Description'];
|
|
$titreRetour = est_anglophone() ? $infovue['titreRetourEng'] : $infovue['titreRetour'];
|
|
$retourVue = $infovue['lienRetour'];
|
|
?>
|
|
|
|
<!DOCTYPE html>
|
|
<html lang="<?= est_anglophone() ? 'en' : 'fr' ?>" class="h-100">
|
|
|
|
<?php require_once 'head.php'; ?>
|
|
|
|
<body class="d-flex flex-column min-vh-100 bg-light">
|
|
|
|
<!-- Header -->
|
|
<?php include 'header.php'; ?>
|
|
|
|
<!-- Main Container -->
|
|
<div class="d-flex flex-grow-1 main-container">
|
|
|
|
<!-- Sidebar -->
|
|
<?php include 'sidebar.php'; ?>
|
|
|
|
<!-- Main Content -->
|
|
<main id="main" class="main flex-grow-1 p-0">
|
|
|
|
<!-- Hidden session variables -->
|
|
<input type="hidden" id="vue" value="<?= $_SESSION['vue'] ?? '' ?>">
|
|
<input type="hidden" id="racineWeb" value="<?= $racineWeb ?>">
|
|
<input type="hidden" id="dureeSession" value="<?= $_SESSION['dureeSession'] ?>">
|
|
<input type="hidden" id="nomSociete" value="<?= htmlspecialchars($_SESSION['nomSociete']) ?>">
|
|
<input type="hidden" id="modeDev" value="<?= $modeDev ?>">
|
|
|
|
<div class="container-fluid p-3 animate__animated animate__fadeIn">
|
|
|
|
<!-- Breadcrumb -->
|
|
<nav aria-label="breadcrumb" class="mb-4 px-2">
|
|
<ol class="breadcrumb bg-white shadow-sm rounded-pill py-2 px-4 border-0">
|
|
<li class="breadcrumb-item">
|
|
<a href="<?= $retourVue; ?>"
|
|
class="text-decoration-none text-muted small d-flex align-items-center">
|
|
<i class="fas fa-arrow-left me-2"></i>
|
|
<?= $titreRetour ?>
|
|
</a>
|
|
</li>
|
|
<li class="breadcrumb-item active text-primary fw-bold small text-uppercase"
|
|
aria-current="page">
|
|
<i class="fas fa-angle-right me-2 text-muted"></i>
|
|
<?= $descriptionVue ?>
|
|
</li>
|
|
</ol>
|
|
</nav>
|
|
|
|
<!-- Secondary Navigation -->
|
|
<?php if (isset($menusvue) && sizeof($menusvue) > 0): ?>
|
|
<div class="tabs-container mb-4 px-2">
|
|
<div class="card border-0 shadow-sm rounded-3 overflow-hidden">
|
|
<div class="d-flex overflow-auto secondary-nav-container">
|
|
<?php foreach ($menusvue as $menu):
|
|
$isActive = (basename($_SERVER['REQUEST_URI']) == basename($menu['lienMenu']));
|
|
$activeClass = $isActive ? 'active' : '';
|
|
?>
|
|
<a class="nav-link-sub p-3 <?= $activeClass ?>"
|
|
href="<?= $menu['lienMenu']; ?>">
|
|
<?php if (!empty($menu['icone'])): ?>
|
|
<i class="<?= $menu['icone'] ?> me-2"></i>
|
|
<?php endif; ?>
|
|
<?= $menu['libeleMenu'] ?>
|
|
<?php if ($isActive): ?>
|
|
<span class="badge bg-white text-primary ms-2 rounded-pill">
|
|
<i class="fas fa-check"></i>
|
|
</span>
|
|
<?php endif; ?>
|
|
</a>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<!-- Main Content Area -->
|
|
<section class="section main-dashboard px-2">
|
|
<div id="contenu" class="animate__animated animate__fadeIn">
|
|
<div id="div_test_gabarit"></div>
|
|
<?= $contenu ?>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
</main>
|
|
|
|
<!-- Context Panel -->
|
|
<?php include 'contexte.php'; ?>
|
|
|
|
<!-- Context Toggle Button -->
|
|
<button class="btn-context-toggle"
|
|
id="showSideNav"
|
|
title="<?= _("Afficher le contexte") ?>">
|
|
<i class="fas fa-chevron-left me-1"></i>
|
|
<i class="fas fa-info-circle"></i>
|
|
</button>
|
|
</div>
|
|
|
|
<!-- ======= Modals ======= -->
|
|
|
|
<!-- Unread Messages Modal -->
|
|
<div class="modal fade animate__animated animate__fadeInDown" id="popmessagerie" tabindex="-1" aria-hidden="true">
|
|
<div class="modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable">
|
|
<div class="modal-content border-0 shadow-lg">
|
|
<div class="modal-header bg-primary text-white">
|
|
<h5 class="modal-title fw-bold">
|
|
<i class="fas fa-envelope-open-text me-2"></i>
|
|
<?= _("Messages non lus") ?>
|
|
<span id="modalMsgCount" class="badge bg-white text-primary ms-2"></span>
|
|
</h5>
|
|
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body p-0">
|
|
<div id="div_messagerie" class="p-4 modal-messages-content">
|
|
<div class="text-center py-5 text-muted">
|
|
<i class="fas fa-envelope-open fa-3x mb-3"></i>
|
|
<p class="mb-0"><?= _("Aucun message non lu") ?></p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer border-top">
|
|
<button type="button" class="btn btn-outline-secondary rounded-pill px-4" data-bs-dismiss="modal">
|
|
<?= _("Fermer") ?>
|
|
</button>
|
|
<button type="button" class="btn btn-primary rounded-pill px-4" onclick="javascript:gerer_messagerie();">
|
|
<i class="fas fa-cog me-2"></i>
|
|
<?= _("Gérer les messages") ?>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- New Message Alert Modal -->
|
|
<div class="modal fade animate__animated animate__bounceIn" id="popderniermessagerie" tabindex="-1" aria-hidden="true">
|
|
<div class="modal-dialog modal-dialog-centered">
|
|
<div class="modal-content border-0 shadow-lg">
|
|
<div class="modal-header border-0 pb-0">
|
|
<h5 class="modal-title fw-bold text-danger">
|
|
<i class="fas fa-bell me-2"></i>
|
|
<?= _("Nouveau Message") ?>
|
|
</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body p-4">
|
|
<div id="div_dernier_messagerie" class="alert alert-info border-0 shadow-sm rounded-3">
|
|
<!-- Content loaded dynamically -->
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer border-0">
|
|
<button id="btn_close_pop_dernier_messagerie" type="button"
|
|
class="btn btn-danger w-100 rounded-pill py-2" data-bs-dismiss="modal">
|
|
<i class="fas fa-times me-2"></i>
|
|
<?= _("Fermer") ?>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Photo Modal -->
|
|
<div class="modal fade" id="pop_photo" tabindex="-1" aria-hidden="true">
|
|
<div class="modal-dialog modal-dialog-centered">
|
|
<div class="modal-content bg-transparent border-0">
|
|
<div class="modal-header border-0">
|
|
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body text-center p-0">
|
|
<?php if (!empty($imgData) && $_SESSION['faceRegistered_C'] == "1"): ?>
|
|
<img src="data:image/jpg;base64,<?= $imgData ?>"
|
|
class="img-fluid rounded shadow-lg border border-5 border-white modal-photo-image"
|
|
alt="<?= _("Photo du bénéficiaire") ?>">
|
|
<h4 class="text-white mt-3 fw-bold"><?= $_SESSION['nomBeneficiaire_C'] ?? '' ?></h4>
|
|
<?php else: ?>
|
|
<div class="bg-white rounded shadow-lg p-5">
|
|
<i class="fas fa-user-slash fa-4x text-muted"></i>
|
|
<h4 class="mt-3 text-muted"><?= _("Photo non disponible") ?></h4>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Hidden Trigger Buttons -->
|
|
<button id="btn_pop_messagerie" type="button" class="d-none" data-bs-toggle="modal" data-bs-target="#popmessagerie"></button>
|
|
<button id="btn_pop_dernier_messagerie" type="button" class="d-none" data-bs-toggle="modal" data-bs-target="#popderniermessagerie"></button>
|
|
|
|
<!-- ======= Scripts ======= -->
|
|
<script src="Bootstrap/js/jquery.min.js"></script>
|
|
<script src="Bootstrap/js/jquery-ui.js"></script>
|
|
|
|
<!-- Bootstrap 5 Bundle -->
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz" crossorigin="anonymous"></script>
|
|
|
|
<!-- Bootstrap Select JS - DOIT être chargé AVANT fonctions.js -->
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap-select@1.14.0-beta3/dist/js/bootstrap-select.min.js"></script>
|
|
|
|
<!-- DataTables -->
|
|
<script src="Bootstrap_new/datatables/datatable.min.js"></script>
|
|
|
|
<!-- Charts -->
|
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
|
|
|
<!-- PDF Generation -->
|
|
<script src="Js/html2pdf.js"></script>
|
|
|
|
<!-- Select2 -->
|
|
<script src="Bootstrap_new/js/select2.min.js"></script>
|
|
|
|
<!-- Timer -->
|
|
<script src="Bootstrap/js/timer.jquery.js"></script>
|
|
|
|
<!-- SweetAlert2 -->
|
|
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
|
|
|
<!-- Toastr -->
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.js"></script>
|
|
|
|
<!-- Datepicker by language -->
|
|
<?php if (est_anglophone()) : ?>
|
|
<script src="Js/datepicker-eng.js"></script>
|
|
<?php else: ?>
|
|
<script src="Js/datepicker-fr.js"></script>
|
|
<?php endif; ?>
|
|
|
|
<!-- Core Functions - DOIT être APRÈS Bootstrap Select -->
|
|
<script src="Js/fonctions.js?ver=<?= date('Y.m.d.H') ?>"></script>
|
|
<script src="<?= $_SESSION['dossierSociete'] . '/Js/societe.js' ?>"></script>
|
|
|
|
<!-- Script d'initialisation corrigé -->
|
|
<script type="text/javascript">
|
|
// Fonction pour patcher temporairement le problème dans fonctions.js
|
|
function patchFunctionsJS() {
|
|
// Sauvegarder la fonction originale $(function(){...})
|
|
var originalJQueryReady = window.jQuery.fn.init;
|
|
|
|
// Surcharger temporairement pour retarder l'exécution
|
|
$(document).ready(function() {
|
|
// Attendre que tout soit chargé
|
|
setTimeout(function() {
|
|
// Ré-exécuter l'initialisation des selectpickers si nécessaire
|
|
if (typeof $.fn.selectpicker !== 'undefined' && $('.selectpicker').length) {
|
|
var initialized = $('.selectpicker').filter(function() {
|
|
return $(this).data('selectpicker') !== undefined;
|
|
}).length;
|
|
|
|
if (initialized === 0) {
|
|
$('.selectpicker').selectpicker();
|
|
console.log("Bootstrap Select réinitialisé depuis gabarit.php");
|
|
}
|
|
}
|
|
}, 100);
|
|
});
|
|
}
|
|
|
|
$(document).ready(function() {
|
|
console.log("=== GABARIT INITIALISATION ===");
|
|
console.log("jQuery version:", $.fn.jquery);
|
|
console.log("Bootstrap Select disponible:", typeof $.fn.selectpicker !== 'undefined');
|
|
console.log("Select2 disponible:", typeof $.fn.select2 !== 'undefined');
|
|
console.log("Toastr disponible:", typeof toastr !== 'undefined');
|
|
|
|
// 1. Initialiser Bootstrap Select IMMÉDIATEMENT
|
|
if (typeof $.fn.selectpicker !== 'undefined') {
|
|
try {
|
|
$('.selectpicker').selectpicker();
|
|
console.log("✅ Bootstrap Select initialisé avec succès");
|
|
console.log(" Nombre de .selectpicker trouvés:", $('.selectpicker').length);
|
|
} catch (error) {
|
|
console.error("❌ Erreur Bootstrap Select:", error);
|
|
}
|
|
} else {
|
|
console.warn("⚠️ Bootstrap Select non disponible");
|
|
// Fallback: utiliser Select2
|
|
if (typeof $.fn.select2 !== 'undefined') {
|
|
$('.selectpicker').each(function() {
|
|
if (!$(this).hasClass('select2-hidden-accessible')) {
|
|
$(this).select2({
|
|
theme: 'bootstrap-5',
|
|
width: '100%'
|
|
}).addClass('selectpicker-fallback');
|
|
}
|
|
});
|
|
console.log("✅ Fallback Select2 appliqué aux .selectpicker");
|
|
}
|
|
}
|
|
|
|
// 2. Initialiser Select2
|
|
if (typeof $.fn.select2 !== 'undefined') {
|
|
$('.select2').select2({
|
|
theme: 'bootstrap-5'
|
|
});
|
|
console.log("✅ Select2 initialisé");
|
|
}
|
|
|
|
// 3. Gestion du sidebar
|
|
$('.toggle-sidebar-btn').on('click', function() {
|
|
$('body').toggleClass('toggle-sidebar');
|
|
console.log("Sidebar togglé");
|
|
});
|
|
|
|
// 4. Gestion de la barre de contexte - VERSION SIMPLIFIÉE ET ROBUSTE
|
|
function initContextPanel() {
|
|
console.log("Initialisation du panneau de contexte...");
|
|
|
|
var $panel = $('#barre_laterale_d');
|
|
var $showBtn = $('#showSideNav');
|
|
var $hideBtn = $('#hideSideNav');
|
|
|
|
// Vérifier que les éléments existent
|
|
if (!$panel.length || !$showBtn.length || !$hideBtn.length) {
|
|
console.error("❌ Éléments du panneau de contexte non trouvés");
|
|
return;
|
|
}
|
|
|
|
console.log("✅ Éléments trouvés:");
|
|
console.log(" - Panel:", $panel.length);
|
|
console.log(" - Bouton show:", $showBtn.length);
|
|
console.log(" - Bouton hide:", $hideBtn.length);
|
|
|
|
// S'assurer que le panel est caché au départ
|
|
$panel.removeClass('active');
|
|
$showBtn.show();
|
|
|
|
// Événement pour montrer le panel
|
|
$showBtn.off('click').on('click', function(e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
console.log("Bouton show cliqué");
|
|
|
|
$panel.addClass('active');
|
|
$(this).hide();
|
|
|
|
// Ajouter une classe au body pour empêcher le scroll
|
|
$('body').addClass('context-panel-open');
|
|
|
|
return false;
|
|
});
|
|
|
|
// Événement pour cacher le panel
|
|
$hideBtn.off('click').on('click', function(e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
console.log("Bouton hide cliqué");
|
|
|
|
$panel.removeClass('active');
|
|
$showBtn.show();
|
|
$('body').removeClass('context-panel-open');
|
|
|
|
return false;
|
|
});
|
|
|
|
// Fermer en cliquant en dehors
|
|
$(document).off('click.context-panel').on('click.context-panel', function(e) {
|
|
if ($panel.hasClass('active') &&
|
|
!$(e.target).closest('#barre_laterale_d').length &&
|
|
!$(e.target).is('#showSideNav')) {
|
|
console.log("Clic en dehors du panel");
|
|
$panel.removeClass('active');
|
|
$showBtn.show();
|
|
$('body').removeClass('context-panel-open');
|
|
}
|
|
});
|
|
|
|
// Empêcher la fermeture quand on clique dans le panel
|
|
$panel.off('click').on('click', function(e) {
|
|
e.stopPropagation();
|
|
});
|
|
|
|
console.log("✅ Panneau de contexte initialisé");
|
|
}
|
|
|
|
// Initialiser le panneau de contexte
|
|
initContextPanel();
|
|
|
|
// 5. Tester manuellement le bouton (debug)
|
|
$('#showSideNav').css({
|
|
'background': 'linear-gradient(135deg, #0088cf, #0066a6)',
|
|
'color': 'white',
|
|
'border': 'none',
|
|
'cursor': 'pointer'
|
|
});
|
|
|
|
/* Ajouter un bouton de test debug (à enlever en production)
|
|
if (typeof modeDev !== 'undefined' && modeDev == "1") {
|
|
$('body').append(
|
|
'<button id="debugTestPanel" style="position:fixed; bottom:20px; left:20px; z-index:9999; padding:10px; background:red; color:white; border:none; border-radius:5px;">DEBUG: Test Panel</button>'
|
|
);
|
|
|
|
$('#debugTestPanel').on('click', function() {
|
|
var $panel = $('#barre_laterale_d');
|
|
if ($panel.hasClass('active')) {
|
|
$panel.removeClass('active');
|
|
$('#showSideNav').show();
|
|
console.log("DEBUG: Panel fermé");
|
|
} else {
|
|
$panel.addClass('active');
|
|
$('#showSideNav').hide();
|
|
console.log("DEBUG: Panel ouvert");
|
|
}
|
|
});
|
|
}
|
|
*/
|
|
// 6. Synchronisation du badge de notifications
|
|
function syncBadge() {
|
|
var count = parseInt($("#msgNonLus").val()) || 0;
|
|
var badge = $("#badge_notif_msg");
|
|
|
|
if (badge.length) {
|
|
if(count > 0) {
|
|
badge.text(count).show();
|
|
badge.data('last-count', count);
|
|
} else {
|
|
badge.hide();
|
|
}
|
|
}
|
|
}
|
|
|
|
setInterval(syncBadge, 2000);
|
|
syncBadge();
|
|
|
|
// 7. Toastr configuration
|
|
if (typeof toastr !== 'undefined') {
|
|
toastr.options = {
|
|
"closeButton": true,
|
|
"progressBar": true,
|
|
"positionClass": "toast-top-right",
|
|
"timeOut": "5000",
|
|
"extendedTimeOut": "1000"
|
|
};
|
|
console.log("✅ Toastr configuré");
|
|
}
|
|
|
|
console.log("=== GABARIT INITIALISATION TERMINÉE ===");
|
|
});
|
|
|
|
// Fonctions globales pour le panneau de contexte
|
|
window.ouvrirPanneauContexte = function() {
|
|
$('#barre_laterale_d').addClass('active');
|
|
$('#showSideNav').hide();
|
|
$('body').addClass('context-panel-open');
|
|
};
|
|
|
|
window.fermerPanneauContexte = function() {
|
|
$('#barre_laterale_d').removeClass('active');
|
|
$('#showSideNav').show();
|
|
$('body').removeClass('context-panel-open');
|
|
};
|
|
|
|
// Appliquer le patch après le chargement
|
|
setTimeout(patchFunctionsJS, 500);
|
|
</script>
|
|
|
|
<!-- AJAX Container -->
|
|
<div id="div_ajaxgabarit" class="d-none"></div>
|
|
|
|
<!-- Global Loading Overlay -->
|
|
<div id="globalLoading" class="global-loading-overlay">
|
|
<div class="spinner-border text-primary global-loading-spinner" role="status">
|
|
<span class="visually-hidden"><?= _("Chargement...") ?></span>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|