This commit is contained in:
KONE SOREL 2026-02-25 08:39:11 +00:00
parent f2cce73a93
commit 69b57a7564
5 changed files with 741 additions and 421 deletions

View File

@ -1,13 +1,20 @@
<?php
/*
* INTER SANTÉ gabarit.php
* Point d'entrée principal Structure modulaire SaaS Premium
* Refonte UI/UX v2025
*/
require_once 'gabarit_queries.php';
$gabary = new Gabary();
/* ── Résolution du menu actif ── */
$_SESSION['firstLevelMenu'] = '';
$current_url = $_SERVER['REQUEST_URI'];
$elements = explode("/", $current_url);
$activeLink = $elements[1];
$fullPath = $gabary->get_full_path($activeLink);
$fullPath = explode("\ ", $fullPath);
$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] : '';
@ -17,43 +24,133 @@ $activeLevel5 = sizeof($fullPath) > 4 ? $fullPath[4] : '';
$_SESSION['firstLevelMenu'] = $activeLink;
const MAX_COMPANY_NAME_LENGTH = 20;
/* ── Constantes ── */
defined('MAX_COMPANY_NAME_LENGTH') || define('MAX_COMPANY_NAME_LENGTH', 20);
defined('APP_VERSION') || define('APP_VERSION', date('YmdHi'));
$companyDisplayName = htmlspecialchars($_SESSION['nomSociete'], ENT_QUOTES);
$modeDev = $_SESSION['modeDev_C'];
$imgData = $_SESSION['photoAssureCrypte'];
/* ── Variables de présentation ── */
$companyDisplayName = htmlspecialchars($_SESSION['nomSociete'] ?? '', ENT_QUOTES);
$modeDev = $_SESSION['modeDev_C'];
$imgData = $_SESSION['photoAssureCrypte'];
/* ── Infos de la vue ── */
$infovue = $gabary->getInfosVue($_SESSION['vue']);
$_SESSION['descriptionVue'] = est_anglophone() ? $infovue['DescriptionEng'] : $infovue['Description'];
$_SESSION['titreRetour'] = est_anglophone() ? $infovue['titreRetourEng'] : $infovue['titreRetour'];
$_SESSION['descriptionVue'] = est_anglophone() ? $infovue['DescriptionEng'] : $infovue['Description'];
$_SESSION['titreRetour'] = est_anglophone() ? $infovue['titreRetourEng'] : $infovue['titreRetour'];
$_SESSION['retourVue'] = $infovue['lienRetour'];
// Pour l'exemple, on désactive le mode test, mais vous pouvez le laisser dynamique
$_SESSION['bdTests_C'] = "0";
$descriptionVue = $_SESSION['descriptionVue'];
?>
<!doctype html>
<?php if (est_anglophone()): ?>
<html lang="en">
<?php else: ?>
<html lang="fr">
<?php endif; ?>
<head>
<?php include('includes/head-meta.php'); ?>
</head>
<html lang="<?= est_anglophone() ? 'en' : 'fr' ?>">
<body class="<?= ($_SESSION['bdTests_C'] == '1') ? 'mode-test-active' : '' ?>">
<?php include('includes/header.php'); ?>
<?php include('includes/sidebar.php'); ?>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<base href="<?= $racineWeb ?>">
<!-- MAIN CONTENT - NE PAS MODIFIER LA STRUCTURE -->
<main id="main" class="main">
<?php include('includes/main-content.php'); ?>
</main>
<!-- Favicon -->
<link rel="icon" href="Bootstrap_new/images/favicon.ico">
<?php include('includes/barre-contexte.php'); ?>
<?php include('includes/modals.php'); ?>
<?php include('includes/scripts-footer.php'); ?>
</body>
</html>
<!-- Google Fonts: Syne + DM Sans -->
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Syne:wght@400;500;600;700;800&family=DM+Sans:ital,opsz,wght@0,9..40,300;0,9..40,400;0,9..40,500;0,9..40,600;1,9..40,400&display=swap" rel="stylesheet">
<!-- Vendor CSS -->
<link href="Bootstrap/vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<link href="Bootstrap/vendor/bootstrap-icons/bootstrap-icons.css" rel="stylesheet">
<link href="Bootstrap/vendor/boxicons/css/boxicons.min.css" rel="stylesheet">
<link href="Bootstrap/vendor/quill/quill.snow.css" rel="stylesheet">
<link href="Bootstrap/vendor/quill/quill.bubble.css" rel="stylesheet">
<link href="Bootstrap/vendor/remixicon/remixicon.css" rel="stylesheet">
<link href="Bootstrap/vendor/simple-datatables/style.css" rel="stylesheet">
<link href="Bootstrap_new/css/datatables.min.css" rel="stylesheet">
<link href="Bootstrap_new/css/select2.min.css" rel="stylesheet">
<link href="Bootstrap_new/select/css/bootstrap-select.min.css" rel="stylesheet">
<!-- SweetAlert2 CSS -->
<link href="https://cdn.jsdelivr.net/npm/sweetalert2@11.14.1/dist/sweetalert2.min.css" rel="stylesheet">
<!-- FontAwesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css" crossorigin="anonymous" referrerpolicy="no-referrer">
<!-- App CSS (Bootstrap original conservé pour rétrocompatibilité) -->
<link href="Bootstrap/css/style.css?ver=2024.03.14.05" rel="stylesheet">
<link href="Bootstrap_new/css/style.css?ver=2025.09.10.00" rel="stylesheet">
<!-- DataTables custom CSS -->
<link rel="stylesheet" href="Bootstrap_new/datatables/datatable.min.css" crossorigin="anonymous">
<!-- THEME MODERNE (override global) -->
<link href="Bootstrap_new/css/theme-modern.css?ver=<?= APP_VERSION ?>" rel="stylesheet">
<!-- Custom overrides -->
<link href="Bootstrap_new/css/custom.css?ver=2025.08.22.06" rel="stylesheet">
<title><?= htmlspecialchars($_SESSION['descriptionVue'] ?? '', ENT_QUOTES) ?></title>
<!-- Libs JS en tête (graphiques peuvent être en head) -->
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2.0.0"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-annotation@1.0.2"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
<!-- Variable globale modeDev -->
<script>
var modeDev = <?= json_encode($_SESSION['modeDev_C']) ?>;
if (modeDev !== '1') {
document.addEventListener('contextmenu', function (e) { e.preventDefault(); }, false);
}
</script>
</head>
<body class="<?= $_SESSION['bdTests_C'] == '1' ? 'mode-test-active' : '' ?>">
<?php include 'includes/header.php'; ?>
<?php include 'includes/sidebar.php'; ?>
<!-- ======= Main ======= -->
<main id="main" class="main">
<!-- Inputs techniques vitaux pour AJAX / JS (sr-only = accessibles mais invisibles) -->
<input class="sr-only" type="text" id="vue" name="vue" value="<?= htmlspecialchars($_SESSION['vue'] ?? '', ENT_QUOTES) ?>">
<input class="sr-only" type="text" id="racineWeb" name="racineWeb" value="<?= htmlspecialchars($racineWeb, ENT_QUOTES) ?>">
<input class="sr-only" type="text" id="dureeSession" name="dureeSession" value="<?= htmlspecialchars($_SESSION['dureeSession'] ?? '', ENT_QUOTES) ?>">
<input class="sr-only" type="text" id="nomSociete" name="nomSociete" value="<?= htmlspecialchars($_SESSION['nomSociete'] ?? '', ENT_QUOTES) ?>">
<input class="sr-only" type="text" id="codeLangue" name="codeLangue" value="<?= est_anglophone() ? 'en_US' : 'fr_FR' ?>">
<!-- Scroll menu des sous-vues -->
<?php if (!empty($menusvue)): ?>
<div class="fixed-div">
<div class="content">
<div class="scrollmenu">
<?php foreach ($menusvue as $menu): ?>
<a href="<?= htmlspecialchars($menu['lienMenu'], ENT_QUOTES) ?>"
title="<?= htmlspecialchars($menu['descriptionMenu'] ?? '', ENT_QUOTES) ?>">
<?= htmlspecialchars($menu['libeleMenu'], ENT_QUOTES) ?>
</a>
<?php endforeach; ?>
</div>
</div>
</div>
<?php endif; ?>
<!-- Contenu de la page -->
<section class="section main-dashboard">
<div id="contenu" class="page-content">
<div id="div_test_gabarit"></div>
<div id="div_entite" class="sr-only"></div>
<?= $contenu ?>
</div>
</section>
</main>
<!-- End Main -->
<?php include 'includes/barre-contexte.php'; ?>
<?php include 'includes/modals.php'; ?>
<?php include 'includes/scripts-footer.php'; ?>
</body>
</html>

