templates/base.html.twig line 1
{# templates/layout/management_workspace.html.twig #}<!doctype html><html lang="en"><head><!-- Required meta tags --><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><!-- Site Title --><title>Smart-Immo | Management</title><!-- Favicon --><link rel="shortcut icon" href="{{ asset('assets/img/smartimmoManagementHead.png') }}" type="image/x-icon">{# === Vendor & App CSS (same stack as Espace Agent) === #}<link href="{{ asset('assets/vendor/bootstrap/dist/css/bootstrap.min.css') }}" rel="stylesheet"><link href="{{ asset('assets/vendor/icons/css/materialdesignicons.min.css') }}" rel="stylesheet"><link rel="stylesheet" href="{{ asset('assets/vendor/date-picker/date-picker.css') }}"><link rel="stylesheet" type="text/css" href="{{ asset('assets/vendor/slick/slick.min.css') }}" /><link rel="stylesheet" type="text/css" href="{{ asset('assets/vendor/slick/slick-theme.min.css') }}" /><link href="{{ asset('assets/css/style.css') }}" rel="stylesheet"><link href="{{ asset('assets/admin/css/dasboard.css') }}" rel="stylesheet"><link href="{{ asset('assets/admin/css/menu.css') }}" rel="stylesheet"> {# add this last #}<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script><link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" /><script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script><script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" defer></script><style type="text/css" media="print">.no-print { display: none; }</style><style>.logo {filter: brightness(0) saturate(100%) invert(23%) sepia(89%) saturate(2111%) hue-rotate(209deg) brightness(91%) contrast(97%);}</style><style>.loader-inner.ball-pulse > div{width:12px;height:12px;margin:0 4px;display:inline-block;border-radius:50%;background:#2C5FD7;animation:ball-pulse 1s infinite ease-in-out;}.loader-inner.ball-pulse > div:nth-child(2){animation-delay:.2s}.loader-inner.ball-pulse > div:nth-child(3){animation-delay:.4s}@keyframes ball-pulse{0%,80%,100%{transform:scale(0)}40%{transform:scale(1)}}</style>{# optional page-level styles #}{% block style %}{% endblock %}</head><body class="bg-light"><div class="container-fluid p-0"><div class="row g-0 position-relative align-items-start">{# ========== Offcanvas (mobile sidebar) ========== #}<div class="offcanvas offcanvas-start admin-offcanvas" tabindex="-1" id="adminSidebar" aria-labelledby="adminSidebarLabel"><div class="offcanvas-header"><a href="{{ path('app_dashboard') }}" class="text-decoration-none d-flex align-items-center gap-2"><img src="{{ asset('assets/img/smartImmoManagement.png') }}" alt="Smart-Immo" class="logo" style="max-width:160px;height:auto;"></a><button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Fermer"></button></div><div class="offcanvas-body p-0"><nav class="admin-nav w-100" role="navigation" aria-label="Menu principal"><div class="nav-section">Menu</div><a class="nav-link{% if app.request.pathinfo == '/admin' %} is-active{% endif %}"href="{{ path('app_dashboard') }}"><span class="mdi mdi-view-dashboard"></span> Tableau de bord</a><a class="nav-link {% if app.request.pathinfo starts with "/admin/entreprise" %} active{% endif %}" href="{{ path('app_entreprise') }}"><span class="mdi mdi-office-building-outline"></span> Entreprises</a><a class="nav-link {% if app.request.pathinfo starts with "/admin/account" %} active{% endif %}" href="{{ path('admin_accounts_index') }}"><span class="mdi mdi-folder-multiple"></span> Comptes</a><a class="nav-link {% if app.request.pathinfo starts with "/admin/sms" %} active{% endif %}" href="{{ path('app_sms_config_index') }}"><span class="mdi mdi-message-bookmark"></span> SMS</a><a href="{{ path('app_habitat') }}" class="nav-link{% if app.request.pathinfo starts with "/admin/biens" %} active{% endif %}"><span class="mdi mdi-home"></span>Biens immobiliers</a><a href="{{ path('app_profil') }}" class="nav-link {% if app.request.pathinfo starts with "/admin/profil/information" %} active{% endif %}"><i class="demo-pli-male-female fs-5 me-2"></i><span class="nav-label mininav-content ms-1">Mon profil</span></a><a class="nav-link" href="{{ path('app_logout') }}"><span class="mdi mdi-logout"></span> Déconnexion</a></nav></div></div>{# ========== Sidebar (desktop) ========== #}<aside class="col-lg-2 d-none d-lg-block admin-sidebar"><nav class="admin-nav"><div class="brand"><a href="{{ path('app_dashboard') }}" class="text-decoration-none"><img src="{{ asset('assets/img/smartImmoManagement.png') }}" alt="Smart-Immo" class="logo"></a></div><div class="mainnav__profile mt-2 d-flex align-items-center flex-column text-center"><div class="mininav-toggle py-2"><img class="mainnav__avatar rounded-circle border"src="{{ asset('assets/img/imageIcon.png') }}"alt="Profile Picture"style="width:60px; height:60px; object-fit:cover;"></div><div class="d-mn-max w-100"><div class="d-grid"><div class="btn shadow-none p-2 d-flex flex-column align-items-center"><p class="mb-1"><span class="text-gray-500">Utilisateur:</span><strong>{% if is_granted('IS_AUTHENTICATED') and app.user.username is not null %}{{ app.user.username }}{% endif %}</strong></p><small class="text-success">{% if is_granted('IS_AUTHENTICATED') %}{{ app.user.role }}{% endif %}</small></div><div id="usernav" class="nav flex-column collapse"><a href="{{ path('app_logout') }}" class="nav-link d-flex align-items-center justify-content-center"><i class="demo-pli-unlock fs-5 me-2"></i><span>Logout</span></a></div></div></div></div><div class="nav-section">Menu</div><a class="nav-link{% if app.request.pathinfo == '/admin' %} is-active{% endif %}" href="{{ path('app_dashboard') }}"><span class="mdi mdi-view-dashboard"></span> Tableau de bord</a><a class="nav-link {% if app.request.pathinfo starts with "/admin/entreprise" %} active{% endif %}" href="{{ path('app_entreprise') }}"><span class="mdi mdi-office-building-outline"></span> Entreprises</a><a class="nav-link {% if app.request.pathinfo starts with "/admin/account" %} active{% endif %}" href="{{ path('admin_accounts_index') }}"><span class="mdi mdi-folder-multiple"></span> Comptes</a><a class="nav-link {% if app.request.pathinfo starts with "/admin/settings/sms" %} active{% endif %}" href="{{ path('app_sms_config_index') }}"><span class="mdi mdi-message"></span> SMS</a><a href="{{ path('app_habitat') }}" class="nav-link{% if app.request.pathinfo starts with "/admin/biens" %} active{% endif %}"><span class="mdi mdi-home"></span>Biens immobiliers</a><a href="{{ path('app_profil') }}" class="nav-link {% if app.request.pathinfo starts with "/admin/profil" %} active{% endif %}"><span class="mdi mdi-account"></span>Mon profil</a>{% if is_granted('ROLE_ADMIN') %}<a href="{{ path('app_user_index') }}" class="nav-link {% if app.request.pathinfo starts with "/admin/user" %} active{% endif %}"><span class="mdi mdi-account-multiple"></span>Utilisateurs</a>{% endif %}<a class="nav-link" href="{{ path('app_logout') }}"><span class="mdi mdi-logout"></span> Déconnexion</a></nav></aside>{# ========== Content ========== #}<div class="col-lg-10 content-dashboard p-3 p-lg-4">{# Top bar #}<!-- Sticky Top Bar Card --><div class="topbar-card topbar-sticky mb-3"><div class="row gx-3 gy-3 align-items-center"><div class="col-6 d-flex align-items-center"><div class="toggle me-2 d-lg-none"><button class="btn bg-white rounded-3 px-2 py-1" type="button"data-bs-toggle="offcanvas" data-bs-target="#adminSidebar" aria-controls="adminSidebar"><i class="mdi mdi-menu fs-5"></i></button></div>{% set hour = "now"|date("G") %}{% set greet = hour < 12 ? 'Bonjour' : (hour < 18 ? 'Bon après-midi' : 'Bonsoir') %}<span class="greet-chip d-none d-md-inline-flex align-items-center me-3" aria-live="polite"><i class="mdi mdi-emoticon-happy-outline me-1"></i>{{ greet }}{% if is_granted('IS_AUTHENTICATED') and app.user and app.user.name is defined and app.user.name %}, {{ app.user.lastname }}{% endif %} 👋</span><!-- Live Clock --><span id="live-clock" class="badge bg-light text-dark border ms-2">--:--:--</span></div><div class="col-6 d-flex justify-content-end align-items-center"><div class="dropdown profile-dropdown"><button class="btn bg-white rounded-9 btn-sm d-flex align-items-center dropdown-toggle py-1 ps-1 pe-2"type="button" id="dropdownMenuButton1" data-bs-toggle="dropdown" aria-expanded="false">{% if is_granted('IS_AUTHENTICATED') %}<img src="{{ asset('assets/img/imageIcon.png') }}" class="img-fluid rounded-9" alt="">{% endif %}<span class="ms-2 me-1">{{ app.user.name }}</span></button><ul class="dropdown-menu border-0 rounded-9 dropdown-menu-end" aria-labelledby="dropdownMenuButton1"><li><a class="dropdown-item" href="{{ path('app_profil') }}"><span class="mdi mdi-account"></span> Mon profil</a></li><li><a class="dropdown-item" href="{{ path('app_logout') }}"><span class="mdi mdi-logout"></span> Logout</a></li></ul></div></div></div></div>{# Toasts (ported) #}<div aria-live="polite" aria-atomic="true" class="position-relative"><div class="toast-container position-fixed top-0 end-0 p-3" style="z-index: 2000;">{% set levels = {'info':'info', 'success':'success', 'warning':'warning', 'error':'danger'} %}{% for level, bs in levels %}{% for message in app.session.flashBag.get(level) %}<div class="toast align-items-center text-bg-{{ bs }} border-0"role="alert" aria-live="assertive" aria-atomic="true"data-bs-delay="4000"><div class="d-flex"><div class="toast-body">{{ message|raw }}</div><button type="button" class="btn-close btn-close-white me-2 m-auto"data-bs-dismiss="toast" aria-label="Fermer"></button></div></div>{% endfor %}{% endfor %}</div></div><div class="dashboard-content pt-2 pt-lg-3">{% block bodyHeader %}{% endblock %}{% block bodyContent %}{% endblock %}</div><footer class="mt-auto py-3"><div class="d-flex flex-column flex-md-row align-items-md-center"><div class="text-nowrap mb-2 mb-md-0 small">Copyright © {{ "now"|date("Y") }}<a href="https://smarttech-rdc.com" class="ms-1 btn-link fw-bold">Smart-Technology</a></div></div></footer></div>{# /Content #}</div></div>{# ========== Modal AJAX loader ========== #}<div class="modal fade" id="modalCenter" tabindex="-1" aria-labelledby="modalCenterTitle" aria-hidden="true"><div class="modal-dialog modal-lg modal-dialog-centered"><div class="modal-content shadow-lg rounded-4 border-0">{# Header with subtle background #}<div class="modal-header bg-light border-0 rounded-top-4"><h5 class="modal-title fw-semibold text-primary" id="modalCenterTitle">Chargement en cours</h5><button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fermer"></button></div>{# Dynamic content wrapper #}<div id="modal-content-ajax"><div class="modal-body d-flex justify-content-center align-items-center flex-column py-5"><div class="spinner-border text-primary mb-3" role="status" style="width: 3rem; height: 3rem;"><span class="visually-hidden">Chargement...</span></div><p class="text-muted small mb-0">Veuillez patienter...</p></div></div></div></div></div>{# ========== JS Config & loaders ========== #}<script>class Config {constructor() {this.basePath = '{{ app.request.basepath }}';Object.seal(this);}}var config = new Config();var loader = `<div class="d-flex justify-content-center align-items-center flex-column py-3"><div class="spinner-border text-primary mb-3" role="status" style="width: 3rem; height: 3rem;"><span class="visually-hidden">Chargement...</span></div><p class="text-muted small mb-0">Veuillez patienter...</p></div>`;var loaderNode = document.createElement("img");loaderNode.src = config.basePath + "/assets/img/ajax-loader.gif";var modalLoader = '<div class="modal-body">' + loader + '</div>';</script>{# === Footer scripts (same stack as Espace Agent) === #}{#<script src="{{ asset('assets/vendor/bootstrap/dist/js/bootstrap.bundle.min.js') }}"></script>#}{#<script type="text/javascript" src="{{ asset('assets/vendor/slick/slick.min.js') }}"></script>#}{#<script src="{{ asset('assets/vendor/date-picker/date-picker.js') }}"></script>#}{##}{#<script type="text/javascript" src="{{ asset('assets/js/bodyevents.js') }}"></script>#}<script src="{{ asset('assets/js/ajax_1.0.1.js') }}"></script><script src="{{ asset('assets/js/settings.js') }}"></script>{#<script src="{{ asset('assets/js/osahan.js') }}"></script>#}<script>function updateClock(){const now = new Date();const h = String(now.getHours()).padStart(2,'0');const m = String(now.getMinutes()).padStart(2,'0');const s = String(now.getSeconds()).padStart(2,'0');document.getElementById('live-clock').textContent = `${h}:${m}:${s}`;}setInterval(updateClock,1000);updateClock();</script>{# Auto-show toasts #}<script>(function () {const run = () => {if (!window.bootstrap) return;document.querySelectorAll('.toast').forEach(el => bootstrap.Toast.getOrCreateInstance(el).show());};if (document.readyState === 'loading') {document.addEventListener('DOMContentLoaded', run);} else {run();}})();</script>{# optional page-level scripts #}{% block javascripts %}{% endblock %}</body></html>