{"id":5769,"date":"2025-12-18T10:57:52","date_gmt":"2025-12-18T09:57:52","guid":{"rendered":"https:\/\/zabalimp.es\/?page_id=5769"},"modified":"2026-01-07T13:26:49","modified_gmt":"2026-01-07T12:26:49","slug":"admin","status":"publish","type":"page","link":"https:\/\/zabalimp.es\/en\/admin\/","title":{"rendered":"Admin"},"content":{"rendered":"<div data-elementor-type=\"wp-page\" data-elementor-id=\"5769\" class=\"elementor elementor-5769\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-da9f6f5 e-flex e-con-boxed e-con e-parent\" data-id=\"da9f6f5\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-d8fcc0b elementor-widget elementor-widget-html\" data-id=\"d8fcc0b\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<div id=\"zb-admin\" class=\"zb-admin\">\r\n  <div class=\"zb-top\">\r\n    <div class=\"zb-title\">\r\n      <div class=\"zb-h1\">Zabalimp - Admin<\/div>\r\n      <div class=\"zb-sub\">Services - Calendar - Contact<\/div>\r\n    <\/div>\r\n\r\n    <div class=\"zb-top-actions\">\r\n      <button id=\"btnInitReload\" class=\"zb-btn ghost\">Recharge all<\/button>\r\n    <\/div>\r\n  <\/div>\r\n\r\n  <div class=\"zb-tabs\">\r\n    <button class=\"zb-tab is-active\" data-tab=\"services\">Services<\/button>\r\n    <button class=\"zb-tab\" data-tab=\"calendar\">Calendar<\/button>\r\n    <button class=\"zb-tab\" data-tab=\"settings\">Contact &amp; Hours<\/button>\r\n  <\/div>\r\n\r\n  <!-- TAB: SERVICES -->\r\n  <section class=\"zb-pane is-active\" id=\"tab-services\">\r\n    <div class=\"zb-card\">\r\n      <div class=\"zb-card-head\">\r\n        <div class=\"zb-card-title\">Services and rates<\/div>\r\n        <div class=\"zb-row\" style=\"margin-left:auto; gap:8px; align-items:end;\">\r\n          <div style=\"min-width:260px\">\r\n            <div class=\"zb-label\">New service<\/div>\r\n            <input id=\"newServiceName\" class=\"zb-inp\" placeholder=\"Name of service\">\r\n          <\/div>\r\n          <button id=\"btnCreateService\" class=\"zb-btn\">Add<\/button>\r\n          <button id=\"btnReloadServices\" class=\"zb-btn ghost\">Recharge<\/button>\r\n        <\/div>\r\n      <\/div>\r\n\r\n      <div class=\"zb-help\">\r\n        Edit and press <b>Save<\/b>. \r\n      <\/div>\r\n\r\n      <div class=\"zb-table-wrap\">\r\n        <table class=\"zb-table\" id=\"servicesTable\">\r\n          <thead>\r\n            <tr>\r\n              <th style=\"width:70px\">ID<\/th>\r\n              <th>Name<\/th>\r\n              <th style=\"width:150px\">Day (normal)<\/th>\r\n              <th style=\"width:150px\">Day (special)<\/th>\r\n              <th style=\"width:150px\">Night (normal)<\/th>\r\n              <th style=\"width:150px\">Night (special)<\/th>\r\n              <th style=\"width:180px\">Shares<\/th>\r\n            <\/tr>\r\n          <\/thead>\r\n          <tbody><\/tbody>\r\n        <\/table>\r\n      <\/div>\r\n<div id=\"servicesCards\" class=\"zb-cards\"><\/div>\r\n\r\n      <div class=\"zb-footnote\" id=\"servicesHint\"><\/div>\r\n    <\/div>\r\n  <\/section>\r\n\r\n  <!-- TAB: CALENDAR -->\r\n  <section class=\"zb-pane\" id=\"tab-calendar\">\r\n    <div class=\"zb-grid\">\r\n      <div class=\"zb-card\">\r\n\t\t<div class=\"zb-cal-top\">\r\n\t\t  <label class=\"zb-switch\">\r\n\t\t\t<input type=\"checkbox\" id=\"blockWeekends\">\r\n\t\t\t<span>Block weekends<\/span>\r\n\t\t  <\/label>\r\n\r\n\t\t  <label class=\"zb-switch\">\r\n\t\t\t<input type=\"checkbox\" id=\"blockHolidays\">\r\n\t\t\t<span>Block holidays<\/span>\r\n\t\t  <\/label>\r\n\r\n\t\t  <div class=\"zb-min\">\r\n\t\t\t<div class=\"zb-label\">Minimum order (\u20ac)<\/div>\r\n\t\t\t<input id=\"minTotal\" class=\"zb-inp\" type=\"number\" min=\"0\" step=\"0.1\" placeholder=\"Ex: 60.00\">\r\n\t\t  <\/div>\r\n\t\t<\/div>\r\n\r\n        <div class=\"zb-row\" style=\"margin-top:12px;\">\r\n\t\t\t<button id=\"btnSaveCalendarSettings\" class=\"zb-btn\" disabled>Save rules<\/button>\r\n\t\t\t<span class=\"zb-note\" id=\"calSaveMsg\">Cargando\u2026<\/span>\r\n        <\/div>\r\n      <\/div>\r\n\r\n      <div class=\"zb-card\">\r\n        <div class=\"zb-card-head\">\r\n          <div class=\"zb-card-title\">Closed days (manual)<\/div>\r\n          <button id=\"btnReloadClosed\" class=\"zb-btn ghost\" style=\"margin-left:auto\">Recharge<\/button>\r\n        <\/div>\r\n\r\n        <div class=\"zb-row\" style=\"gap:10px; align-items:end;\">\r\n          <div style=\"flex:1\">\r\n            <div class=\"zb-label\">Date<\/div>\r\n            <input id=\"closedDay\" class=\"zb-inp\" type=\"date\">\r\n          <\/div>\r\n          <div style=\"flex:1\">\r\n            <div class=\"zb-label\">Reason (optional)<\/div>\r\n            <input id=\"closedReason\" class=\"zb-inp\" placeholder=\"Ex: vacation \/ local vacation\">\r\n          <\/div>\r\n          <button id=\"btnAddClosed\" class=\"zb-btn\">Add<\/button>\r\n        <\/div>\r\n\r\n        <div class=\"zb-table-wrap\" style=\"margin-top:12px;\">\r\n          <table class=\"zb-table\" id=\"closedTable\">\r\n            <thead>\r\n              <tr>\r\n                <th style=\"width:80px\">ID<\/th>\r\n                <th style=\"width:140px\">Day<\/th>\r\n                <th style=\"width:110px\">Type<\/th>\r\n                <th>Motive<\/th>\r\n                <th style=\"width:120px\">Action<\/th>\r\n              <\/tr>\r\n            <\/thead>\r\n            <tbody><\/tbody>\r\n          <\/table>\r\n        <\/div>\r\n\r\n        <div class=\"zb-help\">Here you can add days when the service is not available.<\/div>\r\n      <\/div>\r\n    <\/div>\r\n  <\/section>\r\n\r\n  <!-- TAB: SETTINGS -->\r\n  <section class=\"zb-pane\" id=\"tab-settings\">\r\n    <div class=\"zb-card\">\r\n      <div class=\"zb-card-head\">\r\n        <div class=\"zb-card-title\">Contact<\/div>\r\n        <div class=\"zb-row\" style=\"margin-left:auto; gap:8px;\">\r\n          <button id=\"btnReloadSettings\" class=\"zb-btn ghost\">Recharge<\/button>\r\n          <button id=\"btnSaveSettings\" class=\"zb-btn\">Save<\/button>\r\n        <\/div>\r\n      <\/div>\r\n\r\n      <div class=\"zb-grid2\">\r\n        <div>\r\n          <div class=\"zb-label\">Phone<\/div>\r\n          <input id=\"cPhone\" class=\"zb-inp\" placeholder=\"+34 ...\">\r\n        <\/div>\r\n        <div>\r\n          <div class=\"zb-label\">WhatsApp<\/div>\r\n          <input id=\"cWa\" class=\"zb-inp\" placeholder=\"+34 ...\">\r\n        <\/div>\r\n        <div>\r\n          <div class=\"zb-label\">Email<\/div>\r\n          <input id=\"cEmail\" class=\"zb-inp\" placeholder=\"mail@...\">\r\n        <\/div>\r\n        <div>\r\n          <div class=\"zb-label\">Address (line 1)<\/div>\r\n          <input id=\"cAddr1\" class=\"zb-inp\" placeholder=\"C\/ ...\">\r\n        <\/div>\r\n        <div>\r\n          <div class=\"zb-label\">Address (line 2)<\/div>\r\n          <input id=\"cAddr2\" class=\"zb-inp\" placeholder=\"CP City\">\r\n        <\/div>\r\n      <\/div>\r\n\r\n      <hr class=\"zb-hr\">\r\n\r\n      <div class=\"zb-card-head\" style=\"padding-top:0\">\r\n        <div class=\"zb-card-title\">Schedule<\/div>\r\n      <\/div>\r\n\r\n      <div class=\"zb-grid2\">\r\n        <div>\r\n          <div class=\"zb-label\">Tomorrow - from<\/div>\r\n          <input id=\"hAmFrom\" class=\"zb-inp\" placeholder=\"09:00\">\r\n        <\/div>\r\n        <div>\r\n          <div class=\"zb-label\">Tomorrow - until<\/div>\r\n          <input id=\"hAmTo\" class=\"zb-inp\" placeholder=\"13:30\">\r\n        <\/div>\r\n        <div>\r\n          <div class=\"zb-label\">Afternoon - from<\/div>\r\n          <input id=\"hPmFrom\" class=\"zb-inp\" placeholder=\"16:00\">\r\n        <\/div>\r\n        <div>\r\n          <div class=\"zb-label\">Afternoon - up to<\/div>\r\n          <input id=\"hPmTo\" class=\"zb-inp\" placeholder=\"19:00\">\r\n        <\/div>\r\n        <div style=\"grid-column:1\/-1\">\r\n          <div class=\"zb-label\">Text (optional)<\/div>\r\n          <input id=\"hText\" class=\"zb-inp\" placeholder=\"Monday to Friday: 9:00 - 13:30 and 16:00 - 19:00\">\r\n        <\/div>\r\n      <\/div>\r\n\r\n      <div class=\"zb-row\" style=\"margin-top:12px;\">\r\n        <span class=\"zb-note\" id=\"settingsMsg\"><\/span>\r\n      <\/div>\r\n    <\/div>\r\n  <\/section>\r\n\r\n  <div class=\"zb-toast\" id=\"toast\"><\/div>\r\n<\/div>\r\n\r\n<style>\r\n  \/* \u0444\u043e\u043d \u0438 \u0431\u0430\u0437\u043e\u0432\u0430\u044f \u0442\u0438\u043f\u043e\u0433\u0440\u0430\u0444\u0438\u043a\u0430 *\/\r\n  .zb-admin{max-width:1200px;margin:0 auto;padding:16px;background:#f3f4f6;border-radius:18px}\r\n  .zb-top{display:flex;align-items:flex-end;gap:14px;justify-content:space-between;flex-wrap:wrap}\r\n  .zb-h1{font-size:22px;font-weight:900;color:#111827}\r\n  .zb-sub{color:#6b7280;font-size:13px}\r\n  .zb-top-actions{display:flex;gap:8px}\r\n\r\n  .zb-tabs{display:flex;gap:8px;margin:14px 0 10px;flex-wrap:wrap}\r\n  .zb-tab{border:1px solid #d1d5db;background:#fff;padding:8px 12px;border-radius:999px;cursor:pointer;font-weight:900;color:#111827}\r\n  .zb-tab.is-active{background:#111827;color:#fff;border-color:#111827}\r\n  .zb-pane{display:none}\r\n  .zb-pane.is-active{display:block}\r\n\r\n  .zb-card{background:#fff;border:1px solid #e5e7eb;border-radius:16px;padding:14px;box-shadow:0 12px 30px rgba(0,0,0,.08)}\r\n  .zb-card-head{display:flex;align-items:flex-end;gap:10px;margin-bottom:10px}\r\n  .zb-card-title{font-weight:900;font-size:16px;color:#111827}\r\n  .zb-help{color:#6b7280;font-size:13px;margin-top:8px}\r\n  .zb-footnote{color:#6b7280;font-size:12px;margin-top:10px}\r\n\r\n  .zb-row{display:flex;gap:10px;flex-wrap:wrap}\r\n  .zb-grid{grid-template-columns:1fr 1fr;gap:14px}\r\n  .zb-grid2{display:grid;grid-template-columns:1fr 1fr;gap:12px}\r\n  @media (max-width:980px){.zb-grid{grid-template-columns:1fr}.zb-grid2{grid-template-columns:1fr}}\r\n\r\n  \/* \u0438\u043d\u043f\u0443\u0442\u044b \u0442\u0435\u043f\u0435\u0440\u044c \u043a\u043e\u043d\u0442\u0440\u0430\u0441\u0442\u043d\u044b\u0435 *\/\r\n  .zb-label{font-size:12px;color:#6b7280;margin-bottom:6px;font-weight:900}\r\n  .zb-inp{\r\n    width:100%;\r\n    border:1px solid #cbd5e1;\r\n    border-radius:12px;\r\n    padding:10px 12px;\r\n    outline:none;\r\n    background:#ffffff;\r\n    box-shadow:0 1px 0 rgba(0,0,0,.04);\r\n    color:#111827;\r\n  }\r\n  .zb-inp:focus{\r\n    border-color:#111827;\r\n    box-shadow:0 0 0 3px rgba(17,24,39,.10);\r\n  }\r\n\r\n  .zb-btn{border:1px solid #111827;background:#111827;color:#fff;border-radius:12px;padding:10px 12px;font-weight:900;cursor:pointer}\r\n  .zb-btn.ghost{background:#fff;color:#111827;border-color:#cbd5e1}\r\n  .zb-btn.danger{background:#b91c1c;border-color:#b91c1c}\r\n  .zb-btn:disabled{opacity:.6;cursor:not-allowed}\r\n\r\n  .zb-table-wrap{overflow:auto;border:1px solid #e5e7eb;border-radius:12px;background:#fff}\r\n  .zb-table{width:100%;border-collapse:collapse;min-width:920px}\r\n  .zb-table th,.zb-table td{padding:10px;border-bottom:1px solid #eef2f7;text-align:left;vertical-align:middle}\r\n  .zb-table th{font-size:12px;color:#6b7280;background:#f9fafb;position:sticky;top:0;z-index:1}\r\n  .zb-table td input{width:100%;padding:8px 10px;border:1px solid #cbd5e1;border-radius:10px;background:#fff}\r\n  .zb-actions{display:flex;gap:8px;flex-wrap:wrap}\r\n\r\n  .zb-note{color:#6b7280;font-size:13px}\r\n  .zb-hr{border:0;border-top:1px solid #eef2f7;margin:14px 0}\r\n\r\n  \/* Calendar top row: switches + min total in one line *\/\r\n.zb-cal-top{\r\n  display:flex;\r\n  align-items:flex-end;\r\n  gap:12px;\r\n  flex-wrap:wrap;\r\n  padding-top:6px;\r\n}\r\n\r\n.zb-cal-top .zb-switch{\r\n  margin:0;\r\n  white-space:nowrap;\r\n}\r\n\r\n.zb-min{\r\n  min-width:240px;\r\n  margin-left:auto; \/* \u2705 \u0443\u0432\u043e\u0434\u0438\u043c \u0438\u043d\u043f\u0443\u0442 \u0432\u043f\u0440\u0430\u0432\u043e *\/\r\n}\r\n\r\n@media (max-width: 980px){\r\n  .zb-min{ margin-left:0; width:100%; min-width:0; }\r\n}\r\n\r\n  .zb-switch{display:flex;gap:10px;align-items:center;font-weight:900;color:#111827}\r\n  .zb-switch input{width:18px;height:18px}\r\n\r\n  .zb-toast{position:fixed;right:18px;bottom:18px;background:#111827;color:#fff;padding:10px 12px;border-radius:12px;display:none;max-width:360px;box-shadow:0 12px 30px rgba(0,0,0,.25)}\r\n  \r\n  \/* 1) \u0421\u043d\u044f\u0442\u044c \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u0442\u0435\u043c\u044b\/Elementor \u043f\u043e \u0448\u0438\u0440\u0438\u043d\u0435 *\/\r\n#zb-admin{\r\n  width: min(1180px, calc(100vw - 24px));\r\n  margin: 16px auto;\r\n}\r\n\r\n\/* \u0415\u0441\u043b\u0438 \u0430\u0434\u043c\u0438\u043d\u043a\u0430 \u0432\u043d\u0443\u0442\u0440\u0438 Elementor \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u2014 \u0432\u044b\u0445\u043e\u0434\u0438\u043c \u0438\u0437 \u043d\u0435\u0433\u043e *\/\r\n.elementor .elementor-section .elementor-container:has(#zb-admin){\r\n  max-width: 100% !important;\r\n}\r\n.elementor .elementor-widget-container:has(#zb-admin){\r\n  overflow: visible !important;\r\n}\r\n\/* \u041e\u0431\u0449\u0438\u0435 \u0430\u0434\u0430\u043f\u0442\u0438\u0432\u043d\u044b\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 *\/\r\n#zb-admin *{ box-sizing: border-box; }\r\n\r\n#zb-admin .zb-card{\r\n  width: 100%;\r\n}\r\n\r\n\/* \u0422\u0430\u0431\u044b \u0438 \u043a\u043d\u043e\u043f\u043a\u0438 \u2014 \u043d\u0435 \u0432\u043b\u0435\u0437\u0430\u044e\u0442 -> \u043f\u0435\u0440\u0435\u043d\u043e\u0441 *\/\r\n#zb-admin .zb-tabs,\r\n#zb-admin .zb-actions{\r\n  display:flex;\r\n  flex-wrap:wrap;\r\n  gap:8px;\r\n}\r\n\r\n\/* \u0412\u0435\u0440\u0445\u043d\u044f\u044f \u0441\u0442\u0440\u043e\u043a\u0430 \u043a\u0430\u043b\u0435\u043d\u0434\u0430\u0440\u044f: \u0434\u0432\u0435 \u0433\u0430\u043b\u043e\u0447\u043a\u0438 + \u043c\u0438\u043d\u0438\u043c\u0443\u043c *\/\r\n#zb-admin .zb-cal-top{\r\n  display:flex;\r\n  gap:10px;\r\n  flex-wrap:wrap;\r\n  align-items:flex-end;\r\n}\r\n#zb-admin .zb-min{\r\n  min-width: 220px;\r\n  margin-left: auto;\r\n}\r\n\r\n\/* \u0422\u0430\u0431\u043b\u0438\u0446\u044b: \u043d\u0435 \u043b\u043e\u043c\u0430\u0435\u043c \u0432\u0435\u0440\u0441\u0442\u043a\u0443 \u2014 \u0434\u0435\u043b\u0430\u0435\u043c \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u043a\u0440\u043e\u043b\u043b \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u043d\u0438\u0445 *\/\r\n#zb-admin .zb-table-wrap{\r\n  width:100%;\r\n  overflow-x:auto;\r\n  -webkit-overflow-scrolling: touch;\r\n}\r\n#zb-admin table{\r\n  width:100%;\r\n  border-collapse: collapse;\r\n  min-width: 720px; \/* \u0447\u0442\u043e\u0431\u044b \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u043d\u0435 \u0441\u0436\u0438\u043c\u0430\u043b\u0430\u0441\u044c \u0432 \u043a\u0430\u0448\u0443 *\/\r\n}\r\n\r\n\/* \u041c\u043e\u0431\u0438\u043b\u043a\u0430 *\/\r\n@media (max-width: 720px){\r\n  #zb-admin{\r\n    width: calc(100vw - 16px);\r\n    margin: 10px auto;\r\n  }\r\n\r\n  \/* \u041c\u0438\u043d\u0438\u043c\u0443\u043c \u0443\u0445\u043e\u0434\u0438\u0442 \u043f\u043e\u0434 \u0433\u0430\u043b\u043e\u0447\u043a\u0438 *\/\r\n  #zb-admin .zb-min{\r\n    margin-left: 0;\r\n    width: 100%;\r\n    min-width: 0;\r\n  }\r\n\r\n  \/* \u0423\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u043c \u043a\u043b\u0438\u043a\u0430\u0431\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c *\/\r\n  #zb-admin .zb-btn{\r\n    padding: 12px 14px;\r\n    border-radius: 12px;\r\n    font-size: 15px;\r\n  }\r\n\r\n  #zb-admin .zb-inp,\r\n  #zb-admin select,\r\n  #zb-admin textarea{\r\n    padding: 12px 12px;\r\n    border-radius: 12px;\r\n    font-size: 16px; \/* \u0447\u0442\u043e\u0431\u044b iOS \u043d\u0435 \u0437\u0443\u043c\u0438\u043b \u0438\u043d\u043f\u0443\u0442 *\/\r\n    width:100%;\r\n  }\r\n\r\n  \/* \u0424\u043e\u0440\u043c\u044b: \u0432\u0441\u0451 \u0432 \u043e\u0434\u043d\u0443 \u043a\u043e\u043b\u043e\u043d\u043a\u0443 *\/\r\n  #zb-admin .zb-grid2,\r\n  #zb-admin .zb-grid3{\r\n    display:grid !important;\r\n    grid-template-columns: 1fr !important;\r\n    gap:10px !important;\r\n  }\r\n\r\n  \/* \u041b\u0435\u0439\u0431\u043b\u044b \u0438 \u0447\u0435\u043a\u0431\u043e\u043a\u0441\u044b \u2014 \u043d\u0435 \u0441\u0434\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c *\/\r\n  #zb-admin .zb-switch{\r\n    width: 100%;\r\n  }\r\n}\r\n\/* Mobile cards (Services) *\/\r\n.zb-cards{ display:none; margin-top:12px; gap:12px; }\r\n.zb-card-svc{\r\n  border:1px solid #e5e7eb;\r\n  border-radius:14px;\r\n  padding:12px;\r\n  background:#fff;\r\n}\r\n.zb-card-svc .svc-top{\r\n  display:flex; align-items:center; gap:10px; flex-wrap:wrap;\r\n  margin-bottom:10px;\r\n}\r\n.zb-badge{\r\n  font-weight:900;\r\n  font-size:12px;\r\n  padding:4px 8px;\r\n  border-radius:999px;\r\n  background:#111827;\r\n  color:#fff;\r\n}\r\n.zb-svc-name{\r\n  font-weight:900; font-size:16px; color:#111827;\r\n  flex:1;\r\n}\r\n.zb-svc-grid{\r\n  display:grid;\r\n  grid-template-columns: 1fr 1fr;\r\n  gap:10px;\r\n}\r\n.zb-svc-grid input{\r\n  width:100%;\r\n  padding:10px 12px;\r\n  border:1px solid #cbd5e1;\r\n  border-radius:12px;\r\n}\r\n.zb-svc-actions{\r\n  display:flex; gap:8px; flex-wrap:wrap;\r\n  margin-top:10px;\r\n}\r\n\r\n\/* Switch to cards on phone *\/\r\n@media (max-width: 720px){\r\n  #tab-services .zb-table-wrap{ display:none; }\r\n  #tab-services .zb-cards{ display:grid; }\r\n  .zb-svc-grid{ grid-template-columns: 1fr; } \/* \u0435\u0449\u0451 \u0447\u0438\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u0435\u0435 *\/\r\n}\r\n\/* Cards layout v2 *\/\r\n.zb-cards{ display:none; margin-top:12px; gap:12px; }\r\n.zb-card-svc{\r\n  border:1px solid #e5e7eb;\r\n  border-radius:14px;\r\n  padding:12px;\r\n  background:#fff;\r\n}\r\n\r\n.zb-svc-title{\r\n  display:flex;\r\n  align-items:center;\r\n  justify-content:space-between;\r\n  gap:10px;\r\n  margin-bottom:10px;\r\n}\r\n.zb-svc-title .left{\r\n  display:flex; align-items:center; gap:10px; flex:1; min-width:0;\r\n}\r\n.zb-badge{\r\n  font-weight:900;\r\n  font-size:12px;\r\n  padding:4px 8px;\r\n  border-radius:999px;\r\n  background:#111827;\r\n  color:#fff;\r\n  flex:0 0 auto;\r\n}\r\n.zb-svc-name-inp{\r\n  width:100%;\r\n  padding:10px 12px;\r\n  border:1px solid #cbd5e1;\r\n  border-radius:12px;\r\n  font-weight:900;\r\n  font-size:16px;\r\n}\r\n\r\n.zb-svc-actions{\r\n  display:inline-flex;\r\n  gap:8px;\r\n  flex:0 0 auto;\r\n}\r\n\r\n.zb-iconbtn{\r\n  width:40px;\r\n  height:40px;\r\n  border-radius:12px;\r\n  border:1px solid rgba(0,0,0,.08);\r\n  background:#fff;\r\n  cursor:pointer;\r\n  display:inline-flex;\r\n  align-items:center;\r\n  justify-content:center;\r\n  font-size:18px;\r\n}\r\n.zb-iconbtn:active{ transform: translateY(1px); }\r\n.zb-iconbtn.danger{\r\n  border-color: rgba(185, 28, 28, .25);\r\n}\r\n\r\n.zb-svc-prices{\r\n  display:grid;\r\n  grid-template-columns: repeat(4, minmax(0, 1fr));\r\n  gap:10px;\r\n}\r\n.zb-svc-prices input{\r\n  width:100%;\r\n  padding:10px 12px;\r\n  border:1px solid #cbd5e1;\r\n  border-radius:12px;\r\n  text-align:center;\r\n  font-weight:800;\r\n}\r\n\r\n.zb-price-label{\r\n  font-size:12px;\r\n  color: rgba(0,0,0,.55);\r\n  font-weight:800;\r\n  margin: 0 0 6px 2px;\r\n}\r\n\r\n\/* Mobile *\/\r\n@media (max-width: 720px){\r\n  #tab-services .zb-table-wrap{ display:none; }\r\n  #tab-services .zb-cards{ display:grid; }\r\n\r\n  .zb-svc-prices{\r\n    grid-template-columns: repeat(2, minmax(0, 1fr)); \/* \u2705 2x2 \u043d\u0430 \u0442\u0435\u043b\u0435\u0444\u043e\u043d\u0435 *\/\r\n  }\r\n}\r\n\/* Services cards final layout *\/\r\n#servicesCards{ width:100%; }\r\n\r\n.zb-card-svc{\r\n  width:100%;\r\n  border:1px solid #e5e7eb;\r\n  border-radius:16px;\r\n  padding:14px;\r\n  background:#fff;\r\n}\r\n\r\n\/* \u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u043e\u0439 *\/\r\n.zb-svc-name-row{ margin-bottom:10px; }\r\n.zb-svc-name-inp{\r\n  width:100%;\r\n  padding:12px 14px;\r\n  border:1px solid #cbd5e1;\r\n  border-radius:14px;\r\n  font-weight:900;\r\n  font-size:16px;\r\n}\r\n\r\n\/* \u0426\u0435\u043d\u044b + \u043a\u043d\u043e\u043f\u043a\u0438 \u0432 \u043e\u0434\u043d\u043e\u043c \u0440\u044f\u0434\u0443 *\/\r\n.zb-svc-prices-row{\r\n  display:flex;\r\n  align-items:flex-end;\r\n  gap:12px;\r\n}\r\n\r\n\/* 4 \u0446\u0435\u043d\u044b \u0432 \u043e\u0434\u043d\u0443 \u043b\u0438\u043d\u0438\u044e *\/\r\n.zb-svc-prices{\r\n  flex:1;\r\n  display:grid;\r\n  grid-template-columns: repeat(4, minmax(0, 1fr));\r\n  gap:10px;\r\n}\r\n\r\n.zb-svc-prices input{\r\n  width:100%;\r\n  padding:12px 10px;\r\n  border:1px solid #cbd5e1;\r\n  border-radius:14px;\r\n  text-align:center;\r\n  font-weight:900;\r\n  font-size:16px;\r\n}\r\n\r\n.zb-price-label{\r\n  font-size:12px;\r\n  color: rgba(0,0,0,.55);\r\n  font-weight:900;\r\n  margin: 0 0 6px 2px;\r\n}\r\n\r\n\/* \u041a\u043d\u043e\u043f\u043a\u0438 \u043a\u0440\u0443\u043f\u043d\u0435\u0435 *\/\r\n.zb-svc-actions{\r\n  display:flex;\r\n  gap:10px;\r\n  flex:0 0 auto;\r\n}\r\n\r\n.zb-iconbtn.big{\r\n  width:52px;\r\n  height:52px;\r\n  border-radius:14px;\r\n  font-size:22px;\r\n  border:1px solid rgba(0,0,0,.10);\r\n  background:#fff;\r\n}\r\n\r\n\/* \u041c\u043e\u0431\u0438\u043b\u043a\u0430: \u0446\u0435\u043d\u044b 2x2, \u043a\u043d\u043e\u043f\u043a\u0438 \u043f\u043e\u0434 \u0441\u0435\u0442\u043a\u043e\u0439 *\/\r\n@media (max-width: 720px){\r\n  .zb-svc-prices-row{\r\n    flex-direction:column;\r\n    align-items:stretch;\r\n  }\r\n  .zb-svc-prices{\r\n    grid-template-columns: repeat(2, minmax(0, 1fr));\r\n  }\r\n  .zb-svc-actions{\r\n    justify-content:flex-end;\r\n  }\r\n}\r\n.zb-svc-meta-row{\r\n  display:flex; gap:12px; align-items:flex-end; flex-wrap:wrap;\r\n  margin-bottom:10px;\r\n}\r\n.zb-mini-inp{\r\n  width:120px;\r\n  padding:10px 12px;\r\n  border:1px solid #cbd5e1;\r\n  border-radius:12px;\r\n  font-weight:900;\r\n}\r\n.zb-check{display:flex;align-items:center;gap:10px;font-weight:900;color:#111827}\r\n.zb-check input{width:18px;height:18px}\r\n\r\n.zb-svc-image-row{\r\n  display:grid;\r\n  grid-template-columns: 140px minmax(0,1fr);\r\n  gap:12px;\r\n  align-items:start;\r\n  margin: 6px 0 12px;\r\n}\r\n.zb-svc-thumb{\r\n  width:140px; height:98px;\r\n  border-radius:14px;\r\n  border:1px solid #e5e7eb;\r\n  overflow:hidden;\r\n  background:#f9fafb;\r\n  display:flex; align-items:center; justify-content:center;\r\n}\r\n.zb-svc-thumb img{width:100%;height:100%;object-fit:cover;display:block}\r\n.zb-thumb-ph{font-size:12px;color:#6b7280;font-weight:900;padding:10px;text-align:center}\r\n\r\n.zb-ta{\r\n  width:100%;\r\n  border:1px solid #cbd5e1;\r\n  border-radius:14px;\r\n  padding:12px 12px;\r\n  font-size:14px;\r\n  line-height:1.45;\r\n  resize:vertical;\r\n}\r\n\r\n@media (max-width: 720px){\r\n  .zb-svc-image-row{ grid-template-columns: 1fr; }\r\n  .zb-svc-thumb{ width:100%; height:160px; }\r\n  .zb-mini-inp{ width:100%; }\r\n  \r\n}\r\n\/* \u2705 Use cards everywhere, hide table *\/\r\n#tab-services .zb-cards{ display:grid !important; }\r\n#tab-services .zb-table-wrap{ display:none !important; }\r\n\r\n<\/style>\r\n\r\n<script>\r\n(() => {\r\n  const API_BASE = '\/wp-json\/zabalimp-admin\/v1';\r\n  const $ = (s, root=document) => root.querySelector(s);\r\n  const $$ = (s, root=document) => Array.from(root.querySelectorAll(s));\r\n\r\n  function bust(url){\r\n    const sep = url.includes('?') ? '&' : '?';\r\n    return url + sep + '_ts=' + Date.now();\r\n  }\r\n\r\nasync function apiGet(path){\r\n  const r = await fetch(bust(API_BASE + path), { cache: 'no-store' });\r\n  const txt = await r.text();\r\n  try { return JSON.parse(txt); }\r\n  catch(e){\r\n    console.error('apiGet non-JSON:', path, txt.slice(0,200));\r\n    return { success:false, error:'non-json' };\r\n  }\r\n}\r\n\r\n  async function apiPost(path, data){\r\n    const r = await fetch(API_BASE + path, {\r\n      method:'POST',\r\n      cache:'no-store',\r\n      headers:{ 'Content-Type':'application\/json' },\r\n      body: JSON.stringify(data || {})\r\n    });\r\n    return r.json();\r\n  }\r\n\r\n  function toast(msg){\r\n    const el = $('#toast');\r\n    el.textContent = msg;\r\n    el.style.display = 'block';\r\n    setTimeout(() => el.style.display = 'none', 2400);\r\n  }\r\n\r\n  \/\/ Tabs\r\n  $$('.zb-tab').forEach(btn => {\r\n    btn.addEventListener('click', () => {\r\n      $$('.zb-tab').forEach(b => b.classList.remove('is-active'));\r\n      $$('.zb-pane').forEach(p => p.classList.remove('is-active'));\r\n      btn.classList.add('is-active');\r\n      $('#tab-' + btn.dataset.tab).classList.add('is-active');\r\n    });\r\n  });\r\n\r\n  \/\/ Helpers\r\n  function num(v){\r\n    const n = Number(v);\r\n    return isFinite(n) ? n.toFixed(2) : '0.0';\r\n  }\r\n  function esc(s){\r\n    return String(s).replace(\/[&<>\"']\/g, m => ({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'}[m]));\r\n  }\r\n\r\n  \/\/ -----------------------\r\n  \/\/ Services\r\n  \/\/ -----------------------\r\n  document.getElementById('servicesCards')?.addEventListener('change', async (e) => {\r\n  const inp = e.target.closest('input.zb-file');\r\n  if(!inp) return;\r\n\r\n  const card = inp.closest('.zb-card-svc');\r\n  const id = Number(card?.dataset?.id || 0);\r\n  const file = inp.files && inp.files[0];\r\n  if(!id || !file) return;\r\n\r\n  const fd = new FormData();\r\n  fd.append('service_id', String(id));\r\n  fd.append('file', file);\r\n\r\n  toast('Subiendo imagen\u2026');\r\n\r\n  const r = await fetch(API_BASE + '\/services\/upload-image', {\r\n    method: 'POST',\r\n    body: fd\r\n  });\r\n\r\n  const j = await r.json().catch(()=>null);\r\n  if(!j || !j.success){\r\n    toast('Error subiendo imagen');\r\n    console.error('upload error', j);\r\n    return;\r\n  }\r\n\r\n  \/\/ \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c url \u0432 input \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u043f\u0440\u0435\u0432\u044c\u044e\r\n  const url = j.url;\r\n  const urlInp = card.querySelector('input[data-k=\"image_url\"]');\r\n  if(urlInp) urlInp.value = url;\r\n\r\n  const thumb = card.querySelector('.zb-svc-thumb');\r\n  if(thumb) thumb.innerHTML = `<img decoding=\"async\" src=\"${esc(url)}\" alt=\"\">`;\r\n\r\n  toast('Imagen subida (guarda para confirmar)');\r\n  inp.value = '';\r\n});\r\n  \r\n  \r\n  async function loadServices(){\r\n  \r\n    const j = await apiGet('\/services');\r\n    if(!j.success){ toast('Error cargando servicios'); return; }\r\nconst cards = $('#servicesCards');\r\nif(cards) cards.innerHTML = '';\r\n\r\nj.data.forEach(row => {\r\n  if(!cards) return;\r\n  const div = document.createElement('div');\r\n  div.className = 'zb-card-svc';\r\n  div.dataset.id = row.id;\r\n\r\ndiv.innerHTML = `\r\n  <div class=\"zb-svc-name-row\">\r\n    <input class=\"zb-svc-name-inp\" data-k=\"name\" value=\"${esc(row.name || '')}\" placeholder=\"Nombre del servicio\" \/>\r\n  <\/div>\r\n\r\n  <div class=\"zb-svc-meta-row\">\r\n    <div>\r\n      <div class=\"zb-price-label\">Orden<\/div>\r\n      <input class=\"zb-mini-inp\" data-k=\"sort_order\" inputmode=\"numeric\" value=\"${Number(row.sort_order || 0)}\">\r\n    <\/div>\r\n\r\n    <label class=\"zb-check\">\r\n      <input type=\"checkbox\" data-k=\"is_active\" ${Number(row.is_active ?? 1) ? 'checked' : ''}>\r\n      <span>Activo<\/span>\r\n    <\/label>\r\n  <\/div>\r\n\r\n  <div class=\"zb-svc-image-row\">\r\n    <div class=\"zb-svc-thumb\">\r\n      ${row.image_url ? `<img decoding=\"async\" src=\"${esc(row.image_url)}\" alt=\"\">` : `<div class=\"zb-thumb-ph\">Sin imagen<\/div>`}\r\n    <\/div>\r\n    <div class=\"zb-svc-image-actions\">\r\n      <div class=\"zb-price-label\">Imagen<\/div>\r\n      <input class=\"zb-inp\" data-k=\"image_url\" value=\"${esc(row.image_url || '')}\" placeholder=\"https:\/\/...\" \/>\r\n      <div class=\"zb-row\" style=\"gap:8px;margin-top:8px\">\r\n        <button class=\"zb-btn ghost\" data-act=\"pickimg\" data-id=\"${row.id}\">Subir foto<\/button>\r\n        <button class=\"zb-btn ghost\" data-act=\"clearimg\" data-id=\"${row.id}\">Quitar<\/button>\r\n      <\/div>\r\n      <input type=\"file\" class=\"zb-file\" accept=\"image\/*\" style=\"display:none\">\r\n    <\/div>\r\n  <\/div>\r\n\r\n  <div class=\"zb-svc-desc-row\">\r\n    <div class=\"zb-price-label\">Descripci\u00f3n<\/div>\r\n    <textarea class=\"zb-ta\" data-k=\"description\" rows=\"4\" placeholder=\"Texto...\">${esc(row.description || '')}<\/textarea>\r\n  <\/div>\r\n\r\n  <div class=\"zb-svc-prices-row\">\r\n    <div class=\"zb-svc-prices\">\r\n      <div>\r\n        <div class=\"zb-price-label\">D\u00eda (normal)<\/div>\r\n        <input data-k=\"price_day_normal\" inputmode=\"decimal\" value=\"${num(row.price_day_normal)}\">\r\n      <\/div>\r\n      <div>\r\n        <div class=\"zb-price-label\">D\u00eda (especial)<\/div>\r\n        <input data-k=\"price_day_special\" inputmode=\"decimal\" value=\"${num(row.price_day_special)}\">\r\n      <\/div>\r\n      <div>\r\n        <div class=\"zb-price-label\">Noche (normal)<\/div>\r\n        <input data-k=\"price_night_normal\" inputmode=\"decimal\" value=\"${num(row.price_night_normal)}\">\r\n      <\/div>\r\n      <div>\r\n        <div class=\"zb-price-label\">Noche (especial)<\/div>\r\n        <input data-k=\"price_night_special\" inputmode=\"decimal\" value=\"${num(row.price_night_special)}\">\r\n      <\/div>\r\n    <\/div>\r\n\r\n    <div class=\"zb-svc-actions\">\r\n      <button class=\"zb-iconbtn big\" title=\"Guardar\" data-act=\"save\" data-id=\"${row.id}\">\ud83d\udcbe<\/button>\r\n      <button class=\"zb-iconbtn big danger\" title=\"Eliminar\" data-act=\"del\" data-id=\"${row.id}\">\ud83d\uddd1\ufe0f<\/button>\r\n    <\/div>\r\n  <\/div>\r\n`;\r\n\r\n\r\n  cards.appendChild(div);\r\n});\r\n    const tbody = $('#servicesTable tbody');\r\n    tbody.innerHTML = '';\r\n\r\n    j.data.forEach(row => {\r\n      const tr = document.createElement('tr');\r\n      tr.innerHTML = `\r\n        <td>${row.id}<\/td>\r\n        <td><input data-k=\"name\" value=\"${esc(row.name || '')}\"><\/td>\r\n        <td><input data-k=\"price_day_normal\" value=\"${num(row.price_day_normal)}\"><\/td>\r\n        <td><input data-k=\"price_day_special\" value=\"${num(row.price_day_special)}\"><\/td>\r\n        <td><input data-k=\"price_night_normal\" value=\"${num(row.price_night_normal)}\"><\/td>\r\n        <td><input data-k=\"price_night_special\" value=\"${num(row.price_night_special)}\"><\/td>\r\n        <td>\r\n          <div class=\"zb-actions\">\r\n            <button class=\"zb-btn ghost\" data-act=\"save\" data-id=\"${row.id}\">Guardar<\/button>\r\n            <button class=\"zb-btn danger\" data-act=\"del\" data-id=\"${row.id}\">Eliminar<\/button>\r\n          <\/div>\r\n        <\/td>\r\n      `;\r\n      tbody.appendChild(tr);\r\n    });\r\n\r\n    $('#servicesHint').textContent = `Mostrando ${j.data.length} servicios.`;\r\n  }\r\ndocument.getElementById('servicesCards')?.addEventListener('click', async (e) => {\r\n  const btn = e.target.closest('button[data-act]');\r\n  if(!btn) return;\r\n\r\n  const act = btn.dataset.act;\r\n  const id = Number(btn.dataset.id);\r\n  const card = btn.closest('.zb-card-svc');\r\n  if(!card || !id) return;\r\nif(act === 'clearimg'){\r\n  const urlInp = card.querySelector('input[data-k=\"image_url\"]');\r\n  if(urlInp) urlInp.value = '';\r\n  const img = card.querySelector('.zb-svc-thumb img');\r\n  if(img) img.remove();\r\n  const ph = card.querySelector('.zb-thumb-ph');\r\n  if(!ph) card.querySelector('.zb-svc-thumb').innerHTML = '<div class=\"zb-thumb-ph\">Sin imagen<\/div>';\r\n  toast('Imagen quitada (guarda para aplicar)');\r\n}\r\n\r\nif(act === 'pickimg'){\r\n  const fileInp = card.querySelector('input.zb-file');\r\n  if(!fileInp) return;\r\n  fileInp.click();\r\n}\r\n\r\n  if(act === 'save'){\r\n    btn.disabled = true;\r\n\r\n    const payload = { id };\r\n\r\n\/\/ inputs\r\ncard.querySelectorAll('input[data-k]').forEach(inp => {\r\n  const k = inp.dataset.k;\r\n  if(inp.type === 'checkbox'){\r\n    payload[k] = inp.checked ? 1 : 0;\r\n  } else if(k === 'name' || k === 'image_url'){\r\n    payload[k] = inp.value.trim();\r\n  } else if(k === 'sort_order'){\r\n    payload[k] = Number(inp.value || 0);\r\n  } else {\r\n    payload[k] = Number(String(inp.value).replace(',', '.'));\r\n  }\r\n});\r\n\r\n\/\/ textarea\r\ncard.querySelectorAll('textarea[data-k]').forEach(ta => {\r\n  payload[ta.dataset.k] = ta.value.trim();\r\n});\r\n\r\n    const j = await apiPost('\/services\/update', payload);\r\n    btn.disabled = false;\r\n\r\n    if(j.success){\r\n      toast('Guardado');\r\n      await loadServices();  \/\/ \u0447\u0442\u043e\u0431\u044b \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u044c \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0435\r\n    }else{\r\n      toast('Error guardando');\r\n    }\r\n  }\r\n\r\n  if(act === 'del'){\r\n    if(!confirm('\u00bfEliminar servicio #' + id + '?')) return;\r\n\r\n    btn.disabled = true;\r\n    const j = await apiPost('\/services\/delete', { id });\r\n    btn.disabled = false;\r\n\r\n    if(j.success){\r\n      toast('Eliminado');\r\n      await loadServices();\r\n    }else{\r\n      toast('Error eliminando');\r\n    }\r\n  }\r\n});\r\n\r\n  \/\/ \u0434\u0435\u043b\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u043b\u0438\u043a\u043e\u0432 (save\/delete)\r\n  $('#servicesTable').addEventListener('click', async (e) => {\r\n    const btn = e.target.closest('button[data-act]');\r\n    if(!btn) return;\r\n\r\n    const act = btn.dataset.act;\r\n    const id = Number(btn.dataset.id);\r\n    const tr = btn.closest('tr');\r\n    if(!tr) return;\r\n\r\n    if(act === 'save'){\r\n      btn.disabled = true;\r\n      const payload = { id };\r\n      $$('input[data-k]', tr).forEach(inp => {\r\n        const k = inp.dataset.k;\r\n        payload[k] = (k === 'name') ? inp.value.trim() : Number(inp.value);\r\n      });\r\n      const j = await apiPost('\/services\/update', payload);\r\n      btn.disabled = false;\r\n\r\n      if(j.success){\r\n        toast('Guardado');\r\n        await loadServices(); \/\/ \u2705 \u0436\u0451\u0441\u0442\u043a\u043e \u043f\u0435\u0440\u0435\u0447\u0438\u0442\u0430\u0442\u044c\r\n      } else {\r\n        toast('Error guardando');\r\n      }\r\n    }\r\n\r\n    if(act === 'del'){\r\n      if(!confirm('\u00bfEliminar servicio #' + id + '?')) return;\r\n      btn.disabled = true;\r\n      const j = await apiPost('\/services\/delete', { id });\r\n      btn.disabled = false;\r\n\r\n      if(j.success){\r\n        toast('Eliminado');\r\n        await loadServices(); \/\/ \u2705 \u043f\u0435\u0440\u0435\u0447\u0438\u0442\u0430\u0442\u044c\r\n      } else {\r\n        toast('Error eliminando');\r\n      }\r\n    }\r\n  });\r\n\r\n  $('#btnCreateService').addEventListener('click', async () => {\r\n    const name = $('#newServiceName').value.trim();\r\n    if(!name){ toast('Nombre requerido'); return; }\r\n    $('#btnCreateService').disabled = true;\r\n\r\n    const j = await apiPost('\/services\/create', { name });\r\n\r\n    $('#btnCreateService').disabled = false;\r\n    if(j.success){\r\n      $('#newServiceName').value = '';\r\n      toast('Creado');\r\n      await loadServices(); \/\/ \u2705 \u043f\u0435\u0440\u0435\u0447\u0438\u0442\u0430\u0442\u044c\r\n    } else {\r\n      toast('Error creando');\r\n    }\r\n  });\r\n\r\n  $('#btnReloadServices').addEventListener('click', loadServices);\r\n\r\n  \/\/ -----------------------\r\n  \/\/ Settings (contact\/hours + calendar toggles)\r\n  \/\/ -----------------------\r\n  async function loadSettings(){\r\n\t  \/\/ UI loading state\r\n\t$('#calSaveMsg').textContent = 'Cargando\u2026';\r\n\t$('#btnSaveCalendarSettings').disabled = true;\r\n\t$('#blockWeekends').disabled = true;\r\n\t$('#blockHolidays').disabled = true;\r\n\r\n    const j = await apiGet('\/settings\/get');\r\n    if(!j.success){\r\n\t  toast('Error cargando settings');\r\n\t  $('#calSaveMsg').textContent = '\u274c Error cargando';\r\n\t  return;\r\n\t}\r\n\r\n    const d = j.data || {};\r\n\r\n\tconst cr = d.calendar_rules || {};\r\n\t$('#blockWeekends').checked = !!cr.exclude_weekends;\r\n\t$('#blockHolidays').checked = !!cr.auto_holidays;\r\n\tconst or = d.order_rules || {};\r\n\t$('#minTotal').value = (or.min_total ?? 0);\r\n\r\n\r\n    const c = d.contact || {};\r\n    $('#cPhone').value = c.phone || '';\r\n    $('#cWa').value = c.wa || '';\r\n    $('#cEmail').value = c.email || '';\r\n    $('#cAddr1').value = c.addr1 || '';\r\n    $('#cAddr2').value = c.addr2 || '';\r\n\r\n    const h = d.hours || {};\r\n    $('#hAmFrom').value = h.am_from || '09:00';\r\n    $('#hAmTo').value = h.am_to || '13:30';\r\n    $('#hPmFrom').value = h.pm_from || '16:00';\r\n    $('#hPmTo').value = h.pm_to || '19:00';\r\n    $('#hText').value = h.text || '';\r\n\t$('#blockWeekends').disabled = false;\r\n\t$('#blockHolidays').disabled = false;\r\n\t$('#btnSaveCalendarSettings').disabled = false;\r\n\t$('#calSaveMsg').textContent = '';\r\n\r\n  }\r\n\r\n  async function saveSettings(){\r\n\tconst payload = {\r\n\t  calendar_rules: {\r\n\t\texclude_weekends: $('#blockWeekends').checked ? 1 : 0,\r\n\t\tauto_holidays: $('#blockHolidays').checked ? 1 : 0,\r\n\t\tholiday_country: 'ES',\r\n\t\tmonths_ahead: 12\r\n\t  },\r\n\t  order_rules: {\r\n\t\t  min_total: Number($('#minTotal').value || 0)\r\n\t\t},\r\n    \/\/ \u2705 \u0414\u041e\u0411\u0410\u0412\u0418\u0422\u042c:\r\n    contact: {\r\n      phone: $('#cPhone').value.trim(),\r\n      wa:    $('#cWa').value.trim(),\r\n      email: $('#cEmail').value.trim(),\r\n      addr1: $('#cAddr1').value.trim(),\r\n      addr2: $('#cAddr2').value.trim(),\r\n    },\r\n\t  hours: {\r\n\t\tam_from: $('#hAmFrom').value.trim(),\r\n\t\tam_to: $('#hAmTo').value.trim(),\r\n\t\tpm_from: $('#hPmFrom').value.trim(),\r\n\t\tpm_to: $('#hPmTo').value.trim(),\r\n\t\ttext: $('#hText').value.trim(),\r\n\t  }\r\n\t};\r\n\r\n    const j = await apiPost('\/settings\/save', payload);\r\n    if(j.success){\r\n      toast('Guardado');\r\n      $('#settingsMsg').textContent = '\u2705 Guardado';\r\n      setTimeout(() => $('#settingsMsg').textContent = '', 2000);\r\n    } else {\r\n      toast('Error guardando');\r\n    }\r\n  }\r\n\r\n  $('#btnReloadSettings').addEventListener('click', loadSettings);\r\n  $('#btnSaveSettings').addEventListener('click', saveSettings);\r\n\tasync function regenHolidaysBizkaia(){\r\n\t  return apiPost('\/closed-days\/regen-holidays', {\r\n\t\tservice_id: 0,\r\n\t\tcountry: 'ES',\r\n\t\tmonths: 12,\r\n\t\tregions: ['ES-BI'] \/\/ Bizkaia\r\n\t  });\r\n\t}\r\n\r\n\t$('#btnSaveCalendarSettings').addEventListener('click', async () => {\r\n\t  $('#btnSaveCalendarSettings').disabled = true;\r\n\t  $('#calSaveMsg').textContent = '\u23f3 Guardando\u2026';\r\n\r\n\t  await saveSettings();\r\n\r\n\t  if($('#blockHolidays').checked){\r\n\t\t$('#calSaveMsg').textContent = '\u23f3 Actualizando festivos (Bizkaia)\u2026';\r\n\t\tawait regenHolidaysBizkaia();\r\n\t  }\r\n\r\n\t  await loadSettings();\r\n\t  await loadClosed();\r\n\t  $('#btnSaveCalendarSettings').disabled = false;\r\n\r\n\t  $('#calSaveMsg').textContent = '\u2705 Guardado';\r\n\t  setTimeout(() => $('#calSaveMsg').textContent = '', 2000);\r\n\t});\r\n\r\n\r\n\r\n  \/\/ -----------------------\r\n  \/\/ Closed days (universal: service_id = 0)\r\n  \/\/ -----------------------\r\n  async function loadClosed(){\r\n    const j = await apiGet('\/closed-days\/list?service_id=0');\r\n    if(!j.success){ toast('Error cargando d\u00edas cerrados'); return; }\r\n\r\n    const tbody = $('#closedTable tbody');\r\n    tbody.innerHTML = '';\r\n    j.data.forEach(row => {\r\n      const tr = document.createElement('tr');\r\n      tr.innerHTML = `\r\n        <td>${row.id}<\/td>\r\n        <td>${row.day}<\/td>\r\n        <td>${row.type || ''}<\/td>\r\n        <td>${esc(row.reason || '')}<\/td>\r\n        <td><button class=\"zb-btn danger\" data-del-closed=\"${row.id}\">Quitar<\/button><\/td>\r\n      `;\r\n      tbody.appendChild(tr);\r\n    });\r\n  }\r\n\r\n  $('#btnReloadClosed').addEventListener('click', loadClosed);\r\n\r\n  $('#btnAddClosed').addEventListener('click', async () => {\r\n    const day = $('#closedDay').value;\r\n    const reason = $('#closedReason').value.trim();\r\n    if(!day){ toast('Fecha requerida'); return; }\r\n\r\n    $('#btnAddClosed').disabled = true;\r\n    const j = await apiPost('\/closed-days\/add', { service_id: 0, day, type:'manual', reason });\r\n    $('#btnAddClosed').disabled = false;\r\n\r\n    if(j.success){\r\n      $('#closedReason').value = '';\r\n      toast('A\u00f1adido');\r\n      await loadClosed();\r\n    } else toast('Error a\u00f1adiendo');\r\n  });\r\n\r\n  $('#closedTable').addEventListener('click', async (e) => {\r\n    const btn = e.target.closest('button[data-del-closed]');\r\n    if(!btn) return;\r\n    const id = Number(btn.dataset.delClosed);\r\n    if(!confirm('\u00bfQuitar el d\u00eda cerrado #' + id + '?')) return;\r\n\r\n    btn.disabled = true;\r\n    const j = await apiPost('\/closed-days\/remove', { id });\r\n    btn.disabled = false;\r\n\r\n    if(j.success){ toast('Quitado'); await loadClosed(); }\r\n    else toast('Error quitando');\r\n  });\r\n\r\n  \/\/ Recargar todo\r\n  $('#btnInitReload').addEventListener('click', async () => {\r\n    await loadSettings();\r\n    await loadServices();\r\n    await loadClosed();\r\n    toast('Recargado');\r\n  });\r\n\r\n  \/\/ init\r\n  (async function init(){\r\n    await loadSettings();\r\n    await loadServices();\r\n    await loadClosed();\r\n  })();\r\n})();\r\n<\/script>\r\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>","protected":false},"excerpt":{"rendered":"<p>Zabalimp \u00b7 Admin Servicios \u00b7 Calendario \u00b7 Contacto Recargar todo Servicios Calendario Contacto &#038; Horario Servicios y tarifas Nuevo servicio A\u00f1adir Recargar Edita y pulsa Guardar. ID Nombre D\u00eda (normal) D\u00eda (especial) Noche (normal) Noche (especial) Acciones Bloquear fines de semana Bloquear festivos M\u00ednimo de pedido (\u20ac) Guardar reglas Cargando\u2026 D\u00edas cerrados (manual) Recargar Fecha [&hellip;]<\/p>","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_joinchat":[],"footnotes":""},"class_list":["post-5769","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/zabalimp.es\/en\/wp-json\/wp\/v2\/pages\/5769","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/zabalimp.es\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/zabalimp.es\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/zabalimp.es\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/zabalimp.es\/en\/wp-json\/wp\/v2\/comments?post=5769"}],"version-history":[{"count":0,"href":"https:\/\/zabalimp.es\/en\/wp-json\/wp\/v2\/pages\/5769\/revisions"}],"wp:attachment":[{"href":"https:\/\/zabalimp.es\/en\/wp-json\/wp\/v2\/media?parent=5769"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}