{"id":3764,"date":"2026-06-01T14:54:46","date_gmt":"2026-06-01T14:54:46","guid":{"rendered":"https:\/\/www.wawdocteur.com\/?page_id=3764"},"modified":"2026-06-19T15:59:04","modified_gmt":"2026-06-19T15:59:04","slug":"medecins","status":"publish","type":"page","link":"https:\/\/www.wawdocteur.com\/index.php\/medecins\/","title":{"rendered":"recherche"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"3764\" class=\"elementor elementor-3764\">\n\t\t\t\t<div class=\"elementor-element elementor-element-393a889 e-con-full e-flex e-con e-parent\" data-id=\"393a889\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-027274f elementor-widget elementor-widget-html\" data-id=\"027274f\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!DOCTYPE html>\r\n<html lang=\"fr\">\r\n<head>\r\n  <meta charset=\"UTF-8\" \/>\r\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" \/>\r\n  <title>Recherche m\u00e9decins \u2014 WAW Doctor<\/title>\r\n\r\n  <style>\r\n    @import url('https:\/\/fonts.googleapis.com\/css2?family=Plus+Jakarta+Sans:wght@500;600;700;800&family=Inter:wght@400;500;600;700&display=swap');\r\n\r\n    .page{\r\n      --navy:#121945;\r\n      --navy-light:#1c2763;\r\n      --navy-soft:#2a3570;\r\n      --tint:#eef0f9;\r\n      --tint-border:#dde1f4;\r\n      --tint-strong:#e2e6f6;\r\n      --gold:#c8941f;\r\n      --ink:#161a2e;\r\n      --muted:#6b7280;\r\n      --success:#16a34a;\r\n      --danger:#c0392b;\r\n      --r-lg:20px;\r\n      --r-md:14px;\r\n      --r-sm:10px;\r\n      --sh-sm:0 1px 3px rgba(18,25,69,.07);\r\n      --sh-md:0 6px 20px rgba(18,25,69,.10);\r\n      --sh-lg:0 16px 44px rgba(18,25,69,.18);\r\n      font-family:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;\r\n      color:var(--ink);\r\n    }\r\n    .page .doc-name,\r\n    .page .results-count,\r\n    .page .booking-header h3,\r\n    .page .success-booking h2,\r\n    .page .slots-label{font-family:'Plus Jakarta Sans',sans-serif}\r\n\r\n    \/* \u2500\u2500 SEARCH HEADER \u2500\u2500 *\/\r\n    .search-header{background:linear-gradient(135deg,var(--navy) 0%,var(--navy-light) 100%);padding:28px 28px;border-radius:var(--r-lg);margin-bottom:18px;position:relative;width:100%;box-shadow:var(--sh-lg)}\r\n    .search-header::before{content:\"\";position:absolute;top:0;right:0;width:240px;height:240px;border-radius:var(--r-lg) var(--r-lg) 0 0;background:radial-gradient(circle at top right,rgba(255,255,255,.10),transparent 70%);pointer-events:none;z-index:0}\r\n    .search-bar{display:flex;background:#fff;border-radius:50px;overflow:hidden;border:1px solid rgba(255,255,255,.18);box-shadow:var(--sh-md);position:relative;z-index:1}\r\n    .search-field{flex:1;display:flex;align-items:center;padding:0 20px;gap:10px}\r\n    .search-field + .search-field{border-left:1px solid #eef0f5}\r\n    .search-field i{color:var(--navy-soft);font-size:18px;flex-shrink:0;opacity:.75}\r\n    .search-field input{border:none;outline:none;font-size:14.5px;color:var(--ink);background:transparent;height:56px;width:100%;font-family:inherit}\r\n    .search-field input::placeholder{color:#a3a7ba}\r\n    .search-btn{background:var(--navy);color:#fff;border:none;padding:0 34px;font-size:15px;font-weight:700;letter-spacing:.01em;cursor:pointer;white-space:nowrap;display:flex;align-items:center;gap:8px;border-radius:0 50px 50px 0;min-height:56px;transition:background .2s,transform .12s}\r\n    .search-btn:hover{background:var(--navy-light)}\r\n    .search-btn:active{transform:scale(.98)}\r\n    .search-btn i{font-size:16px}\r\n\r\n    \/* \u2500\u2500 AUTOCOMPLETE \u2500\u2500 *\/\r\n    .autocomplete-box{display:none;position:absolute;left:28px;right:28px;top:94px;background:#fff;border-radius:var(--r-md);box-shadow:var(--sh-lg);z-index:9999;overflow:hidden;border:1px solid var(--tint-border)}\r\n    .autocomplete-item{padding:13px 18px;cursor:pointer;border-bottom:1px solid #f2f3f8;font-size:14px;display:flex;align-items:center;gap:10px;transition:background .12s}\r\n    .autocomplete-item:last-child{border-bottom:none}\r\n    .autocomplete-item:hover{background:var(--tint)}\r\n    .autocomplete-item i{color:var(--navy);font-size:16px}\r\n\r\n    \/* \u2500\u2500 FILTERS \u2500\u2500 *\/\r\n    .filters{display:flex;gap:8px;margin-bottom:18px;flex-wrap:wrap}\r\n    .filter-btn{display:inline-flex;align-items:center;gap:6px;padding:9px 17px;border:1px solid var(--tint-border);background:#fff;border-radius:50px;font-size:13px;font-weight:600;color:var(--navy-soft);cursor:pointer;font-family:inherit;transition:all .15s}\r\n    .filter-btn:hover{border-color:var(--navy);color:var(--navy);background:var(--tint)}\r\n    .filter-btn.active{background:var(--navy);color:#fff;border-color:var(--navy);box-shadow:var(--sh-sm)}\r\n    .filter-btn i{font-size:15px}\r\n\r\n    \/* \u2500\u2500 RESULTS COUNT \u2500\u2500 *\/\r\n    .results-count{font-size:21px;font-weight:800;color:var(--navy);margin-bottom:4px;letter-spacing:-.01em}\r\n    .results-sub{font-size:13px;color:var(--navy-soft);margin-bottom:20px}\r\n\r\n    \/* \u2500\u2500 LAYOUT \u2500\u2500 *\/\r\n    .results-layout{display:flex;gap:24px;align-items:flex-start}\r\n    .results-list{flex:1;min-width:0}\r\n    .map-col{width:320px;flex-shrink:0;position:sticky;top:16px}\r\n    #mapFrame{width:100%;height:400px;border:none;border-radius:var(--r-lg);display:block;box-shadow:var(--sh-sm)}\r\n\r\n    \/* \u2500\u2500 DISTANCE \u2500\u2500 *\/\r\n    .meta-row.distance{color:var(--navy);font-weight:600}\r\n    .meta-row.distance i{color:var(--navy);opacity:1}\r\n\r\n    \/* \u2500\u2500 PAGINATION \u2500\u2500 *\/\r\n    .pagination{display:flex;align-items:center;justify-content:center;gap:6px;margin:28px 0 8px;flex-wrap:wrap}\r\n    .page-btn{min-width:36px;height:36px;padding:0 10px;border:1px solid var(--tint-border);background:#fff;border-radius:var(--r-sm);font-size:13px;font-weight:600;color:var(--navy-soft);cursor:pointer;font-family:inherit;transition:all .15s}\r\n    .page-btn:hover{border-color:var(--navy);color:var(--navy);background:var(--tint)}\r\n    .page-btn.active{background:var(--navy);color:#fff;border-color:var(--navy)}\r\n    .page-nav{width:36px;height:36px;border:1px solid var(--tint-border);background:#fff;border-radius:var(--r-sm);display:flex;align-items:center;justify-content:center;color:var(--navy-soft);cursor:pointer;font-family:inherit;transition:all .15s}\r\n    .page-nav:hover:not(:disabled){border-color:var(--navy);color:var(--navy);background:var(--tint)}\r\n    .page-nav:disabled{opacity:.35;cursor:not-allowed}\r\n    .page-ellipsis{padding:0 4px;color:#aab0c4;font-size:13px}\r\n\r\n    \/* \u2500\u2500 DOCTOR CARD \u2500\u2500 *\/\r\n    .doctor-card{background:#fff;border:1px solid #edeff5;border-radius:var(--r-lg);padding:22px;margin-bottom:16px;display:flex;gap:18px;position:relative;overflow:hidden;transition:box-shadow .2s,transform .2s,border-color .2s}\r\n    .doctor-card::before{content:\"\";position:absolute;left:0;top:0;bottom:0;width:4px;background:var(--navy);transform:scaleY(0);transition:transform .25s ease}\r\n    .doctor-card:hover{box-shadow:var(--sh-md);transform:translateY(-2px);border-color:var(--tint-border)}\r\n    .doctor-card:hover::before{transform:scaleY(1)}\r\n    .doc-body{flex:1;min-width:0}\r\n    .doc-top{display:flex;align-items:flex-start;justify-content:space-between;flex-wrap:wrap;gap:8px;margin-bottom:8px}\r\n    .doc-name{font-size:17.5px;font-weight:800;color:var(--navy);text-decoration:none;letter-spacing:-.01em}\r\n    .doc-name:hover{color:var(--navy-light);text-decoration:underline}\r\n    .doc-speciality{font-size:13px;color:var(--muted);margin-top:3px}\r\n    .rating{display:inline-flex;align-items:center;gap:4px;font-size:13px;color:#946a0b;font-weight:700;white-space:nowrap;background:#fdf6e8;padding:4px 10px;border-radius:50px}\r\n    .rating i{font-size:14px;color:var(--gold)}\r\n    .rating span{color:#a08746;font-weight:500}\r\n    .doc-meta{display:flex;flex-direction:column;gap:5px;margin-bottom:12px}\r\n    .meta-row{display:flex;align-items:center;gap:7px;font-size:13px;color:var(--muted)}\r\n    .meta-row i{font-size:14px;color:var(--navy-soft);opacity:.7;flex-shrink:0}\r\n    .price-badge{display:inline-flex;align-items:center;gap:5px;font-size:12.5px;padding:5px 13px;background:var(--tint);color:var(--navy);border-radius:50px;border:1px solid var(--tint-border);margin-bottom:10px;font-weight:500}\r\n    .price-badge strong{font-weight:800}\r\n\r\n    \/* \u2500\u2500 COVERAGES \u2500\u2500 *\/\r\n    .coverages{display:flex;flex-wrap:wrap;gap:4px;margin-bottom:14px}\r\n    .cov-tag{font-size:11px;padding:4px 10px;background:#f6f7fb;border:1px solid #e8eaf2;border-radius:50px;color:var(--muted);font-weight:500}\r\n    .cov-more{font-size:11px;padding:4px 10px;background:transparent;border:1px solid var(--tint-border);border-radius:50px;color:var(--navy);cursor:pointer;font-weight:600;transition:background .15s}\r\n    .cov-more:hover{background:var(--tint)}\r\n\r\n    \/* \u2500\u2500 SLOTS \u2500\u2500 *\/\r\n    .slots-section{border-top:1px solid #f1f2f7;padding-top:14px;margin-top:4px}\r\n    .slots-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:10px}\r\n    .slots-label{font-size:12px;font-weight:700;color:var(--navy);text-transform:uppercase;letter-spacing:.06em}\r\n    .slots-nav{display:flex;gap:4px}\r\n    .nav-btn{width:28px;height:28px;border:1px solid var(--tint-border);background:#fff;border-radius:8px;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--navy-soft);font-size:16px;transition:all .15s}\r\n    .nav-btn:hover{border-color:var(--navy);color:var(--navy);background:var(--tint)}\r\n    .slots-grid{display:grid;grid-template-columns:repeat(7,minmax(110px,1fr));gap:8px;overflow-x:auto;padding-bottom:4px}\r\n    .slot-col{text-align:center}\r\n    .slot-day-name{font-size:12px;font-weight:700;color:var(--navy);margin-bottom:2px}\r\n    .slot-day-date{font-size:11px;color:#9a9eb0;margin-bottom:8px}\r\n    .slot-btn{display:block;width:100%;padding:8px 4px;background:var(--tint);border:1px solid var(--tint-border);border-radius:var(--r-sm);font-size:12px;font-weight:700;color:var(--navy);cursor:pointer;font-family:inherit;margin-bottom:5px;text-align:center;transition:all .15s}\r\n    .slot-btn:hover{background:var(--navy);color:#fff;border-color:var(--navy);transform:scale(1.03);box-shadow:var(--sh-sm)}\r\n    .slot-dash{display:block;text-align:center;font-size:16px;color:#d4d6e2;padding:5px 0;margin-bottom:5px}\r\n\r\n    \/* \u2500\u2500 LOADING \/ EMPTY \u2500\u2500 *\/\r\n    .loading{text-align:center;padding:60px 20px;color:var(--muted);font-size:15px}\r\n    .loading i{font-size:32px;display:block;margin-bottom:12px;color:var(--navy);animation:spin 1s linear infinite}\r\n    @keyframes spin{to{transform:rotate(360deg)}}\r\n    .empty{text-align:center;padding:60px 20px;color:var(--muted)}\r\n    .empty i{font-size:48px;display:block;margin-bottom:12px;opacity:.25;color:var(--navy)}\r\n\r\n    \/* \u2500\u2500 ACCESSIBILIT\u00c9 \u2500\u2500 *\/\r\n    .search-btn:focus-visible,.filter-btn:focus-visible,.slot-btn:focus-visible,\r\n    .nav-btn:focus-visible,.btn-confirm:focus-visible,.btn-cancel:focus-visible,\r\n    .coverage-item:focus-visible,.booking-close:focus-visible{outline:2px solid var(--navy);outline-offset:2px}\r\n    @media (prefers-reduced-motion:reduce){\r\n      .doctor-card,.search-btn,.slot-btn,.btn-confirm,.booking-recap{transition:none!important;animation:none!important}\r\n    }\r\n\r\n    \/* \u2500\u2500 RESPONSIVE \u2500\u2500 *\/\r\n    @media (max-width:991px){\r\n      .search-bar{flex-direction:column;border-radius:18px}\r\n      .search-field{border-left:none!important;border-bottom:1px solid #e5e5e5}\r\n      .search-field:last-of-type{border-bottom:none}\r\n      .search-btn{border-radius:0 0 18px 18px;justify-content:center;padding:14px}\r\n      .results-layout{flex-direction:column}\r\n      .map-col{width:100%;position:static}\r\n      #mapFrame{height:280px}\r\n      .doctor-card{flex-direction:column;align-items:center;text-align:center}\r\n      .doctor-card::before{display:none}\r\n      .doc-top{justify-content:center}\r\n      .meta-row{justify-content:center}\r\n      .slots-grid{grid-template-columns:repeat(3,1fr)}\r\n    }\r\n\r\n    \/* \u2500\u2500 BOOKING MODAL \u2500\u2500 *\/\r\n    .booking-modal{display:none;position:fixed;inset:0;background:rgba(10,14,38,.7);z-index:999999;align-items:center;justify-content:center;padding:20px;backdrop-filter:blur(4px)}\r\n    .booking-recap{width:700px;max-width:95%;max-height:90vh;display:flex;flex-direction:column;background:#fff;border-radius:24px;overflow:hidden;box-shadow:var(--sh-lg);animation:wawSlideIn .25s ease}\r\n    @keyframes wawSlideIn{from{opacity:0;transform:translateY(20px) scale(.97)}to{opacity:1;transform:translateY(0) scale(1)}}\r\n    .booking-header{background:linear-gradient(135deg,var(--navy),var(--navy-light));color:#fff;padding:22px 26px;display:flex;justify-content:space-between;align-items:center}\r\n    .booking-header h3{margin:0;font-size:21px;color:#fff;font-weight:700}\r\n    .booking-close{border:none;background:none;color:#fff;font-size:28px;cursor:pointer;line-height:1;opacity:.8;transition:opacity .15s}\r\n    .booking-close:hover{opacity:1}\r\n    .booking-body{flex:1;overflow-y:auto;padding:26px}\r\n    .booking-actions{flex-shrink:0;position:sticky;bottom:0;background:#fff;border-top:1px solid #edf1f7;padding:18px 26px;display:flex;justify-content:flex-end;gap:12px}\r\n    .recap-card{border:1px solid var(--tint-border);border-radius:var(--r-md);overflow:hidden;margin-bottom:25px}\r\n    .recap-row{display:flex;justify-content:space-between;align-items:center;padding:14px 18px;border-bottom:1px solid var(--tint-border)}\r\n    .recap-row:last-child{border-bottom:none}\r\n    .recap-row:nth-child(even){background:#fafbfd}\r\n    .recap-row span{color:var(--muted);font-size:13.5px}\r\n    .recap-row strong{color:var(--navy);font-size:14px}\r\n    .coverage-block{margin-bottom:20px}\r\n    .coverage-label{display:block;margin-bottom:10px;font-weight:700;color:var(--navy);font-size:14px}\r\n    .coverage-list{max-height:180px;overflow-y:auto;display:flex;flex-direction:column;gap:8px;padding-right:4px}\r\n    .coverage-item{border:1.5px solid var(--tint-border);border-radius:var(--r-sm);padding:12px 16px;cursor:pointer;background:#fff;color:var(--navy);font-weight:600;font-size:14px;transition:all .2s;user-select:none}\r\n    .coverage-item:hover{border-color:var(--navy);background:var(--tint)}\r\n    .coverage-item.active{background:var(--navy);color:#fff;border-color:var(--navy);box-shadow:var(--sh-sm)}\r\n    .btn-cancel{height:46px;padding:0 22px;border:1.5px solid var(--tint-border);background:#fff;border-radius:var(--r-sm);cursor:pointer;font-family:inherit;font-size:14px;font-weight:600;color:var(--muted);transition:all .15s}\r\n    .btn-cancel:hover{border-color:var(--navy-soft);color:var(--navy)}\r\n    .btn-confirm{height:46px;padding:0 24px;border:none;background:linear-gradient(135deg,var(--navy),var(--navy-light));color:#fff;border-radius:var(--r-sm);font-weight:700;font-size:14px;cursor:pointer;font-family:inherit;display:flex;align-items:center;gap:8px;transition:all .2s}\r\n    .btn-confirm:hover{transform:translateY(-1px);box-shadow:var(--sh-md)}\r\n    .btn-confirm:disabled{opacity:.6;cursor:not-allowed;transform:none}\r\n    .btn-spinner{width:16px;height:16px;border:2px solid rgba(255,255,255,.3);border-top-color:#fff;border-radius:50%;animation:spin .7s linear infinite}\r\n    .success-booking{text-align:center;padding:30px 20px}\r\n    .success-booking .success-icon{font-size:64px;color:var(--success);display:block;margin-bottom:16px}\r\n    .success-booking h2{color:var(--navy);margin:0 0 8px;font-weight:800}\r\n    .success-booking p{color:var(--muted);margin:4px 0}\r\n    .success-booking .dossier{font-size:15px;margin-top:12px}\r\n    .success-booking .dossier strong{color:var(--navy)}\r\n\r\n    \/* \u2500\u2500 TOAST \u2500\u2500 *\/\r\n    .waw-toast{position:fixed;bottom:24px;left:50%;transform:translateX(-50%) translateY(80px);background:var(--navy);color:#fff;padding:13px 26px;border-radius:50px;font-size:14px;font-weight:600;z-index:9999999;box-shadow:var(--sh-lg);transition:transform .3s ease;white-space:nowrap}\r\n    .waw-toast.show{transform:translateX(-50%) translateY(0)}\r\n    .waw-toast.error{background:var(--danger)}\r\n  <\/style>\r\n<\/head>\r\n\r\n<body>\r\n  <div class=\"page\">\r\n\r\n    <!-- SEARCH HEADER -->\r\n    <div class=\"search-header\">\r\n      <form id=\"searchForm\" class=\"search-bar\">\r\n        <div class=\"search-field\">\r\n          <i class=\"ti ti-search\"><\/i>\r\n          <input type=\"text\" id=\"query\" placeholder=\"Nom, sp\u00e9cialit\u00e9, \u00e9tablissement...\" autocomplete=\"off\" \/>\r\n        <\/div>\r\n        <div class=\"search-field\">\r\n          <i class=\"ti ti-map-pin\"><\/i>\r\n          <input type=\"text\" id=\"location\" placeholder=\"O\u00f9 ?\" autocomplete=\"off\" \/>\r\n        <\/div>\r\n        <input type=\"hidden\" id=\"lat\" \/>\r\n        <input type=\"hidden\" id=\"lng\" \/>\r\n        <button type=\"submit\" class=\"search-btn\">\r\n          <i class=\"ti ti-search\"><\/i> Rechercher\r\n        <\/button>\r\n      <\/form>\r\n\r\n      <div id=\"doctorAutocompleteBox\" class=\"autocomplete-box\"><\/div>\r\n      <div id=\"locationAutocompleteBox\" class=\"autocomplete-box\"><\/div>\r\n    <\/div>\r\n\r\n    <!-- FILTERS -->\r\n    <div class=\"filters\">\r\n      <button class=\"filter-btn\" id=\"availableBtn\" onclick=\"toggleAvailable()\">\r\n        <i class=\"ti ti-calendar-event\"><\/i> Disponible\r\n      <\/button>\r\n      <button class=\"filter-btn\" id=\"nearestBtn\" onclick=\"sortNearest()\">\r\n        <i class=\"ti ti-map-pin\"><\/i> Plus proche\r\n      <\/button>\r\n      <button class=\"filter-btn\" onclick=\"resetFilters()\">\r\n        <i class=\"ti ti-refresh\"><\/i> R\u00e9initialiser\r\n      <\/button>\r\n    <\/div>\r\n\r\n    <div id=\"resultsCount\" class=\"results-count\"><\/div>\r\n    <div id=\"resultsSub\" class=\"results-sub\"><\/div>\r\n\r\n    <div class=\"results-layout\">\r\n      <div class=\"results-list\">\r\n        <div id=\"searchResults\">\r\n          <div class=\"loading\"><i class=\"ti ti-loader-2\"><\/i> Chargement...<\/div>\r\n        <\/div>\r\n        <div id=\"pagination\" class=\"pagination\"><\/div>\r\n      <\/div>\r\n\r\n      <div class=\"map-col\">\r\n        <iframe id=\"mapFrame\" loading=\"lazy\" allowfullscreen><\/iframe>\r\n      <\/div>\r\n    <\/div>\r\n  <\/div>\r\n\r\n  <!-- BOOKING MODAL -->\r\n  <div id=\"bookingModal\" class=\"booking-modal\">\r\n    <div class=\"booking-content booking-recap\">\r\n      <div class=\"booking-header\">\r\n        <h3>Confirmation du rendez-vous<\/h3>\r\n        <button class=\"booking-close\" onclick=\"closeBookingModal()\">\u00d7<\/button>\r\n      <\/div>\r\n\r\n      <div class=\"booking-body\">\r\n        <div class=\"coverage-block\">\r\n          <label class=\"coverage-label\">Prise en charge<\/label>\r\n          <div id=\"coverageList\" class=\"coverage-list\"><\/div>\r\n        <\/div>\r\n\r\n        <div class=\"recap-card\">\r\n          <div class=\"recap-row\"><span>M\u00e9decin<\/span> <strong id=\"recapDoctor\"><\/strong><\/div>\r\n          <div class=\"recap-row\"><span>Date<\/span> <strong id=\"recapDate\"><\/strong><\/div>\r\n          <div class=\"recap-row\"><span>Heure<\/span> <strong id=\"recapTime\"><\/strong><\/div>\r\n          <div class=\"recap-row\"><span>Tarif<\/span> <strong id=\"recapPrice\"><\/strong><\/div>\r\n          <div class=\"recap-row\"><span>Prise en charge<\/span> <strong id=\"recapCoverage\">Paiement personnel<\/strong><\/div>\r\n        <\/div>\r\n      <\/div>\r\n\r\n      <div class=\"booking-actions\">\r\n        <button class=\"btn-cancel\" onclick=\"closeBookingModal()\">Retour<\/button>\r\n        <button class=\"btn-confirm\" id=\"confirmBtn\" onclick=\"confirmAppointment()\">\r\n          <i class=\"ti ti-calendar-check\"><\/i> Confirmer\r\n        <\/button>\r\n      <\/div>\r\n    <\/div>\r\n  <\/div>\r\n\r\n  <!-- TOAST -->\r\n  <div id=\"wawToast\" class=\"waw-toast\"><\/div>\r\n\r\n  <script>\r\n    'use strict';\r\n\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    \/\/ SESSION STORE \u2014 sessionStorage uniquement\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    const Session = {\r\n      get(key) { try { const raw = sessionStorage.getItem(key); return raw ? JSON.parse(raw) : null; } catch { return null; } },\r\n      set(key, value) { try { sessionStorage.setItem(key, JSON.stringify(value)); } catch {} },\r\n      remove(key) { try { sessionStorage.removeItem(key); } catch {} }\r\n    };\r\n\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    \/\/ CONSTANTES API\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    const API_SEARCH  = \"https:\/\/waw.consi.sn\/search\";\r\n    const API_PLACES  = \"https:\/\/waw.consi.sn\/places\/autocomplete\";\r\n    const API_DETAILS = \"https:\/\/waw.consi.sn\/places\/details\";\r\n    const API_APPT    = \"https:\/\/waw.consi.sn\/appointment\";\r\n\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    \/\/ DOM REFS\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    const queryInput    = document.getElementById(\"query\");\r\n    const locationInput = document.getElementById(\"location\");\r\n    const latInput      = document.getElementById(\"lat\");\r\n    const lngInput      = document.getElementById(\"lng\");\r\n    const doctorBox     = document.getElementById(\"doctorAutocompleteBox\");\r\n    const locationBox   = document.getElementById(\"locationAutocompleteBox\");\r\n    const resultsBox    = document.getElementById(\"searchResults\");\r\n    const resultsCount  = document.getElementById(\"resultsCount\");\r\n    const resultsSub    = document.getElementById(\"resultsSub\");\r\n    const mapFrame      = document.getElementById(\"mapFrame\");\r\n\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    \/\/ STATE\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    let selectedDoctor   = null;\r\n    let selectedSlot     = null;\r\n    let selectedTime     = null;\r\n    let selectedTimeISO  = null;\r\n    let selectedCoverage = null;\r\n    let doctorsCache     = [];\r\n    let allDoctors       = [];\r\n    let filteredDoctors  = [];\r\n    let expandedDoctors  = {};\r\n    let doctorWeekOffset = {};\r\n    let availableOnly    = false;\r\n    let currentPage      = 1;\r\n    const PAGE_SIZE      = 10;\r\n\r\n    const DAYS   = [\"Dim\",\"Lun\",\"Mar\",\"Mer\",\"Jeu\",\"Ven\",\"Sam\"];\r\n    const MONTHS = [\"jan\",\"f\u00e9v\",\"mar\",\"avr\",\"mai\",\"jun\",\"jul\",\"ao\u00fb\",\"sep\",\"oct\",\"nov\",\"d\u00e9c\"];\r\n\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    \/\/ TOAST\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    function showToast(msg, type = \"success\") {\r\n      const t = document.getElementById(\"wawToast\");\r\n      t.textContent = msg;\r\n      t.className   = \"waw-toast\" + (type === \"error\" ? \" error\" : \"\");\r\n      requestAnimationFrame(() => t.classList.add(\"show\"));\r\n      setTimeout(() => t.classList.remove(\"show\"), 3000);\r\n    }\r\n\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    \/\/ AUTH HELPERS\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    function isLoggedIn() { return !!Session.get(\"token\"); }\r\n\r\n    window.restorePendingAppointment = function () {\r\n      if (!isLoggedIn()) return;\r\n      const pending = Session.get(\"pendingAppointment\");\r\n      if (!pending) return;\r\n      Session.remove(\"pendingAppointment\");\r\n      selectSlot(pending.doctorId, pending.slotId, pending.time, pending.startTimeISO);\r\n    };\r\n\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    \/\/ GEO HELPERS (plus proche = position actuelle user)\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    function parseLatLngFromSphere1(sphere1) {\r\n      if (!sphere1 || typeof sphere1 !== \"string\") return null;\r\n      const parts = sphere1.split(\",\").map(s => s.trim());\r\n      if (parts.length !== 2) return null;\r\n      const lat = Number(parts[0]);\r\n      const lng = Number(parts[1]);\r\n      if (!Number.isFinite(lat) || !Number.isFinite(lng)) return null;\r\n      return { lat, lng };\r\n    }\r\n\r\n    function distanceKm(lat1, lng1, lat2, lng2) {\r\n      const R = 6371;\r\n      const toRad = d => d * Math.PI \/ 180;\r\n      const dLat = toRad(lat2 - lat1);\r\n      const dLng = toRad(lng2 - lng1);\r\n      const a = Math.sin(dLat \/ 2) ** 2\r\n        + Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) * Math.sin(dLng \/ 2) ** 2;\r\n      return 2 * R * Math.asin(Math.sqrt(a));\r\n    }\r\n\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    \/\/ G\u00c9N\u00c9RATION DES HEURES (SANS HEURES PASS\u00c9ES)\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    function generateTimes(startISO, endISO, consultMin) {\r\n      const step = (consultMin && parseInt(consultMin, 10) > 0) ? parseInt(consultMin, 10) : 30;\r\n\r\n      const now = new Date();\r\n      const times = [];\r\n      let cur = new Date(startISO);\r\n      const end = new Date(endISO);\r\n\r\n      while (cur < end) {\r\n        if (cur >= now) {\r\n          times.push(cur.toLocaleTimeString(\"fr-FR\", {\r\n            hour: \"2-digit\",\r\n            minute: \"2-digit\",\r\n            timeZone: \"Africa\/Dakar\"\r\n          }));\r\n        }\r\n        cur = new Date(cur.getTime() + step * 60000);\r\n      }\r\n      return times;\r\n    }\r\n\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    \/\/ NAVIGATION SEMAINE\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    function toggleDoctorSlots(doctorId) {\r\n      expandedDoctors[doctorId] = !expandedDoctors[doctorId];\r\n      renderDoctorsList(filteredDoctors.length ? filteredDoctors : allDoctors);\r\n    }\r\n\r\n    function nextWeek(doctorId) {\r\n      doctorWeekOffset[doctorId] = (doctorWeekOffset[doctorId] || 0) + 7;\r\n      renderDoctorsList(filteredDoctors.length ? filteredDoctors : allDoctors);\r\n    }\r\n\r\n    \/\/ bloque navigation vers le pass\u00e9\r\n    function prevWeek(doctorId) {\r\n      const next = (doctorWeekOffset[doctorId] || 0) - 7;\r\n      doctorWeekOffset[doctorId] = Math.max(0, next);\r\n      renderDoctorsList(filteredDoctors.length ? filteredDoctors : allDoctors);\r\n    }\r\n\r\n    function getDoctorStartDate(slots) {\r\n      if (!slots?.length) return new Date();\r\n      return new Date([...slots].sort((a, b) => new Date(a.start_time) - new Date(b.start_time))[0].start_time);\r\n    }\r\n\r\n    function getWeekDays(startDate, offsetDays = 0) {\r\n      const start = new Date(startDate);\r\n      start.setDate(start.getDate() + offsetDays);\r\n      return Array.from({ length: 7 }, (_, i) => {\r\n        const d = new Date(start);\r\n        d.setDate(start.getDate() + i);\r\n        return d;\r\n      });\r\n    }\r\n\r\n    function findSlotForDate(slots, day) {\r\n      return slots.find(s => {\r\n        const d = new Date(s.start_time);\r\n        return d.getFullYear() === day.getFullYear()\r\n          && d.getMonth() === day.getMonth()\r\n          && d.getDate() === day.getDate();\r\n      });\r\n    }\r\n\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    \/\/ SLOTS (sans slots\/jours pass\u00e9s)\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    function renderSlots(slots, doctor) {\r\n      const doctorId = doctor.id;\r\n      const consultMin = (doctor.consultation_time && parseInt(doctor.consultation_time, 10) > 0)\r\n        ? parseInt(doctor.consultation_time, 10)\r\n        : 30;\r\n\r\n      const expanded = expandedDoctors[doctorId] || false;\r\n      const offset   = doctorWeekOffset[doctorId] || 0;\r\n      const weekDays = getWeekDays(getDoctorStartDate(slots), offset);\r\n\r\n      const cols = weekDays.map(day => {\r\n        const slot = findSlotForDate(slots, day);\r\n        const dayName = DAYS[day.getDay()];\r\n        const label = `${day.getDate()} ${MONTHS[day.getMonth()]}`;\r\n\r\n        if (!slot) {\r\n          return `<div class=\"slot-col\">\r\n            <div class=\"slot-day-name\">${dayName}<\/div>\r\n            <div class=\"slot-day-date\">${label}<\/div>\r\n            <span class=\"slot-dash\">\u2014<\/span>\r\n          <\/div>`;\r\n        }\r\n\r\n        const now = new Date();\r\n        const slotEnd = new Date(slot.end_time);\r\n        if (slotEnd <= now) {\r\n          return `<div class=\"slot-col\">\r\n            <div class=\"slot-day-name\">${dayName}<\/div>\r\n            <div class=\"slot-day-date\">${label}<\/div>\r\n            <span class=\"slot-dash\">\u2014<\/span>\r\n          <\/div>`;\r\n        }\r\n\r\n        const allTimes = generateTimes(slot.start_time, slot.end_time, consultMin);\r\n        if (!allTimes.length) {\r\n          return `<div class=\"slot-col\">\r\n            <div class=\"slot-day-name\">${dayName}<\/div>\r\n            <div class=\"slot-day-date\">${label}<\/div>\r\n            <span class=\"slot-dash\">\u2014<\/span>\r\n          <\/div>`;\r\n        }\r\n\r\n        const visibleTimes = expanded ? allTimes : allTimes.slice(0, 3);\r\n\r\n        return `<div class=\"slot-col\">\r\n          <div class=\"slot-day-name\">${dayName}<\/div>\r\n          <div class=\"slot-day-date\">${label}<\/div>\r\n          ${visibleTimes.map(time => `\r\n            <button class=\"slot-btn\" onclick=\"selectSlot(${doctorId}, ${slot.id}, '${time}', '${slot.start_time}')\">\r\n              ${time}\r\n            <\/button>\r\n          `).join(\"\")}\r\n        <\/div>`;\r\n      }).join(\"\");\r\n\r\n      const sw = weekDays[0], ew = weekDays[6];\r\n\r\n      return `<div class=\"slots-section\">\r\n        <div class=\"slots-header\">\r\n          <span class=\"slots-label\">\r\n            ${sw.getDate()} ${MONTHS[sw.getMonth()]} \u2013 ${ew.getDate()} ${MONTHS[ew.getMonth()]}\r\n          <\/span>\r\n          <div class=\"slots-nav\">\r\n            <button class=\"nav-btn\" title=\"Semaine pr\u00e9c\u00e9dente\" onclick=\"prevWeek(${doctorId})\">\u2039<\/button>\r\n            <button class=\"nav-btn\" title=\"Semaine suivante\" onclick=\"nextWeek(${doctorId})\">\u203a<\/button>\r\n          <\/div>\r\n        <\/div>\r\n        <div class=\"slots-grid\">${cols}<\/div>\r\n        <div style=\"text-align:center;margin-top:12px;\">\r\n          <button class=\"filter-btn\" onclick=\"toggleDoctorSlots(${doctorId})\">\r\n            ${expanded ? \"Voir moins\" : \"Voir tous les cr\u00e9neaux\"}\r\n          <\/button>\r\n        <\/div>\r\n      <\/div>`;\r\n    }\r\n\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    \/\/ CARTE M\u00c9DECIN\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    function renderDoctor(d) {\r\n      const price = d.prices?.[0]?.price || 0;\r\n      const covShow = (d.coverages || []).slice(0, 5);\r\n      const covMore = (d.coverages || []).length - 5;\r\n      const slots = d.Slots || [];\r\n      const initials = ((d.first_name?.[0] || \"\") + (d.last_name?.[0] || \"\")).toUpperCase();\r\n\r\n      const palette = [\r\n        [\"#e3e7f5\",\"#121945\"], [\"#e7e3f5\",\"#2d2470\"], [\"#dfeaf6\",\"#1e3a6e\"],\r\n        [\"#deeeec\",\"#0f4c46\"], [\"#f2e4ee\",\"#5c1f4a\"], [\"#f5ecdc\",\"#7a5a17\"]\r\n      ];\r\n      const [bg, fg] = palette[d.id % palette.length];\r\n\r\n      const avatarHTML = d.image\r\n        ? `<img decoding=\"async\" src=\"${d.image}\" alt=\"Dr ${d.first_name} ${d.last_name}\"\r\n             style=\"width:90px;height:90px;border-radius:50%;object-fit:cover;flex-shrink:0;border:3px solid #e3e7f5;\"\r\n             onerror=\"this.style.display='none';this.nextElementSibling.style.display='flex';\">\r\n           <div style=\"display:none;width:90px;height:90px;border-radius:50%;background:${bg};color:${fg};\r\n             align-items:center;justify-content:center;font-size:28px;font-weight:700;flex-shrink:0;\">\r\n             ${initials}\r\n           <\/div>`\r\n        : `<div style=\"width:90px;height:90px;border-radius:50%;background:${bg};color:${fg};display:flex;\r\n             align-items:center;justify-content:center;font-size:28px;font-weight:700;flex-shrink:0;\">\r\n             ${initials}\r\n           <\/div>`;\r\n\r\n      const covTags = covShow.map(c => `<span class=\"cov-tag\">${c.name}<\/span>`).join(\"\");\r\n      const moreTag = covMore > 0 ? `<span class=\"cov-more\">+${covMore} assurances<\/span>` : \"\";\r\n\r\n      const slotsHTML = slots.length\r\n        ? renderSlots(slots, d)\r\n        : `<div class=\"slots-section\" style=\"padding-top:12px;border-top:1px solid #f0f0f0;font-size:13px;color:#888;\">\r\n             <i class=\"ti ti-calendar-off\" style=\"margin-right:6px;\"><\/i>Aucun cr\u00e9neau disponible\r\n           <\/div>`;\r\n\r\n      return `<div class=\"doctor-card\">\r\n        ${avatarHTML}\r\n        <div class=\"doc-body\">\r\n          <div class=\"doc-top\">\r\n            <div>\r\n              <a class=\"doc-name\" href=\"\/index.php\/medecins?id=${d.id}\">Dr ${d.first_name} ${d.last_name}<\/a>\r\n              <div class=\"doc-speciality\">${d.Speciality?.name || \"\"}<\/div>\r\n            <\/div>\r\n            <div class=\"rating\">\r\n              <i class=\"ti ti-star-filled\"><\/i>\r\n              ${d.averageRating || 0}\r\n              <span>(${d.totalRatings || 0} avis)<\/span>\r\n            <\/div>\r\n          <\/div>\r\n\r\n          <div class=\"doc-meta\">\r\n            ${typeof d._distanceKm === \"number\" ? `\r\n              <div class=\"meta-row distance\"><i class=\"ti ti-map-pin-2\"><\/i>${d._distanceKm.toFixed(1)} km<\/div>` : \"\"}\r\n            ${d.Health_structure?.name ? `\r\n              <div class=\"meta-row\"><i class=\"ti ti-building-hospital\"><\/i>\r\n                ${d.Health_structure.name}${d.Health_structure.type ? ` \u00b7 <em style=\"color:#999\">${d.Health_structure.type}<\/em>` : \"\"}\r\n              <\/div>` : \"\"}\r\n            ${d.Health_structure?.address ? `\r\n              <div class=\"meta-row\"><i class=\"ti ti-map-pin\"><\/i>${d.Health_structure.address}<\/div>` : \"\"}\r\n            ${d.experience ? `\r\n              <div class=\"meta-row\"><i class=\"ti ti-clock\"><\/i>${d.experience} ans d'exp\u00e9rience<\/div>` : \"\"}\r\n          <\/div>\r\n\r\n          <div>\r\n            <span class=\"price-badge\">\r\n              <i class=\"ti ti-currency-franc\" style=\"font-size:13px\"><\/i>\r\n              Consultation : <strong>${price.toLocaleString(\"fr-FR\")} FCFA<\/strong>\r\n            <\/span>\r\n          <\/div>\r\n\r\n          ${(covTags || moreTag) ? `<div class=\"coverages\">${covTags}${moreTag}<\/div>` : \"\"}\r\n\r\n          ${slotsHTML}\r\n        <\/div>\r\n      <\/div>`;\r\n    }\r\n\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    \/\/ CHARGEMENT\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    async function loadDoctors() {\r\n      const params = new URLSearchParams(window.location.search);\r\n      queryInput.value = params.get(\"query\") || \"\";\r\n      locationInput.value = params.get(\"location\") || \"\";\r\n\r\n      resultsBox.innerHTML = `<div class=\"loading\"><i class=\"ti ti-loader-2\"><\/i> Chargement...<\/div>`;\r\n      currentPage = 1;\r\n\r\n      try {\r\n        const resp = await fetch(API_SEARCH + \"?\" + params.toString());\r\n        const data = await resp.json();\r\n        const doctors = data.doctors || [];\r\n\r\n        doctorsCache = doctors;\r\n        allDoctors = doctors;\r\n        filteredDoctors = doctors;\r\n\r\n        resultsSub.textContent = `Prenez rendez-vous avec ${params.get(\"query\") || \"un m\u00e9decin\"} \u00e0 ${params.get(\"location\") || \"votre zone\"}`;\r\n\r\n        if (!doctors.length) {\r\n          resultsCount.textContent = \"0 m\u00e9decin(s) trouv\u00e9(s)\";\r\n          resultsBox.innerHTML = `<div class=\"empty\"><i class=\"ti ti-user-search\"><\/i>Aucun m\u00e9decin trouv\u00e9 pour cette recherche.<\/div>`;\r\n          return;\r\n        }\r\n\r\n        renderDoctorsList(doctors);\r\n\r\n        const first = doctors[0];\r\n        const pos = parseLatLngFromSphere1(first?.Health_structure?.sphere1);\r\n        if (pos) {\r\n          mapFrame.src = `https:\/\/maps.google.com\/maps?q=${pos.lat},${pos.lng}&z=13&output=embed`;\r\n        }\r\n      } catch (err) {\r\n        console.error(err);\r\n        resultsBox.innerHTML = `<div class=\"empty\"><i class=\"ti ti-wifi-off\"><\/i>Erreur lors du chargement. Veuillez r\u00e9essayer.<\/div>`;\r\n      }\r\n    }\r\n\r\n    function renderDoctorsList(list) {\r\n      const totalPages = Math.max(1, Math.ceil(list.length \/ PAGE_SIZE));\r\n      if (currentPage > totalPages) currentPage = totalPages;\r\n      if (currentPage < 1) currentPage = 1;\r\n\r\n      const start = (currentPage - 1) * PAGE_SIZE;\r\n      const pageItems = list.slice(start, start + PAGE_SIZE);\r\n\r\n      resultsBox.innerHTML = pageItems.length\r\n        ? pageItems.map(renderDoctor).join(\"\")\r\n        : `<div class=\"empty\"><i class=\"ti ti-user-search\"><\/i>Aucun m\u00e9decin trouv\u00e9 pour cette recherche.<\/div>`;\r\n\r\n      resultsCount.textContent = `${list.length} m\u00e9decin(s) trouv\u00e9(s)`;\r\n      renderPagination(list.length);\r\n    }\r\n\r\n    function renderPagination(totalItems) {\r\n      const container = document.getElementById(\"pagination\");\r\n      if (!container) return;\r\n\r\n      const totalPages = Math.ceil(totalItems \/ PAGE_SIZE);\r\n      if (totalPages <= 1) { container.innerHTML = \"\"; return; }\r\n\r\n      const pages = [];\r\n      for (let p = 1; p <= totalPages; p++) {\r\n        if (p === 1 || p === totalPages || (p >= currentPage - 1 && p <= currentPage + 1)) {\r\n          pages.push(p);\r\n        } else if (pages[pages.length - 1] !== \"\u2026\") {\r\n          pages.push(\"\u2026\");\r\n        }\r\n      }\r\n\r\n      const numbersHTML = pages.map(p => p === \"\u2026\"\r\n        ? `<span class=\"page-ellipsis\">\u2026<\/span>`\r\n        : `<button class=\"page-btn ${p === currentPage ? \"active\" : \"\"}\" onclick=\"goToPage(${p})\">${p}<\/button>`\r\n      ).join(\"\");\r\n\r\n      container.innerHTML = `\r\n        <button class=\"page-nav\" ${currentPage === 1 ? \"disabled\" : \"\"} onclick=\"goToPage(${currentPage - 1})\" aria-label=\"Page pr\u00e9c\u00e9dente\">\r\n          <i class=\"ti ti-chevron-left\"><\/i>\r\n        <\/button>\r\n        ${numbersHTML}\r\n        <button class=\"page-nav\" ${currentPage === totalPages ? \"disabled\" : \"\"} onclick=\"goToPage(${currentPage + 1})\" aria-label=\"Page suivante\">\r\n          <i class=\"ti ti-chevron-right\"><\/i>\r\n        <\/button>\r\n      `;\r\n    }\r\n\r\n    function goToPage(p) {\r\n      currentPage = p;\r\n      renderDoctorsList(filteredDoctors.length ? filteredDoctors : allDoctors);\r\n      document.getElementById(\"searchResults\")?.scrollIntoView({ behavior: \"smooth\", block: \"start\" });\r\n    }\r\n\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    \/\/ FILTRES (Disponible revu + Plus proche = position actuelle user)\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    function doctorHasFutureAvailability(d) {\r\n      const slots = d.Slots || [];\r\n      if (!slots.length) return false;\r\n\r\n      const consultMin = (d.consultation_time && parseInt(d.consultation_time, 10) > 0)\r\n        ? parseInt(d.consultation_time, 10)\r\n        : 30;\r\n\r\n      const now = new Date();\r\n      return slots.some(slot => {\r\n        const end = new Date(slot.end_time);\r\n        if (!(end > now)) return false;\r\n        const times = generateTimes(slot.start_time, slot.end_time, consultMin);\r\n        return times.length > 0;\r\n      });\r\n    }\r\n\r\n    function toggleAvailable() {\r\n      availableOnly = !availableOnly;\r\n      document.getElementById(\"availableBtn\").classList.toggle(\"active\", availableOnly);\r\n\r\n      filteredDoctors = availableOnly\r\n        ? allDoctors.filter(doctorHasFutureAvailability)\r\n        : [...allDoctors];\r\n\r\n      currentPage = 1;\r\n      renderDoctorsList(filteredDoctors);\r\n    }\r\n\r\n    function sortNearest() {\r\n      if (!navigator.geolocation) {\r\n        showToast(\"G\u00e9olocalisation non disponible\", \"error\");\r\n        return;\r\n      }\r\n\r\n      showToast(\"Localisation en cours\u2026\");\r\n\r\n      navigator.geolocation.getCurrentPosition(\r\n        ({ coords }) => {\r\n          const uLat = coords.latitude;\r\n          const uLng = coords.longitude;\r\n\r\n          const base = (filteredDoctors.length ? filteredDoctors : allDoctors);\r\n\r\n          base.forEach(d => {\r\n            const pos = parseLatLngFromSphere1(d.Health_structure?.sphere1);\r\n            d._distanceKm = pos ? distanceKm(uLat, uLng, pos.lat, pos.lng) : null;\r\n          });\r\n\r\n          const sorted = [...base].sort((a, b) => {\r\n            if (a._distanceKm == null && b._distanceKm == null) return 0;\r\n            if (a._distanceKm == null) return 1;\r\n            if (b._distanceKm == null) return -1;\r\n            return a._distanceKm - b._distanceKm;\r\n          });\r\n\r\n          filteredDoctors = sorted;\r\n          currentPage = 1;\r\n          renderDoctorsList(sorted);\r\n\r\n          \/\/ Mettre la map sur le plus proche\r\n          const first = sorted[0];\r\n          const pos = parseLatLngFromSphere1(first?.Health_structure?.sphere1);\r\n          if (pos) mapFrame.src = `https:\/\/maps.google.com\/maps?q=${pos.lat},${pos.lng}&z=13&output=embed`;\r\n\r\n          showToast(\"Tri\u00e9s par proximit\u00e9 \u2713\");\r\n        },\r\n        (err) => {\r\n          console.error(err);\r\n          showToast(\"Veuillez autoriser la localisation\", \"error\");\r\n        },\r\n        { enableHighAccuracy: true, timeout: 10000, maximumAge: 0 }\r\n      );\r\n    }\r\n\r\n    function resetFilters() {\r\n      availableOnly = false;\r\n      document.getElementById(\"availableBtn\").classList.remove(\"active\");\r\n      filteredDoctors = [...allDoctors];\r\n      currentPage = 1;\r\n      renderDoctorsList(allDoctors);\r\n    }\r\n\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    \/\/ S\u00c9LECTION D'UN SLOT \/ MODAL\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    function selectSlot(doctorId, slotId, time, startTimeISO) {\r\n      if (!isLoggedIn()) {\r\n        Session.set(\"redirect_after_login\", location.href);\r\n        Session.set(\"pendingAppointment\", { doctorId, slotId, time, startTimeISO });\r\n        if (typeof window.openLoginModal === \"function\") window.openLoginModal();\r\n        else showToast(\"Veuillez vous connecter pour r\u00e9server\", \"error\");\r\n        return;\r\n      }\r\n\r\n      selectedDoctor  = doctorsCache.find(d => d.id === doctorId);\r\n      if (!selectedDoctor) { showToast(\"M\u00e9decin introuvable\", \"error\"); return; }\r\n\r\n      selectedSlot    = slotId;\r\n      selectedTime    = time;\r\n      selectedTimeISO = startTimeISO;\r\n\r\n      document.getElementById(\"recapDoctor\").textContent = `Dr ${selectedDoctor.first_name} ${selectedDoctor.last_name}`;\r\n      document.getElementById(\"recapDate\").textContent = new Date(startTimeISO).toLocaleDateString(\"fr-FR\", {\r\n        weekday: \"long\", day: \"numeric\", month: \"long\", year: \"numeric\"\r\n      });\r\n      document.getElementById(\"recapTime\").textContent  = time;\r\n      document.getElementById(\"recapPrice\").textContent = `${(selectedDoctor.prices?.[0]?.price || 0).toLocaleString(\"fr-FR\")} FCFA`;\r\n      document.getElementById(\"recapCoverage\").textContent = \"Paiement personnel\";\r\n\r\n      selectedCoverage = null;\r\n      const coverageList = document.getElementById(\"coverageList\");\r\n      coverageList.innerHTML = \"\";\r\n\r\n      const personal = document.createElement(\"div\");\r\n      personal.className = \"coverage-item active\";\r\n      personal.textContent = \"Paiement personnel\";\r\n      personal.onclick = () => chooseCoverage(personal, null);\r\n      coverageList.appendChild(personal);\r\n\r\n      (selectedDoctor.coverages || []).forEach(c => {\r\n        const item = document.createElement(\"div\");\r\n        item.className = \"coverage-item\";\r\n        item.textContent = c.name;\r\n        item.onclick = () => chooseCoverage(item, c.id);\r\n        coverageList.appendChild(item);\r\n      });\r\n\r\n      const confirmBtn = document.getElementById(\"confirmBtn\");\r\n      confirmBtn.disabled = false;\r\n      confirmBtn.innerHTML = `<i class=\"ti ti-calendar-check\"><\/i> Confirmer`;\r\n\r\n      document.getElementById(\"bookingModal\").style.display = \"flex\";\r\n      document.body.style.overflow = \"hidden\";\r\n    }\r\n\r\n    function chooseCoverage(el, id) {\r\n      document.querySelectorAll(\".coverage-item\").forEach(x => x.classList.remove(\"active\"));\r\n      el.classList.add(\"active\");\r\n      selectedCoverage = id ?? null;\r\n      const rc = document.getElementById(\"recapCoverage\");\r\n      if (rc) rc.textContent = el.textContent.trim();\r\n    }\r\n\r\n    function closeBookingModal() {\r\n      document.getElementById(\"bookingModal\").style.display = \"none\";\r\n      document.body.style.overflow = \"\";\r\n    }\r\n\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    \/\/ CONFIRMATION RDV\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    async function confirmAppointment() {\r\n      const token = Session.get(\"token\");\r\n      const patient = Session.get(\"user\");\r\n      const patientId = patient?.Patients?.[0]?.id ?? patient?.id;\r\n\r\n      if (!token || !patient) {\r\n        showToast(\"Session expir\u00e9e. Veuillez vous reconnecter.\", \"error\");\r\n        closeBookingModal();\r\n        window.openLoginModal?.();\r\n        return;\r\n      }\r\n\r\n      const confirmBtn = document.getElementById(\"confirmBtn\");\r\n      confirmBtn.disabled = true;\r\n      confirmBtn.innerHTML = `<div class=\"btn-spinner\"><\/div> En cours\u2026`;\r\n\r\n      try {\r\n        const response = await fetch(API_APPT, {\r\n          method: \"POST\",\r\n          headers: {\r\n            \"Content-Type\": \"application\/json\",\r\n            \"Authorization\": \"Bearer \" + token\r\n          },\r\n          body: JSON.stringify({\r\n            id_doctor: selectedDoctor.id,\r\n            id_patient: patientId,\r\n            id_slot: selectedSlot,\r\n            start_time: selectedTimeISO,\r\n            idprisecharge: selectedCoverage\r\n          })\r\n        });\r\n\r\n        const data = await response.json();\r\n\r\n        if (!response.ok) {\r\n          showToast(data.message || \"Erreur de r\u00e9servation\", \"error\");\r\n          confirmBtn.disabled = false;\r\n          confirmBtn.innerHTML = `<i class=\"ti ti-calendar-check\"><\/i> Confirmer`;\r\n          return;\r\n        }\r\n\r\n        \/\/ retirer le slot des caches\r\n        [doctorsCache, allDoctors, filteredDoctors].forEach(cache => {\r\n          const doc = cache.find(d => d.id === selectedDoctor.id);\r\n          if (doc) doc.Slots = (doc.Slots || []).filter(s => s.id !== selectedSlot);\r\n        });\r\n\r\n        document.querySelector(\".booking-body\").innerHTML = `\r\n          <div class=\"success-booking\">\r\n            <i class=\"ti ti-circle-check success-icon\"><\/i>\r\n            <h2>Rendez-vous confirm\u00e9 !<\/h2>\r\n            <p>Votre demande a bien \u00e9t\u00e9 enregistr\u00e9e.<\/p>\r\n            <p class=\"dossier\">N\u00b0 dossier : <strong>${data.dossier_number}<\/strong><\/p>\r\n          <\/div>`;\r\n\r\n        document.querySelector(\".booking-actions\").innerHTML = `\r\n          <button class=\"btn-confirm\" onclick=\"closeBookingModal()\">\r\n            <i class=\"ti ti-check\"><\/i> Fermer\r\n          <\/button>`;\r\n\r\n        showToast(\"Rendez-vous confirm\u00e9 \u2713\");\r\n      } catch (err) {\r\n        console.error(err);\r\n        showToast(\"Erreur serveur. Veuillez r\u00e9essayer.\", \"error\");\r\n        confirmBtn.disabled = false;\r\n        confirmBtn.innerHTML = `<i class=\"ti ti-calendar-check\"><\/i> Confirmer`;\r\n      }\r\n    }\r\n\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    \/\/ FORM SUBMIT\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    document.getElementById(\"searchForm\").addEventListener(\"submit\", function (e) {\r\n      e.preventDefault();\r\n      const params = new URLSearchParams();\r\n      if (queryInput.value) params.set(\"query\", queryInput.value);\r\n      if (locationInput.value) params.set(\"location\", locationInput.value);\r\n      if (latInput.value) params.set(\"lat\", latInput.value);\r\n      if (lngInput.value) params.set(\"lng\", lngInput.value);\r\n      window.location.href = \"\/index.php\/medecins?\" + params.toString();\r\n    });\r\n\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    \/\/ AUTOCOMPLETE M\u00c9DECIN\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    let doctorTimer;\r\n    queryInput.addEventListener(\"input\", function () {\r\n      clearTimeout(doctorTimer);\r\n      if (this.value.length < 2) { doctorBox.style.display = \"none\"; return; }\r\n      doctorTimer = setTimeout(async () => {\r\n        try {\r\n          const resp = await fetch(`${API_SEARCH}?query=${encodeURIComponent(this.value)}&limit=5`);\r\n          const data = await resp.json();\r\n          const items = (data.doctors || []).map(d => `\r\n            <div class=\"autocomplete-item\" onclick=\"selectDoctorQuery('${d.first_name} ${d.last_name}')\">\r\n              <i class=\"ti ti-user-circle\"><\/i>\r\n              Dr ${d.first_name} ${d.last_name}\r\n              <span style=\"margin-left:auto;font-size:12px;color:#888\">${d.Speciality?.name || \"\"}<\/span>\r\n            <\/div>\r\n          `).join(\"\");\r\n\r\n          doctorBox.innerHTML = items || `<div class=\"autocomplete-item\" style=\"color:#888\">Aucun r\u00e9sultat<\/div>`;\r\n          doctorBox.style.display = \"block\";\r\n        } catch {}\r\n      }, 300);\r\n    });\r\n\r\n    function selectDoctorQuery(name) {\r\n      queryInput.value = name;\r\n      doctorBox.style.display = \"none\";\r\n    }\r\n\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    \/\/ AUTOCOMPLETE LOCALISATION\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    let locationTimer;\r\n    locationInput.addEventListener(\"input\", function () {\r\n      clearTimeout(locationTimer);\r\n      if (this.value.length < 2) { locationBox.style.display = \"none\"; return; }\r\n      locationTimer = setTimeout(async () => {\r\n        try {\r\n          const resp  = await fetch(`${API_PLACES}?input=${encodeURIComponent(this.value)}`);\r\n          const data  = await resp.json();\r\n          const items = (data.predictions || []).map(p => `\r\n            <div class=\"autocomplete-item\" data-id=\"${p.place_id}\">\r\n              <i class=\"ti ti-map-pin\"><\/i>${p.description}\r\n            <\/div>\r\n          `).join(\"\");\r\n\r\n          locationBox.innerHTML = items || `<div class=\"autocomplete-item\" style=\"color:#888\">Aucun r\u00e9sultat<\/div>`;\r\n          locationBox.style.display = \"block\";\r\n\r\n          locationBox.querySelectorAll(\".autocomplete-item[data-id]\").forEach(item => {\r\n            item.onclick = async function () {\r\n              locationInput.value = this.innerText.trim();\r\n              locationBox.style.display = \"none\";\r\n              try {\r\n                const det = await fetch(`${API_DETAILS}?place_id=${this.dataset.id}`);\r\n                const json = await det.json();\r\n                const loc = json.result?.geometry?.location;\r\n                if (loc) { latInput.value = loc.lat; lngInput.value = loc.lng; }\r\n              } catch {}\r\n            };\r\n          });\r\n        } catch {}\r\n      }, 300);\r\n    });\r\n\r\n    document.addEventListener(\"click\", e => {\r\n      if (!e.target.closest(\".search-header\")) {\r\n        doctorBox.style.display = \"none\";\r\n        locationBox.style.display = \"none\";\r\n      }\r\n    });\r\n\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    \/\/ INIT\r\n    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\r\n    document.addEventListener(\"DOMContentLoaded\", async () => {\r\n      await loadDoctors();\r\n      restorePendingAppointment();\r\n    });\r\n  <\/script>\r\n<\/body>\r\n<\/html>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Recherche m\u00e9decins \u2014 WAW Doctor Rechercher Disponible Plus proche R\u00e9initialiser Chargement&#8230; Confirmation du rendez-vous \u00d7 Prise en charge M\u00e9decin Date Heure Tarif Prise en charge Paiement personnel Retour Confirmer<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_eb_attr":"","footnotes":""},"class_list":["post-3764","page","type-page","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.7 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>recherche - Waw docteur<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.wawdocteur.com\/index.php\/medecins\/\" \/>\n<meta property=\"og:locale\" content=\"fr_FR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"recherche - Waw docteur\" \/>\n<meta property=\"og:description\" content=\"Recherche m\u00e9decins \u2014 WAW Doctor Rechercher Disponible Plus proche R\u00e9initialiser Chargement&#8230; Confirmation du rendez-vous \u00d7 Prise en charge M\u00e9decin Date Heure Tarif Prise en charge Paiement personnel Retour Confirmer\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.wawdocteur.com\/index.php\/medecins\/\" \/>\n<meta property=\"og:site_name\" content=\"Waw docteur\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/web.facebook.com\/p\/Waw-docteur-61585875793992\/?_rdc=1&amp;_rdr#\" \/>\n<meta property=\"article:modified_time\" content=\"2026-06-19T15:59:04+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:site\" content=\"@DocteurWaw64590\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.wawdocteur.com\\\/index.php\\\/medecins\\\/\",\"url\":\"https:\\\/\\\/www.wawdocteur.com\\\/index.php\\\/medecins\\\/\",\"name\":\"recherche - Waw docteur\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.wawdocteur.com\\\/#website\"},\"datePublished\":\"2026-06-01T14:54:46+00:00\",\"dateModified\":\"2026-06-19T15:59:04+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.wawdocteur.com\\\/index.php\\\/medecins\\\/#breadcrumb\"},\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.wawdocteur.com\\\/index.php\\\/medecins\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.wawdocteur.com\\\/index.php\\\/medecins\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\\\/\\\/www.wawdocteur.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"recherche\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.wawdocteur.com\\\/#website\",\"url\":\"https:\\\/\\\/www.wawdocteur.com\\\/\",\"name\":\"Waw docteur\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.wawdocteur.com\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.wawdocteur.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"fr-FR\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.wawdocteur.com\\\/#organization\",\"name\":\"Waw docteur\",\"url\":\"https:\\\/\\\/www.wawdocteur.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"fr-FR\",\"@id\":\"https:\\\/\\\/www.wawdocteur.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.wawdocteur.com\\\/wp-content\\\/uploads\\\/2026\\\/05\\\/cropped-cropped-logowawdoctorhome-1.png\",\"contentUrl\":\"https:\\\/\\\/www.wawdocteur.com\\\/wp-content\\\/uploads\\\/2026\\\/05\\\/cropped-cropped-logowawdoctorhome-1.png\",\"width\":512,\"height\":512,\"caption\":\"Waw docteur\"},\"image\":{\"@id\":\"https:\\\/\\\/www.wawdocteur.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/web.facebook.com\\\/p\\\/Waw-docteur-61585875793992\\\/?_rdc=1&_rdr#\",\"https:\\\/\\\/x.com\\\/DocteurWaw64590\",\"https:\\\/\\\/www.linkedin.com\\\/company\\\/waw-docteur\\\/\",\"https:\\\/\\\/www.instagram.com\\\/waw.docteur4\\\/\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"recherche - Waw docteur","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.wawdocteur.com\/index.php\/medecins\/","og_locale":"fr_FR","og_type":"article","og_title":"recherche - Waw docteur","og_description":"Recherche m\u00e9decins \u2014 WAW Doctor Rechercher Disponible Plus proche R\u00e9initialiser Chargement&#8230; Confirmation du rendez-vous \u00d7 Prise en charge M\u00e9decin Date Heure Tarif Prise en charge Paiement personnel Retour Confirmer","og_url":"https:\/\/www.wawdocteur.com\/index.php\/medecins\/","og_site_name":"Waw docteur","article_publisher":"https:\/\/web.facebook.com\/p\/Waw-docteur-61585875793992\/?_rdc=1&_rdr#","article_modified_time":"2026-06-19T15:59:04+00:00","twitter_card":"summary_large_image","twitter_site":"@DocteurWaw64590","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.wawdocteur.com\/index.php\/medecins\/","url":"https:\/\/www.wawdocteur.com\/index.php\/medecins\/","name":"recherche - Waw docteur","isPartOf":{"@id":"https:\/\/www.wawdocteur.com\/#website"},"datePublished":"2026-06-01T14:54:46+00:00","dateModified":"2026-06-19T15:59:04+00:00","breadcrumb":{"@id":"https:\/\/www.wawdocteur.com\/index.php\/medecins\/#breadcrumb"},"inLanguage":"fr-FR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.wawdocteur.com\/index.php\/medecins\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.wawdocteur.com\/index.php\/medecins\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.wawdocteur.com\/"},{"@type":"ListItem","position":2,"name":"recherche"}]},{"@type":"WebSite","@id":"https:\/\/www.wawdocteur.com\/#website","url":"https:\/\/www.wawdocteur.com\/","name":"Waw docteur","description":"","publisher":{"@id":"https:\/\/www.wawdocteur.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.wawdocteur.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"fr-FR"},{"@type":"Organization","@id":"https:\/\/www.wawdocteur.com\/#organization","name":"Waw docteur","url":"https:\/\/www.wawdocteur.com\/","logo":{"@type":"ImageObject","inLanguage":"fr-FR","@id":"https:\/\/www.wawdocteur.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.wawdocteur.com\/wp-content\/uploads\/2026\/05\/cropped-cropped-logowawdoctorhome-1.png","contentUrl":"https:\/\/www.wawdocteur.com\/wp-content\/uploads\/2026\/05\/cropped-cropped-logowawdoctorhome-1.png","width":512,"height":512,"caption":"Waw docteur"},"image":{"@id":"https:\/\/www.wawdocteur.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/web.facebook.com\/p\/Waw-docteur-61585875793992\/?_rdc=1&_rdr#","https:\/\/x.com\/DocteurWaw64590","https:\/\/www.linkedin.com\/company\/waw-docteur\/","https:\/\/www.instagram.com\/waw.docteur4\/"]}]}},"_links":{"self":[{"href":"https:\/\/www.wawdocteur.com\/index.php\/wp-json\/wp\/v2\/pages\/3764","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.wawdocteur.com\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.wawdocteur.com\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.wawdocteur.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wawdocteur.com\/index.php\/wp-json\/wp\/v2\/comments?post=3764"}],"version-history":[{"count":171,"href":"https:\/\/www.wawdocteur.com\/index.php\/wp-json\/wp\/v2\/pages\/3764\/revisions"}],"predecessor-version":[{"id":4719,"href":"https:\/\/www.wawdocteur.com\/index.php\/wp-json\/wp\/v2\/pages\/3764\/revisions\/4719"}],"wp:attachment":[{"href":"https:\/\/www.wawdocteur.com\/index.php\/wp-json\/wp\/v2\/media?parent=3764"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}