{"id":1733,"date":"2026-03-01T10:26:59","date_gmt":"2026-03-01T10:26:59","guid":{"rendered":"https:\/\/orangepetclinics.com\/?page_id=1733"},"modified":"2026-03-17T14:38:26","modified_gmt":"2026-03-17T14:38:26","slug":"appointment","status":"publish","type":"page","link":"https:\/\/orangepetclinics.com\/?page_id=1733","title":{"rendered":"Appointment"},"content":{"rendered":"\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n  <meta charset=\"UTF-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <title>Orange Pet Clinic Booking<\/title>\n\n  <!-- Restore Tailwind CSS for proper responsive layout -->\n  <script src=\"https:\/\/cdn.tailwindcss.com\"><\/script>\n\n  <style>\n    \/* \u2500\u2500 PREVENT WORDPRESS OVERRIDES on INPUTS & SELECTS \u2500\u2500 *\/\n    #bookingForm input,\n    #bookingForm select {\n      font-size: 16px !important;\n      line-height: 22px !important;\n      min-height: 50px !important;\n      box-sizing: border-box !important;\n    }\n\n    \/* Fix iOS Safari date input rendering *\/\n    input[type=\"date\"] {\n      -webkit-appearance: none;\n      -moz-appearance: none;\n      appearance: none;\n      background-color: #ffffff;\n      padding: 12px 16px !important;\n    }\n\n    input[type=\"date\"]::-webkit-calendar-picker-indicator {\n      opacity: 1;\n      cursor: pointer;\n      padding: 4px;\n    }\n\n    \/* Fix select styling & arrow on iOS *\/\n    select {\n      -webkit-appearance: none;\n      -moz-appearance: none;\n      appearance: none;\n      background-image: url(\"data:image\/svg+xml,%3Csvg xmlns='http:\/\/www.w3.org\/2000\/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23ea580c' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'\/%3E%3C\/svg%3E\") !important;\n      background-repeat: no-repeat !important;\n      background-position: right 12px center !important;\n      background-size: 18px !important;\n      padding-right: 40px !important;\n    }\n\n    \/* Slot custom buttons *\/\n    .slot-btn {\n      border: 1px solid #fdba74;\n      padding: 10px 4px;\n      text-align: center;\n      border-radius: 8px;\n      cursor: pointer;\n      color: #ea580c;\n      font-weight: 500;\n      font-size: 14px;\n      transition: background 0.15s, color 0.15s;\n      -webkit-tap-highlight-color: transparent;\n      user-select: none;\n    }\n\n    .slot-btn:hover:not(.disabled),\n    .slot-btn.active {\n      background-color: #ea580c;\n      color: #ffffff;\n    }\n\n    .slot-btn.disabled {\n      border-color: #e5e7eb;\n      background-color: #f3f4f6;\n      color: #9ca3af;\n      cursor: not-allowed;\n      text-decoration: line-through;\n    }\n  <\/style>\n<\/head>\n\n<body class=\"bg-gray-50 m-0 p-0\">\n  <div class=\"max-w-4xl mx-auto py-8 px-4 sm:px-6\">\n\n    <h1 class=\"text-2xl sm:text-3xl lg:text-4xl font-bold text-center mb-8 text-gray-800\">\n      Appointments \u2014 <span class=\"text-orange-600\">Orange Pet Clinic<\/span>\n    <\/h1>\n\n    <!-- \u2500\u2500 TABS \u2500\u2500 -->\n    <div class=\"flex flex-col sm:flex-row gap-2 mb-6 max-w-lg mx-auto\">\n      <button id=\"tabBooking\" onclick=\"switchTab('booking')\"\n        class=\"flex-1 py-3 px-4 rounded-xl font-bold text-center transition-all bg-orange-600 text-white shadow-md\">\n        Book Appointment\n      <\/button>\n      <button id=\"tabReschedule\" onclick=\"switchTab('reschedule')\"\n        class=\"flex-1 py-3 px-4 rounded-xl font-bold text-center transition-all bg-white text-gray-600 border border-gray-200 hover:bg-gray-50\">\n        Reschedule\n      <\/button>\n    <\/div>\n\n    <!-- \u2500\u2500 BOOKING FORM \u2500\u2500 -->\n    <form id=\"bookingForm\" class=\"bg-white p-5 sm:p-8 rounded-2xl shadow-lg w-full\">\n\n      <!-- CUSTOMER DETAILS -->\n      <div class=\"grid grid-cols-1 sm:grid-cols-2 gap-4 mb-5\">\n        <input type=\"text\" id=\"name\" placeholder=\"Customer Name\"\n          class=\"w-full border-2 border-orange-300 p-3 rounded-lg focus:outline-none focus:border-orange-500 text-gray-700\"\n          required>\n        <input type=\"email\" id=\"email\" placeholder=\"Email Address\"\n          class=\"w-full border-2 border-orange-300 p-3 rounded-lg focus:outline-none focus:border-orange-500 text-gray-700\"\n          required>\n        <input type=\"tel\" id=\"phone\" placeholder=\"Mobile Number\"\n          class=\"w-full border-2 border-orange-300 p-3 rounded-lg focus:outline-none focus:border-orange-500 text-gray-700 sm:col-span-2\"\n          required>\n      <\/div>\n\n      <!-- SERVICE TYPE -->\n      <div class=\"mb-5\">\n        <label class=\"block font-semibold mb-3 text-gray-700\">What do you need?<\/label>\n        <div class=\"flex flex-col sm:flex-row gap-4 sm:gap-8\">\n          <label class=\"flex items-center gap-2 cursor-pointer font-medium text-gray-700\">\n            <input type=\"radio\" name=\"serviceType\" value=\"grooming\" class=\"w-5 h-5 accent-orange-600\" checked\n              onchange=\"toggleServiceFields()\">\n            <span>Grooming \/ Spa<\/span>\n          <\/label>\n          <label class=\"flex items-center gap-2 cursor-pointer font-medium text-gray-700\">\n            <input type=\"radio\" name=\"serviceType\" value=\"doctor\" class=\"w-5 h-5 accent-orange-600\"\n              onchange=\"toggleServiceFields()\">\n            <span>Doctor Consultation<\/span>\n          <\/label>\n        <\/div>\n      <\/div>\n\n      <!-- GROOMING FIELDS -->\n      <div id=\"groomingFields\">\n        <!-- CATEGORY -->\n        <div class=\"mb-5\">\n          <label class=\"block font-semibold mb-2 text-gray-700\">Select Category<\/label>\n          <select id=\"category\"\n            class=\"w-full border-2 border-orange-300 p-3 rounded-lg focus:outline-none focus:border-orange-500 text-gray-700\"\n            onchange=\"updatePrice()\">\n            <option value=\"\">&#8212; Choose a category &#8212;<\/option>\n            <option value=\"Normal Bathing\">Bathing (Normal)<\/option>\n            <option value=\"Medicated Bathing\">Bathing (Medicated)<\/option>\n            <option value=\"Tick Bathing\">Bathing (Tick)<\/option>\n            <option value=\"Grooming Bathing\">Grooming &amp; Bathing<\/option>\n            <option value=\"Private Hair Cut\">Private Part Hair Cut<\/option>\n            <option value=\"Zero Hair Cut\">Zero Hair Cut<\/option>\n          <\/select>\n        <\/div>\n\n        <!-- BREED -->\n        <div class=\"mb-5\">\n          <label class=\"block font-semibold mb-2 text-gray-700\">Select Breed Size<\/label>\n          <select id=\"breed\"\n            class=\"w-full border-2 border-orange-300 p-3 rounded-lg focus:outline-none focus:border-orange-500 text-gray-700\"\n            onchange=\"updatePrice()\">\n            <option value=\"\">&#8212; Choose a breed size &#8212;<\/option>\n            <option value=\"Small\">Small Breed<\/option>\n            <option value=\"Medium\">Medium Breed<\/option>\n            <option value=\"Large\">Large Breed<\/option>\n            <option value=\"Puppy\">Puppy<\/option>\n          <\/select>\n        <\/div>\n      <\/div>\n\n      <!-- DOCTOR FIELDS -->\n      <div id=\"doctorFields\" class=\"hidden\">\n        <div class=\"mb-5\">\n          <label class=\"block font-semibold mb-2 text-gray-700\">Select Doctor<\/label>\n          <select id=\"doctor\"\n            class=\"w-full border-2 border-orange-300 p-3 rounded-lg focus:outline-none focus:border-orange-500 text-gray-700\"\n            onchange=\"updatePrice()\">\n            <option value=\"\">&#8212; Choose a doctor &#8212;<\/option>\n            <option value=\"Dr. Malli babu\">Dr. Malli babu &#8211; General Vet<\/option>\n            <option value=\"Dr. Jane Smith\">Dr. Jane Smith &#8211; Surgeon<\/option>\n            <option value=\"Dr. Alan Walker\">Dr. Alan Walker &#8211; Dermatologist<\/option>\n          <\/select>\n        <\/div>\n      <\/div>\n\n      <!-- DATE PICKER -->\n      <div class=\"mb-5\">\n        <label class=\"block font-semibold mb-2 text-gray-700\">Select Date<\/label>\n        <input type=\"date\" id=\"dateInput\"\n          class=\"w-full border-2 border-orange-300 p-3 rounded-lg focus:outline-none focus:border-orange-500 text-gray-700 cursor-pointer\"\n          onchange=\"updateDateDisplay()\" min=\"\">\n        <div id=\"dateDisplay\" class=\"hidden mt-2 text-center text-orange-600 font-bold text-lg\"><\/div>\n      <\/div>\n\n      <!-- TIME SLOTS -->\n      <div class=\"mb-6\">\n        <label class=\"block font-semibold mb-2 text-gray-700\">Select Time Slot<\/label>\n        <div id=\"slots\" class=\"grid grid-cols-2 sm:grid-cols-3 gap-3\">\n          <div class=\"col-span-full text-center text-gray-500 py-4\">Please select a date first<\/div>\n        <\/div>\n      <\/div>\n\n      <!-- PRICE BREAKDOWN -->\n      <div id=\"priceBreakdown\" class=\"hidden bg-orange-50 border border-orange-200 rounded-xl p-4 mb-6\">\n        <h3 class=\"font-semibold text-gray-800 mb-3\">Price Breakdown<\/h3>\n        <div id=\"priceDetails\" class=\"text-sm text-gray-600 space-y-2\"><\/div>\n        <div class=\"border-t border-orange-300 mt-4 pt-3 flex justify-between items-center\">\n          <span class=\"font-bold text-gray-900\">Total Amount<\/span>\n          <span id=\"price\" class=\"text-2xl font-black text-orange-600\">\u20b90<\/span>\n        <\/div>\n      <\/div>\n\n      <!-- FALLBACK PRICE -->\n      <p id=\"priceZero\" class=\"text-2xl font-black text-orange-600 mb-6\">\u20b90<\/p>\n\n      <!-- PAYMENT METHOD (STILL VISIBLE BUT ONLY ONE CHOICE) -->\n      <div class=\"mb-6\">\n        <label class=\"block font-semibold mb-3 text-gray-700\">Payment Method<\/label>\n        <div class=\"flex flex-col sm:flex-row gap-4 sm:gap-8\">\n          <label class=\"flex items-center gap-2 cursor-pointer font-medium text-gray-700\">\n            <input type=\"radio\" name=\"payment\" value=\"cash\" class=\"w-5 h-5 accent-orange-600\" checked>\n            <span>Pay at Clinic<\/span>\n          <\/label>\n        <\/div>\n      <\/div>\n\n      <button type=\"submit\"\n        class=\"w-full bg-orange-600 hover:bg-orange-700 text-white py-4 rounded-xl font-bold text-lg transition-colors shadow-md\">\n        Confirm Booking\n      <\/button>\n\n    <\/form>\n\n    <!-- \u2500\u2500 RESCHEDULE FORM \u2500\u2500 -->\n    <div id=\"rescheduleForm\" class=\"hidden bg-white p-5 sm:p-8 rounded-2xl shadow-lg w-full mt-6\">\n      <h2 class=\"text-xl font-bold text-gray-800 mb-4\">Find Your Appointment<\/h2>\n\n      <!-- Lookup Section -->\n      <div id=\"lookupSection\" class=\"flex flex-col sm:flex-row gap-4 mb-6\">\n        <input type=\"tel\" id=\"rPhone\" placeholder=\"Mobile Number\"\n          class=\"flex-1 border-2 border-orange-300 p-3 rounded-lg focus:outline-none focus:border-orange-500 text-gray-700\"\n          required>\n        <button onclick=\"fetchAppointment()\"\n          class=\"bg-gray-800 hover:bg-gray-900 text-white px-6 py-3 rounded-lg font-bold transition-colors whitespace-nowrap\">\n          Find Booking\n        <\/button>\n      <\/div>\n\n      <!-- Result Messages -->\n      <div id=\"rMessage\" class=\"hidden p-4 rounded-lg mb-6 font-medium text-center\"><\/div>\n\n      <!-- Reallocation Section (Hidden by default) -->\n      <div id=\"reallocationSection\" class=\"hidden border-t border-gray-200 pt-6 mt-6\">\n        <h3 class=\"text-lg font-bold text-gray-800 mb-4\">Select New Slot<\/h3>\n        <p class=\"text-sm text-gray-600 mb-4\">Original Slot: <span id=\"originalSlotText\"\n            class=\"font-bold text-orange-600\"><\/span><\/p>\n\n        <!-- DATE PICKER (Reschedule) -->\n        <div class=\"mb-5\">\n          <label class=\"block font-semibold mb-2 text-gray-700\">Select New Date<\/label>\n          <input type=\"date\" id=\"rDateInput\"\n            class=\"w-full border-2 border-orange-300 p-3 rounded-lg focus:outline-none focus:border-orange-500 text-gray-700 cursor-pointer\"\n            onchange=\"updateRDateDisplay()\" min=\"\">\n          <div id=\"rDateDisplay\" class=\"hidden mt-2 text-center text-orange-600 font-bold text-lg\"><\/div>\n        <\/div>\n\n        <!-- TIME SLOTS (Reschedule) -->\n        <div class=\"mb-6\">\n          <label class=\"block font-semibold mb-2 text-gray-700\">Select New Time<\/label>\n          <div id=\"rSlots\" class=\"grid grid-cols-2 sm:grid-cols-3 gap-3\">\n            <div class=\"col-span-full text-center text-gray-500 py-4\">Please select a new date first<\/div>\n          <\/div>\n        <\/div>\n\n        <button onclick=\"submitReschedule()\"\n          class=\"w-full bg-orange-600 hover:bg-orange-700 text-white py-4 rounded-xl font-bold text-lg transition-colors shadow-md mt-4\">\n          Confirm Reschedule\n        <\/button>\n      <\/div>\n    <\/div>\n  <\/div>\n\n  <script>\n    \/\/ \u2500\u2500\u2500 TABS LOGIC \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n    function switchTab(tab) {\n      const bookingForm = document.getElementById('bookingForm');\n      const rescheduleForm = document.getElementById('rescheduleForm');\n      const tabB = document.getElementById('tabBooking');\n      const tabR = document.getElementById('tabReschedule');\n\n      if (tab === 'booking') {\n        bookingForm.classList.remove('hidden');\n        rescheduleForm.classList.add('hidden');\n        tabB.className = \"flex-1 py-3 px-4 rounded-xl font-bold text-center transition-all bg-orange-600 text-white shadow-md\";\n        tabR.className = \"flex-1 py-3 px-4 rounded-xl font-bold text-center transition-all bg-white text-gray-600 border border-gray-200 hover:bg-gray-50\";\n      } else {\n        bookingForm.classList.add('hidden');\n        rescheduleForm.classList.remove('hidden');\n        tabR.className = \"flex-1 py-3 px-4 rounded-xl font-bold text-center transition-all bg-orange-600 text-white shadow-md\";\n        tabB.className = \"flex-1 py-3 px-4 rounded-xl font-bold text-center transition-all bg-white text-gray-600 border border-gray-200 hover:bg-gray-50\";\n      }\n    }\n\n    \/\/ \u2500\u2500\u2500 DYNAMIC PRICING TABLE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n    let prices = {};\n    let doctorFees = {};\n\n    \/\/ Fetch live prices from WordPress backend\n    fetch(\"\/wp-admin\/admin-ajax.php?action=get_service_prices\")\n      .then(res => res.json())\n      .then(result => {\n        if (result.success) {\n          prices = result.data.grooming;\n          doctorFees = result.data.doctors;\n        } else {\n          console.error(\"Failed to load prices\");\n        }\n      })\n      .catch(err => console.error(\"Error fetching prices:\", err));\n\n    const complimentary = {\n      \"Normal Bathing\": [\"Nail Cutting\", \"Ear Cleaning\"],\n      \"Medicated Bathing\": [\"Nail Cutting\", \"Ear Cleaning\"],\n      \"Tick Bathing\": [\"Nail Cutting\", \"Ear Cleaning\"],\n      \"Grooming Bathing\": [\"Nail Cutting\", \"Ear Cleaning\"]\n    };\n\n    \/\/ \u2500\u2500\u2500 LIVE PRICE UPDATE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n    function toggleServiceFields() {\n      const type = document.querySelector('input[name=\"serviceType\"]:checked').value;\n      const groomingFields = document.getElementById(\"groomingFields\");\n      const doctorFields = document.getElementById(\"doctorFields\");\n\n      if (type === \"doctor\") {\n        groomingFields.classList.add(\"hidden\");\n        doctorFields.classList.remove(\"hidden\");\n\n        \/\/ Clear grooming fields\n        document.getElementById(\"category\").value = \"\";\n        document.getElementById(\"breed\").value = \"\";\n      } else {\n        groomingFields.classList.remove(\"hidden\");\n        doctorFields.classList.add(\"hidden\");\n\n        \/\/ Clear doctor fields\n        document.getElementById(\"doctor\").value = \"\";\n      }\n\n      updatePrice();\n      \/\/ Re-fetch slots if date is already selected\n      if (document.getElementById(\"dateInput\").value) {\n        updateDateDisplay();\n      }\n    }\n\n    function updatePrice() {\n      const breakdown = document.getElementById(\"priceBreakdown\");\n      const priceZero = document.getElementById(\"priceZero\");\n      const priceEl = document.getElementById(\"price\");\n      const detailEl = document.getElementById(\"priceDetails\");\n      const type = document.querySelector('input[name=\"serviceType\"]:checked').value;\n\n      if (type === \"doctor\") {\n        const doc = document.getElementById(\"doctor\").value;\n        if (!doc) {\n          breakdown.classList.add(\"hidden\");\n          priceZero.style.display = \"block\";\n          priceZero.textContent = \"\u20b90\";\n          priceZero.classList.remove(\"text-red-600\");\n          priceZero.classList.add(\"text-orange-600\", \"text-2xl\");\n          return;\n        }\n\n        const fee = doctorFees[doc];\n        priceZero.style.display = \"none\";\n        detailEl.innerHTML = `<div class=\"flex justify-between font-medium\"><span>Doctor Consultation<\/span><span>\u20b9${fee}<\/span><\/div>\n                              <div class=\"flex justify-between text-gray-500 font-medium text-xs mt-1\"><span>${doc}<\/span><span><\/span><\/div>`;\n        priceEl.textContent = `\u20b9${fee}`;\n        breakdown.classList.remove(\"hidden\");\n        return;\n      }\n\n      \/\/ GROOMING LOGIC\n      const cat = document.getElementById(\"category\").value;\n      const breed = document.getElementById(\"breed\").value;\n\n      if (!cat || !breed) {\n        breakdown.classList.add(\"hidden\");\n        priceZero.style.display = \"block\";\n        priceZero.textContent = \"\u20b90\";\n        priceZero.classList.remove(\"text-red-600\");\n        priceZero.classList.add(\"text-orange-600\", \"text-2xl\");\n        return;\n      }\n\n      const amount = prices[cat]?.[breed];\n\n      if (amount === null) {\n        breakdown.classList.add(\"hidden\");\n        priceZero.style.display = \"block\";\n        priceZero.textContent = \"\u26a0\ufe0f Not available for Puppy\";\n        priceZero.classList.remove(\"text-orange-600\", \"text-2xl\");\n        priceZero.classList.add(\"text-red-600\", \"text-base\", \"font-semibold\");\n        return;\n      }\n\n      priceZero.style.display = \"none\";\n\n      let html = `<div class=\"flex justify-between font-medium\"><span>${cat} \u2014 ${breed} Breed<\/span><span>\u20b9${amount}<\/span><\/div>`;\n      const extras = complimentary[cat];\n      if (extras) {\n        extras.forEach(item => {\n          html += `<div class=\"flex justify-between text-green-600 font-medium\"><span>${item}<\/span><span>Complimentary \u2713<\/span><\/div>`;\n        });\n      }\n\n      detailEl.innerHTML = html;\n      priceEl.textContent = `\u20b9${amount}`;\n      breakdown.classList.remove(\"hidden\");\n    }\n\n    \/\/ \u2500\u2500\u2500 DATE PICKER (Booking) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n    const dateInput = document.getElementById(\"dateInput\");\n    const dateDisplay = document.getElementById(\"dateDisplay\");\n\n    \/\/ \u2500\u2500\u2500 DATE PICKER (Reschedule) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n    const rDateInput = document.getElementById(\"rDateInput\");\n    const rDateDisplay = document.getElementById(\"rDateDisplay\");\n\n    const today = new Date();\n    const yyyy = today.getFullYear();\n    const mm = String(today.getMonth() + 1).padStart(2, \"0\");\n    const dd = String(today.getDate()).padStart(2, \"0\");\n    dateInput.min = `${yyyy}-${mm}-${dd}`;\n    rDateInput.min = `${yyyy}-${mm}-${dd}`;\n\n    function formatDate(dateStr) {\n      if (!dateStr) return \"\";\n      const d = new Date(dateStr + \"T00:00:00\");\n      return d.toLocaleDateString(\"en-IN\", { day: \"numeric\", month: \"short\", year: \"numeric\" });\n    }\n\n    function updateDateDisplay() {\n      const rawDate = dateInput.value;\n      const formatted = formatDate(rawDate);\n      if (formatted) {\n        dateDisplay.textContent = \"\ud83d\udcc5 \" + formatted;\n        dateDisplay.classList.remove(\"hidden\");\n        fetchAndRenderSlots(rawDate);\n      } else {\n        dateDisplay.classList.add(\"hidden\");\n        slotsContainer.innerHTML = '<div class=\"col-span-full text-center text-gray-500 py-4 font-medium\">Please select a date first<\/div>';\n        selectedTime = null;\n      }\n    }\n\n    \/\/ \u2500\u2500\u2500 TIME SLOTS RENDERER \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n    const slotsContainer = document.getElementById(\"slots\");\n    const rSlotsContainer = document.getElementById(\"rSlots\");\n    let selectedTime = null;\n    let rSelectedTime = null;\n    let globalRescheduleType = 'grooming'; \/\/ Fallback for old bookings\n\n    \/\/ Master list of all possible slots\n    const allSlots = [];\n    for (let i = 10; i <= 20; i++) {\n      let hour = i > 12 ? i - 12 : i;\n      let ampm = i >= 12 ? \"PM\" : \"AM\";\n      if (i === 12) ampm = \"PM\";\n      allSlots.push(`${hour}:00 ${ampm}`);\n    }\n\n    async function fetchAndRenderSlots(selectedDate, isReschedule = false) {\n      const container = isReschedule ? rSlotsContainer : slotsContainer;\n\n      \/\/ 1. Show loading UI\n      container.innerHTML = '<div class=\"col-span-full text-center text-orange-600 font-bold py-4 animate-pulse\">Checking availability...<\/div>';\n\n      if (isReschedule) rSelectedTime = null;\n      else selectedTime = null;\n\n      try {\n        const type = isReschedule ? globalRescheduleType : document.querySelector('input[name=\"serviceType\"]:checked').value;\n\n        \/\/ 2. Fetch booked slots from WordPress backend\n        const formData = new FormData();\n        formData.append(\"action\", \"get_booked_slots\");\n        formData.append(\"date\", selectedDate);\n        formData.append(\"type\", type);\n\n        const response = await fetch(\"\/wp-admin\/admin-ajax.php\", {\n          method: \"POST\",\n          body: formData\n        });\n\n        const result = await response.json();\n        const bookedSlots = result.success && Array.isArray(result.data) ? result.data : [];\n\n        \/\/ 3. Render time slots\n        container.innerHTML = \"\";\n\n        allSlots.forEach(time => {\n          let div = document.createElement(\"div\");\n          const isBooked = bookedSlots.includes(time);\n\n          div.innerText = isBooked ? `${time} (Booked)` : time;\n          div.className = isBooked ? \"slot-btn disabled\" : \"slot-btn\";\n\n          if (!isBooked) {\n            div.addEventListener(\"click\", function () {\n              const selector = isReschedule ? \"#rSlots .slot-btn:not(.disabled)\" : \"#slots .slot-btn:not(.disabled)\";\n              document.querySelectorAll(selector).forEach(el => el.classList.remove(\"active\"));\n              div.classList.add(\"active\");\n\n              if (isReschedule) rSelectedTime = time;\n              else selectedTime = time;\n            });\n          }\n\n          container.appendChild(div);\n        });\n\n      } catch (error) {\n        console.error(\"Failed to fetch slots:\", error);\n        container.innerHTML = '<div class=\"col-span-full text-center text-red-500 py-4 font-medium\">Error loading slots. Please refresh and try again.<\/div>';\n      }\n    }\n\n    \/\/ \u2500\u2500\u2500 FORM SUBMIT \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n    document.getElementById(\"bookingForm\").addEventListener(\"submit\", function (e) {\n      e.preventDefault();\n\n      const btn = this.querySelector('button[type=\"submit\"]');\n      if (btn.disabled) return;\n\n      const name = document.getElementById(\"name\").value;\n      const email = document.getElementById(\"email\").value;\n      const phone = document.getElementById(\"phone\").value;\n      const type = document.querySelector('input[name=\"serviceType\"]:checked').value;\n      const category = document.getElementById(\"category\").value;\n      const breed = document.getElementById(\"breed\").value;\n      const doctor = document.getElementById(\"doctor\").value;\n      const date = dateInput.value;\n      const paymentEl = document.querySelector('input[name=\"payment\"]:checked');\n\n      if (type === \"grooming\") {\n        if (!category) { alert(\"Please select a category.\"); return; }\n        if (!breed) { alert(\"Please select a breed size.\"); return; }\n      } else {\n        if (!doctor) { alert(\"Please select a doctor.\"); return; }\n      }\n\n      if (!date) { alert(\"Please select a date.\"); return; }\n      if (!selectedTime) { alert(\"Please select a time slot.\"); return; }\n      if (!paymentEl) { alert(\"Please select a payment method.\"); return; }\n\n      const payment = paymentEl.value;\n      let amount = 0;\n      let description = \"\";\n\n      if (type === \"grooming\") {\n        amount = prices[category]?.[breed] || 0;\n        description = `${category} \u2014 ${breed} Breed`;\n      } else {\n        amount = doctorFees[doctor] || 0;\n        description = `Doctor Consultation \u2014 ${doctor}`;\n      }\n\n      \/\/ Disable button to prevent duplicate submissions\n      const origText = btn.innerText;\n      btn.disabled = true;\n      btn.innerText = \"Processing...\";\n\n      const data = { name, email, phone, type, category, breed, doctor, date, time: selectedTime, payment, amount };\n\n      fetch(\"\/wp-admin\/admin-ajax.php?action=pet_booking\", {\n        method: \"POST\",\n        headers: { \"Content-Type\": \"application\/json\" },\n        body: JSON.stringify(data)\n      })\n        .then(res => res.json())\n        .then(response => {\n          if (response.success) {\n            alert(\"\u2705 Booking confirmed! Please pay at the clinic.\");\n            window.location.reload();\n          } else {\n            alert(\"\u274c Booking Failed: \" + (response.data || \"Unknown server error.\"));\n          }\n        })\n        .catch(error => {\n          console.error(\"Booking Error:\", error);\n          alert(\"\u274c Booking Failed: Network or server error. Please try again.\");\n        })\n        .finally(() => {\n          btn.disabled = false;\n          btn.innerText = origText;\n        });\n    });\n\n    \/\/ \u2500\u2500\u2500 RESCHEDULE LOGIC \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n    let globalRescheduleBookingId = null;\n\n    function parseTimeStr(timeStr) {\n      const [time, modifier] = timeStr.split(' ');\n      let [hours, minutes] = time.split(':');\n      if (hours === '12') hours = '00';\n      if (modifier === 'PM') hours = parseInt(hours, 10) + 12;\n      return new Date().setHours(hours, minutes, 0, 0);\n    }\n\n    async function fetchAppointment() {\n      const phone = document.getElementById(\"rPhone\").value;\n      const msgBox = document.getElementById(\"rMessage\");\n      const rSection = document.getElementById(\"reallocationSection\");\n\n      if (!phone) {\n        alert(\"Please enter a mobile number.\");\n        return;\n      }\n\n      msgBox.className = \"hidden\";\n      msgBox.textContent = \"Searching...\";\n      msgBox.classList.remove(\"hidden\");\n      msgBox.classList.add(\"bg-orange-100\", \"text-orange-800\");\n\n      try {\n        const formData = new FormData();\n        formData.append(\"action\", \"fetch_booking_by_phone\");\n        formData.append(\"phone\", phone);\n\n        const response = await fetch(\"\/wp-admin\/admin-ajax.php\", {\n          method: \"POST\",\n          body: formData\n        });\n\n        const result = await response.json();\n\n        if (!result.success || !result.data) {\n          throw new Error(\"No active appointment found for this number.\");\n        }\n\n        const booking = result.data;\n        globalRescheduleBookingId = booking.id;\n        globalRescheduleType = booking.type || 'grooming';\n\n        \/\/ \u2500\u2500\u2500 1.5 HOUR Cutoff Logic \u2500\u2500\u2500\n        const now = new Date();\n        const appointmentDateStr = booking.date; \n        const appointmentTimeStr = booking.time; \n\n        const [time, modifier] = appointmentTimeStr.split(' ');\n        let [hours, minutes] = time.split(':');\n        if (hours === '12') hours = '00';\n        if (modifier === 'PM') hours = parseInt(hours, 10) + 12;\n\n        const appointmentDateTime = new Date(`${appointmentDateStr}T${hours.toString().padStart(2, '0')}:${minutes}:00`);\n\n        const diffMs = appointmentDateTime.getTime() - now.getTime();\n        const diffHours = diffMs \/ (1000 * 60 * 60);\n\n        msgBox.classList.remove(\"hidden\", \"bg-orange-100\", \"text-orange-800\");\n\n        if (diffHours < 1.5) {\n          msgBox.classList.add(\"bg-red-100\", \"text-red-700\");\n          if (diffHours < 0) {\n            msgBox.innerHTML = `\u26a0\ufe0f This appointment (${formatDate(appointmentDateStr)} at ${appointmentTimeStr}) has already passed and cannot be rescheduled.`;\n          } else {\n            msgBox.innerHTML = `\u26a0\ufe0f Cannot reschedule. Changes are not permitted within 1.5 hours of your appointment time (${appointmentTimeStr}).`;\n          }\n          rSection.classList.add(\"hidden\");\n        } else {\n          msgBox.classList.add(\"bg-green-100\", \"text-green-800\");\n          msgBox.innerHTML = `\u2705 Found appointment on ${formatDate(appointmentDateStr)} at ${appointmentTimeStr}.`;\n\n          document.getElementById(\"originalSlotText\").textContent = `${formatDate(appointmentDateStr)} at ${appointmentTimeStr}`;\n          rSection.classList.remove(\"hidden\");\n        }\n\n      } catch (error) {\n        msgBox.className = \"p-4 rounded-lg font-medium text-center bg-red-100 text-red-700\";\n        msgBox.textContent = error.message || \"Failed to find booking. Are you sure you booked with this number?\";\n        rSection.classList.add(\"hidden\");\n      }\n    }\n\n    function updateRDateDisplay() {\n      const rawDate = rDateInput.value;\n      const formatted = formatDate(rawDate);\n      if (formatted) {\n        rDateDisplay.textContent = \"\ud83d\udcc5 \" + formatted;\n        rDateDisplay.classList.remove(\"hidden\");\n        fetchAndRenderSlots(rawDate, true);\n      } else {\n        rDateDisplay.classList.add(\"hidden\");\n        rSlotsContainer.innerHTML = '<div class=\"col-span-full text-center text-gray-500 py-4 font-medium\">Please select a date first<\/div>';\n        rSelectedTime = null;\n      }\n    }\n\n    function submitReschedule() {\n      const newDate = rDateInput.value;\n      const phone = document.getElementById(\"rPhone\").value;\n\n      if (!newDate) { alert(\"Please select a new date.\"); return; }\n      if (!rSelectedTime) { alert(\"Please select a new time slot.\"); return; }\n\n      const data = {\n        phone: phone,\n        new_date: newDate,\n        new_time: rSelectedTime\n      };\n\n      fetch(\"\/wp-admin\/admin-ajax.php?action=reschedule_booking\", {\n        method: \"POST\",\n        headers: { \"Content-Type\": \"application\/json\" },\n        body: JSON.stringify(data)\n      })\n        .then(res => res.json())\n        .then((res) => {\n          if (res.status === 'success') {\n            alert(`\u2705 Appointment successfully rescheduled to ${formatDate(newDate)} at ${rSelectedTime}!`);\n          } else {\n            alert(res.data || \"An error occurred.\");\n          }\n        })\n        .catch((err) => alert(\"Failed to reschedule. Please try again later.\"));\n    }\n\n  <\/script>\n\n<\/body>\n\n<\/html>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Orange Pet Clinic Booking Appointments \u2014 Orange Pet Clinic Book Appointment Reschedule What do you need? Grooming \/ Spa Doctor Consultation Select Category &#8212; Choose a category &#8212;Bathing (Normal)Bathing (Medicated)Bathing (Tick)Grooming &amp; BathingPrivate Part Hair CutZero Hair Cut Select Breed Size &#8212; Choose a breed size &#8212;Small BreedMedium BreedLarge BreedPuppy Select Doctor &#8212; Choose a [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-1733","page","type-page","status-publish","hentry"],"blocksy_meta":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.7 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Appointment - Orange Pet Clinics<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/orangepetclinics.com\/?page_id=1733\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Appointment - Orange Pet Clinics\" \/>\n<meta property=\"og:description\" content=\"Orange Pet Clinic Booking Appointments \u2014 Orange Pet Clinic Book Appointment Reschedule What do you need? Grooming \/ Spa Doctor Consultation Select Category &#8212; Choose a category &#8212;Bathing (Normal)Bathing (Medicated)Bathing (Tick)Grooming &amp; BathingPrivate Part Hair CutZero Hair Cut Select Breed Size &#8212; Choose a breed size &#8212;Small BreedMedium BreedLarge BreedPuppy Select Doctor &#8212; Choose a [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/orangepetclinics.com\/?page_id=1733\" \/>\n<meta property=\"og:site_name\" content=\"Orange Pet Clinics\" \/>\n<meta property=\"article:modified_time\" content=\"2026-03-17T14:38:26+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"1 minute\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/orangepetclinics.com\\\/?page_id=1733\",\"url\":\"https:\\\/\\\/orangepetclinics.com\\\/?page_id=1733\",\"name\":\"Appointment - Orange Pet Clinics\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/orangepetclinics.com\\\/#website\"},\"datePublished\":\"2026-03-01T10:26:59+00:00\",\"dateModified\":\"2026-03-17T14:38:26+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/orangepetclinics.com\\\/?page_id=1733#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/orangepetclinics.com\\\/?page_id=1733\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/orangepetclinics.com\\\/?page_id=1733#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/orangepetclinics.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Appointment\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/orangepetclinics.com\\\/#website\",\"url\":\"https:\\\/\\\/orangepetclinics.com\\\/\",\"name\":\"Orange Pet Clinics\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/orangepetclinics.com\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/orangepetclinics.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/orangepetclinics.com\\\/#organization\",\"name\":\"Orange Pet Clinics\",\"url\":\"https:\\\/\\\/orangepetclinics.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/orangepetclinics.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/orangepetclinics.com\\\/wp-content\\\/uploads\\\/2026\\\/02\\\/Untitled-26-scaled.png\",\"contentUrl\":\"https:\\\/\\\/orangepetclinics.com\\\/wp-content\\\/uploads\\\/2026\\\/02\\\/Untitled-26-scaled.png\",\"width\":2560,\"height\":564,\"caption\":\"Orange Pet Clinics\"},\"image\":{\"@id\":\"https:\\\/\\\/orangepetclinics.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Appointment - Orange Pet Clinics","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:\/\/orangepetclinics.com\/?page_id=1733","og_locale":"en_US","og_type":"article","og_title":"Appointment - Orange Pet Clinics","og_description":"Orange Pet Clinic Booking Appointments \u2014 Orange Pet Clinic Book Appointment Reschedule What do you need? Grooming \/ Spa Doctor Consultation Select Category &#8212; Choose a category &#8212;Bathing (Normal)Bathing (Medicated)Bathing (Tick)Grooming &amp; BathingPrivate Part Hair CutZero Hair Cut Select Breed Size &#8212; Choose a breed size &#8212;Small BreedMedium BreedLarge BreedPuppy Select Doctor &#8212; Choose a [&hellip;]","og_url":"https:\/\/orangepetclinics.com\/?page_id=1733","og_site_name":"Orange Pet Clinics","article_modified_time":"2026-03-17T14:38:26+00:00","twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"1 minute"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/orangepetclinics.com\/?page_id=1733","url":"https:\/\/orangepetclinics.com\/?page_id=1733","name":"Appointment - Orange Pet Clinics","isPartOf":{"@id":"https:\/\/orangepetclinics.com\/#website"},"datePublished":"2026-03-01T10:26:59+00:00","dateModified":"2026-03-17T14:38:26+00:00","breadcrumb":{"@id":"https:\/\/orangepetclinics.com\/?page_id=1733#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/orangepetclinics.com\/?page_id=1733"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/orangepetclinics.com\/?page_id=1733#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/orangepetclinics.com\/"},{"@type":"ListItem","position":2,"name":"Appointment"}]},{"@type":"WebSite","@id":"https:\/\/orangepetclinics.com\/#website","url":"https:\/\/orangepetclinics.com\/","name":"Orange Pet Clinics","description":"","publisher":{"@id":"https:\/\/orangepetclinics.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/orangepetclinics.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/orangepetclinics.com\/#organization","name":"Orange Pet Clinics","url":"https:\/\/orangepetclinics.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/orangepetclinics.com\/#\/schema\/logo\/image\/","url":"https:\/\/orangepetclinics.com\/wp-content\/uploads\/2026\/02\/Untitled-26-scaled.png","contentUrl":"https:\/\/orangepetclinics.com\/wp-content\/uploads\/2026\/02\/Untitled-26-scaled.png","width":2560,"height":564,"caption":"Orange Pet Clinics"},"image":{"@id":"https:\/\/orangepetclinics.com\/#\/schema\/logo\/image\/"}}]}},"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/orangepetclinics.com\/index.php?rest_route=\/wp\/v2\/pages\/1733","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/orangepetclinics.com\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/orangepetclinics.com\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/orangepetclinics.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/orangepetclinics.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1733"}],"version-history":[{"count":9,"href":"https:\/\/orangepetclinics.com\/index.php?rest_route=\/wp\/v2\/pages\/1733\/revisions"}],"predecessor-version":[{"id":2884,"href":"https:\/\/orangepetclinics.com\/index.php?rest_route=\/wp\/v2\/pages\/1733\/revisions\/2884"}],"wp:attachment":[{"href":"https:\/\/orangepetclinics.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1733"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}