View File

@ -1,116 +1,239 @@
<!-- Bouton flottant pour ouvrir le panneau de contexte -->
<button class="btn-context-toggle" id="showSideNav" title="<?= _('Afficher le contexte') ?>">
<i class="fa-solid fa-angles-left"></i>
<i class="fa fa-cog fa-spin"></i>
<?php
/*
* INTER SANTÉ includes/barre-contexte.php
* Panneau contextuel coulissant (Drawer) style SaaS Premium
* Contient : Garant, Souscripteur, Police, Adhérent, Bénéficiaire, Photo
*/
?>
<!-- Inputs techniques (cachés mais disponibles pour JS/AJAX) -->
<input type="hidden" id="numeroClient_C" name="numeroClient_C" value="<?= $this->nettoyer($_SESSION['numeroClient_C']) ?>">
<input type="hidden" id="codeGcAssureur_C" name="codeGcAssureur_C" value="<?= $this->nettoyer($_SESSION['codeGcAssureur_C']) ?>">
<!-- ======= Bouton Ouvrir le Panneau ======= -->
<button class="btn-info-context" id="showSideNav"
title="<?= _('Afficher le contexte') ?>"
aria-label="<?= _('Afficher le panneau de contexte') ?>">
<i class="fas fa-angle-double-left"></i>
<i class="fas fa-id-card" style="font-size:14px; opacity:0.8;"></i>
</button>
<!-- Panneau de contexte (Drawer) -->
<div id="barre_laterale_d" class="context-drawer">
<div class="context-drawer-content">
<!-- En-tête du drawer avec bouton de fermeture -->
<div class="drawer-header">
<h5 class="drawer-title"><i class="fa fa-cog me-2"></i><?= _('Contexte actuel') ?></h5>
<button class="btn-close" id="hideSideNav" aria-label="Fermer"></button>
</div>
<!-- ======= Panneau de Contexte (Drawer) ======= -->
<div id="barre_laterale_d" role="complementary" aria-label="<?= _('Panneau de contexte') ?>">
<div class="drawer-inner">
<!-- Contenu de la fiche d'identité -->
<div class="drawer-body">
<!-- Garant -->
<div class="context-card">
<div class="context-card-header">
<i class="fas fa-user-shield"></i> <?= _('Garant') ?>
</div>
<div class="context-card-body">
<a href="javascript:afficher_garant('<?= $this->nettoyer($_SESSION['codeGcAssureur_C']) ?>');" class="context-link">
<strong><?= $this->nettoyer($_SESSION['codeGcAssureur_C']) ?></strong>
</a>
<p class="text-muted small mb-0"><?= $_SESSION['nomGcAssureur_C'] ?? '' ?></p>
</div>
</div>
<!-- Header du panneau -->
<button class="btn-cacher-contexte" id="hideSideNav"
title="<?= _('Fermer le panneau') ?>"
aria-label="<?= _('Fermer le panneau de contexte') ?>">
<i class="fas fa-times-circle me-2"></i>
<?= _('Fermer le contexte') ?>
<i class="fas fa-angle-double-right ms-auto"></i>
</button>
<!-- Souscripteur -->
<div class="context-card">
<div class="context-card-header">
<i class="fas fa-user-tie"></i> <?= _('Souscripteur') ?>
</div>
<div class="context-card-body">
<a href="javascript:afficher_client_id();" class="context-link">
<strong><?= $this->nettoyer($_SESSION['numeroClient_C']) ?></strong>
</a>
<p class="text-muted small mb-0"><?= $this->nettoyer($_SESSION['nomClient_C']) ?></p>
</div>
</div>
<!-- Police en cours -->
<div class="context-card">
<div class="context-card-header">
<i class="fa fa-file-text"></i> <?= _('Police en cours') ?>
</div>
<div class="context-card-body">
<a href="javascript:afficher_police_id();" class="context-link">
<?= $this->nettoyer($_SESSION['numeroPolice_C']) ?>
</a>
<p class="text-muted small mb-1"><?= dateLang($_SESSION['dateEffet_C'], $_SESSION['lang']) ?> - <?= dateLang($_SESSION['dateEcheance_C'], $_SESSION['lang']) ?></p>
<div class="family-stats">
<span class="badge bg-light text-dark"><i class="fas fa-users me-1"></i>Fam. <?= format_N($_SESSION['ndAdh_C']) ?></span>
<span class="badge bg-light text-dark"><i class="fas fa-users me-1"></i>Dép. <?= format_N($_SESSION['ndDep_C']) ?></span>
<span class="badge bg-light text-dark"><i class="fas fa-user me-1"></i>Bén. <?= format_N($_SESSION['ndActif_C']) ?></span>
</div>
</div>
</div>
<!-- Adhérent -->
<div class="context-card">
<div class="context-card-header">
<i class="fa-solid fa-users"></i> <?= _('Famille en cours') ?>
</div>
<div class="context-card-body">
<a href="javascript:afficher_adherent_id();" class="context-link">
<?= $this->nettoyer($_SESSION['numeroAdherent_C']) ?>
</a>
<p class="text-muted small mb-0"><?= substr($this->nettoyer($_SESSION['adherent_C']), 0, 35) ?></p>
</div>
</div>
<!-- Bénéficiaire + Photo -->
<div class="context-card">
<div class="context-card-header">
<i class="fa-solid fa-user"></i> <?= _('Bénéficiaire en cours') ?>
</div>
<div class="context-card-body">
<div class="d-flex align-items-start gap-3">
<div>
<a href="javascript:afficher_beneficiaire_id();" class="context-link">
<?= $this->nettoyer($_SESSION['numeroBeneficiaire_C']) ?>
</a>
<p class="text-muted small mb-1"><?= substr($this->nettoyer($_SESSION['beneficiaire_C']), 0, 35) ?></p>
<p class="small mb-0"><i class="bi bi-calendar me-1"></i><?= dateLang($_SESSION['dateEntreeBeneficiaire_C'], $_SESSION['lang']) ?> - <?= dateLang($_SESSION['dateEcheancePolice_C'], $_SESSION['lang']) ?></p>
</div>
<?php if ($_SESSION['faceRegistered_C'] == "1" && $_SESSION['idBeneficiaire_C'] > 0): ?>
<img src="data:image/jpg;base64,<?= $imgData ?>" class="beneficiary-photo rounded-circle" alt="Photo" data-bs-toggle="modal" data-bs-target="#pop_photo">
<?php endif; ?>
</div>
</div>
</div>
<!-- Dernières polices ouvertes -->
<div class="context-card">
<div class="context-card-header">
<i class="bi bi-clock-history"></i> <?= _('Dernières polices') ?>
</div>
<div class="context-card-body p-0">
<ul class="list-unstyled mb-0">
<?php foreach ($_SESSION['contextPolice'] as $contextPolice): ?>
<li class="border-bottom p-2">
<a href="javascript:selectionner_police(<?= $contextPolice['idPolice'] ?>,'<?= $contextPolice['numeroPolice'] ?>');afficher_police_id();" class="text-decoration-none d-block">
<span class="fw-semibold"><?= htmlspecialchars($contextPolice['libellePolice']) ?></span>
<small class="text-muted d-block"><?= $contextPolice['numeroPolice'] ?></small>
</a>
</li>
<?php endforeach; ?>
</ul>
</div>
</div>
</div>
<!-- ── GARANT ── -->
<div class="context-card">
<div class="context-card-label">
<i class="fas fa-user-shield"></i>
<?= _('Garant') ?>
<a href="javascript:afficher_garant('<?= $this->nettoyer($_SESSION['codeGcAssureur_C']) ?>');"
title="<?= _('Afficher le Garant') ?>">
#<?= $this->nettoyer($_SESSION['codeGcAssureur_C']) ?>
</a>
</div>
<button class="context-btn btn-primary-context"
onclick="javascript:afficher_garant('<?= $this->nettoyer($_SESSION['codeGcAssureur_C']) ?>');"
title="<?= _('Afficher le Garant') ?>">
<i class="fas fa-user-shield"></i>
<?= isset($_SESSION['nomGcAssureur_C']) ? htmlspecialchars($_SESSION['nomGcAssureur_C'], ENT_QUOTES) : '' ?>
</button>
</div>
</div>
<!-- ── SOUSCRIPTEUR ── -->
<div class="context-card">
<div class="context-card-label">
<i class="fas fa-user-tie"></i>
<?= _('Souscripteur') ?>
<a href="javascript:afficher_client_id();"
title="<?= _('Afficher le Souscripteur') ?>">
#<?= $this->nettoyer($_SESSION['numeroClient_C']) ?>
</a>
</div>
<button class="context-btn btn-primary-context"
onclick="javascript:afficher_client_id();">
<i class="fas fa-user-tie"></i>
<?= $this->nettoyer($_SESSION['nomClient_C']) ?>
</button>
</div>
<!-- ── POLICE ── -->
<div class="context-card">
<div class="context-card-label">
<i class="fas fa-file-contract"></i>
<?= _('Police en cours') ?>
</div>
<button class="context-btn btn-primary-context"
id="numeroPolice_C" name="numeroPolice_C"
onclick="javascript:afficher_police_id();"
title="<?= _('Couverture') . ': ' . dateLang($_SESSION['dateEffet_C'], $_SESSION['lang']) . ' → ' . dateLang($_SESSION['dateEcheance_C'], $_SESSION['lang']) ?>">
<i class="fas fa-file-contract"></i>
<?= _('Police') . ' : ' . $this->nettoyer($_SESSION['numeroPolice_C']) ?>
</button>
</div>
<!-- ── STATISTIQUES FAMILLE ── -->
<div class="context-stats">
<div class="context-stat">
<div class="context-stat-value"><?= format_N($_SESSION['ndAdh_C']) ?></div>
<div class="context-stat-label"><?= _('Fam.') ?></div>
</div>
<div class="context-stat">
<div class="context-stat-value"><?= format_N($_SESSION['ndDep_C']) ?></div>
<div class="context-stat-label"><?= _('Dép.') ?></div>
</div>
<div class="context-stat">
<div class="context-stat-value"><?= format_N($_SESSION['ndActif_C']) ?></div>
<div class="context-stat-label"><?= _('Bén.') ?></div>
</div>
</div>
<!-- ── ADHÉRENT ── -->
<div class="context-card">
<div class="context-card-label">
<i class="fas fa-users"></i>
<?= _('Famille en cours') ?>
<a href="javascript:afficher_adherent_id();" title="<?= _('Voir les membres de famille') ?>">
#<?= $this->nettoyer($_SESSION['numeroAdherent_C']) ?>
</a>
</div>
<button class="context-btn btn-primary-context"
onclick="javascript:afficher_adherent_id();"
id="numeroAdherent_C" name="numeroAdherent_C"
title="<?= _('Voir les membres de famille') ?>">
<i class="fas fa-users"></i>
<?= _('Famille') . ' : ' . $this->nettoyer($_SESSION['numeroAdherent_C']) ?>
</button>
<button class="context-btn mt-1"
onclick="javascript:afficher_adherent_id();">
<?= substr($this->nettoyer($_SESSION['adherent_C']), 0, 28) ?>
</button>
</div>
<!-- ── BÉNÉFICIAIRE ── -->
<div class="context-card">
<div class="context-card-label">
<i class="fas fa-user"></i>
<?= _('Bénéficiaire en cours') ?>
<a href="javascript:afficher_beneficiaire_id();">
#<?= $this->nettoyer($_SESSION['numeroBeneficiaire_C']) ?>
</a>
</div>
<button class="context-btn btn-primary-context"
onclick="javascript:afficher_beneficiaire_id();"
id="numeroBeneficiaire_C" name="numeroBeneficiaire_C"
title="<?= _('Couverture') . ': ' . dateLang($_SESSION['dateEntreeBeneficiaire_C'], $_SESSION['lang']) . ' → ' . dateLang($_SESSION['dateEcheancePolice_C'], $_SESSION['lang']) ?>">
<i class="fas fa-user"></i>
<?= _('Bénéficiaire') . ' : ' . $this->nettoyer($_SESSION['numeroBeneficiaire_C']) ?>
</button>
<button class="context-btn mt-1"
onclick="javascript:afficher_beneficiaire_id();">
<?= substr($this->nettoyer($_SESSION['beneficiaire_C']), 0, 28) ?>
</button>
</div>
<!-- ── PHOTO ── -->
<?php if ($_SESSION['faceRegistered_C'] == '1' && $_SESSION['idBeneficiaire_C'] > '0'): ?>
<div class="photo-container">
<img src="data:image/jpg;base64,<?= $imgData ?>"
class="img-fluid"
data-bs-toggle="modal"
data-bs-target="#pop_photo"
alt="<?= _('Photo du bénéficiaire') ?>"
title="<?= _('Cliquer pour agrandir') ?>">
</div>
<?php endif; ?>
<!-- ── DERNIÈRES POLICES ── -->
<?php if (!empty($_SESSION['contextPolice'])): ?>
<div class="mb-3">
<div class="recent-policies-title">
<i class="bi bi-clock-history"></i>
<?= _('Dernières polices ouvertes') ?>
</div>
<?php foreach ($_SESSION['contextPolice'] as $contextPolice):
$idPolice = $contextPolice['idPolice'];
$numeroPolice = $contextPolice['numeroPolice'];
?>
<a href="javascript:selectionner_police(<?= $idPolice ?>, '<?= $numeroPolice ?>'); afficher_police_id();"
class="policy-item"
title="<?= htmlspecialchars($contextPolice['libellePolice'] ?? '', ENT_QUOTES) ?>">
<i class="fas fa-file-medical-alt me-1" style="color:var(--color-primary);font-size:0.65rem;"></i>
<?= htmlspecialchars($contextPolice['libellePolice'] ?? $numeroPolice, ENT_QUOTES) ?>
</a>
<?php endforeach; ?>
</div>
<?php endif; ?>
<!-- ── MESSAGES ── -->
<button class="context-btn mb-2"
onclick="javascript:gerer_messagerie();"
style="border-color:var(--color-info);color:var(--color-info);">
<i class="fas fa-comments"></i>
<?= _('Gérer Messages') ?>
</button>
<!-- ── CHANGER MOT DE PASSE ── -->
<a href="javascript:change_password();"
class="change-pwd-link"
title="<?= isset($_SESSION['lang']) && $_SESSION['lang'] == 'en_US' ? 'Change password' : 'Changer le mot de passe' ?>">
<img src="Bootstrap_new/images/pwd.png" alt="mot de passe">
<span><?= isset($_SESSION['lang']) && $_SESSION['lang'] == 'en_US' ? 'Change Password' : 'Changer le mot de passe' ?></span>
</a>
<!-- ── MODE COTATION / DEVIS ── -->
<?php if ($_SESSION['modeDevis'] == '1'): ?>
<div class="mode-devis-banner">
<i class="fas fa-tag me-2"></i><?= _('GESTION DES COTATIONS') ?>
</div>
<div class="context-card">
<div class="context-card-label">
<i class="fas fa-user-times"></i>
<?= _('Prospect') ?>
</div>
<button class="context-btn btn-primary-context"
onclick="javascript:afficher_client_d_id();"
id="numeroClient_d_C" name="numeroClient_d_C">
<i class="fas fa-user-times"></i>
<?= _('Prospect') . ' : ' . $this->nettoyer($_SESSION['numeroClient_d_C']) ?>
</button>
<button class="context-btn mt-1" onclick="javascript:afficher_client_d_id();">
<?= substr($this->nettoyer($_SESSION['nomClient_d_C']), 0, 28) ?>
</button>
</div>
<div class="context-card">
<div class="context-card-label">
<i class="fas fa-file-signature"></i>
<?= _('Devis') ?>
</div>
<button class="context-btn btn-primary-context"
id="numeroPolice_d_C" name="numeroPolice_d_C"
onclick="javascript:afficher_police_d_id_init();">
<i class="fas fa-file-signature"></i>
<?= $this->nettoyer($_SESSION['numeroPolice_d_C']) ?>
</button>
</div>
<?php endif; ?>
<!-- Footer technique (timer, inputs cachés) -->
<footer class="container-fluid" style="padding:0 0 6px;">
<div id="nbMessagesNonLus" name="nbMessagesNonLus">
<input class="sr-only timer" id="timer" name="timer" type="button" value="0">
<input class="sr-only" id="msgNonLus" name="msgNonLus" type="text" value="0">
</div>
</footer>
</div><!-- /.drawer-inner -->
</div>
<!-- End Barre Latérale Contexte -->

