templates/partenaires/index.html.twig line 1
{% extends 'base.html.twig' %}{% block style %}Partenaires de santé | CAREN{% endblock %}{% block body %}<style>/* ── Hero image ── */.ps-hero-img {width: 100%; height: 40vh; object-fit: cover; display: block;}.ps-hero-wrap {position: relative; overflow: hidden;}.ps-hero-overlay {position: absolute; inset: 0;display: flex; flex-direction: column;align-items: center; justify-content: center;text-align: center; padding: 1rem;}.ps-hero-overlay h1 {font-family: 'Poppins', sans-serif; font-weight: 700;font-size: 2rem; color: #fff; margin-bottom: .4rem;}.ps-hero-overlay p {color: rgba(255,255,255,.78); font-size: .9rem; margin-bottom: 1.25rem;}/* ── Bouton recherche hero ── */.btn-search-toggle {display: inline-flex; align-items: center; gap: .5rem;padding: .55rem 1.6rem; border-radius: 50px;background: #fff; color: #2a1266;font-weight: 600; font-size: .85rem; border: none;box-shadow: 0 4px 20px rgba(0,0,0,.18);transition: transform .2s, box-shadow .2s;cursor: pointer;}.btn-search-toggle:hover {transform: translateY(-2px);box-shadow: 0 8px 28px rgba(0,0,0,.22);}.btn-search-toggle .bi { font-size: 1rem; }/* ── Search bar inline dans hero ── */.hero-search-box {display: none; width: 100%; max-width: 520px;margin-top: .75rem; animation: fadeSlideDown .25s ease;}.hero-search-box.open { display: flex; }@keyframes fadeSlideDown {from { opacity: 0; transform: translateY(-8px); }to { opacity: 1; transform: translateY(0); }}.hero-search-box .form-control {border-radius: 12px 0 0 12px; border: none;padding: .6rem 1rem; font-size: .88rem;box-shadow: 0 4px 20px rgba(0,0,0,.15);}.hero-search-box .form-control:focus { box-shadow: none; outline: none; }.hero-search-box .btn-go {border-radius: 0 12px 12px 0; background: #2a1266;border: none; color: #fff; padding: .6rem 1.1rem;display: flex; align-items: center; gap: .35rem;font-size: .85rem; cursor: pointer;box-shadow: 0 4px 20px rgba(0,0,0,.15);transition: background .2s;}.hero-search-box .btn-go:hover { background: #1e0d4e; }/* ── Tabs ── */.ps-tab-bar {background: #fff;border-bottom: 2px solid #f0edf8;padding: 0 1rem;overflow-x: auto;-webkit-overflow-scrolling: touch;scrollbar-width: none;}.ps-tab-bar::-webkit-scrollbar { display: none; }.ps-tab-bar .nav { flex-wrap: nowrap; min-width: max-content; }.ps-tab-bar .nav-link {border: none; border-radius: 0;padding: .85rem clamp(.5rem, 2vw, 1.3rem);font-family: 'Poppins', sans-serif;font-size: clamp(.65rem, 1.5vw, .78rem);font-weight: 600; letter-spacing: .04em; text-transform: uppercase;color: #a098be; position: relative; white-space: nowrap;display: flex; align-items: center; gap: .4rem;transition: color .2s; background: none;}.ps-tab-bar .nav-link::after {content: ''; position: absolute; bottom: -2px; left: 0; right: 0;height: 2.5px; background: #2a1266; border-radius: 2px;transform: scaleX(0); transition: transform .25s;}.ps-tab-bar .nav-link.active { color: #2a1266; }.ps-tab-bar .nav-link.active::after { transform: scaleX(1); }.ps-tab-bar .nav-link:hover { color: #2a1266; background: none; }.ps-tab-bar .nav-link .bi { font-size: clamp(.85rem, 2vw, 1.05rem); flex-shrink: 0; }.ps-tab-bar .nav-link .tab-label { overflow: hidden; text-overflow: ellipsis; max-width: 18ch; }.tab-count {background: #ede9f8; color: #6a5aaa;font-size: .6rem; font-weight: 600;padding: 1px 6px; border-radius: 20px; flex-shrink: 0;}.ps-tab-bar .nav-link.active .tab-count { background: #2a1266; color: #fff; }/* Très petits écrans : icône seule, libellé masqué */@media (max-width: 300px) {.ps-tab-bar .nav-link .tab-label { display: none; }.ps-tab-bar .nav-link { padding: .75rem .9rem; }.tab-count { display: none; }}/* ── Content ── */.ps-content { background: #f8f7fc; padding: 2rem 0 4rem; min-height: 55vh; }/* ── Cards ── */.ps-card {border: 1.5px solid #ede9f8; border-radius: 14px;background: #fff; height: 100%; overflow: hidden;transition: transform .2s, box-shadow .2s, border-color .2s;}.ps-card:hover {transform: translateY(-4px);box-shadow: 0 14px 36px rgba(42,18,102,.11), 0 2px 6px rgba(42,18,102,.06);border-color: #c8bfee;}.ps-card .card-top-bar {height: 3px;background: linear-gradient(90deg, #2a1266 0%, #7c5cbf 100%);}.ps-card .card-body { padding: 1.1rem 1.2rem .85rem; }.ps-card .card-icon {width: 36px; height: 36px; border-radius: 14px;background: rgba(42,18,102,.06);display: flex; align-items: center; justify-content: center; flex-shrink: 0;padding: 6px;}.ps-card .card-icon img {width: 100%; height: 100%; object-fit: contain;}.ps-card .card-name {font-family: 'Poppins', sans-serif; font-weight: 700;font-size: .9rem; color: #0d0820; line-height: 1.3;}.ps-card .card-addr {font-size: .75rem; color: #9896b8; margin-top: 2px;display: flex; align-items: center; gap: .25rem;}.ps-card .info-list {margin-top: .6rem; padding-top: .6rem;border-top: 1px solid #f0edf8;}.ps-card .info-row {display: flex; align-items: center; gap: .45rem;font-size: .79rem; color: #6a6890; padding: .12rem 0;}.ps-card .info-row .bi { font-size: .85rem; color: #2a1266; flex-shrink: 0; }.ps-card .info-row a { color: #2a1266; text-decoration: none; font-weight: 500; }.ps-card .info-row a:hover { text-decoration: underline; }.ps-card .card-footer-btns {padding: .7rem 1.2rem; border-top: 1px solid #f0edf8;background: #faf9fe; display: flex; gap: .45rem;}.ps-card .card-footer-btns .btn-action {flex: 1; font-size: .75rem; font-weight: 500;border-radius: 8px; padding: .38rem .5rem;display: flex; align-items: center; justify-content: center; gap: .3rem;border: 1.5px solid #e0daf0; color: #2a1266; background: #fff;text-decoration: none; transition: background .18s, border-color .18s;}.ps-card .card-footer-btns .btn-action:hover {background: rgba(42,18,102,.07); border-color: #b9b0e0;}.ps-card .card-footer-btns .btn-action .bi { font-size: .88rem; }/* ── Empty ── */.ps-empty { text-align: center; padding: 3.5rem 1rem; color: #b0adcc; }.ps-empty .bi { font-size: 3rem; display: block; margin-bottom: .75rem; color: #ddd9ef; }/* ── Pagination ── */.ps-pag-bar {margin-top: 1.75rem; display: flex;justify-content: space-between; align-items: center;flex-wrap: wrap; gap: .5rem;}.ps-pag-bar .pg-info { font-size: .8rem; color: #9896b8; }.ps-pag-bar .pagination { margin: 0; }.ps-pag-bar .page-link {color: #2a1266; border-color: #e0daf0;font-size: .82rem; padding: .3rem .65rem;border-radius: 8px !important; margin: 0 2px;}.ps-pag-bar .page-item.active .page-link {background: #2a1266; border-color: #2a1266; color: #fff;}.ps-pag-bar .page-link:hover:not(.active) { background: rgba(42,18,102,.07); }.ps-pag-bar .page-item.disabled .page-link { opacity: .4; }</style>{# ── Hero ── #}<div class="ps-hero-wrap wow fadeIn" data-wow-delay="0.1s"><img class="ps-hero-img" src="{{ asset('assets/img/IMAGE4.jpg') }}" alt="Partenaires de santé" /><div class="ps-hero-overlay"><h1><i class="bi bi-heart-pulse-fill me-2"></i>Partenaires de santé</h1><p>Pharmacies, cliniques et établissements conventionnés avec CAREN</p>{# Bouton qui révèle la recherche #}<button class="btn-search-toggle" id="heroSearchToggle" onclick="toggleHeroSearch()"><i class="bi bi-search"></i> Rechercher un partenaire</button><div class="hero-search-box" id="heroSearchBox"><input type="text" id="heroSearchInput" class="form-control"placeholder="Nom ou adresse du partenaire…"oninput="applyHeroSearch()" onkeydown="if(event.key==='Escape') closeHeroSearch()"><button class="btn-go" onclick="applyHeroSearch()"><i class="bi bi-search"></i> Rechercher</button></div></div></div>{# ── Tabs bar ── #}{% if partenaires_by_type is not empty %}<div class="ps-tab-bar shadow-sm"><div class="container"><ul class="nav" id="psTabs">{% for typeLibelle, partenaires in partenaires_by_type %}{% set tid = loop.index %}<li class="nav-item"><button class="nav-link {% if loop.first %}active{% endif %}"data-tid="{{ tid }}"data-bs-toggle="tab"data-bs-target="#panel{{ tid }}"type="button">{% if typeLibelle|lower == 'pharmacie' %}<i class="bi bi-capsule"></i>{% elseif typeLibelle|lower in ['clinique','hôpital','hopital','polyclinique'] %}<i class="bi bi-hospital"></i>{% elseif typeLibelle|lower in ['laboratoire','labo'] %}<i class="bi bi-eyedropper"></i>{% elseif typeLibelle|lower in ['dentiste','cabinet dentaire'] %}<i class="bi bi-emoji-smile"></i>{% elseif typeLibelle|lower in ['opticien','optique'] %}<i class="bi bi-eyeglasses"></i>{% else %}<i class="bi bi-building-plus"></i>{% endif %}<span class="tab-label">{{ typeLibelle }}</span><span class="tab-count">{{ partenaires|length }}</span></button></li>{% endfor %}</ul></div></div>{% endif %}{# ── Content ── #}<div class="ps-content"><div class="container">{% if partenaires_by_type is empty %}<div class="ps-empty"><i class="bi bi-building-slash"></i><p class="mb-0">Aucun partenaire de santé enregistré pour le moment.</p></div>{% else %}<div class="tab-content" id="psTabContent">{% for typeLibelle, partenaires in partenaires_by_type %}{% set tid = loop.index %}{% set tlower = typeLibelle|lower %}{% if tlower == 'pharmacie' %}{% set icon_file = 'pharmacie1.png' %}{% elseif tlower in ['clinique','polyclinique'] %}{% set icon_file = 'clinique1.png' %}{% elseif tlower in ['hôpital','hopital','hopitaux'] %}{% set icon_file = 'hopital1.png' %}{% else %}{% set icon_file = 'cabinet-medical1.png' %}{% endif %}<div class="tab-pane fade {% if loop.first %}show active{% endif %}"id="panel{{ tid }}" role="tabpanel"><div class="row g-3" id="grid{{ tid }}">{% for p in partenaires %}<div class="col-sm-6 col-lg-4 col-xl-3 ps-item-{{ tid }}"data-nom="{{ p.nom|default('')|lower }}"data-adr="{{ p.adresse|default('')|lower }}"style="display:none;"><div class="ps-card"><div class="card-top-bar"></div><div class="card-body"><div class="d-flex align-items-start gap-3"><div class="card-icon"><img src="{{ asset('assets/media/partenaire_sante/' ~ icon_file) }}"alt="{{ typeLibelle }}"></div><div class="flex-grow-1 min-w-0"><div class="card-name">{{ p.nom }}</div><div class="card-addr"><i class="bi bi-geo-alt" style="font-size:.72rem;"></i>{{ p.adresse ?: '—' }}</div></div></div>{% if p.telephone or p.email or p.responsable %}<div class="info-list">{% if p.telephone %}<div class="info-row"><i class="bi bi-telephone-fill"></i><a href="tel:{{ p.telephone }}">{{ p.telephone }}</a></div>{% endif %}{% if p.email %}<div class="info-row"><i class="bi bi-envelope-fill"></i><span>{{ p.email }}</span></div>{% endif %}{% if p.responsable %}<div class="info-row"><i class="bi bi-person-fill"></i><span>{{ p.responsable }}</span></div>{% endif %}</div>{% endif %}</div>{% if p.telephone or (p.latitude and p.longitude) %}<div class="card-footer-btns">{% if p.telephone %}<a href="tel:{{ p.telephone }}" class="btn-action"><i class="bi bi-telephone"></i> Appeler</a>{% endif %}{% if p.latitude and p.longitude %}<a href="https://maps.google.com/?q={{ p.latitude }},{{ p.longitude }}"target="_blank" rel="noopener" class="btn-action"><i class="bi bi-geo-alt-fill"></i> Carte</a>{% endif %}</div>{% endif %}</div></div>{% else %}<div class="col-12"><div class="ps-empty"><i class="bi bi-building-slash"></i><p>Aucun partenaire enregistré pour ce type.</p></div></div>{% endfor %}</div><div class="ps-pag-bar" id="pgWrap{{ tid }}"><span class="pg-info" id="pgInfo{{ tid }}"></span><ul class="pagination" id="pg{{ tid }}"></ul></div></div>{% endfor %}</div>{% endif %}</div></div>{% endblock %}{% block script %}<script>(function () {var PER = 12;var tabIds = Array.from(document.querySelectorAll('[data-tid]')).map(function (el) {return parseInt(el.dataset.tid);});var pages = {};tabIds.forEach(function (id) { pages[id] = 1; });/* ── Recherche hero ── */window.toggleHeroSearch = function () {var box = document.getElementById('heroSearchBox');var toggle = document.getElementById('heroSearchToggle');var isOpen = box.classList.contains('open');if (isOpen) {closeHeroSearch();} else {box.classList.add('open');toggle.innerHTML = '<i class="bi bi-x-lg"></i> Fermer';document.getElementById('heroSearchInput').focus();}};window.closeHeroSearch = function () {var box = document.getElementById('heroSearchBox');var toggle = document.getElementById('heroSearchToggle');box.classList.remove('open');toggle.innerHTML = '<i class="bi bi-search"></i> Rechercher un partenaire';document.getElementById('heroSearchInput').value = '';applyHeroSearch();};window.applyHeroSearch = function () {var q = (document.getElementById('heroSearchInput').value || '').toLowerCase().trim();/* Applique sur l'onglet actif */var activeTid = getActiveTid();if (activeTid) {applyFilter(activeTid, q);}};function getActiveTid() {var active = document.querySelector('[data-tid].active, [data-tid][aria-selected="true"]');if (!active) active = document.querySelector('[data-tid]');return active ? parseInt(active.dataset.tid) : null;}function applyFilter(tid, q) {document.querySelectorAll('.ps-item-' + tid).forEach(function (col) {var match = !q || col.dataset.nom.includes(q) || col.dataset.adr.includes(q);col.style.display = match ? '' : 'none';});pages[tid] = 1;paginate(tid);}/* ── Pagination ── */function paginate(tid) {var page = pages[tid];var all = Array.from(document.querySelectorAll('.ps-item-' + tid));var vis = all.filter(function (c) { return c.style.display !== 'none'; });var total = vis.length;var nPages = Math.ceil(total / PER) || 1;var start = (page - 1) * PER;all.forEach(function (c) { c.style.display = 'none'; });vis.forEach(function (c, i) { if (i >= start && i < start + PER) c.style.display = ''; });var info = document.getElementById('pgInfo' + tid);if (info) info.textContent = total ? total + ' résultat' + (total > 1 ? 's' : '') : 'Aucun résultat';var pg = document.getElementById('pg' + tid);if (!pg) return;if (nPages <= 1) { pg.innerHTML = ''; return; }var h = '<li class="page-item' + (page === 1 ? ' disabled' : '') + '">'+ '<button class="page-link" onclick="goPage(' + tid + ',' + (page - 1) + ')">'+ '<i class="bi bi-chevron-left" style="font-size:.75rem;"></i></button></li>';for (var i = 1; i <= nPages; i++) {if (i === 1 || i === nPages || Math.abs(i - page) <= 1) {h += '<li class="page-item' + (i === page ? ' active' : '') + '">'+ '<button class="page-link" onclick="goPage(' + tid + ',' + i + ')">' + i + '</button></li>';} else if (Math.abs(i - page) === 2) {h += '<li class="page-item disabled"><span class="page-link">…</span></li>';}}h += '<li class="page-item' + (page === nPages ? ' disabled' : '') + '">'+ '<button class="page-link" onclick="goPage(' + tid + ',' + (page + 1) + ')">'+ '<i class="bi bi-chevron-right" style="font-size:.75rem;"></i></button></li>';pg.innerHTML = h;}window.goPage = function (tid, p) { pages[tid] = p; paginate(tid); };/* ── Init ── */tabIds.forEach(function (tid) { applyFilter(tid, ''); });/* Ré-appliquer le filtre hero au changement d'onglet */document.querySelectorAll('[data-tid]').forEach(function (btn) {btn.addEventListener('shown.bs.tab', function () {var tid = parseInt(this.dataset.tid);var q = (document.getElementById('heroSearchInput').value || '').toLowerCase().trim();applyFilter(tid, q);});});})();</script>{% endblock %}