{"id":2385,"date":"2026-06-24T13:30:33","date_gmt":"2026-06-24T05:30:33","guid":{"rendered":"https:\/\/www.meditech.com.eg\/meditech-vms\/"},"modified":"2026-06-24T13:34:35","modified_gmt":"2026-06-24T05:34:35","slug":"meditech-vms","status":"publish","type":"page","link":"https:\/\/www.meditech.com.eg\/meditech-vms\/","title":{"rendered":"\u0646\u0638\u0627\u0645 \u0645\u064a\u062f\u064a\u062a\u0643 VMS"},"content":{"rendered":"    <div id=\"mvms-wrap\">\n    <script>\n    window.MVMS_API   = \"https:\\\/\\\/www.meditech.com.eg\\\/wp-json\\\/mvms\\\/v1\";\n    window.MVMS_NONCE = \"13e402cacd\";\n    window.MVMS_PAGE  = \"https:\\\/\\\/www.meditech.com.eg\\\/meditech-vms\\\/\";\n    <\/script>\n    \n\n\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>Meditech \u2014 Visitor Management System<\/title>\n\n\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/xlsx\/0.18.5\/xlsx.full.min.js\"><\/script>\n<style>\n:root{\n  --navy:#0D2B45;--teal:#00A896;--teal2:#02C39A;--red:#E63946;\n  --amber:#F4A261;--white:#F8FAFB;--border:#DDE3EC;\n  --text:#1A2A3A;--muted:#6B7A90;--sidebar:220px;\n  --radius:10px;--shadow:0 2px 12px rgba(13,43,69,.10);\n  --tr:all .2s cubic-bezier(.4,0,.2,1);\n}\n*{box-sizing:border-box;margin:0;padding:0}\nbody{font-family:'Segoe UI',system-ui,sans-serif;background:var(--white);color:var(--text);font-size:14px;overflow-x:hidden}\n\n\/* AUTH *\/\n#auth-screen{display:flex;align-items:center;justify-content:center;min-height:100vh;background:linear-gradient(135deg,var(--navy) 0%,#143d60 50%,#0a4a7c 100%)}\n.auth-card{background:#fff;border-radius:18px;padding:44px 40px;width:420px;max-width:95vw;box-shadow:0 24px 60px rgba(0,0,0,.25)}\n.auth-logo{display:flex;align-items:center;gap:12px;margin-bottom:30px}\n.auth-logo-icon{width:48px;height:48px;background:var(--teal);border-radius:12px;display:flex;align-items:center;justify-content:center}\n.auth-logo-icon i{color:#fff;font-size:24px}\n.auth-logo-text h1{font-size:22px;font-weight:700;color:var(--navy);line-height:1}\n.auth-logo-text span{font-size:11px;color:var(--muted);letter-spacing:.5px;text-transform:uppercase}\n.auth-card label{font-size:12px;font-weight:600;color:var(--muted);text-transform:uppercase;letter-spacing:.5px;margin-bottom:5px;display:block}\n.auth-card .form-control{border:1.5px solid var(--border);border-radius:8px;padding:10px 14px;font-size:14px;transition:var(--tr)}\n.auth-card .form-control:focus{border-color:var(--teal);box-shadow:0 0 0 3px rgba(0,168,150,.15)}\n\n\/* APP LAYOUT *\/\n#app{display:none;min-height:100vh}\n.sidebar{position:fixed;top:0;left:0;width:var(--sidebar);height:100vh;background:var(--navy);display:flex;flex-direction:column;z-index:100;transition:var(--tr)}\n.sidebar-logo{padding:20px 18px;border-bottom:1px solid rgba(255,255,255,.08);display:flex;align-items:center;gap:10px}\n.sidebar-logo-icon{width:36px;height:36px;background:var(--teal);border-radius:9px;display:flex;align-items:center;justify-content:center;flex-shrink:0}\n.sidebar-logo-icon i{color:#fff;font-size:18px}\n.sidebar-logo-text h2{font-size:15px;font-weight:700;color:#fff;line-height:1.1}\n.sidebar-logo-text span{font-size:10px;color:rgba(255,255,255,.4);text-transform:uppercase;letter-spacing:.8px}\n.nav-section-label{padding:18px 18px 6px;font-size:10px;font-weight:600;color:rgba(255,255,255,.3);text-transform:uppercase;letter-spacing:1px}\n.sidebar nav a{display:flex;align-items:center;gap:10px;padding:10px 18px;color:rgba(255,255,255,.65);text-decoration:none;font-size:13px;transition:var(--tr);border-left:3px solid transparent}\n.sidebar nav a i{font-size:16px;width:20px;text-align:center}\n.sidebar nav a:hover{color:#fff;background:rgba(255,255,255,.07);border-left-color:var(--teal)}\n.sidebar nav a.active{color:#fff;background:rgba(0,168,150,.18);border-left-color:var(--teal)}\n.nav-badge{margin-left:auto;background:var(--red);color:#fff;font-size:10px;font-weight:700;padding:1px 6px;border-radius:10px;min-width:18px;text-align:center}\n.sidebar-footer{margin-top:auto;padding:16px;border-top:1px solid rgba(255,255,255,.08)}\n.user-chip{display:flex;align-items:center;gap:10px}\n.user-avatar{width:34px;height:34px;border-radius:50%;background:var(--teal);display:flex;align-items:center;justify-content:center;color:#fff;font-weight:700;font-size:13px;flex-shrink:0}\n.user-info strong{display:block;color:#fff;font-size:12px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n.user-info span{font-size:11px;color:rgba(255,255,255,.4);text-transform:capitalize}\n.btn-logout{background:none;border:none;color:rgba(255,255,255,.4);cursor:pointer;padding:4px;border-radius:6px;transition:var(--tr)}\n.btn-logout:hover{color:var(--red)}\n\n\/* MAIN *\/\n.main-content{margin-left:var(--sidebar);min-height:100vh;display:flex;flex-direction:column}\n.topbar{background:#fff;border-bottom:1px solid var(--border);padding:0 28px;height:58px;display:flex;align-items:center;justify-content:space-between;position:sticky;top:0;z-index:50;box-shadow:0 1px 4px rgba(0,0,0,.04)}\n.topbar-title{font-size:17px;font-weight:600;color:var(--navy)}\n.topbar-actions{display:flex;align-items:center;gap:10px}\n.page-content{padding:24px 28px;flex:1}\n\n\/* CARDS *\/\n.card{background:#fff;border:1px solid var(--border);border-radius:var(--radius);box-shadow:var(--shadow)}\n.card-hdr{padding:16px 20px;border-bottom:1px solid var(--border);display:flex;align-items:center;justify-content:space-between}\n.card-hdr h5{font-size:14px;font-weight:600;color:var(--navy);margin:0}\n.stat-card{background:#fff;border:1px solid var(--border);border-radius:var(--radius);padding:20px;box-shadow:var(--shadow);transition:var(--tr)}\n.stat-card:hover{transform:translateY(-2px);box-shadow:0 8px 24px rgba(13,43,69,.12)}\n.stat-icon{width:48px;height:48px;border-radius:12px;display:flex;align-items:center;justify-content:center;font-size:22px;margin-bottom:14px}\n.stat-num{font-size:32px;font-weight:700;color:var(--navy);line-height:1}\n.stat-label{font-size:12px;color:var(--muted);margin-top:4px}\n\n\/* BUTTONS *\/\n.btn-teal{background:var(--teal);color:#fff;border:none;padding:8px 18px;border-radius:8px;font-size:13px;font-weight:500;cursor:pointer;transition:var(--tr);display:inline-flex;align-items:center;gap:6px}\n.btn-teal:hover{background:var(--teal2);color:#fff;transform:translateY(-1px)}\n.btn-navy{background:none;border:1.5px solid var(--navy);color:var(--navy);padding:7px 16px;border-radius:8px;font-size:13px;font-weight:500;cursor:pointer;transition:var(--tr);display:inline-flex;align-items:center;gap:6px}\n.btn-navy:hover{background:var(--navy);color:#fff}\n.btn-icon{width:30px;height:30px;border-radius:7px;border:1px solid var(--border);background:#fff;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;color:var(--muted);transition:var(--tr)}\n.btn-icon:hover{background:var(--navy);color:#fff;border-color:var(--navy)}\n.btn-del{background:rgba(230,57,70,.1);color:var(--red);border:none;padding:5px 12px;border-radius:6px;font-size:12px;cursor:pointer;transition:var(--tr)}\n.btn-del:hover{background:var(--red);color:#fff}\n\n\/* BADGES *\/\n.bs{padding:4px 10px;border-radius:20px;font-size:11px;font-weight:600;display:inline-flex;align-items:center;gap:4px}\n.bs-in{background:rgba(0,168,150,.12);color:#00896A}\n.bs-out{background:rgba(72,202,228,.15);color:#1B7CCC}\n.bs-cancel{background:rgba(230,57,70,.1);color:var(--red)}\n.role-admin{background:rgba(230,57,70,.1);color:var(--red);padding:3px 10px;border-radius:20px;font-size:11px;font-weight:600}\n.role-receptionist{background:rgba(0,168,150,.12);color:#00896A;padding:3px 10px;border-radius:20px;font-size:11px;font-weight:600}\n.role-security{background:rgba(244,162,97,.15);color:#b5591a;padding:3px 10px;border-radius:20px;font-size:11px;font-weight:600}\n\n\/* TABLE *\/\n.tbl{width:100%;border-collapse:collapse}\n.tbl th{padding:10px 14px;font-size:11px;font-weight:600;color:var(--muted);text-transform:uppercase;letter-spacing:.5px;border-bottom:2px solid var(--border);text-align:left;white-space:nowrap}\n.tbl td{padding:12px 14px;border-bottom:1px solid var(--border);font-size:13px;vertical-align:middle}\n.tbl tr:hover td{background:rgba(0,168,150,.03)}\n.tbl tr:last-child td{border-bottom:none}\n\n\/* FORM *\/\n.form-label{font-size:12px;font-weight:600;color:var(--muted);text-transform:uppercase;letter-spacing:.4px;margin-bottom:5px}\n.form-control,.form-select{border:1.5px solid var(--border);border-radius:8px;padding:9px 13px;font-size:13px;transition:var(--tr);background:#fff}\n.form-control:focus,.form-select:focus{border-color:var(--teal);box-shadow:0 0 0 3px rgba(0,168,150,.12);outline:none}\n.sec-title{font-size:13px;font-weight:700;color:var(--navy);padding-bottom:10px;border-bottom:2px solid var(--teal);margin-bottom:18px;display:flex;align-items:center;gap:8px}\n\n\/* TOAST *\/\n#toast-wrap{position:fixed;top:20px;right:20px;z-index:9999;display:flex;flex-direction:column;gap:8px}\n.toast-msg{background:#fff;border:1px solid var(--border);border-radius:10px;padding:12px 18px;box-shadow:0 8px 24px rgba(0,0,0,.12);display:flex;align-items:center;gap:10px;min-width:280px;font-size:13px;animation:slideIn .25s ease}\n@keyframes slideIn{from{transform:translateX(120%);opacity:0}to{transform:translateX(0);opacity:1}}\n.toast-ok{border-left:4px solid var(--teal)}\n.toast-err{border-left:4px solid var(--red)}\n\n\/* MODAL *\/\n.modal-header{background:var(--navy);color:#fff;border-radius:var(--radius) var(--radius) 0 0}\n.modal-header .btn-close{filter:invert(1)}\n.modal-title{font-size:15px;font-weight:600}\n\n\/* CAMERA *\/\n#cam-preview{border-radius:10px;overflow:hidden;background:#000;aspect-ratio:4\/3;width:100%}\n#cam-preview video,#cam-preview canvas,#cam-preview img{width:100%;height:100%;object-fit:cover;display:block}\n.sig-canvas{border:2px solid var(--border);border-radius:8px;cursor:crosshair;background:#fff;touch-action:none}\n\n\/* BADGE *\/\n.vbadge{border-radius:12px;overflow:hidden;box-shadow:0 8px 32px rgba(0,0,0,.15);max-width:380px;margin:0 auto}\n.vbadge-hdr{background:var(--navy);color:#fff;padding:16px 20px;text-align:center}\n.vbadge-hdr h4{font-size:18px;font-weight:700;margin:0 0 2px}\n\n\/* CURRENTLY IN CARDS *\/\n.ci-card{background:#fff;border:1.5px solid var(--border);border-radius:12px;padding:18px;transition:var(--tr)}\n.ci-card:hover{border-color:var(--teal);box-shadow:0 4px 16px rgba(0,168,150,.1)}\n.ci-avatar{width:50px;height:50px;border-radius:50%;background:linear-gradient(135deg,var(--teal),var(--navy));display:flex;align-items:center;justify-content:center;color:#fff;font-size:20px;font-weight:700;flex-shrink:0}\n.ci-info-row{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--muted);margin-top:4px}\n.ci-info-row i{color:var(--teal);font-size:13px}\n\n\/* MISC *\/\n#live-clock{font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums}\n.mini-bar{display:flex;align-items:flex-end;gap:4px;height:60px}\n.mini-bar-col{background:rgba(0,168,150,.25);border-radius:3px 3px 0 0;flex:1;min-width:6px;transition:var(--tr)}\n.mini-bar-col:hover{background:var(--teal)}\n.hamburger{display:none;background:none;border:none;font-size:20px;cursor:pointer;color:var(--navy)}\n@media(max-width:768px){\n  .hamburger{display:flex}\n  .sidebar{transform:translateX(-100%)}\n  .sidebar.open{transform:translateX(0)}\n  .main-content{margin-left:0}\n  .page-content{padding:16px}\n}\n<\/style>\n\n\n\n<!-- AUTH -->\n<div id=\"auth-screen\">\n  <div class=\"auth-card\">\n    <div class=\"auth-logo\">\n      <div class=\"auth-logo-icon\"><i class=\"bi bi-shield-check\"><\/i><\/div>\n      <div class=\"auth-logo-text\"><h1>Meditech<\/h1><span>Visitor Management<\/span><\/div>\n    <\/div>\n    <div class=\"mb-3\">\n      <label>Email Address<\/label>\n      <input type=\"email\" id=\"login-email\" class=\"form-control\" placeholder=\"your@email.com\" autocomplete=\"username\">\n    <\/div>\n    <div class=\"mb-4\">\n      <label>Password<\/label>\n      <input type=\"password\" id=\"login-password\" class=\"form-control\" placeholder=\"\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\" autocomplete=\"current-password\">\n    <\/div>\n    <button class=\"btn-teal w-100 justify-content-center py-2\" style=\"font-size:15px\" onclick=\"doLogin()\">\n      <i class=\"bi bi-box-arrow-in-right\"><\/i> Sign In\n    <\/button>\n    <div id=\"login-error\" class=\"text-danger mt-2 text-center\" style=\"font-size:13px\"><\/div>\n  <\/div>\n<\/div>\n\n<!-- APP -->\n<div id=\"app\">\n  <aside class=\"sidebar\" id=\"sidebar\">\n    <div class=\"sidebar-logo\">\n      <div class=\"sidebar-logo-icon\"><i class=\"bi bi-shield-check\"><\/i><\/div>\n      <div class=\"sidebar-logo-text\"><h2>Meditech<\/h2><span>VMS<\/span><\/div>\n    <\/div>\n    <div class=\"nav-section-label\">Main<\/div>\n    <nav>\n      <a href=\"#\" onclick=\"showPage('dashboard')\" id=\"nav-dashboard\" class=\"active\"><i class=\"bi bi-grid-1x2-fill\"><\/i> Dashboard<\/a>\n      <a href=\"#\" onclick=\"showPage('currently-in')\" id=\"nav-currently-in\"><i class=\"bi bi-person-check-fill\"><\/i> Currently Inside <span class=\"nav-badge\" id=\"nav-badge-in\">0<\/span><\/a>\n    <\/nav>\n    <div class=\"nav-section-label\">Visitors<\/div>\n    <nav>\n      <a href=\"#\" onclick=\"showPage('checkin')\" id=\"nav-checkin\"><i class=\"bi bi-box-arrow-in-right\"><\/i> Check-In<\/a>\n      <a href=\"#\" onclick=\"showPage('visitors')\" id=\"nav-visitors\"><i class=\"bi bi-people-fill\"><\/i> Visitor Records<\/a>\n      <a href=\"#\" onclick=\"showPage('visits')\" id=\"nav-visits\"><i class=\"bi bi-calendar2-check\"><\/i> Visit Log<\/a>\n    <\/nav>\n    <div class=\"nav-section-label\" id=\"nav-section-admin\">Admin<\/div>\n    <nav id=\"admin-nav\">\n      <a href=\"#\" onclick=\"showPage('reports')\" id=\"nav-reports\"><i class=\"bi bi-bar-chart-fill\"><\/i> Reports<\/a>\n      <a href=\"#\" onclick=\"showPage('users')\" id=\"nav-users\"><i class=\"bi bi-person-badge-fill\"><\/i> Users<\/a>\n      <a href=\"#\" onclick=\"showPage('settings')\" id=\"nav-settings\"><i class=\"bi bi-gear-fill\"><\/i> Settings<\/a>\n    <\/nav>\n    <div class=\"sidebar-footer\">\n      <div class=\"user-chip\">\n        <div class=\"user-avatar\" id=\"sidebar-avatar\">A<\/div>\n        <div class=\"user-info\"><strong id=\"sidebar-name\">User<\/strong><span id=\"sidebar-role\">role<\/span><\/div>\n        <button class=\"btn-logout ms-auto\" onclick=\"doLogout()\"><i class=\"bi bi-power\"><\/i><\/button>\n      <\/div>\n    <\/div>\n  <\/aside>\n\n  <div class=\"main-content\">\n    \n      <div class=\"d-flex align-items-center gap-3\">\n        <button class=\"hamburger\" onclick=\"document.getElementById('sidebar').classList.toggle('open')\"><i class=\"bi bi-list\"><\/i><\/button>\n        <span class=\"topbar-title\" id=\"page-title\">Dashboard<\/span>\n      <\/div>\n      <div class=\"topbar-actions\">\n        <span id=\"live-clock\"><\/span>\n        <button class=\"btn-teal\" onclick=\"showPage('checkin')\"><i class=\"bi bi-plus-circle\"><\/i> New Check-In<\/button>\n      <\/div>\n    <\/header>\n    <div class=\"page-content\" id=\"page-content\"><\/div>\n  <\/div>\n<\/div>\n\n<div id=\"toast-wrap\"><\/div>\n\n<!-- MODALS -->\n<div class=\"modal fade\" id=\"visitorModal\" tabindex=\"-1\">\n  <div class=\"modal-dialog modal-lg\"><div class=\"modal-content border-0 shadow\">\n    <div class=\"modal-header\"><h5 class=\"modal-title\"><i class=\"bi bi-person-circle me-2\"><\/i>Visitor Profile<\/h5><button type=\"button\" class=\"btn-close\" data-bs-dismiss=\"modal\"><\/button><\/div>\n    <div class=\"modal-body\" id=\"visitor-modal-body\">Loading\u2026<\/div>\n  <\/div><\/div>\n<\/div>\n<div class=\"modal fade\" id=\"badgeModal\" tabindex=\"-1\">\n  <div class=\"modal-dialog modal-sm\"><div class=\"modal-content border-0 shadow\">\n    <div class=\"modal-header\"><h5 class=\"modal-title\"><i class=\"bi bi-qr-code me-2\"><\/i>Visitor Badge<\/h5><button type=\"button\" class=\"btn-close\" data-bs-dismiss=\"modal\"><\/button><\/div>\n    <div class=\"modal-body\" id=\"badge-modal-body\"><\/div>\n    <div class=\"modal-footer\"><button class=\"btn-teal\" onclick=\"window.print()\"><i class=\"bi bi-printer\"><\/i> Print<\/button><\/div>\n  <\/div><\/div>\n<\/div>\n<div class=\"modal fade\" id=\"checkoutModal\" tabindex=\"-1\">\n  <div class=\"modal-dialog modal-sm\"><div class=\"modal-content border-0\">\n    <div class=\"modal-header\"><h5 class=\"modal-title\">Confirm Check-Out<\/h5><button type=\"button\" class=\"btn-close\" data-bs-dismiss=\"modal\"><\/button><\/div>\n    <div class=\"modal-body\" id=\"checkout-modal-body\"><\/div>\n    <div class=\"modal-footer\">\n      <button class=\"btn btn-secondary btn-sm\" data-bs-dismiss=\"modal\">Cancel<\/button>\n      <button class=\"btn btn-success btn-sm\" id=\"confirm-checkout-btn\">Check Out<\/button>\n    <\/div>\n  <\/div><\/div>\n<\/div>\n<div class=\"modal fade\" id=\"cameraModal\" tabindex=\"-1\">\n  <div class=\"modal-dialog\"><div class=\"modal-content border-0\">\n    <div class=\"modal-header\"><h5 class=\"modal-title\" id=\"cam-title\"><i class=\"bi bi-camera me-2\"><\/i>Capture Photo<\/h5><button type=\"button\" class=\"btn-close\" data-bs-dismiss=\"modal\" onclick=\"stopCamera()\"><\/button><\/div>\n    <div class=\"modal-body\">\n      <input type=\"file\" id=\"cam-file\" accept=\"image\/*\" style=\"display:none\" onchange=\"onCamFile(event)\">\n      <div id=\"cam-preview\"><div id=\"cam-idle\" style=\"display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;padding:30px 0;gap:10px\"><i class=\"bi bi-camera\" style=\"font-size:50px;color:var(--muted)\"><\/i><p style=\"color:var(--muted);font-size:13px;margin:0\">Loading\u2026<\/p><\/div>\n        <video id=\"cam-video\" autoplay playsinline style=\"display:none\"><\/video>\n        <canvas id=\"cam-canvas\" style=\"display:none\"><\/canvas>\n        <img id=\"cam-img\" style=\"display:none;width:100%;height:100%;object-fit:cover\" alt=\"\">\n      <\/div>\n      <div class=\"d-flex gap-2 mt-3 justify-content-center flex-wrap\">\n        <button class=\"btn-teal\" id=\"cam-capture-btn\" onclick=\"capturePhoto()\" style=\"display:none\"><i class=\"bi bi-camera\"><\/i> Capture<\/button>\n        <button class=\"btn-navy\" id=\"cam-retake-btn\" onclick=\"retakePhoto()\" style=\"display:none\"><i class=\"bi bi-arrow-counterclockwise\"><\/i> Retake<\/button>\n        <button class=\"btn-navy\" id=\"cam-upload-btn\" onclick=\"document.getElementById('cam-file').click()\" style=\"display:none\"><i class=\"bi bi-upload\"><\/i> Upload Photo<\/button>\n      <\/div>\n    <\/div>\n    <div class=\"modal-footer\">\n      <button class=\"btn btn-secondary btn-sm\" data-bs-dismiss=\"modal\" onclick=\"stopCamera()\">Cancel<\/button>\n      <button class=\"btn-teal\" id=\"cam-use-btn\" style=\"display:none\" onclick=\"usePhoto()\"><i class=\"bi bi-check-lg\"><\/i> Use Photo<\/button>\n    <\/div>\n  <\/div><\/div>\n<\/div>\n<div class=\"modal fade\" id=\"signatureModal\" tabindex=\"-1\">\n  <div class=\"modal-dialog\"><div class=\"modal-content border-0\">\n    <div class=\"modal-header\"><h5 class=\"modal-title\"><i class=\"bi bi-pen me-2\"><\/i>Visitor Signature<\/h5><button type=\"button\" class=\"btn-close\" data-bs-dismiss=\"modal\"><\/button><\/div>\n    <div class=\"modal-body text-center\">\n      <canvas id=\"sig-canvas\" class=\"sig-canvas\" width=\"460\" height=\"180\"><\/canvas>\n      <div class=\"mt-3\"><button class=\"btn-navy\" onclick=\"clearSig()\"><i class=\"bi bi-trash\"><\/i> Clear<\/button><\/div>\n    <\/div>\n    <div class=\"modal-footer\">\n      <button class=\"btn btn-secondary btn-sm\" data-bs-dismiss=\"modal\">Cancel<\/button>\n      <button class=\"btn-teal\" onclick=\"saveSig()\">Save Signature<\/button>\n    <\/div>\n  <\/div><\/div>\n<\/div>\n<div class=\"modal fade\" id=\"userModal\" tabindex=\"-1\">\n  <div class=\"modal-dialog\"><div class=\"modal-content border-0\">\n    <div class=\"modal-header\"><h5 class=\"modal-title\" id=\"user-modal-title\">Add User<\/h5><button type=\"button\" class=\"btn-close\" data-bs-dismiss=\"modal\"><\/button><\/div>\n    <div class=\"modal-body\" id=\"user-modal-body\"><\/div>\n    <div class=\"modal-footer\">\n      <button class=\"btn btn-secondary btn-sm\" data-bs-dismiss=\"modal\">Cancel<\/button>\n      <button class=\"btn-teal\" id=\"save-user-btn\">Save<\/button>\n    <\/div>\n  <\/div><\/div>\n<\/div>\n\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/bootstrap\/5.3.2\/js\/bootstrap.bundle.min.js\"><\/script>\n<script>\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\u2550\n\/\/  CORE UTILS\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\u2550\nconst API   = (window.MVMS_API   || window.location.origin+'\/wp-json\/mvms\/v1');\nconst NONCE = (window.MVMS_NONCE || '');\nlet TOKEN = localStorage.getItem('vms_token');\nlet USER  = JSON.parse(localStorage.getItem('vms_user')||'null');\nconst DEMO = false;\n\n\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\u2550\n\/\/  CORE UTILS\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\u2550\nconst API   = (window.MVMS_API   || window.location.origin+'\/wp-json\/mvms\/v1');\nconst NONCE = (window.MVMS_NONCE || '');\nlet TOKEN = localStorage.getItem('vms_token');\nlet USER  = JSON.parse(localStorage.getItem('vms_user')||'null');\nconst DEMO = false;\n\nconst $   = id => document.getElementById(id);\nconst fd  = d => d?new Date(d).toLocaleDateString('en-GB',{day:'2-digit',month:'short',year:'numeric'}):'\u2014';\nconst ft  = t => t?t.slice(0,5):'\u2014';\n\nfunction toast(msg,type='ok'){\n  const t=document.createElement('div');\n  t.className=`toast-msg toast-${type}`;\n  t.innerHTML=`<i class=\"bi bi-${type==='ok'?'check-circle-fill text-success':'x-circle-fill text-danger'}\"><\/i><span>${msg}<\/span>`;\n  $('toast-wrap').appendChild(t);\n  setTimeout(()=>t.remove(),3500);\n}\n\nasync function api(method,ep,body=null){\n  const opts={method,headers:{'Authorization':'Bearer '+TOKEN,'X-WP-Nonce':NONCE}};\n  if(body){opts.headers['Content-Type']='application\/json';opts.body=JSON.stringify(body);}\n  try{\n    const r=await fetch(API+ep,opts);\n    const j=await r.json();\n    return {\n      success: j.ok||j.success||false,\n      ok:      j.ok||j.success||false,\n      data:    j.data,\n      message: j.msg||j.message||'',\n      msg:     j.msg||j.message||''\n    };\n  }catch(e){\n    return {success:false,ok:false,data:null,message:e.message,msg:e.message};\n  }\n}\n\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\u2550\n\/\/  AUTH\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\u2550\nasync function doLogin(){\n  const email=($('login-email').value||'').trim().toLowerCase();\n  const pw=$('login-password').value||'';\n  const err=$('login-error');\n  err.textContent='';\n  if(!email||!pw){err.textContent='Please enter email and password.';return;}\n  const r=await api('POST','\/login',{email,password:pw});\n  if(!r.ok){err.textContent=r.msg||'Invalid email or password.';return;}\n  TOKEN=r.data.token; USER=r.data.user;\n  localStorage.setItem('vms_token',TOKEN);\n  localStorage.setItem('vms_user',JSON.stringify(USER));\n  bootApp();\n}\n\nfunction doLogout(){\n  localStorage.removeItem('vms_token'); localStorage.removeItem('vms_user');\n  TOKEN=null; USER=null;\n  $('app').style.display='none'; $('auth-screen').style.display='flex';\n}\n\nfunction bootApp(){\n  if(!USER){$('auth-screen').style.display='flex';return;}\n  $('auth-screen').style.display='none';\n  $('app').style.display='flex';\n  $('sidebar-name').textContent=USER.full_name;\n  $('sidebar-role').textContent=USER.role;\n  $('sidebar-avatar').textContent=USER.full_name[0].toUpperCase();\n  if(USER.role!=='admin'){$('admin-nav').style.display='none';$('nav-section-admin').style.display='none';}\n  else{$('admin-nav').style.display='';$('nav-section-admin').style.display='';}\n  const tick=()=>{$('live-clock').textContent=new Date().toLocaleTimeString('en-GB',{hour:'2-digit',minute:'2-digit',second:'2-digit'})};\n  tick(); setInterval(tick,1000);\n  showPage('dashboard');\n  refreshBadge();\n  setInterval(refreshBadge,30000);\n}\n\nasync function refreshBadge(){\n  const r=await api('GET','\/visits\/currently-in');\n  if(r.success) $('nav-badge-in').textContent=r.count||0;\n}\n\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\u2550\n\/\/  ROUTING\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\u2550\nfunction showPage(page){\n  document.querySelectorAll('.sidebar nav a').forEach(a=>a.classList.remove('active'));\n  const n=$(`nav-${page}`); if(n) n.classList.add('active');\n  const titles={dashboard:'Dashboard',checkin:'Check-In Visitor','currently-in':'Currently Inside',\n    visitors:'Visitor Records',visits:'Visit Log',reports:'Reports & Analytics',users:'User Management',settings:'Settings'};\n  $('page-title').textContent=titles[page]||page;\n  ({dashboard:renderDashboard,checkin:renderCheckin,'currently-in':renderCurrentlyIn,\n    visitors:renderVisitors,visits:renderVisits,reports:renderReports,users:renderUsers,settings:renderSettings}[page]||renderDashboard)();\n}\n\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\u2550\n\/\/  DASHBOARD\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\u2550\nasync function renderDashboard(){\n  const el=$('page-content');\n  el.innerHTML='<div class=\"text-center py-5\"><div class=\"spinner-border text-secondary\"><\/div><\/div>';\n  const r=await api('GET','\/reports\/summary'); if(!r.success){el.innerHTML='<div class=\"alert alert-danger\">Failed<\/div>';return;}\n  const d=r.data, trend=d.dailyTrend||[];\n  const maxT=Math.max(...trend.map(x=>x.count),1);\n  const bars=trend.map(x=>`<div class=\"mini-bar-col\" style=\"height:${Math.round(x.count\/maxT*100)}%\" title=\"${x.visit_date}: ${x.count}\"><\/div>`).join('');\n  el.innerHTML=`\n  <div class=\"row g-3 mb-4\">\n    <div class=\"col-6 col-lg-3\"><div class=\"stat-card\"><div class=\"stat-icon\" style=\"background:rgba(0,168,150,.1)\"><i class=\"bi bi-person-plus text-success\" style=\"font-size:22px\"><\/i><\/div><div class=\"stat-num\">${d.total_today}<\/div><div class=\"stat-label\">Today's Visitors<\/div><\/div><\/div>\n    <div class=\"col-6 col-lg-3\"><div class=\"stat-card\"><div class=\"stat-icon\" style=\"background:rgba(72,202,228,.12)\"><i class=\"bi bi-person-check-fill\" style=\"font-size:22px;color:#1B7CCC\"><\/i><\/div><div class=\"stat-num\" style=\"color:var(--teal)\">${d.currently_in}<\/div><div class=\"stat-label\">Currently Inside<\/div><\/div><\/div>\n    <div class=\"col-6 col-lg-3\"><div class=\"stat-card\"><div class=\"stat-icon\" style=\"background:rgba(244,162,97,.12)\"><i class=\"bi bi-calendar-week\" style=\"font-size:22px;color:#b5591a\"><\/i><\/div><div class=\"stat-num\">${d.total_week}<\/div><div class=\"stat-label\">This Week<\/div><\/div><\/div>\n    <div class=\"col-6 col-lg-3\"><div class=\"stat-card\"><div class=\"stat-icon\" style=\"background:rgba(13,43,69,.08)\"><i class=\"bi bi-people-fill\" style=\"font-size:22px;color:var(--navy)\"><\/i><\/div><div class=\"stat-num\">${d.total}<\/div><div class=\"stat-label\">Total Visitors<\/div><\/div><\/div>\n  <\/div>\n  <div class=\"row g-3 mb-3\">\n    <div class=\"col-lg-7\"><div class=\"card\"><div class=\"card-hdr\"><h5><i class=\"bi bi-graph-up me-2 text-success\"><\/i>Visit Trend<\/h5><\/div><div class=\"p-3\"><div class=\"mini-bar\" style=\"height:80px;gap:5px\">${bars}<\/div><\/div><\/div><\/div>\n    <div class=\"col-lg-5\"><div class=\"card h-100\"><div class=\"card-hdr\"><h5><i class=\"bi bi-person-lines-fill me-2 text-primary\"><\/i>Top Hosts<\/h5><\/div><div class=\"p-3\">${(d.topHosts||[]).map((h,i)=>`<div class=\"d-flex align-items-center gap-2 mb-2\"><div style=\"width:20px;font-size:11px;font-weight:700;color:var(--muted)\">#${i+1}<\/div><div style=\"flex:1;font-size:13px\">${h.host_name}<\/div><span class=\"bs bs-in\">${h.visits}<\/span><\/div>`).join('')}<\/div><\/div><\/div>\n  <\/div>\n  <div class=\"card\"><div class=\"card-hdr\"><h5><i class=\"bi bi-person-check-fill me-2\" style=\"color:var(--teal)\"><\/i>Currently Inside<\/h5><a href=\"#\" onclick=\"showPage('currently-in')\" style=\"font-size:12px;color:var(--teal)\">View all \u2192<\/a><\/div><div class=\"p-3\" id=\"dash-ci\">Loading\u2026<\/div><\/div>`;\n  const ci=await api('GET','\/visits\/currently-in');\n  const ciel=$('dash-ci');\n  if(ci.success&&ci.data.length){\n    ciel.innerHTML=`<div class=\"row g-2\">${ci.data.slice(0,4).map(v=>`<div class=\"col-md-6\"><div class=\"ci-card d-flex align-items-center gap-3\"><div class=\"ci-avatar\">${(v.visitor_name||'?')[0]}<\/div><div style=\"flex:1;min-width:0\"><strong style=\"font-size:13px\">${v.visitor_name}<\/strong><div class=\"ci-info-row\"><i class=\"bi bi-building\"><\/i>${v.company_name||'Individual'}<\/div><div class=\"ci-info-row\"><i class=\"bi bi-clock\"><\/i>Since ${ft(v.check_in_time)}<\/div><\/div><button class=\"btn-teal\" onclick=\"startCheckout(${v.id},'${(v.visitor_name||'').replace(\/'\/g,\"\\\\'\")}')\"><i class=\"bi bi-box-arrow-right\"><\/i><\/button><\/div><\/div>`).join('')}<\/div>`;\n  } else ciel.innerHTML='<div style=\"color:var(--muted);font-size:13px\">No visitors currently inside.<\/div>';\n}\n\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\u2550\n\/\/  CHECK-IN\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\u2550\nlet ciPhoto=null, ciSig=null, ciVisitorId=null;\nasync function renderCheckin(){\n  const el=$('page-content');\n  const td=TODAY, tn=new Date().toTimeString().slice(0,5);\n  el.innerHTML=`\n  <div class=\"row justify-content-center\"><div class=\"col-xl-8\"><div class=\"card\">\n  <div class=\"card-hdr\"><h5><i class=\"bi bi-person-plus-fill me-2\" style=\"color:var(--teal)\"><\/i>New Visitor Check-In<\/h5><\/div>\n  <div class=\"p-4\">\n    <div class=\"sec-title\"><i class=\"bi bi-person-vcard\"><\/i>Visitor Information<\/div>\n    <div class=\"row g-3 mb-4\">\n      <div class=\"col-md-6\"><label class=\"form-label\">Full Name *<\/label><input type=\"text\" id=\"ci-name\" class=\"form-control\" placeholder=\"John Smith\"><\/div>\n      <div class=\"col-md-6\"><label class=\"form-label\">ID Card \/ Passport<\/label>\n        <div class=\"input-group\"><input type=\"text\" id=\"ci-idnum\" class=\"form-control\" placeholder=\"A12345678 (optional)\" oninput=\"lookupVisitor()\"><span class=\"input-group-text\" id=\"ci-look\" style=\"background:#fff\"><i class=\"bi bi-search text-secondary\"><\/i><\/span><\/div>\n        <div id=\"ci-notice\" style=\"font-size:11px;color:var(--teal);margin-top:4px\"><\/div>\n      <\/div>\n      <div class=\"col-md-6\"><label class=\"form-label\">Job Title<\/label><input type=\"text\" id=\"ci-job\" class=\"form-control\" placeholder=\"CEO, Engineer\u2026\"><\/div>\n      <div class=\"col-md-6\"><label class=\"form-label\">Phone *<\/label><input type=\"tel\" id=\"ci-phone\" class=\"form-control\" placeholder=\"+1-555-0100\"><\/div>\n      <div class=\"col-md-6\"><label class=\"form-label\">Company<\/label><input type=\"text\" id=\"ci-company\" class=\"form-control\" placeholder=\"(optional)\"><\/div>\n      <div class=\"col-md-6\"><label class=\"form-label\">Email<\/label><input type=\"email\" id=\"ci-email\" class=\"form-control\" placeholder=\"(optional)\"><\/div>\n    <\/div>\n    <div class=\"sec-title\"><i class=\"bi bi-camera\"><\/i>Capture (Optional)<\/div>\n    <div class=\"row g-3 mb-4\">\n      <div class=\"col-md-6\"><label class=\"form-label\">Photo<\/label>\n        <div class=\"d-flex gap-2 align-items-center\">\n          <div id=\"photo-preview\" style=\"width:60px;height:60px;border-radius:50%;background:var(--border);display:flex;align-items:center;justify-content:center;overflow:hidden;flex-shrink:0\"><i class=\"bi bi-person\" style=\"font-size:26px;color:var(--muted)\"><\/i><\/div>\n          <button class=\"btn-navy\" type=\"button\" onclick=\"openCamera()\"><i class=\"bi bi-camera\"><\/i> Capture<\/button>\n        <\/div>\n      <\/div>\n      <div class=\"col-md-6\"><label class=\"form-label\">Signature<\/label>\n        <div class=\"d-flex gap-2 align-items-center\">\n          <div id=\"sig-preview\" style=\"width:100px;height:40px;border:1.5px solid var(--border);border-radius:6px;background:#fff;display:flex;align-items:center;justify-content:center\"><span style=\"font-size:10px;color:var(--muted)\">No signature<\/span><\/div>\n          <button class=\"btn-navy\" type=\"button\" onclick=\"openSig()\"><i class=\"bi bi-pen\"><\/i> Sign<\/button>\n        <\/div>\n      <\/div>\n    <\/div>\n    <div class=\"sec-title\"><i class=\"bi bi-calendar-check\"><\/i>Visit Details<\/div>\n    <div class=\"row g-3 mb-4\">\n      <div class=\"col-md-12\"><label class=\"form-label\">Purpose of Visit *<\/label><input type=\"text\" id=\"ci-purpose\" class=\"form-control\" placeholder=\"Meeting, Interview, Delivery\u2026\"><\/div>\n      <div class=\"col-md-6\"><label class=\"form-label\">Host Name *<\/label><input type=\"text\" id=\"ci-host\" class=\"form-control\" placeholder=\"Dr. Ahmed Salam\"><\/div>\n      <div class=\"col-md-6\"><label class=\"form-label\">Host Phone<\/label><input type=\"tel\" id=\"ci-hostph\" class=\"form-control\" placeholder=\"(optional)\"><\/div>\n      <div class=\"col-md-6\"><label class=\"form-label\">Department<\/label><input type=\"text\" id=\"ci-dept\" class=\"form-control\" placeholder=\"IT, Finance, HR\u2026\"><\/div>\n      <div class=\"col-md-3\"><label class=\"form-label\">Date<\/label><input type=\"date\" id=\"ci-date\" class=\"form-control\" value=\"${td}\"><\/div>\n      <div class=\"col-md-3\"><label class=\"form-label\">Time<\/label><input type=\"time\" id=\"ci-time\" class=\"form-control\" value=\"${tn}\"><\/div>\n    <\/div>\n    <div class=\"sec-title\"><i class=\"bi bi-bell\"><\/i>Notifications<\/div>\n    <div class=\"d-flex gap-4 mb-4\">\n      <div class=\"form-check\"><input class=\"form-check-input\" type=\"checkbox\" id=\"ci-sms\"><label class=\"form-check-label\" for=\"ci-sms\">SMS to Host<\/label><\/div>\n      <div class=\"form-check\"><input class=\"form-check-input\" type=\"checkbox\" id=\"ci-email2\"><label class=\"form-check-label\" for=\"ci-email2\">Email to Host<\/label><\/div>\n    <\/div>\n    <div class=\"mb-4\"><label class=\"form-label\">Notes<\/label><textarea id=\"ci-notes\" class=\"form-control\" rows=\"2\" placeholder=\"Any additional notes\u2026\"><\/textarea><\/div>\n    <div class=\"d-flex gap-3\">\n      <button class=\"btn-teal px-4 py-2\" style=\"font-size:14px\" onclick=\"submitCheckin()\"><i class=\"bi bi-box-arrow-in-right\"><\/i> Check In & Generate Badge<\/button>\n      <button class=\"btn-navy\" onclick=\"ciPhoto=null;ciSig=null;ciVisitorId=null;renderCheckin()\"><i class=\"bi bi-x-circle\"><\/i> Reset<\/button>\n    <\/div>\n    <div id=\"ci-err\" class=\"text-danger mt-2\" style=\"font-size:13px\"><\/div>\n  <\/div><\/div><\/div><\/div>`;\n  ciPhoto=null; ciSig=null; ciVisitorId=null;\n}\n\nlet lookTimer=null;\nfunction lookupVisitor(){\n  clearTimeout(lookTimer);\n  lookTimer=setTimeout(async()=>{\n    const q=($('ci-idnum')||{value:''}).value.trim();\n    if(q.length<3) return;\n    const r=await api('GET',`\/visitors?q=${encodeURIComponent(q)}`);\n    if(r.success&&r.data){\n      const m=r.data.find(v=>v.id_number===q);\n      if(m){\n        ciVisitorId=m.id;\n        $('ci-name').value=m.full_name||''; $('ci-job').value=m.job_title||'';\n        $('ci-phone').value=m.phone||''; $('ci-company').value=m.company_name||''; $('ci-email').value=m.email||'';\n        $('ci-notice').innerHTML='<i class=\"bi bi-check-circle-fill\"><\/i> Returning visitor \u2014 details pre-filled';\n        $('ci-look').innerHTML='<i class=\"bi bi-check-circle-fill\" style=\"color:var(--teal)\"><\/i>';\n      } else { ciVisitorId=null; $('ci-notice').textContent=''; }\n    }\n  },400);\n}\n\nasync function submitCheckin(){\n  const name=($('ci-name').value||'').trim(), phone=($('ci-phone').value||'').trim();\n  const purpose=($('ci-purpose').value||'').trim(), host=($('ci-host').value||'').trim();\n  const errEl=$('ci-err');\n  if(!name||!phone||!purpose||!host){errEl.textContent='Name, Phone, Purpose and Host Name are required.';return;}\n  errEl.textContent='';\n  let vid=ciVisitorId;\n  if(!vid){\n    const vr=await api('POST','\/visitors',{full_name:name,id_number:($('ci-idnum').value||'').trim(),job_title:$('ci-job').value,phone,company_name:$('ci-company').value,email:$('ci-email').value});\n    if(!vr.success){errEl.textContent=vr.message||'Failed to create visitor';return;}\n    vid=vr.data.id;\n  }\n  const vr2=await api('POST','\/visits',{\n    visitor_id:vid,purpose,host_name:host,host_phone:($('ci-hostph').value||''),\n    host_department:$('ci-dept').value,visit_date:$('ci-date').value,\n    check_in_time:$('ci-time').value+':00',notes:$('ci-notes').value,\n    notify_sms:$('ci-sms').checked,notify_email:$('ci-email2').checked\n  });\n  if(!vr2.success){errEl.textContent=vr2.message||'Failed to check in';return;}\n  toast(`${name} checked in!`);\n  refreshBadge();\n  showBadge(vr2.data);\n}\n\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\u2550\n\/\/  CURRENTLY INSIDE  \u2014 full-width cards, same layout as other pages\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\u2550\nasync function renderCurrentlyIn(){\n  const el=$('page-content');\n  el.innerHTML='<div class=\"text-center py-5\"><div class=\"spinner-border text-secondary\"><\/div><\/div>';\n  const r=await api('GET','\/visits\/currently-in');\n  if(!r.success){el.innerHTML='<div class=\"alert alert-danger\">Error loading<\/div>';return;}\n  const list=r.data;\n  el.innerHTML=`\n  <div class=\"d-flex justify-content-between align-items-center mb-3\">\n    <h6 class=\"mb-0\" style=\"color:var(--muted)\">${list.length} visitor${list.length!==1?'s':''} currently inside<\/h6>\n    <button class=\"btn-teal\" onclick=\"renderCurrentlyIn()\"><i class=\"bi bi-arrow-clockwise\"><\/i> Refresh<\/button>\n  <\/div>\n  ${list.length===0?`<div class=\"card p-5 text-center\"><i class=\"bi bi-building-check\" style=\"font-size:52px;color:var(--border)\"><\/i><p class=\"mt-3 mb-0 text-muted\">No visitors currently inside<\/p><\/div>`:''}\n  <div class=\"row g-3\">\n  ${list.map(v=>`\n    <div class=\"col-md-6 col-xl-4\">\n      <div class=\"ci-card\">\n        <div class=\"d-flex align-items-center gap-3 mb-3\">\n          <div class=\"ci-avatar\">${(v.visitor_name||'?')[0]}<\/div>\n          <div style=\"flex:1;min-width:0\">\n            <strong style=\"font-size:15px;display:block\">${v.visitor_name}<\/strong>\n            <span style=\"font-size:12px;color:var(--muted)\">${v.id_number||'\u2014'}<\/span>\n          <\/div>\n          <span class=\"bs bs-in\"><i class=\"bi bi-circle-fill\" style=\"font-size:7px\"><\/i> Inside<\/span>\n        <\/div>\n        <div style=\"background:#f8fafb;border-radius:8px;padding:10px 12px;margin-bottom:12px\">\n          <div class=\"ci-info-row mb-1\"><i class=\"bi bi-building\"><\/i><span>${v.company_name||'Individual'}<\/span><\/div>\n          <div class=\"ci-info-row mb-1\"><i class=\"bi bi-bullseye\"><\/i><span>${v.purpose}<\/span><\/div>\n          <div class=\"ci-info-row mb-1\"><i class=\"bi bi-person\"><\/i><span>Host: <strong>${v.host_name}<\/strong>${v.host_department?' ('+v.host_department+')':''}<\/span><\/div>\n          <div class=\"ci-info-row\"><i class=\"bi bi-clock\"><\/i><span>Checked in at <strong>${ft(v.check_in_time)}<\/strong><\/span><\/div>\n        <\/div>\n        <div class=\"d-flex gap-2\">\n          <button class=\"btn-teal flex-fill justify-content-center\" onclick=\"startCheckout(${v.id},'${(v.visitor_name||'').replace(\/'\/g,\"\\\\'\")}')\"><i class=\"bi bi-box-arrow-right\"><\/i> Check Out<\/button>\n          <button class=\"btn-icon\" title=\"Badge\" onclick=\"showBadgeCode('${v.badge_code}','${(v.visitor_name||'').replace(\/'\/g,\"\\\\'\")}')\"><i class=\"bi bi-qr-code\"><\/i><\/button>\n        <\/div>\n      <\/div>\n    <\/div>`).join('')}\n  <\/div>`;\n}\n\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\u2550\n\/\/  VISITOR RECORDS\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\u2550\nasync function renderVisitors(page=1,q=''){\n  const el=$('page-content');\n  el.innerHTML=`<div class=\"card\"><div class=\"card-hdr\"><h5><i class=\"bi bi-people-fill me-2\" style=\"color:var(--teal)\"><\/i>Visitor Records<\/h5><div class=\"d-flex gap-2\"><div class=\"input-group\" style=\"width:220px\"><span class=\"input-group-text\" style=\"background:#fff\"><i class=\"bi bi-search text-secondary\"><\/i><\/span><input type=\"text\" id=\"vsearch\" class=\"form-control\" placeholder=\"Search\u2026\" value=\"${q}\" oninput=\"renderVisitors(1,this.value)\"><\/div><button class=\"btn-teal\" onclick=\"showPage('checkin')\"><i class=\"bi bi-plus\"><\/i> New<\/button><\/div><\/div>\n  <div class=\"table-responsive\"><table class=\"tbl\"><thead><tr><th>Visitor<\/th><th>ID Number<\/th><th>Phone<\/th><th>Company<\/th><th>Registered<\/th><th>Status<\/th><th>Actions<\/th><\/tr><\/thead>\n  <tbody id=\"vtbody\"><tr><td colspan=\"7\" class=\"text-center py-4\"><div class=\"spinner-border spinner-border-sm text-secondary\"><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n  <div class=\"p-3 d-flex justify-content-between align-items-center\" style=\"border-top:1px solid var(--border)\"><span id=\"vcount\" style=\"font-size:12px;color:var(--muted)\"><\/span><div class=\"d-flex gap-1\" id=\"vpager\"><\/div><\/div><\/div>`;\n  const r=await api('GET',`\/visitors?q=${encodeURIComponent(q)}&page=${page}&limit=15`);\n  const tb=$('vtbody');\n  if(!r.success||!r.data.length){tb.innerHTML=`<tr><td colspan=\"7\" class=\"text-center py-4 text-muted\">No visitors found<\/td><\/tr>`;return;}\n  $('vcount').textContent=`Showing ${r.data.length} of ${r.total}`;\n  tb.innerHTML=r.data.map(v=>`<tr>\n    <td><div class=\"d-flex align-items-center gap-2\"><div style=\"width:32px;height:32px;border-radius:50%;background:var(--teal);display:flex;align-items:center;justify-content:center;color:#fff;font-weight:700;font-size:13px;flex-shrink:0\">${v.full_name[0]}<\/div><div><strong style=\"font-size:13px\">${v.full_name}<\/strong><div style=\"font-size:11px;color:var(--muted)\">${v.job_title||''}<\/div><\/div><\/div><\/td>\n    <td style=\"font-family:monospace;font-size:12px\">${v.id_number||'\u2014'}<\/td>\n    <td>${v.phone}<\/td><td>${v.company_name||'\u2014'}<\/td><td>${fd(v.created_at)}<\/td>\n    <td>${v.is_blocked?'<span class=\"bs bs-cancel\"><i class=\"bi bi-slash-circle\"><\/i> Blocked<\/span>':'<span class=\"bs bs-in\"><i class=\"bi bi-check\"><\/i> Active<\/span>'}<\/td>\n    <td><div class=\"d-flex gap-1\"><button class=\"btn-icon\" title=\"View\" onclick=\"viewVisitor(${v.id})\"><i class=\"bi bi-eye\"><\/i><\/button><button class=\"btn-icon\" title=\"Check-In\" onclick=\"quickCheckin(${v.id},'${v.full_name.replace(\/'\/g,\"\\\\'\")}')\"><i class=\"bi bi-box-arrow-in-right\"><\/i><\/button><\/div><\/td>\n  <\/tr>`).join('');\n  const pages=Math.ceil(r.total\/15), pg=$('vpager'); pg.innerHTML='';\n  if(pages>1){const mk=(p,l)=>{const b=document.createElement('button');b.textContent=l||p;b.style.cssText='width:30px;height:30px;border-radius:7px;border:1px solid var(--border);background:#fff;cursor:pointer;font-size:12px';if(p===page)b.style.background='var(--teal)',b.style.color='#fff',b.style.border='none';b.onclick=()=>renderVisitors(p,q);pg.appendChild(b)};if(page>1)mk(page-1,'\u2039');for(let i=Math.max(1,page-2);i<=Math.min(pages,page+2);i++)mk(i);if(page<pages)mk(page+1,'\u203a');}\n}\n\nasync function viewVisitor(id){\n  const modal=new bootstrap.Modal($('visitorModal'));\n  $('visitor-modal-body').innerHTML='<div class=\"text-center py-4\"><div class=\"spinner-border text-secondary\"><\/div><\/div>';\n  modal.show();\n  const r=await api('GET',`\/visitors\/${id}`);\n  if(!r.success){$('visitor-modal-body').innerHTML='<div class=\"alert alert-danger\">Failed to load<\/div>';return;}\n  const v=r.data;\n  $('visitorModal').querySelector('.modal-title').innerHTML='<i class=\"bi bi-person-circle me-2\"><\/i>Visitor Profile';\n  $('visitor-modal-body').innerHTML=`<div class=\"row g-3\">\n    <div class=\"col-md-4 text-center\"><div style=\"width:90px;height:90px;border-radius:50%;background:var(--teal);display:flex;align-items:center;justify-content:center;color:#fff;font-size:36px;font-weight:700;margin:0 auto 12px\">${v.full_name[0]}<\/div>\n    <h5>${v.full_name}<\/h5><div style=\"font-size:12px;color:var(--muted)\">${v.job_title||''}<\/div>\n    <div class=\"mt-2\">${v.is_blocked?'<span class=\"bs bs-cancel\">Blocked<\/span>':'<span class=\"bs bs-in\">Active<\/span>'}<\/div><\/div>\n    <div class=\"col-md-8\"><div class=\"row g-2 mb-3\">\n      <div class=\"col-6\"><div style=\"font-size:11px;color:var(--muted)\">ID\/Passport<\/div><div style=\"font-size:13px;font-family:monospace\">${v.id_number||'\u2014'}<\/div><\/div>\n      <div class=\"col-6\"><div style=\"font-size:11px;color:var(--muted)\">Phone<\/div><div style=\"font-size:13px\">${v.phone}<\/div><\/div>\n      <div class=\"col-6\"><div style=\"font-size:11px;color:var(--muted)\">Company<\/div><div style=\"font-size:13px\">${v.company_name||'\u2014'}<\/div><\/div>\n      <div class=\"col-6\"><div style=\"font-size:11px;color:var(--muted)\">Email<\/div><div style=\"font-size:13px\">${v.email||'\u2014'}<\/div><\/div>\n      <div class=\"col-6\"><div style=\"font-size:11px;color:var(--muted)\">Registered<\/div><div style=\"font-size:13px\">${fd(v.created_at)}<\/div><\/div>\n      <div class=\"col-6\"><div style=\"font-size:11px;color:var(--muted)\">Total Visits<\/div><div style=\"font-size:13px\">${v.visits?.length||0}<\/div><\/div>\n    <\/div>\n    <div style=\"font-size:12px;font-weight:700;color:var(--navy);margin-bottom:8px\">Recent Visits<\/div>\n    <div style=\"max-height:160px;overflow-y:auto\">${(v.visits||[]).slice(0,5).map(vl=>`<div class=\"d-flex align-items-center gap-2 mb-2 p-2 rounded\" style=\"background:#f8f9fa\"><div style=\"flex:1\"><strong style=\"font-size:12px\">${vl.purpose}<\/strong><div style=\"font-size:11px;color:var(--muted)\">${vl.visit_date} \u00b7 ${vl.host_name}<\/div><\/div><span class=\"bs ${vl.status==='checked_in'?'bs-in':vl.status==='checked_out'?'bs-out':'bs-cancel'}\">${vl.status.replace('_',' ')}<\/span><\/div>`).join('')||'<p class=\"text-muted\" style=\"font-size:12px\">No visits<\/p>'}<\/div>\n    <\/div><\/div>`;\n}\n\nfunction quickCheckin(id,name){\n  showPage('checkin');\n  setTimeout(()=>{ciVisitorId=id;$('ci-name').value=name;$('ci-notice').innerHTML='<i class=\"bi bi-check-circle-fill\"><\/i> Returning visitor \u2014 fill visit details below';},100);\n}\n\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\u2550\n\/\/  VISIT LOG\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\u2550\nasync function renderVisits(q=''){\n  const el=$('page-content');\n  el.innerHTML=`<div class=\"card\"><div class=\"card-hdr\"><h5><i class=\"bi bi-journal-text me-2\" style=\"color:var(--teal)\"><\/i>Visit Log<\/h5>\n  <div class=\"d-flex gap-2 flex-wrap\">\n    <input type=\"text\" id=\"vsearch2\" class=\"form-control form-control-sm\" style=\"width:200px\" placeholder=\"Search\u2026\" value=\"${q}\" oninput=\"renderVisits(this.value)\">\n    <select id=\"vstat\" class=\"form-select form-select-sm\" style=\"width:140px\" onchange=\"renderVisits(document.getElementById('vsearch2').value)\">\n      <option value=\"\">All Status<\/option><option value=\"checked_in\">Checked In<\/option><option value=\"checked_out\">Checked Out<\/option><option value=\"cancelled\">Cancelled<\/option>\n    <\/select>\n  <\/div><\/div>\n  <div class=\"table-responsive\"><table class=\"tbl\"><thead><tr><th>Visitor<\/th><th>Date<\/th><th>In<\/th><th>Out<\/th><th>Purpose<\/th><th>Host<\/th><th>Status<\/th><th>Actions<\/th><\/tr><\/thead>\n  <tbody id=\"vtbody2\"><tr><td colspan=\"8\" class=\"text-center py-4\"><div class=\"spinner-border spinner-border-sm text-secondary\"><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n  <div class=\"p-3\" style=\"border-top:1px solid var(--border)\"><span id=\"vcount2\" style=\"font-size:12px;color:var(--muted)\"><\/span><\/div><\/div>`;\n  const st=document.getElementById('vstat')?.value||'';\n  const r=await api('GET',`\/visits?q=${encodeURIComponent(q)}&status=${st}&limit=50`);\n  const tb=$('vtbody2');\n  if(!r.success||!r.data.length){tb.innerHTML=`<tr><td colspan=\"8\" class=\"text-center py-4 text-muted\">No visits found<\/td><\/tr>`;return;}\n  $('vcount2').textContent=`${r.data.length} records`;\n  tb.innerHTML=r.data.map(v=>`<tr>\n    <td><strong style=\"font-size:13px\">${v.visitor_name}<\/strong><div style=\"font-size:11px;color:var(--muted)\">${v.id_number||'\u2014'}<\/div><\/td>\n    <td style=\"font-size:12px\">${v.visit_date}<\/td><td style=\"font-size:12px\">${ft(v.check_in_time)}<\/td><td style=\"font-size:12px\">${ft(v.check_out_time)}<\/td>\n    <td style=\"font-size:12px\">${v.purpose}<\/td><td style=\"font-size:12px\">${v.host_name}<\/td>\n    <td><span class=\"bs ${v.status==='checked_in'?'bs-in':v.status==='checked_out'?'bs-out':'bs-cancel'}\">${v.status.replace('_',' ')}<\/span><\/td>\n    <td><div class=\"d-flex gap-1\">${v.status==='checked_in'?`<button class=\"btn-teal\" style=\"padding:4px 10px;font-size:12px\" onclick=\"startCheckout(${v.id},'${(v.visitor_name||'').replace(\/'\/g,\"\\\\'\")}')\"><i class=\"bi bi-box-arrow-right\"><\/i><\/button>`:''}<button class=\"btn-icon\" onclick=\"showBadgeCode('${v.badge_code}','${(v.visitor_name||'').replace(\/'\/g,\"\\\\'\")}')\"><i class=\"bi bi-qr-code\"><\/i><\/button><\/div><\/td>\n  <\/tr>`).join('');\n}\n\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\u2550\n\/\/  REPORTS\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\u2550\nasync function renderReports(){\n  if(USER.role!=='admin'&&USER.role!=='receptionist'){$('page-content').innerHTML='<div class=\"alert alert-warning\">Access denied.<\/div>';return;}\n  const m30=new Date(Date.now()-30*864e5).toISOString().slice(0,10);\n  $('page-content').innerHTML=`\n  <div class=\"card mb-3\"><div class=\"card-hdr\"><h5><i class=\"bi bi-sliders me-2\"><\/i>Export & Filter<\/h5><\/div><div class=\"p-4\">\n    <div class=\"row g-3 align-items-end\">\n      <div class=\"col-md-3\"><label class=\"form-label\">From Date<\/label><input type=\"date\" id=\"rf\" class=\"form-control\" value=\"${m30}\" onchange=\"loadRptTable()\"><\/div>\n      <div class=\"col-md-3\"><label class=\"form-label\">To Date<\/label><input type=\"date\" id=\"rt\" class=\"form-control\" value=\"${TODAY}\" onchange=\"loadRptTable()\"><\/div>\n      <div class=\"col-md-2\"><label class=\"form-label\">Status<\/label><select id=\"rs\" class=\"form-select\" onchange=\"loadRptTable()\"><option value=\"\">All<\/option><option value=\"checked_in\">Checked In<\/option><option value=\"checked_out\">Checked Out<\/option><\/select><\/div>\n      <div class=\"col-md-4 d-flex gap-2\">\n        <button class=\"btn-teal flex-fill justify-content-center\" onclick=\"exportReport('excel')\"><i class=\"bi bi-file-earmark-excel\"><\/i> Excel<\/button>\n        <button class=\"btn-navy flex-fill justify-content-center\" onclick=\"exportReport('pdf')\"><i class=\"bi bi-file-earmark-pdf\"><\/i> PDF<\/button>\n      <\/div>\n    <\/div>\n  <\/div><\/div>\n  <div class=\"card\"><div class=\"card-hdr\"><h5><i class=\"bi bi-table me-2\"><\/i>Visit Records <span id=\"rpt-cnt\" style=\"font-size:12px;color:var(--muted);font-weight:400\"><\/span><\/h5><span style=\"font-size:12px;color:var(--teal)\"><i class=\"bi bi-hand-index me-1\"><\/i>Click any row for full details<\/span><\/div>\n  <div class=\"table-responsive\"><table class=\"tbl\"><thead><tr><th>Visitor<\/th><th>ID<\/th><th>Company<\/th><th>Date<\/th><th>In<\/th><th>Out<\/th><th>Purpose<\/th><th>Host<\/th><th>Status<\/th><\/tr><\/thead>\n  <tbody id=\"rpt-tbody\"><tr><td colspan=\"9\" class=\"text-center py-4\"><div class=\"spinner-border spinner-border-sm text-secondary\"><\/div><\/td><\/tr><\/tbody><\/table><\/div><\/div>`;\n  loadRptTable();\n}\n\nasync function loadRptTable(){\n  const tb=$('rpt-tbody'); if(!tb) return;\n  tb.innerHTML='<tr><td colspan=\"9\" class=\"text-center py-4\"><div class=\"spinner-border spinner-border-sm text-secondary\"><\/div><\/td><\/tr>';\n  const r=await api('GET',`\/visits?limit=200`);\n  if(!r.success||!r.data?.length){tb.innerHTML='<tr><td colspan=\"9\" class=\"text-center py-4 text-muted\">No records found.<\/td><\/tr>';const c=$('rpt-cnt');if(c)c.textContent='';return;}\n  const c=$('rpt-cnt');if(c)c.textContent=`\u2014 ${r.data.length} records`;\n  tb.innerHTML=r.data.map(v=>`<tr onclick=\"openVisitDetail(${v.id})\" style=\"cursor:pointer\" onmouseover=\"this.style.background='rgba(0,168,150,.05)'\" onmouseout=\"this.style.background=''\">\n    <td><div class=\"d-flex align-items-center gap-2\"><div style=\"width:28px;height:28px;border-radius:50%;background:var(--teal);display:flex;align-items:center;justify-content:center;color:#fff;font-weight:700;font-size:11px\">${(v.visitor_name||'?')[0]}<\/div><strong style=\"font-size:13px\">${v.visitor_name||'\u2014'}<\/strong><\/div><\/td>\n    <td style=\"font-family:monospace;font-size:12px\">${v.id_number||'\u2014'}<\/td>\n    <td style=\"font-size:12px\">${v.company_name||'\u2014'}<\/td>\n    <td style=\"font-size:12px\">${v.visit_date}<\/td>\n    <td style=\"font-size:12px\">${ft(v.check_in_time)}<\/td>\n    <td style=\"font-size:12px\">${ft(v.check_out_time)}<\/td>\n    <td style=\"font-size:12px\">${v.purpose}<\/td>\n    <td style=\"font-size:12px\">${v.host_name}<\/td>\n    <td><span class=\"bs ${v.status==='checked_in'?'bs-in':v.status==='checked_out'?'bs-out':'bs-cancel'}\">${v.status.replace('_',' ')}<\/span><\/td>\n  <\/tr>`).join('');\n}\n\nasync function openVisitDetail(visitId){\n  let visit=null, visitor=null;\n  const r=await api('GET',`\/visits\/${visitId}`);\n  if(r.ok){visit=r.data;visitor={...r.data};}\n  if(!visit){toast('Record not found','err');return;}\n  const modal=new bootstrap.Modal($('visitorModal'));\n  $('visitorModal').querySelector('.modal-title').innerHTML='<i class=\"bi bi-clipboard2-data me-2\"><\/i>Visit Detail';\n  const df=(lbl,val,mono=false)=>`<div class=\"col-6 col-md-4\"><div style=\"font-size:10px;color:var(--muted);text-transform:uppercase;letter-spacing:.4px;margin-bottom:2px\">${lbl}<\/div><div style=\"font-size:13px;font-weight:500${mono?';font-family:monospace':''}\">${val}<\/div><\/div>`;\n  $('visitor-modal-body').innerHTML=`<div id=\"vdp\">\n  <div style=\"background:var(--navy);color:#fff;border-radius:8px;padding:14px 20px;margin-bottom:20px;display:flex;align-items:center;justify-content:space-between\">\n    <div><div style=\"font-size:10px;opacity:.6;text-transform:uppercase\">Meditech VMS \u2014 Visit Record<\/div><div style=\"font-size:17px;font-weight:700;margin-top:2px\">${visit.visitor_name||'\u2014'}<\/div><\/div>\n    <span class=\"bs ${visit.status==='checked_in'?'bs-in':visit.status==='checked_out'?'bs-out':'bs-cancel'}\" style=\"font-size:13px;padding:6px 14px\">${(visit.status||'').replace('_',' ')}<\/span>\n  <\/div>\n  <div class=\"row g-3\">\n    <div class=\"col-md-3 text-center\">\n      <div style=\"width:90px;height:90px;border-radius:50%;background:linear-gradient(135deg,var(--teal),var(--navy));display:flex;align-items:center;justify-content:center;color:#fff;font-size:34px;font-weight:700;margin:0 auto 10px\">${(visit.visitor_name||'?')[0]}<\/div>\n    <\/div>\n    <div class=\"col-md-9\">\n      <div style=\"font-size:11px;font-weight:700;color:var(--teal);text-transform:uppercase;margin-bottom:10px;border-bottom:2px solid var(--teal);padding-bottom:4px\">Visitor Info<\/div>\n      <div class=\"row g-2 mb-3\">\n        ${df('Full Name',visit.visitor_name||'\u2014')}${df('ID \/ Passport',visit.id_number||'\u2014',true)}\n        ${df('Phone',visitor?.phone||'\u2014')}${df('Company',visit.company_name||'\u2014')}\n        ${df('Email',visitor?.email||'\u2014')}${df('Job Title',visitor?.job_title||'\u2014')}\n      <\/div>\n      <div style=\"font-size:11px;font-weight:700;color:var(--navy);text-transform:uppercase;margin-bottom:10px;border-bottom:2px solid var(--navy);padding-bottom:4px\">Visit Info<\/div>\n      <div class=\"row g-2\">\n        ${df('Purpose',visit.purpose||'\u2014')}${df('Host',visit.host_name||'\u2014')}\n        ${df('Host Phone',visit.host_phone||'\u2014')}${df('Department',visit.host_department||'\u2014')}\n        ${df('Date',visit.visit_date||'\u2014')}${df('Check-In',ft(visit.check_in_time))}\n        ${df('Check-Out',ft(visit.check_out_time)||'Still inside')}${df('Badge',visit.badge_code||'\u2014',true)}\n      <\/div>\n    <\/div>\n  <\/div>\n  <div class=\"d-flex gap-2 justify-content-end mt-3 pt-3\" style=\"border-top:1px solid var(--border)\">\n    <button class=\"btn-navy\" onclick=\"printVD()\"><i class=\"bi bi-printer\"><\/i> Print<\/button>\n    ${visit.status==='checked_in'?`<button class=\"btn-teal\" onclick=\"bootstrap.Modal.getInstance($('visitorModal'))?.hide();startCheckout(${visit.id},'${(visit.visitor_name||'').replace(\/'\/g,\"\\\\'\")}')\"><i class=\"bi bi-box-arrow-right\"><\/i> Check Out<\/button>`:''}\n  <\/div><\/div>`;\n  modal.show();\n}\n\nfunction printVD(){\n  const c=document.getElementById('vdp')?.innerHTML;\n  if(!c) return;\n  const w=window.open('','_blank','width=800,height=600');\n  w.document.write(`<title>Visit Detail<\/title><style>body{padding:30px;font-family:'Segoe UI',sans-serif}@media print{button{display:none}}<\/style>${c}<script>window.onload=()=>window.print()<\\\/script>`);\n  w.document.close();\n}\n\nfunction getRptRows(){\n  const rows=[];\n  document.querySelectorAll('#rpt-tbody tr').forEach(tr=>{\n    const td=[...tr.querySelectorAll('td')];\n    if(td.length<9) return;\n    rows.push({visitor_name:td[0].querySelector('strong')?.textContent||'',id_number:td[1].textContent.trim(),company_name:td[2].textContent.trim(),visit_date:td[3].textContent.trim(),check_in_time:td[4].textContent.trim(),check_out_time:td[5].textContent.trim(),purpose:td[6].textContent.trim(),host_name:td[7].textContent.trim(),status:td[8].textContent.trim()});\n  });\n  return rows;\n}\n\nasync function exportReport(type){\n  const rows=getRptRows();\n  if(!rows.length){toast('No data to export','err');return;}\n  if(type==='excel') exportExcel(rows); else exportPDF(rows);\n}\n\nfunction exportExcel(rows){\n  if(typeof XLSX==='undefined'){toast('Library loading, try again','err');return;}\n  const hdr=['#','Visitor','ID','Company','Date','In','Out','Purpose','Host','Status'];\n  const data=[hdr,...rows.map((r,i)=>[i+1,r.visitor_name,r.id_number,r.company_name,r.visit_date,r.check_in_time,r.check_out_time,r.purpose,r.host_name,r.status])];\n  const ws=XLSX.utils.aoa_to_sheet(data);\n  ws['!cols']=[{wch:5},{wch:22},{wch:16},{wch:18},{wch:12},{wch:10},{wch:10},{wch:26},{wch:20},{wch:13}];\n  const wb=XLSX.utils.book_new(); XLSX.utils.book_append_sheet(wb,ws,'Visit Report');\n  XLSX.writeFile(wb,`Meditech-Visits-${TODAY}.xlsx`);\n  toast('Excel downloaded!');\n}\n\nfunction exportPDF(rows){\n  const now=new Date().toLocaleString();\n  const html=`<meta charset=\"UTF-8\"><title>Visit Report<\/title><style>*{box-sizing:border-box;margin:0;padding:0}body{font-family:'Segoe UI',Arial,sans-serif;font-size:11px}.hdr{background:#0D2B45;color:#fff;padding:16px 28px;display:flex;justify-content:space-between;align-items:center}.hdr h1{font-size:18px;font-weight:700}.hdr .m{font-size:10px;opacity:.7;text-align:right;line-height:1.6}.sumbar{display:flex;border-bottom:2px solid #0D2B45}.si{flex:1;padding:8px 16px;border-right:1px solid #dde3ec}.si .n{font-size:20px;font-weight:700;color:#0D2B45}.si .l{font-size:10px;color:#6b7a90;text-transform:uppercase}table{width:100%;border-collapse:collapse}th{background:#0D2B45;color:#fff;padding:7px 10px;font-size:10px;font-weight:600;text-transform:uppercase;text-align:left}td{padding:6px 10px;border-bottom:1px solid #edf0f4}tr:nth-child(even) td{background:#f8fafb}@media print{body{-webkit-print-color-adjust:exact;print-color-adjust:exact}@page{margin:0;size:A4 landscape}}<\/style>\n  <div class=\"hdr\"><div><h1>MEDITECH<\/h1><div style=\"font-size:11px;opacity:.8;margin-top:2px\">Visitor Management System \u2014 Visit Report<\/div><\/div><div class=\"m\">Generated: ${now}<br>Total: ${rows.length}<\/div><\/div>\n  <div class=\"sumbar\"><div class=\"si\"><div class=\"n\">${rows.length}<\/div><div class=\"l\">Total<\/div><\/div><div class=\"si\"><div class=\"n\" style=\"color:#00A896\">${rows.filter(r=>r.status.includes('checked in')).length}<\/div><div class=\"l\">Checked In<\/div><\/div><div class=\"si\"><div class=\"n\" style=\"color:#1B7CCC\">${rows.filter(r=>r.status.includes('checked out')).length}<\/div><div class=\"l\">Checked Out<\/div><\/div><\/div>\n  <table><thead><tr><th>#<\/th><th>Visitor<\/th><th>ID<\/th><th>Company<\/th><th>Date<\/th><th>In<\/th><th>Out<\/th><th>Purpose<\/th><th>Host<\/th><th>Status<\/th><\/tr><\/thead>\n  <tbody>${rows.map((r,i)=>`<tr><td>${i+1}<\/td><td>${r.visitor_name}<\/td><td style=\"font-family:monospace\">${r.id_number}<\/td><td>${r.company_name}<\/td><td>${r.visit_date}<\/td><td>${r.check_in_time}<\/td><td>${r.check_out_time||'\u2014'}<\/td><td>${r.purpose}<\/td><td>${r.host_name}<\/td><td>${r.status}<\/td><\/tr>`).join('')}<\/tbody><\/table>\n  <script>window.onload=()=>window.print()<\\\/script>`;\n  const w=window.open('','_blank','width=1100,height=750');\n  if(!w){toast('Allow pop-ups and try again','err');return;}\n  w.document.write(html); w.document.close(); toast('PDF dialog opened!');\n}\n\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\u2550\n\/\/  USERS\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\u2550\nasync function renderUsers(){\n  if(USER.role!=='admin'){$('page-content').innerHTML='<div class=\"alert alert-warning\">Admin access required.<\/div>';return;}\n  const r=await api('GET','\/users');\n  $('page-content').innerHTML=`<div class=\"card\"><div class=\"card-hdr\"><h5><i class=\"bi bi-person-badge-fill me-2\" style=\"color:var(--teal)\"><\/i>System Users<\/h5><button class=\"btn-teal\" onclick=\"openUserModal()\"><i class=\"bi bi-plus\"><\/i> Add User<\/button><\/div>\n  <div class=\"table-responsive\"><table class=\"tbl\"><thead><tr><th>Name<\/th><th>Email<\/th><th>Role<\/th><th>Phone<\/th><th>Last Login<\/th><th>Status<\/th><th>Actions<\/th><\/tr><\/thead>\n  <tbody>${r.data.map(u=>`<tr>\n    <td><div class=\"d-flex align-items-center gap-2\"><div style=\"width:32px;height:32px;border-radius:50%;background:var(--navy);display:flex;align-items:center;justify-content:center;color:#fff;font-weight:700;font-size:13px;flex-shrink:0\">${u.full_name[0]}<\/div><strong style=\"font-size:13px\">${u.full_name}<\/strong><\/div><\/td>\n    <td style=\"font-size:12px\">${u.email}<\/td>\n    <td><span class=\"role-${u.role}\">${u.role}<\/span><\/td>\n    <td style=\"font-size:12px\">${u.phone||'\u2014'}<\/td>\n    <td style=\"font-size:11px;color:var(--muted)\">${u.last_login_at?fd(u.last_login_at):'Never'}<\/td>\n    <td>${u.is_active?'<span class=\"bs bs-in\">Active<\/span>':'<span class=\"bs bs-cancel\">Inactive<\/span>'}<\/td>\n    <td><div class=\"d-flex gap-1\">\n      <button class=\"btn-icon\" title=\"Edit\" onclick='openUserModal(${JSON.stringify(u)})'><i class=\"bi bi-pencil\"><\/i><\/button>\n      ${u.id!==USER.id?`<button class=\"btn-icon\" title=\"${u.is_active?'Deactivate':'Activate'}\" onclick=\"toggleActive(${u.id},'${u.full_name.replace(\/'\/g,\"\\\\'\")}',${u.is_active})\"><i class=\"bi bi-person-${u.is_active?'dash':'check'}\"><\/i><\/button>`:'<span style=\"font-size:11px;color:var(--muted);padding:4px 6px\">You<\/span>'}\n    <\/div><\/td>\n  <\/tr>`).join('')}<\/tbody><\/table><\/div><\/div>`;\n}\n\nfunction openUserModal(eu=null){\n  const isEdit=!!eu;\n  $('user-modal-title').innerHTML=isEdit?`<i class=\"bi bi-pencil me-2\"><\/i>Edit \u2014 ${eu.full_name}`:`<i class=\"bi bi-person-plus me-2\"><\/i>Add New User`;\n  $('user-modal-body').innerHTML=`\n  <div class=\"row g-3\">\n    <div class=\"col-md-6\"><label class=\"form-label\">Full Name *<\/label><input type=\"text\" id=\"um-name\" class=\"form-control\" value=\"${isEdit?eu.full_name:''}\"><\/div>\n    <div class=\"col-md-6\"><label class=\"form-label\">Email *<\/label><input type=\"email\" id=\"um-email\" class=\"form-control\" value=\"${isEdit?eu.email:''}\" ${isEdit?'readonly style=\"background:#f8f9fa\"':''}>${isEdit?'<div style=\"font-size:11px;color:var(--muted);margin-top:2px\">Email cannot be changed<\/div>':''}<\/div>\n    <div class=\"col-md-6\"><label class=\"form-label\">Role *<\/label><select id=\"um-role\" class=\"form-select\"><option value=\"receptionist\" ${isEdit&&eu.role==='receptionist'?'selected':''}>Receptionist<\/option><option value=\"security\" ${isEdit&&eu.role==='security'?'selected':''}>Security<\/option><option value=\"admin\" ${isEdit&&eu.role==='admin'?'selected':''}>Admin<\/option><\/select><\/div>\n    <div class=\"col-md-6\"><label class=\"form-label\">Phone<\/label><input type=\"text\" id=\"um-phone\" class=\"form-control\" value=\"${isEdit?(eu.phone||''):''}\"><\/div>\n    <div class=\"col-12\"><div style=\"background:#f8f9fa;border-radius:8px;padding:14px;border:1px solid var(--border)\">\n      ${isEdit?`<div class=\"d-flex justify-content-between align-items-center mb-2\">\n        <label class=\"form-label mb-0\" style=\"font-size:12px\"><i class=\"bi bi-key me-1\"><\/i>Change Password<\/label>\n        <div class=\"form-check form-switch mb-0\"><input class=\"form-check-input\" type=\"checkbox\" id=\"um-toggle\" onchange=\"document.getElementById('um-pwbox').style.display=this.checked?'block':'none';if(!this.checked){document.getElementById('um-pw').value='';document.getElementById('um-pw2').value=''}\"><label class=\"form-check-label\" for=\"um-toggle\" style=\"font-size:12px\">Reset password<\/label><\/div>\n      <\/div><p id=\"um-hint\" style=\"font-size:11px;color:var(--muted);margin:0\">Enable the toggle to set a new password.<\/p>\n      <div id=\"um-pwbox\" style=\"display:none\"><div class=\"row g-2 mt-1\"><div class=\"col-6\"><label class=\"form-label\" style=\"font-size:11px\">New Password<\/label><input type=\"password\" id=\"um-pw\" class=\"form-control form-control-sm\" placeholder=\"Min 8 chars\"><\/div><div class=\"col-6\"><label class=\"form-label\" style=\"font-size:11px\">Confirm<\/label><input type=\"password\" id=\"um-pw2\" class=\"form-control form-control-sm\" placeholder=\"Repeat\"><\/div><\/div><\/div>`\n      :`<label class=\"form-label\" style=\"font-size:12px\"><i class=\"bi bi-key me-1\"><\/i>Password *<\/label>\n      <div class=\"row g-2\"><div class=\"col-6\"><input type=\"password\" id=\"um-pw\" class=\"form-control form-control-sm\" placeholder=\"Min 8 characters\"><\/div><div class=\"col-6\"><input type=\"password\" id=\"um-pw2\" class=\"form-control form-control-sm\" placeholder=\"Confirm password\"><\/div><\/div>`}\n    <\/div><\/div>\n  <\/div>\n  <div id=\"um-err\" class=\"text-danger mt-2\" style=\"font-size:12px\"><\/div>`;\n\n  const modal=new bootstrap.Modal($('userModal'));\n  $('save-user-btn').onclick=async()=>{\n    const err=$('um-err'); err.textContent='';\n    const name=($('um-name').value||'').trim();\n    const email=isEdit?eu.email:($('um-email').value||'').trim().toLowerCase();\n    const role=($('um-role').value||'').trim();\n    const phone=($('um-phone').value||'').trim();\n    if(!name){err.textContent='Name is required.';return;}\n    if(!isEdit&&!email){err.textContent='Email is required.';return;}\n\n    const payload={full_name:name,role,phone};\n    if(!isEdit) payload.email=email;\n\n    \/\/ Password\n    const toggle=$('um-toggle');\n    const needPw=!isEdit||(toggle&&toggle.checked);\n    if(needPw){\n      const pw=($('um-pw')||{value:''}).value;\n      const pw2=($('um-pw2')||{value:''}).value;\n      if(!pw){err.textContent='Password is required.';return;}\n      if(pw.length<8){err.textContent='Password must be at least 8 characters.';return;}\n      if(pw!==pw2){err.textContent='Passwords do not match.';return;}\n      payload.password=pw;\n    }\n\n    const r=isEdit?await api('PUT',`\/users\/${eu.id}`,payload):await api('POST','\/users',payload);\n    if(!r.success){err.textContent=r.message||'Failed to save.';return;}\n    toast(isEdit?'User updated!':'User created! They can now log in with their email and password.');\n    modal.hide(); renderUsers();\n  };\n  modal.show();\n}\n\nasync function toggleActive(id,name,active){\n  if(!confirm(`${active?'Deactivate':'Activate'} \"${name}\"?`)) return;\n  const r=active?await api('DELETE',`\/users\/${id}`):await api('PUT',`\/users\/${id}`,{is_active:1});\n  if(r.success){toast(`User ${active?'deactivated':'activated'}.`);renderUsers();}\n  else toast(r.message||'Failed','err');\n}\n\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\u2550\n\/\/  SETTINGS  \u2014 real server-side IP restriction\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\u2550\nasync function renderSettings(){\n  if(USER.role!=='admin'){$('page-content').innerHTML='<div class=\"alert alert-warning\">Admin access required.<\/div>';return;}\n  const pc=$('page-content');\n  pc.innerHTML='<div class=\"text-center py-5\"><div class=\"spinner-border text-secondary\"><\/div><\/div>';\n  const [ipsR, sR, myIpR] = await Promise.all([\n    api('GET','\/ips'), api('GET','\/settings'), api('GET','\/my-ip')\n  ]);\n  const ips=ipsR.ok?ipsR.data:[];\n  const s=sR.ok?sR.data:{};\n  const myIp=myIpR.ok?myIpR.data.ip:'Unknown';\n  const enabled=s.ip_restriction_enabled==='1';\n\n  pc.innerHTML=`<div class=\"row g-3\">\n  <div class=\"col-lg-6\"><div class=\"card\"><div class=\"card-hdr\"><h5><i class=\"bi bi-gear me-2\"><\/i>General<\/h5><\/div><div class=\"p-4\">\n    <div class=\"mb-3\"><label class=\"form-label\">Company Name<\/label><input type=\"text\" id=\"s-cn\" class=\"form-control\" value=\"${s.company_name||'Meditech'}\"><\/div>\n    <div class=\"mb-3\"><label class=\"form-label\">Badge Prefix<\/label><input type=\"text\" id=\"s-bp\" class=\"form-control\" value=\"${s.badge_prefix||'MTK'}\"><\/div>\n    <button class=\"btn-teal\" onclick=\"saveGeneral()\"><i class=\"bi bi-save\"><\/i> Save<\/button>\n  <\/div><\/div><\/div>\n  <div class=\"col-lg-6\"><div class=\"card\"><div class=\"card-hdr\"><h5><i class=\"bi bi-envelope me-2\"><\/i>Notifications<\/h5><\/div><div class=\"p-4\">\n    <div class=\"mb-3\"><label class=\"form-label\">SMTP Host<\/label><input type=\"text\" id=\"s-sh\" class=\"form-control\" placeholder=\"smtp.gmail.com\" value=\"${s.smtp_host||''}\"><\/div>\n    <div class=\"row g-2 mb-3\"><div class=\"col-8\"><label class=\"form-label\">SMTP User<\/label><input type=\"text\" id=\"s-su\" class=\"form-control\" value=\"${s.smtp_user||''}\"><\/div><div class=\"col-4\"><label class=\"form-label\">Port<\/label><input type=\"number\" id=\"s-sp\" class=\"form-control\" value=\"${s.smtp_port||'587'}\"><\/div><\/div>\n    <div class=\"mb-3\"><label class=\"form-label\">SMTP Password<\/label><input type=\"password\" id=\"s-spw\" class=\"form-control\" placeholder=\"(unchanged)\"><\/div>\n    <button class=\"btn-teal\" onclick=\"saveNotify()\"><i class=\"bi bi-save\"><\/i> Save<\/button>\n  <\/div><\/div><\/div>\n\n  <div class=\"col-12\"><div class=\"card\">\n    <div class=\"card-hdr\">\n      <div><h5><i class=\"bi bi-shield-lock me-2\"><\/i>IP Address Restriction<\/h5>\n      <div style=\"font-size:12px;color:var(--muted);margin-top:3px\">Enforced server-side \u2014 blocked IPs never receive any page content<\/div><\/div>\n      <div class=\"d-flex align-items-center gap-3\">\n        <span class=\"bs ${enabled?'bs-in':'bs-cancel'}\" style=\"font-size:13px;padding:6px 14px\">${enabled?'ACTIVE':'DISABLED'}<\/span>\n        <button class=\"btn-teal\" onclick=\"toggleIPR(${!enabled})\">${enabled?'<i class=\"bi bi-toggle-on\"><\/i> Disable':'<i class=\"bi bi-toggle-off\"><\/i> Enable'}<\/button>\n      <\/div>\n    <\/div>\n    <div class=\"p-4\">\n      ${enabled?`<div style=\"background:#fff3cd;border:1px solid #ffc107;border-radius:8px;padding:12px 16px;margin-bottom:20px;display:flex;gap:10px\"><i class=\"bi bi-exclamation-triangle-fill\" style=\"color:#f59e0b;font-size:18px;flex-shrink:0\"><\/i><div style=\"font-size:13px\"><strong>ACTIVE:<\/strong> Only IPs below can access this system. The server rejects all others before sending any content.<\/div><\/div>`\n      :`<div style=\"background:#f0fdf4;border:1px solid #86efac;border-radius:8px;padding:12px 16px;margin-bottom:20px;display:flex;gap:10px\"><i class=\"bi bi-info-circle-fill\" style=\"color:#22c55e;font-size:18px;flex-shrink:0\"><\/i><div style=\"font-size:13px\"><strong>DISABLED:<\/strong> Everyone can access. Add your IPs then click Enable.<\/div><\/div>`}\n\n      <div style=\"background:#f8fafb;border:1px solid var(--border);border-radius:8px;padding:12px 16px;margin-bottom:20px;display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:10px\">\n        <div><div style=\"font-size:11px;color:var(--muted);text-transform:uppercase;margin-bottom:3px\">Your IP (detected by server)<\/div>\n        <div style=\"font-family:monospace;font-size:18px;font-weight:700;color:var(--navy)\">${myIp}<\/div><\/div>\n        <button class=\"btn-teal\" onclick=\"addMyIp('${myIp}')\"><i class=\"bi bi-plus-circle\"><\/i> Add My IP<\/button>\n      <\/div>\n\n      <div style=\"border:1px solid var(--border);border-radius:8px;padding:16px;margin-bottom:16px\">\n        <div style=\"font-size:13px;font-weight:600;color:var(--navy);margin-bottom:12px\"><i class=\"bi bi-plus me-1\"><\/i>Add IP \/ CIDR Range<\/div>\n        <div class=\"row g-2 align-items-end\">\n          <div class=\"col-md-5\"><label class=\"form-label\">IP or CIDR<\/label><input type=\"text\" id=\"new-ip\" class=\"form-control\" placeholder=\"192.168.1.50 or 192.168.1.0\/24\"><\/div>\n          <div class=\"col-md-4\"><label class=\"form-label\">Label<\/label><input type=\"text\" id=\"new-ip-lbl\" class=\"form-control\" placeholder=\"Reception Desk\"><\/div>\n          <div class=\"col-md-3\"><button class=\"btn-teal w-100 justify-content-center\" onclick=\"addIp()\"><i class=\"bi bi-plus\"><\/i> Add<\/button><\/div>\n        <\/div>\n        <div style=\"font-size:11px;color:var(--muted);margin-top:8px\"><i class=\"bi bi-lightbulb me-1\"><\/i><strong>Exact:<\/strong> 192.168.1.100 &nbsp;|&nbsp; <strong>Range:<\/strong> 192.168.1.0\/24 &nbsp;|&nbsp; <strong>Network:<\/strong> 10.0.0.0\/8<\/div>\n        <div id=\"ip-err\" style=\"color:var(--red);font-size:12px;margin-top:6px\"><\/div>\n      <\/div>\n      <div id=\"ip-list\">${renderIpList(ips)}<\/div>\n    <\/div>\n  <\/div><\/div><\/div>`;\n}\n\nfunction renderIpList(ips){\n  if(!ips||!ips.length) return '<div style=\"text-align:center;padding:24px;color:var(--muted)\"><i class=\"bi bi-shield-x\" style=\"font-size:28px;display:block;margin-bottom:8px\"><\/i>No IPs added. Add at least one before enabling.<\/div>';\n  return `<table class=\"table-mt\"><thead><tr><th>IP \/ CIDR<\/th><th>Label<\/th><th>Added<\/th><th>Action<\/th><\/tr><\/thead><tbody>\n  ${ips.map(x=>`<tr><td><span style=\"font-family:monospace;font-size:13px;font-weight:600\">${x.ip}<\/span>${x.ip.includes('\/')?'<span style=\"font-size:10px;background:rgba(0,168,150,.1);color:var(--teal);padding:1px 6px;border-radius:10px;margin-left:6px\">CIDR<\/span>':''}<\/td><td style=\"font-size:12px;color:var(--muted)\">${x.label||'\u2014'}<\/td><td style=\"font-size:11px;color:var(--muted)\">${fd(x.created_at)}<\/td><td><button class=\"btn-danger-sm\" onclick=\"delIp(${x.id})\"><i class=\"bi bi-trash\"><\/i> Remove<\/button><\/td><\/tr>`).join('')}\n  <\/tbody><\/table>`;\n}\n\nasync function saveGeneral(){\n  const r=await api('POST','\/settings',{company_name:($('s-cn')||{value:'Meditech'}).value,badge_prefix:($('s-bp')||{value:'MTK'}).value});\n  r.ok?toast('Saved!'):toast(r.msg,'err');\n}\n\nasync function saveNotify(){\n  const payload={smtp_host:($('s-sh')||{value:''}).value,smtp_user:($('s-su')||{value:''}).value,smtp_port:($('s-sp')||{value:'587'}).value};\n  if(($('s-spw')||{value:''}).value) payload.smtp_pass=$('s-spw').value;\n  const r=await api('POST','\/settings',payload);\n  r.ok?toast('Notification settings saved!'):toast(r.msg,'err');\n}\n\nasync function toggleIPR(enable){\n  if(enable){\n    const chk=await api('GET','\/ips');\n    if(chk.ok&&!chk.data.length){toast('Add at least one IP before enabling restriction.','err');return;}\n  }\n  const r=await api('POST','\/settings',{ip_restriction_enabled:enable?'1':'0'});\n  if(r.ok){toast(enable?'IP restriction ENABLED \u2014 only listed IPs can access the system.':'IP restriction disabled.');renderSettings();}\n  else toast(r.msg,'err');\n}\n\nfunction addMyIp(ip){\n  if(!ip||ip==='Unknown'){toast('Cannot detect IP.','err');return;}\n  $('new-ip').value=ip; $('new-ip-lbl').value='My IP'; addIp();\n}\n\nasync function addIp(){\n  const ip=($('new-ip')||{value:''}).value.trim(), lbl=($('new-ip-lbl')||{value:''}).value.trim();\n  const errEl=$('ip-err'); if(errEl) errEl.textContent='';\n  if(!ip){if(errEl)errEl.textContent='Enter an IP address.';return;}\n  if(!\/^(\\d{1,3}\\.){3}\\d{1,3}(\\\/\\d{1,2})?$\/.test(ip)){if(errEl)errEl.textContent='Invalid format.';return;}\n  const r=await api('POST','\/ips',{ip,label:lbl});\n  if(!r.ok){if(errEl)errEl.textContent=r.msg||'Failed.';return;}\n  toast(`${ip} added.`);\n  if($('new-ip'))$('new-ip').value=''; if($('new-ip-lbl'))$('new-ip-lbl').value='';\n  const lr=await api('GET','\/ips'); const el=$('ip-list'); if(el&&lr.ok)el.innerHTML=renderIpList(lr.data);\n}\n\nasync function delIp(id){\n  if(!confirm('Remove this IP from the whitelist?'))return;\n  const r=await api('DELETE',`\/ips\/${id}`);\n  if(r.ok){toast('IP removed.');const lr=await api('GET','\/ips');const el=$('ip-list');if(el&&lr.ok)el.innerHTML=renderIpList(lr.data);}\n  else toast(r.msg,'err');\n}\n\n\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\u2550\n\/\/  CHECK-OUT\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\u2550\n\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\u2550\n\/\/  CHECK-OUT\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\u2550\nlet pendingCO=null;\nfunction startCheckout(id,name){\n  pendingCO=id;\n  $('checkout-modal-body').innerHTML=`Check out <strong>${name}<\/strong> at <strong>${new Date().toLocaleTimeString('en-GB',{hour:'2-digit',minute:'2-digit'})}<\/strong>?`;\n  $('confirm-checkout-btn').onclick=doCheckout;\n  new bootstrap.Modal($('checkoutModal')).show();\n}\nasync function doCheckout(){\n  if(!pendingCO) return;\n  const r=await api('PUT',`\/visits\/${pendingCO}\/checkout`,{});\n  bootstrap.Modal.getInstance($('checkoutModal'))?.hide();\n  if(r.success){toast(`${r.data.visitor_name} checked out`);refreshBadge();const a=document.querySelector('.sidebar nav a.active');if(a)a.click();}\n  else toast(r.message||'Failed','err');\n}\n\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\u2550\n\/\/  BADGE\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\u2550\nfunction showBadge(visit){\n  $('badge-modal-body').innerHTML=`<div class=\"vbadge\"><div class=\"vbadge-hdr\"><h4>MEDITECH<\/h4><span style=\"font-size:11px;opacity:.6;letter-spacing:1px\">VISITOR PASS<\/span><\/div>\n  <div style=\"background:#fff;padding:20px\">\n    <div class=\"d-flex align-items-center gap-3 mb-3\">\n      <div style=\"width:70px;height:70px;border-radius:50%;background:linear-gradient(135deg,var(--teal),var(--navy));display:flex;align-items:center;justify-content:center;color:#fff;font-size:28px;font-weight:700\">${(visit.visitor_name||'?')[0]}<\/div>\n      <div><div style=\"font-size:17px;font-weight:700;color:var(--navy)\">${visit.visitor_name||'\u2014'}<\/div><div style=\"font-size:12px;color:var(--muted)\">${visit.company_name||'Individual'}<\/div><\/div>\n    <\/div>\n    <div class=\"row g-2 mb-3\">\n      <div class=\"col-7\"><div style=\"font-size:11px;color:var(--muted)\">Purpose<\/div><div style=\"font-size:13px;font-weight:600\">${visit.purpose||'\u2014'}<\/div>\n      <div style=\"font-size:11px;color:var(--muted);margin-top:6px\">Host<\/div><div style=\"font-size:13px\">${visit.host_name||'\u2014'}<\/div>\n      <div style=\"font-size:11px;color:var(--muted);margin-top:6px\">Date & Time<\/div><div style=\"font-size:12px\">${visit.visit_date||''} ${ft(visit.check_in_time)}<\/div><\/div>\n      <div class=\"col-5 text-center\"><div style=\"width:90px;height:90px;background:#f0f0f0;border-radius:8px;display:flex;align-items:center;justify-content:center;margin:0 auto\"><i class=\"bi bi-qr-code\" style=\"font-size:42px;color:var(--navy)\"><\/i><\/div>\n      <div style=\"font-size:9px;color:var(--muted);margin-top:4px;word-break:break-all\">${visit.badge_code||''}<\/div><\/div>\n    <\/div>\n    <div style=\"background:var(--teal);color:#fff;padding:6px 12px;border-radius:6px;font-size:11px;text-align:center;font-weight:600\">\u2713 AUTHORIZED VISITOR \u2014 ESCORT REQUIRED<\/div>\n  <\/div><\/div>`;\n  new bootstrap.Modal($('badgeModal')).show();\n}\nfunction showBadgeCode(code,name){showBadge({visitor_name:name,company_name:'',purpose:'\u2014',host_name:'\u2014',visit_date:'',check_in_time:'',badge_code:code});}\n\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\u2550\n\/\/  CAMERA\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\u2550\nlet camStream=null, camPhoto=null;\nconst isMob=\/Mobi|Android|iPhone|iPad\/i.test(navigator.userAgent);\n\nasync function openCamera(){\n  camPhoto=null;\n  const gel=id=>document.getElementById(id);\n  gel('cam-capture-btn').style.display='none';\n  gel('cam-retake-btn').style.display='none';\n  gel('cam-use-btn').style.display='none';\n  gel('cam-upload-btn').style.display='none';\n  gel('cam-video').style.display='none';\n  gel('cam-canvas').style.display='none';\n  gel('cam-img').style.display='none';\n  gel('cam-idle').style.display='flex';\n  gel('cam-idle').querySelector('p').textContent='Starting camera\u2026';\n  new bootstrap.Modal($('cameraModal')).show();\n  if(isMob){\n    gel('cam-idle').querySelector('p').textContent='Tap button below to open camera';\n    gel('cam-upload-btn').style.display='inline-flex';\n    gel('cam-upload-btn').textContent=''; gel('cam-upload-btn').innerHTML='<i class=\"bi bi-camera\"><\/i> Open Camera';\n    document.getElementById('cam-file').setAttribute('capture','environment');\n    return;\n  }\n  if(!navigator.mediaDevices||location.protocol==='http:'&&!['localhost','127.0.0.1'].includes(location.hostname)){\n    gel('cam-idle').querySelector('p').textContent='Camera unavailable \u2014 use upload';\n    gel('cam-upload-btn').style.display='inline-flex';\n    return;\n  }\n  try{\n    camStream=await navigator.mediaDevices.getUserMedia({video:{facingMode:'user'},audio:false});\n    gel('cam-video').srcObject=camStream;\n    gel('cam-video').style.display='block';\n    gel('cam-idle').style.display='none';\n    gel('cam-capture-btn').style.display='inline-flex';\n    gel('cam-upload-btn').style.display='inline-flex';\n  }catch(e){\n    gel('cam-idle').querySelector('p').textContent='Camera denied \u2014 use upload instead';\n    gel('cam-upload-btn').style.display='inline-flex';\n  }\n}\nfunction capturePhoto(){\n  const v=document.getElementById('cam-video'),c=document.getElementById('cam-canvas');\n  c.width=v.videoWidth||640; c.height=v.videoHeight||480;\n  c.getContext('2d').drawImage(v,0,0);\n  camPhoto=c.toDataURL('image\/jpeg',.85);\n  const img=document.getElementById('cam-img'); img.src=camPhoto; img.style.display='block';\n  v.style.display='none';\n  document.getElementById('cam-capture-btn').style.display='none';\n  document.getElementById('cam-retake-btn').style.display='inline-flex';\n  document.getElementById('cam-use-btn').style.display='inline-flex';\n  document.getElementById('cam-upload-btn').style.display='none';\n}\nfunction retakePhoto(){\n  camPhoto=null;\n  document.getElementById('cam-img').style.display='none';\n  document.getElementById('cam-retake-btn').style.display='none';\n  document.getElementById('cam-use-btn').style.display='none';\n  if(camStream){document.getElementById('cam-video').style.display='block';document.getElementById('cam-capture-btn').style.display='inline-flex';}\n  else{document.getElementById('cam-upload-btn').style.display='inline-flex';}\n}\nfunction onCamFile(e){\n  const f=e.target.files[0]; if(!f) return;\n  const r=new FileReader(); r.onload=ev=>{\n    camPhoto=ev.target.result;\n    const img=document.getElementById('cam-img'); img.src=camPhoto; img.style.display='block';\n    document.getElementById('cam-idle').style.display='none';\n    document.getElementById('cam-retake-btn').style.display='inline-flex';\n    document.getElementById('cam-use-btn').style.display='inline-flex';\n    document.getElementById('cam-upload-btn').style.display='none';\n  }; r.readAsDataURL(f); e.target.value='';\n}\nfunction usePhoto(){\n  if(!camPhoto) return;\n  ciPhoto=camPhoto;\n  const p=document.getElementById('photo-preview');\n  if(p) p.innerHTML=`<img decoding=\"async\" src=\"${camPhoto}\" style=\"width:100%;height:100%;object-fit:cover;border-radius:50%\">`;\n  stopCamera(); bootstrap.Modal.getInstance($('cameraModal'))?.hide(); toast('Photo saved!');\n}\nfunction stopCamera(){if(camStream){camStream.getTracks().forEach(t=>t.stop());camStream=null;}}\n\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\u2550\n\/\/  SIGNATURE\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\u2550\nlet sigPaint=false, sigCtx=null;\nfunction openSig(){\n  new bootstrap.Modal($('signatureModal')).show();\n  setTimeout(()=>{\n    const c=$('sig-canvas'); sigCtx=c.getContext('2d');\n    sigCtx.clearRect(0,0,c.width,c.height);\n    sigCtx.strokeStyle='#0D2B45'; sigCtx.lineWidth=2.5; sigCtx.lineCap='round'; sigCtx.lineJoin='round';\n    const gp=e=>{const r=c.getBoundingClientRect(),s=e.touches?e.touches[0]:e;return{x:s.clientX-r.left,y:s.clientY-r.top};};\n    c.onmousedown=c.ontouchstart=e=>{e.preventDefault();sigPaint=true;const p=gp(e);sigCtx.beginPath();sigCtx.moveTo(p.x,p.y);};\n    c.onmousemove=c.ontouchmove=e=>{e.preventDefault();if(!sigPaint)return;const p=gp(e);sigCtx.lineTo(p.x,p.y);sigCtx.stroke();};\n    c.onmouseup=c.ontouchend=()=>{sigPaint=false;};\n  },300);\n}\nfunction clearSig(){if(sigCtx)sigCtx.clearRect(0,0,$('sig-canvas').width,$('sig-canvas').height);}\nfunction saveSig(){\n  ciSig=$('sig-canvas').toDataURL('image\/png');\n  const p=$('sig-preview'); if(p) p.innerHTML=`<img decoding=\"async\" src=\"${ciSig}\" style=\"width:100%;height:100%;object-fit:contain\">`;\n  bootstrap.Modal.getInstance($('signatureModal'))?.hide(); toast('Signature saved!');\n}\n\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\u2550\n\/\/  INIT\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\u2550\ndocument.addEventListener('keydown',e=>{if(e.key==='Enter'&&$('auth-screen')&&$('auth-screen').style.display!=='none')doLogin();});\nif(TOKEN&&USER) bootApp(); else $('auth-screen').style.display='flex';\n<\/script>\n\n\n    <\/div>\n    \n","protected":false},"excerpt":{"rendered":"","protected":false},"author":0,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"footnotes":""},"class_list":["post-2385","page","type-page","status-publish","hentry"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.2 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\r\n<title>\u0646\u0638\u0627\u0645 \u0645\u064a\u062f\u064a\u062a\u0643 VMS<\/title>\r\n<meta name=\"description\" content=\"\u0646\u0638\u0627\u0645 \u0625\u062f\u0627\u0631\u0629 \u0627\u0644\u0641\u064a\u062f\u064a\u0648 \u0645\u0646 \u0645\u064a\u062f\u064a\u062a\u0643 \u0644\u0639\u0631\u0636 \u0648\u0645\u0631\u0627\u0642\u0628\u0629 \u0627\u0644\u0623\u062c\u0647\u0632\u0629 \u0627\u0644\u0637\u0628\u064a\u0629.\" \/>\r\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\r\n<link rel=\"canonical\" href=\"https:\/\/www.meditech.com.eg\/meditech-vms\/\" \/>\r\n<meta property=\"og:locale\" content=\"en_US\" \/>\r\n<meta property=\"og:type\" content=\"article\" \/>\r\n<meta property=\"og:title\" content=\"\u0646\u0638\u0627\u0645 \u0645\u064a\u062f\u064a\u062a\u0643 VMS\" \/>\r\n<meta property=\"og:description\" content=\"\u0646\u0638\u0627\u0645 \u0625\u062f\u0627\u0631\u0629 \u0627\u0644\u0641\u064a\u062f\u064a\u0648 \u0645\u0646 \u0645\u064a\u062f\u064a\u062a\u0643 \u0644\u0639\u0631\u0636 \u0648\u0645\u0631\u0627\u0642\u0628\u0629 \u0627\u0644\u0623\u062c\u0647\u0632\u0629 \u0627\u0644\u0637\u0628\u064a\u0629.\" \/>\r\n<meta property=\"og:url\" content=\"https:\/\/www.meditech.com.eg\/meditech-vms\/\" \/>\r\n<meta property=\"og:site_name\" content=\"\u0627\u0644\u0645\u0648\u0642\u0639 \u0627\u0644\u0631\u0633\u0645\u064a \u0644\u0645\u062c\u0645\u0648\u0639\u0629 \u0645\u064a\u062f\u064a\u062a\u0643 | \u0645\u0635\u0646\u0639 \u0627\u0644\u0645\u0639\u062f\u0627\u062a \u0627\u0644\u0637\u0628\u064a\u0629 \u0648\u0645\u0632\u0648\u062f \u062d\u0644\u0648\u0644 \u0637\u0628\u064a\u0629 \u0639\u0627\u0644\u0645\u064a\u0629 | \u0627\u0644\u0635\u064a\u0646\" \/>\r\n<meta property=\"article:modified_time\" content=\"2026-06-24T05:34:35+00:00\" \/>\r\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\r\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.meditech.com.eg\\\/meditech-vms\\\/\",\"url\":\"https:\\\/\\\/www.meditech.com.eg\\\/meditech-vms\\\/\",\"name\":\"\u0646\u0638\u0627\u0645 \u0645\u064a\u062f\u064a\u062a\u0643 VMS\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.meditech.com.eg\\\/#website\"},\"datePublished\":\"2026-06-24T05:30:33+00:00\",\"dateModified\":\"2026-06-24T05:34:35+00:00\",\"description\":\"\u0646\u0638\u0627\u0645 \u0625\u062f\u0627\u0631\u0629 \u0627\u0644\u0641\u064a\u062f\u064a\u0648 \u0645\u0646 \u0645\u064a\u062f\u064a\u062a\u0643 \u0644\u0639\u0631\u0636 \u0648\u0645\u0631\u0627\u0642\u0628\u0629 \u0627\u0644\u0623\u062c\u0647\u0632\u0629 \u0627\u0644\u0637\u0628\u064a\u0629.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.meditech.com.eg\\\/meditech-vms\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.meditech.com.eg\\\/meditech-vms\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.meditech.com.eg\\\/meditech-vms\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9875\",\"item\":\"https:\\\/\\\/www.meditech.com.eg\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"\u0646\u0638\u0627\u0645 \u0645\u064a\u062f\u064a\u062a\u0643 VMS\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.meditech.com.eg\\\/#website\",\"url\":\"https:\\\/\\\/www.meditech.com.eg\\\/\",\"name\":\"\u0627\u0644\u0645\u0648\u0642\u0639 \u0627\u0644\u0631\u0633\u0645\u064a \u0644\u0645\u062c\u0645\u0648\u0639\u0629 \u0645\u064a\u062f\u064a\u062a\u0643 | \u0645\u0635\u0646\u0639 \u0627\u0644\u0645\u0639\u062f\u0627\u062a \u0627\u0644\u0637\u0628\u064a\u0629 \u0648\u0645\u0632\u0648\u062f \u062d\u0644\u0648\u0644 \u0637\u0628\u064a\u0629 \u0639\u0627\u0644\u0645\u064a\u0629 | \u0627\u0644\u0635\u064a\u0646\",\"description\":\"\u0627\u0644\u0645\u0648\u0642\u0639 \u0627\u0644\u0631\u0633\u0645\u064a \u0644\u0645\u062c\u0645\u0648\u0639\u0629 \u0645\u064a\u062f\u064a\u062a\u0643 | \u0645\u0635\u0646\u0639 \u0627\u0644\u0645\u0639\u062f\u0627\u062a \u0627\u0644\u0637\u0628\u064a\u0629 \u0648\u0645\u0632\u0648\u062f \u062d\u0644\u0648\u0644 \u0637\u0628\u064a\u0629 \u0639\u0627\u0644\u0645\u064a\u0629 | \u0627\u0644\u0635\u064a\u0646\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.meditech.com.eg\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.meditech.com.eg\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.meditech.com.eg\\\/#organization\",\"name\":\"\u0627\u0644\u0645\u0648\u0642\u0639 \u0627\u0644\u0631\u0633\u0645\u064a \u0644\u0645\u062c\u0645\u0648\u0639\u0629 \u0645\u064a\u062f\u064a\u062a\u0643 | \u0645\u0635\u0646\u0639 \u0627\u0644\u0645\u0639\u062f\u0627\u062a \u0627\u0644\u0637\u0628\u064a\u0629 \u0648\u0645\u0632\u0648\u062f \u062d\u0644\u0648\u0644 \u0637\u0628\u064a\u0629 \u0639\u0627\u0644\u0645\u064a\u0629 | \u0627\u0644\u0635\u064a\u0646\",\"url\":\"https:\\\/\\\/www.meditech.com.eg\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.meditech.com.eg\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"\\\/wp-content\\\/uploads\\\/2026\\\/06\\\/cropped-logo11.webp\",\"contentUrl\":\"\\\/wp-content\\\/uploads\\\/2026\\\/06\\\/cropped-logo11.webp\",\"width\":1006,\"height\":212,\"caption\":\"\u0627\u0644\u0645\u0648\u0642\u0639 \u0627\u0644\u0631\u0633\u0645\u064a \u0644\u0645\u062c\u0645\u0648\u0639\u0629 \u0645\u064a\u062f\u064a\u062a\u0643 | \u0645\u0635\u0646\u0639 \u0627\u0644\u0645\u0639\u062f\u0627\u062a \u0627\u0644\u0637\u0628\u064a\u0629 \u0648\u0645\u0632\u0648\u062f \u062d\u0644\u0648\u0644 \u0637\u0628\u064a\u0629 \u0639\u0627\u0644\u0645\u064a\u0629 | \u0627\u0644\u0635\u064a\u0646\"},\"image\":{\"@id\":\"https:\\\/\\\/www.meditech.com.eg\\\/#\\\/schema\\\/logo\\\/image\\\/\"}}]}<\/script>\r\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"\u0646\u0638\u0627\u0645 \u0645\u064a\u062f\u064a\u062a\u0643 VMS","description":"\u0646\u0638\u0627\u0645 \u0625\u062f\u0627\u0631\u0629 \u0627\u0644\u0641\u064a\u062f\u064a\u0648 \u0645\u0646 \u0645\u064a\u062f\u064a\u062a\u0643 \u0644\u0639\u0631\u0636 \u0648\u0645\u0631\u0627\u0642\u0628\u0629 \u0627\u0644\u0623\u062c\u0647\u0632\u0629 \u0627\u0644\u0637\u0628\u064a\u0629.","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.meditech.com.eg\/meditech-vms\/","og_locale":"en_US","og_type":"article","og_title":"\u0646\u0638\u0627\u0645 \u0645\u064a\u062f\u064a\u062a\u0643 VMS","og_description":"\u0646\u0638\u0627\u0645 \u0625\u062f\u0627\u0631\u0629 \u0627\u0644\u0641\u064a\u062f\u064a\u0648 \u0645\u0646 \u0645\u064a\u062f\u064a\u062a\u0643 \u0644\u0639\u0631\u0636 \u0648\u0645\u0631\u0627\u0642\u0628\u0629 \u0627\u0644\u0623\u062c\u0647\u0632\u0629 \u0627\u0644\u0637\u0628\u064a\u0629.","og_url":"https:\/\/www.meditech.com.eg\/meditech-vms\/","og_site_name":"\u0627\u0644\u0645\u0648\u0642\u0639 \u0627\u0644\u0631\u0633\u0645\u064a \u0644\u0645\u062c\u0645\u0648\u0639\u0629 \u0645\u064a\u062f\u064a\u062a\u0643 | \u0645\u0635\u0646\u0639 \u0627\u0644\u0645\u0639\u062f\u0627\u062a \u0627\u0644\u0637\u0628\u064a\u0629 \u0648\u0645\u0632\u0648\u062f \u062d\u0644\u0648\u0644 \u0637\u0628\u064a\u0629 \u0639\u0627\u0644\u0645\u064a\u0629 | \u0627\u0644\u0635\u064a\u0646","article_modified_time":"2026-06-24T05:34:35+00:00","twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.meditech.com.eg\/meditech-vms\/","url":"https:\/\/www.meditech.com.eg\/meditech-vms\/","name":"\u0646\u0638\u0627\u0645 \u0645\u064a\u062f\u064a\u062a\u0643 VMS","isPartOf":{"@id":"https:\/\/www.meditech.com.eg\/#website"},"datePublished":"2026-06-24T05:30:33+00:00","dateModified":"2026-06-24T05:34:35+00:00","description":"\u0646\u0638\u0627\u0645 \u0625\u062f\u0627\u0631\u0629 \u0627\u0644\u0641\u064a\u062f\u064a\u0648 \u0645\u0646 \u0645\u064a\u062f\u064a\u062a\u0643 \u0644\u0639\u0631\u0636 \u0648\u0645\u0631\u0627\u0642\u0628\u0629 \u0627\u0644\u0623\u062c\u0647\u0632\u0629 \u0627\u0644\u0637\u0628\u064a\u0629.","breadcrumb":{"@id":"https:\/\/www.meditech.com.eg\/meditech-vms\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.meditech.com.eg\/meditech-vms\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.meditech.com.eg\/meditech-vms\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9875","item":"https:\/\/www.meditech.com.eg\/"},{"@type":"ListItem","position":2,"name":"\u0646\u0638\u0627\u0645 \u0645\u064a\u062f\u064a\u062a\u0643 VMS"}]},{"@type":"WebSite","@id":"https:\/\/www.meditech.com.eg\/#website","url":"https:\/\/www.meditech.com.eg\/","name":"\u0627\u0644\u0645\u0648\u0642\u0639 \u0627\u0644\u0631\u0633\u0645\u064a \u0644\u0645\u062c\u0645\u0648\u0639\u0629 \u0645\u064a\u062f\u064a\u062a\u0643 | \u0645\u0635\u0646\u0639 \u0627\u0644\u0645\u0639\u062f\u0627\u062a \u0627\u0644\u0637\u0628\u064a\u0629 \u0648\u0645\u0632\u0648\u062f \u062d\u0644\u0648\u0644 \u0637\u0628\u064a\u0629 \u0639\u0627\u0644\u0645\u064a\u0629 | \u0627\u0644\u0635\u064a\u0646","description":"\u0627\u0644\u0645\u0648\u0642\u0639 \u0627\u0644\u0631\u0633\u0645\u064a \u0644\u0645\u062c\u0645\u0648\u0639\u0629 \u0645\u064a\u062f\u064a\u062a\u0643 | \u0645\u0635\u0646\u0639 \u0627\u0644\u0645\u0639\u062f\u0627\u062a \u0627\u0644\u0637\u0628\u064a\u0629 \u0648\u0645\u0632\u0648\u062f \u062d\u0644\u0648\u0644 \u0637\u0628\u064a\u0629 \u0639\u0627\u0644\u0645\u064a\u0629 | \u0627\u0644\u0635\u064a\u0646","publisher":{"@id":"https:\/\/www.meditech.com.eg\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.meditech.com.eg\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.meditech.com.eg\/#organization","name":"\u0627\u0644\u0645\u0648\u0642\u0639 \u0627\u0644\u0631\u0633\u0645\u064a \u0644\u0645\u062c\u0645\u0648\u0639\u0629 \u0645\u064a\u062f\u064a\u062a\u0643 | \u0645\u0635\u0646\u0639 \u0627\u0644\u0645\u0639\u062f\u0627\u062a \u0627\u0644\u0637\u0628\u064a\u0629 \u0648\u0645\u0632\u0648\u062f \u062d\u0644\u0648\u0644 \u0637\u0628\u064a\u0629 \u0639\u0627\u0644\u0645\u064a\u0629 | \u0627\u0644\u0635\u064a\u0646","url":"https:\/\/www.meditech.com.eg\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.meditech.com.eg\/#\/schema\/logo\/image\/","url":"\/wp-content\/uploads\/2026\/06\/cropped-logo11.webp","contentUrl":"\/wp-content\/uploads\/2026\/06\/cropped-logo11.webp","width":1006,"height":212,"caption":"\u0627\u0644\u0645\u0648\u0642\u0639 \u0627\u0644\u0631\u0633\u0645\u064a \u0644\u0645\u062c\u0645\u0648\u0639\u0629 \u0645\u064a\u062f\u064a\u062a\u0643 | \u0645\u0635\u0646\u0639 \u0627\u0644\u0645\u0639\u062f\u0627\u062a \u0627\u0644\u0637\u0628\u064a\u0629 \u0648\u0645\u0632\u0648\u062f \u062d\u0644\u0648\u0644 \u0637\u0628\u064a\u0629 \u0639\u0627\u0644\u0645\u064a\u0629 | \u0627\u0644\u0635\u064a\u0646"},"image":{"@id":"https:\/\/www.meditech.com.eg\/#\/schema\/logo\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/www.meditech.com.eg\/wp-json\/wp\/v2\/pages\/2385","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.meditech.com.eg\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.meditech.com.eg\/wp-json\/wp\/v2\/types\/page"}],"replies":[{"embeddable":true,"href":"https:\/\/www.meditech.com.eg\/wp-json\/wp\/v2\/comments?post=2385"}],"version-history":[{"count":1,"href":"https:\/\/www.meditech.com.eg\/wp-json\/wp\/v2\/pages\/2385\/revisions"}],"predecessor-version":[{"id":2386,"href":"https:\/\/www.meditech.com.eg\/wp-json\/wp\/v2\/pages\/2385\/revisions\/2386"}],"wp:attachment":[{"href":"https:\/\/www.meditech.com.eg\/wp-json\/wp\/v2\/media?parent=2385"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}