View File

@ -1,101 +1,150 @@
<?php
$flag = (est_anglophone()) ? 'england.png' : 'france.png';
$alt = (est_anglophone()) ? 'English' : 'Français';
$lib = (est_anglophone()) ? 'En' : 'Fr';
/*
* INTER SANTÉ includes/header.php
* Header épuré SaaS Premium
*/
$flag = est_anglophone() ? 'england.png' : 'france.png';
$alt = est_anglophone() ? 'English' : 'Français';
$lib = est_anglophone() ? 'En' : 'Fr';
$styleTest = '';
$labelTest = '';
if ($_SESSION['bdTests_C'] == '1') {
$colorTests = $_SESSION['colorTests'];
$styleTest = "background: {$colorTests};";
$labelTest = '<span class="mode-test-badge">MODE TEST</span>';
}
?>
<header id="header" class="header">
<div class="header-left">
<a href="<?= $racineWeb ?>" class="logo">
<img src="Bootstrap_new/images/new/favicon.png" alt="Inter Santé">
<span class="brand-name">INTER SANTE</span>
<!-- ======= Header ======= -->
<header id="header" class="header fixed-top d-flex align-items-center <?= $_SESSION['bdTests_C'] == '1' ? 'header-test' : '' ?>" style="<?= $styleTest ?>">
<!-- Left: Logo + Toggle -->
<div class="d-flex align-items-center gap-2 me-3">
<a href="#" class="logo d-flex align-items-center text-decoration-none">
<img src="Bootstrap_new/images/new/favicon.png" alt="Logo Inter Santé">
<span class="d-none d-lg-block">INTER SANTÉ</span>
</a>
<i class="bi bi-list toggle-sidebar-btn" role="button" title="<?= _('Réduire / Étendre le menu') ?>"></i>
</div>
<!-- Center: Breadcrumb -->
<nav aria-label="breadcrumb" class="flex-grow-1 d-none d-md-block">
<ol class="breadcrumb mb-0">
<?php if (!empty($_SESSION['retourVue'])): ?>
<li class="breadcrumb-item">
<a href="<?= $_SESSION['retourVue'] ?>" class="d-flex align-items-center gap-1">
<i class="fas fa-arrow-left" style="font-size:0.65rem;"></i>
<?= htmlspecialchars($_SESSION['titreRetour'], ENT_QUOTES) ?>
</a>
<i class="bi bi-list toggle-sidebar-btn"></i>
</div>
</li>
<?php endif; ?>
<li class="breadcrumb-item active">
<?= htmlspecialchars($_SESSION['descriptionVue'] ?? '', ENT_QUOTES) ?>
</li>
</ol>
</nav>
<!-- BREADCRUMB - Navigation -->
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="<?= $_SESSION['retourVue'] ?? '#' ?>">
<i class="fas fa-arrow-left me-1"></i>
<?= htmlspecialchars($_SESSION['titreRetour'] ?? _('Retour')) ?>
</a>
</li>
<li class="breadcrumb-item active">
<?= htmlspecialchars($_SESSION['descriptionVue'] ?? '') ?>
</li>
</ol>
</nav>
<!-- Right: Navigation Items -->
<nav class="header-nav ms-auto">
<ul class="d-flex align-items-center gap-1 mb-0 list-unstyled">
<!-- ICONES DROITE -->
<nav class="header-nav ms-auto">
<ul class="d-flex align-items-center">
<!-- Mode test -->
<?php if ($_SESSION['bdTests_C'] == "1"): ?>
<li class="nav-item">
<span class="test-badge"><?= _("MODE TEST") ?></span>
</li>
<?php endif; ?>
<!-- Mode test indicator -->
<?php if (!empty($labelTest)): ?>
<li class="nav-item">
<span class="mode-test-badge" style="background:rgba(255,255,255,0.25);color:white;font-weight:800;font-size:0.65rem;letter-spacing:0.1em;padding:4px 10px;border-radius:999px;cursor:pointer;"
onclick="javascript:alert_ebene('TEST', 'TEST');">TEST</span>
</li>
<?php endif; ?>
<!-- Notifications -->
<li class="nav-item">
<a class="nav-link" href="javascript:pop_messagerie();" title="<?= _("Messages") ?>">
<i class="bi bi-bell"></i>
<span id="span_notification" class="badge-notification">0</span>
</a>
</li>
<!-- Notifications -->
<li class="nav-item">
<a class="nav-link nav-icon position-relative" href="#"
onclick="javascript:pop_messagerie(); return false;"
title="<?= _('Notifications') ?>">
<i class="bi bi-bell" style="font-size:1.1rem;"></i>
<span id="span_notification"
class="badge-number"
title="<?= _('Notification') ?>">0</span>
</a>
</li>
<!-- Logo société -->
<li class="nav-item">
<a class="nav-link d-flex align-items-center" href="javascript:infos_entite();"
title="<?= _("Gestionnaire d'assurance santé") ?>">
<img src="<?= $_SESSION['lienLogo'] ?>" alt="Logo" class="entity-logo">
<span class="entity-name"><?= $companyDisplayName ?></span>
</a>
</li>
<!-- Company Logo -->
<li class="nav-item d-none d-lg-flex">
<a class="company-logo-area text-decoration-none"
href="javascript:infos_entite();"
title="<?= _('Gestionnaire d\'assurance santé') ?>">
<img src="<?= $_SESSION['lienLogo'] ?>"
alt="<?= htmlspecialchars($_SESSION['nomSociete'], ENT_QUOTES) ?>">
<span class="company-name"><?= $companyDisplayName ?></span>
</a>
</li>
<!-- Langue -->
<li class="nav-item dropdown">
<a class="nav-link" href="#" data-bs-toggle="dropdown" title="<?= _("Changer la langue") ?>">
<img src="Bootstrap_new/images/<?= $flag ?>" alt="<?= $alt ?>" width="24" class="rounded-circle">
<span class="ms-1 d-none d-md-inline"><?= $lib ?></span>
</a>
<ul class="dropdown-menu dropdown-menu-end">
<li>
<a class="dropdown-item" href="javascript:changer_langue();">
<i class="fa fa-exchange me-2"></i><?= _("Changer de langue") ?>
</a>
</li>
</ul>
</li>
<!-- Aide -->
<li class="nav-item">
<a class="nav-link" href="Guideutilisation/" title="<?= _("Guide d'utilisation") ?>">
<i class="bi bi-question-circle"></i>
</a>
</li>
<!-- Profil -->
<li class="nav-item dropdown">
<a class="nav-link" href="#" data-bs-toggle="dropdown" title="<?= _("Mon profil") ?>">
<span class="user-initials"><?= $_SESSION['userInitials_C'] ?? 'U' ?></span>
</a>
<ul class="dropdown-menu dropdown-menu-end">
<li>
<a class="dropdown-item" href="javascript:change_password();">
<i class="fa fa-user-circle me-2"></i><?= $_SESSION['utilisateur_C'] ?? '' ?>
</a>
</li>
<li><hr class="dropdown-divider"></li>
<li>
<a class="dropdown-item" href="#">
<i class="bi bi-box-arrow-right me-2"></i><?= _("Déconnexion") ?>
</a>
</li>
</ul>
</li>
<!-- Language Switcher -->
<li class="nav-item dropdown">
<a class="nav-link d-flex align-items-center gap-1 lang-selector"
href="#"
data-bs-toggle="dropdown"
title="<?= _('Changer la langue actuelle') ?>">
<img src="Bootstrap_new/images/<?= $flag ?>" alt="<?= $alt ?>" width="22" class="rounded-1">
<span class="d-none d-md-block dropdown-toggle" style="font-size:0.78rem;font-weight:600;"><?= $lib ?></span>
</a>
<ul class="dropdown-menu dropdown-menu-end">
<li>
<a class="dropdown-item" href="javascript:changer_langue();">
<i class="fa fa-exchange"></i>
<?= _('Changer de langue') ?>
</a>
</li>
</ul>
</nav>
</header>
</li>
<!-- Help -->
<li class="nav-item">
<a class="nav-link nav-icon"
href="Guideutilisation/"
title="<?= _('Guide d\'utilisation') ?>">
<i class="bi bi-question-circle" style="font-size:1.05rem;"></i>
</a>
</li>
<!-- User Profile -->
<li class="nav-item dropdown">
<a class="nav-link d-flex align-items-center gap-2 pe-0"
href="#"
data-bs-toggle="dropdown"
title="<?= _('Profil utilisateur') ?>">
<span class="initials"><?= htmlspecialchars($_SESSION['userInitials_C'] ?? '??', ENT_QUOTES) ?></span>
<i class="bi bi-chevron-down d-none d-md-inline" style="font-size:0.6rem;color:var(--text-muted);"></i>
</a>
<ul class="dropdown-menu dropdown-menu-end" style="min-width:200px;">
<li>
<div class="px-3 py-2 border-bottom" style="border-color:var(--border-light)!important;">
<div style="font-weight:700;font-size:0.82rem;color:var(--text-primary);">
<?= htmlspecialchars($_SESSION['utilisateur_C'] ?? '', ENT_QUOTES) ?>
</div>
<div style="font-size:0.72rem;color:var(--text-muted);"><?= htmlspecialchars($_SESSION['nomSociete'] ?? '', ENT_QUOTES) ?></div>
</div>
</li>
<li>
<a class="dropdown-item" href="javascript:change_password();">
<i class="fa fa-user-circle"></i>
<?= _('Mon profil / Mot de passe') ?>
</a>
</li>
<li><hr class="dropdown-divider my-1"></li>
<li>
<a class="dropdown-item text-danger" href="#">
<i class="bi bi-box-arrow-right"></i>
<?= _('Déconnexion') ?>
</a>
</li>
</ul>
</li>
</ul>
</nav>
</header>
<!-- End Header -->

View File

@ -1,164 +1,171 @@
<?php
// Version pour le cache
$version = date('YmdHi');
?>
<!-- ======= Scripts Footer INTER SANTÉ ======= -->
<!-- IMPORTANT: Respecter strictement l'ordre de chargement -->
<!-- ================================================= -->
<!-- CHARGEMENT SÉQUENTIEL DES SCRIPTS -->
<!-- ================================================= -->
<!-- 1. Script spécifique à la société -->
<script src="<?= $_SESSION['dossierSociete'] . '/Js/societe.js' ?>"></script>
<!-- 1. jQuery en premier (TOUJOURS en premier) -->
<!-- 2. Vendor Libs (Bootstrap ecosystem) -->
<script src="Bootstrap/vendor/apexcharts/apexcharts.min.js"></script>
<script src="Bootstrap/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
<script src="Bootstrap/vendor/chart.js/chart.umd.js"></script>
<script src="Bootstrap/vendor/echarts/echarts.min.js"></script>
<script src="Bootstrap/vendor/quill/quill.min.js"></script>
<script src="Bootstrap/vendor/simple-datatables/simple-datatables.js"></script>
<script src="Bootstrap/vendor/php-email-form/validate.js"></script>
<!-- 3. jQuery (DOIT précéder tout le reste) -->
<script src="Bootstrap/js/jquery.min.js"></script>
<script src="Bootstrap/js/jquery-ui.js"></script>
<script src="Bootstrap/js/timer.jquery.js"></script>
<!-- 2. Bootstrap et ses dépendances -->
<script src="Bootstrap/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
<!-- 3. Plugins jQuery (Select2, etc.) -->
<!-- 4. Select2 & Bootstrap-Select -->
<script src="Bootstrap_new/js/select2.min.js"></script>
<script src="Bootstrap_new/select/js/bootstrap-select.min.js"></script>
<script src="Bootstrap_new/datatables/datatable.min.js"></script>
<!-- 4. Scripts principaux de l'application -->
<!-- 5. Template main -->
<script src="Bootstrap/js/main.js"></script>
<script src="Js/html2pdf.js"></script>
<script src="Bootstrap_new/datatables/datatable.min.js" crossorigin="anonymous"></script>
<!-- 5. FONCTIONS.JS - Contient raffraichir_messagerie et autres fonctions critiques -->
<script src="Js/fonctions.js?ver=<?= $version ?>"></script>
<!-- 6. Internationalisation (dépend de fonctions.js pour certaines fonctions) -->
<!-- 6. Datepicker selon langue -->
<?php if (est_anglophone()): ?>
<script src="Js/datepicker-eng.js"></script>
<script src="Js/datepicker-eng.js"></script>
<?php else: ?>
<script src="Js/datepicker-fr.js"></script>
<script src="Js/datepicker-fr.js"></script>
<?php endif; ?>
<!-- 7. Librairies tierces -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.js"></script>
<!-- 7. Utilitaires -->
<script src="Js/html2pdf.js"></script>
<!-- 8. Toastr notifications -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.css" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.js" crossorigin="anonymous"></script>
<!-- 9. SweetAlert2 -->
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11.14.1/dist/sweetalert2.all.min.js"></script>
<!-- 10. Fonctions applicatives Inter Santé -->
<script src="Js/fonctions.js?ver=<?= defined('APP_VERSION') ? APP_VERSION : date('YmdHi') ?>"></script>
<!-- 11. Vue.js -->
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<!-- 8. Script spécifique à la société -->
<script src="<?= $_SESSION['dossierSociete'] ?>/Js/societe.js"></script>
<!-- 12. Chart.js (dédupliqué déjà en head, mais conservé pour compatibilité) -->
<!-- <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> -->
<!-- ================================================= -->
<!-- INPUTS CACHÉS ESSENTIELS -->
<!-- ================================================= -->
<div style="display: none;">
<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="codeLangue" value="<?= $_SESSION['lang'] ?? 'fr_FR' ?>">
<input type="hidden" id="timer" value="0">
<input type="hidden" id="msgNonLus" value="0">
</div>
<!-- 13. Bootstrap JS -->
<script src="Bootstrap/js/bootstrap.min.js"></script>
<!-- ================================================= -->
<!-- DIV POUR AJAX -->
<!-- ================================================= -->
<!-- ===== Conteneur AJAX gabarit ===== -->
<div id="div_ajaxgabarit"></div>
<!-- ================================================= -->
<!-- SCRIPT D'INITIALISATION (APRÈS TOUS LES CHARGEMENTS) -->
<!-- ================================================= -->
<script>
// Attendre que le DOM soit complètement chargé et que toutes les fonctions soient disponibles
(function() {
// Fonction pour initialiser l'application
function initApp() {
console.log('Initialisation de l\'application...');
// Vérifier que jQuery est chargé
if (typeof jQuery === 'undefined') {
console.error('jQuery n\'est pas chargé !');
setTimeout(initApp, 100);
return;
}
// Vérifier que nos fonctions sont chargées
if (typeof raffraichir_messagerie === 'undefined') {
console.warn('raffraichir_messagerie pas encore disponible, nouvelle tentative dans 300ms...');
setTimeout(initApp, 300);
return;
}
// Une fois que tout est prêt, on initialise
$(document).ready(function() {
console.log('Tous les scripts sont chargés, initialisation...');
// Gestion du drawer de contexte
$('#showSideNav').on('click', function() {
$('#barre_laterale_d').addClass('show');
});
$('#hideSideNav').on('click', function() {
$('#barre_laterale_d').removeClass('show');
});
// Initialisation du timer pour la messagerie
if ($('#timer').length) {
try {
$('#timer').timer({
duration: '60s',
callback: function() {
console.log('Timer callback - rafraîchissement messagerie');
if (typeof raffraichir_messagerie === 'function') {
raffraichir_messagerie();
}
},
repeat: true
});
console.log('Timer initialisé avec succès');
} catch(e) {
console.error('Erreur lors de l\'initialisation du timer:', e);
}
}
// Initialisation des tooltips Bootstrap
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
tooltipTriggerList.map(function(tooltipTriggerEl) {
return new bootstrap.Tooltip(tooltipTriggerEl);
});
// Appel initial pour rafraîchir la messagerie
if (typeof raffraichir_messagerie === 'function') {
setTimeout(function() {
raffraichir_messagerie();
}, 1000); // Attendre 1 seconde avant le premier appel
}
<!-- ===== Initialisation applicative ===== -->
<script type="text/javascript">
/* Rafraîchissement du gabarit */
raffraichier_gabarit();
/* Timer messagerie (60s) */
$(document).ready(function () {
/* --- Panneau contexte : Drawer animé --- */
$('#barre_laterale_d').hide();
$('#showSideNav').hide(); // Masqué jusqu'au scroll ou action
// Afficher le bouton déclencheur après un court délai
setTimeout(function () {
$('#showSideNav').fadeIn(300);
}, 800);
// Ouverture du panneau
$('#showSideNav').on('click', function () {
$('#barre_laterale_d').stop(true).show('slide', { direction: 'right' }, 350);
$(this).fadeOut(150);
});
// Fermeture du panneau
$('#hideSideNav').on('click', function () {
$('#barre_laterale_d').stop(true).hide('slide', { direction: 'right' }, 350, function () {
$('#showSideNav').fadeIn(200);
});
});
// Fermeture en cliquant en dehors du panneau
$(document).on('click', function (e) {
if ($('#barre_laterale_d').is(':visible') &&
!$(e.target).closest('#barre_laterale_d, #showSideNav').length) {
$('#barre_laterale_d').stop(true).hide('slide', { direction: 'right' }, 300, function () {
$('#showSideNav').fadeIn(200);
});
}
});
/* --- Timer messagerie --- */
$('#timer').timer({
duration: '60s',
callback: function () {
raffraichier_messagerie();
},
repeat: true
});
/* --- Select2 global --- */
if ($.fn.select2) {
$('select.select2, .select-field').each(function () {
$(this).select2({ theme: 'bootstrap-5', width: '100%' });
});
}
// Démarrer l'initialisation
initApp();
})();
/* --- Bootstrap Select global --- */
if ($.fn.selectpicker) {
$('select.selectpicker').selectpicker('refresh');
}
/* --- Sidebar toggle responsive --- */
$('.toggle-sidebar-btn').on('click', function () {
$('body').toggleClass('toggle-sidebar');
// Sur mobile, slide le sidebar
if ($(window).width() < 1200) {
$('#sidebar').toggleClass('sidebar-open');
}
});
/* --- Highlight ligne active DataTable au clic --- */
$(document).on('click', '.table tbody tr', function () {
$(this).closest('tbody').find('tr').removeClass('row-selected');
$(this).addClass('row-selected');
});
/* --- Toastr config globale --- */
if (typeof toastr !== 'undefined') {
toastr.options = {
positionClass: 'toast-top-right',
timeOut: 4000,
closeButton: true,
progressBar: true,
preventDuplicates: true,
newestOnTop: true
};
}
}); // end document.ready
</script>
<!-- ================================================= -->
<!-- SCRIPT DE SECOURS SI FONCTIONS.JS N'EST PAS CHARGÉ -->
<!-- ================================================= -->
<script>
// Définition des fonctions critiques si elles n'existent pas (fallback)
window.raffraichir_messagerie = window.raffraichir_messagerie || function() {
console.log('Fallback: raffraichir_messagerie appelée');
// Faire un appel AJAX simple pour récupérer les messages
if (typeof jQuery !== 'undefined') {
$.ajax({
url: '/ajax/messagerie.php',
method: 'GET',
success: function(data) {
$('#span_notification').text(data.nbNonLus || '0');
},
error: function() {
console.error('Erreur lors du rafraîchissement de la messagerie');
}
});
}
};
<!-- Style additionnel pour la ligne sélectionnée dans les tables -->
<style>
.table tbody tr.row-selected > td {
background: rgba(26, 107, 74, 0.08) !important;
border-left: 3px solid var(--color-accent, #0abf7c);
}
window.pop_messagerie = window.pop_messagerie || function() {
console.log('Fallback: pop_messagerie appelée');
$('#btn_pop_messagerie').click();
};
</script>
/* Sidebar toggle body class */
body.toggle-sidebar #sidebar { width: var(--sidebar-collapsed, 68px); }
body.toggle-sidebar #sidebar .nav-link span,
body.toggle-sidebar #sidebar .nav-link .bi-chevron-down,
body.toggle-sidebar #sidebar .sidebar-section-label { display: none; }
body.toggle-sidebar #main { margin-left: var(--sidebar-collapsed, 68px); }
body.toggle-sidebar #sidebar .nav-link { justify-content: center; padding: 10px; }
body.toggle-sidebar #sidebar .nav-link i:first-child { font-size: 1.2rem; width: auto; }
body.toggle-sidebar #sidebar .nav-content { display: none !important; }
</style>
</body>
</html>

View File

@ -1,47 +1,91 @@
<aside id="sidebar" class="sidebar">
<div class="sidebar-brand">
<img src="Bootstrap_new/images/new/favicon.png" alt="Inter Santé">
<span>INTER SANTE</span>
</div>
<?php
/*
* INTER SANTÉ includes/sidebar.php
* Sidebar navigation moderne avec micro-animations
*/
?>
<ul class="sidebar-nav">
<?php foreach ($menus as $menuParent):
$menuChildren = $gabary->get_menus_by_parent_code($menuParent['vue']);
$hasChildren = !empty($menuChildren);
$isActive = (strtolower($menuParent['libeleMenu']) == strtolower($activeLevel1));
?>
<li class="nav-item">
<?php if ($hasChildren): ?>
<a class="nav-link <?= $isActive ? '' : 'collapsed' ?>"
data-bs-target="#menu-<?= $menuParent['codeMenu'] ?>"
data-bs-toggle="collapse"
href="#"
title="<?= htmlspecialchars($menuParent['libeleMenu']) ?>">
<i class="<?= $menuParent['icone'] ?>"></i>
<span><?= htmlspecialchars($menuParent['libeleMenu']) ?></span>
<i class="bi bi-chevron-down ms-auto"></i>
</a>
<ul id="menu-<?= $menuParent['codeMenu'] ?>"
class="nav-content collapse <?= $isActive ? 'show' : '' ?>">
<?php foreach ($menuChildren as $child): ?>
<li>
<a href="<?= $child['lienMenu'] ?>"
title="<?= htmlspecialchars($child['descriptionMenu'] ?? '') ?>">
<i class="bi bi-circle"></i>
<span><?= htmlspecialchars($child['libeleMenu']) ?></span>
</a>
</li>
<?php endforeach; ?>
</ul>
<?php else: ?>
<a class="nav-link <?= ($menuParent['lienMenu'] == $current_url) ? 'active' : '' ?>"
href="<?= $menuParent['lienMenu'] ?>"
title="<?= htmlspecialchars($menuParent['libeleMenu']) ?>">
<i class="<?= $menuParent['icone'] ?>"></i>
<span><?= htmlspecialchars($menuParent['libeleMenu']) ?></span>
</a>
<?php endif; ?>
</li>
<?php endforeach; ?>
</ul>
</aside>
<!-- ======= Sidebar ======= -->
<aside id="sidebar" class="sidebar">
<ul class="sidebar-nav" id="sidebar-nav">
<?php foreach ($menus as $key0 => $menuParent):
$menuChildrenLevelOne = $gabary->get_menus_by_parent_code($menuParent['vue']);
$hasChildren = sizeof($menuChildrenLevelOne) > 0;
$parentLink = explode('/', $menuParent['lienMenu'])[0];
$isActive = strtolower($menuParent['libeleMenu']) == strtolower($activeLevel1)
|| $parentLink == $activeLevel1;
?>
<?php if ($hasChildren): ?>
<!-- Menu parent avec sous-menus -->
<li class="nav-item">
<a class="nav-link collapsed <?= $isActive ? 'parent-active' : '' ?>"
data-bs-target="#nav-<?= $menuParent['codeMenu'] . $key0 ?>"
data-bs-toggle="collapse"
href="#"
aria-expanded="<?= $isActive ? 'true' : 'false' ?>">
<i class="<?= htmlspecialchars($menuParent['icone'], ENT_QUOTES) ?>"></i>
<span class="<?= $isActive ? 'active-main' : '' ?>">
<?= htmlspecialchars($menuParent['libeleMenu'], ENT_QUOTES) ?>
</span>
<i class="bi bi-chevron-down ms-auto"></i>
</a>
<ul id="nav-<?= $menuParent['codeMenu'] . $key0 ?>"
class="nav-content collapse <?= $isActive ? 'show' : '' ?>"
data-bs-parent="#sidebar-nav">
<?php foreach ($menuChildrenLevelOne as $key1 => $menuChild):
$linkClean = explode('/', $menuChild['lienMenu'])[0];
$activeLink = $_SESSION['firstLevelMenu'];
$isSubActive = $linkClean == $activeLink;
?>
<li>
<a href="<?= htmlspecialchars($menuChild['lienMenu'], ENT_QUOTES) ?>"
class="<?= $isSubActive ? 'active-submenu' : '' ?>"
title="<?= htmlspecialchars($menuChild['libeleMenu'], ENT_QUOTES) ?>">
<span><?= htmlspecialchars($menuChild['libeleMenu'], ENT_QUOTES) ?></span>
</a>
</li>
<?php endforeach; ?>
</ul>
</li>
<?php else: ?>
<!-- Menu parent sans sous-menus (lien direct) -->
<li class="nav-item">
<a class="nav-link collapsed <?= $isActive ? 'parent-active' : '' ?>"
href="<?= htmlspecialchars($menuParent['lienMenu'], ENT_QUOTES) ?>">
<i class="<?= htmlspecialchars($menuParent['icone'], ENT_QUOTES) ?>"></i>
<span><?= htmlspecialchars($menuParent['libeleMenu'], ENT_QUOTES) ?></span>
</a>
</li>
<?php endif; ?>
<?php endforeach; ?>
</ul>
</aside>
<!-- End Sidebar -->
<style>
/* Sidebar — styles inline spécifiques au composant */
#sidebar { background: var(--bg-sidebar, #0f2d20); }
/* Active parent: highlight subtle */
#sidebar .nav-link.parent-active {
background: rgba(255,255,255,0.08);
color: white;
}
#sidebar .nav-link.parent-active > i:first-child {
color: var(--color-accent, #0abf7c);
}
</style>