Pranav Nachanekar | afe52e8 | 2019-10-03 16:35:08 +0530 | [diff] [blame] | 1 | frappe.ready(async () => { |
Ankush Menat | ec74a5e | 2024-03-10 19:45:40 +0530 | [diff] [blame] | 2 | initialise_select_date(); |
| 3 | }); |
Pranav Nachanekar | afe52e8 | 2019-10-03 16:35:08 +0530 | [diff] [blame] | 4 | |
Pranav Nachanekar | 10711dd | 2019-09-09 15:41:20 +0530 | [diff] [blame] | 5 | async function initialise_select_date() { |
Ankush Menat | ec74a5e | 2024-03-10 19:45:40 +0530 | [diff] [blame] | 6 | navigate_to_page(1); |
| 7 | await get_global_variables(); |
| 8 | setup_date_picker(); |
| 9 | setup_timezone_selector(); |
| 10 | hide_next_button(); |
pranav nachnekar | 2791054 | 2019-09-03 12:04:52 +0530 | [diff] [blame] | 11 | } |
| 12 | |
Pranav Nachanekar | 10711dd | 2019-09-09 15:41:20 +0530 | [diff] [blame] | 13 | async function get_global_variables() { |
Ankush Menat | ec74a5e | 2024-03-10 19:45:40 +0530 | [diff] [blame] | 14 | // Using await through this file instead of then. |
| 15 | window.appointment_settings = ( |
| 16 | await frappe.call({ |
| 17 | method: "erpnext.www.book_appointment.index.get_appointment_settings", |
| 18 | }) |
| 19 | ).message; |
| 20 | window.timezones = ( |
| 21 | await frappe.call({ |
| 22 | method: "erpnext.www.book_appointment.index.get_timezones", |
| 23 | }) |
| 24 | ).message; |
Pranav Nachanekar | 10711dd | 2019-09-09 15:41:20 +0530 | [diff] [blame] | 25 | } |
| 26 | |
| 27 | function setup_timezone_selector() { |
Ankush Menat | ec74a5e | 2024-03-10 19:45:40 +0530 | [diff] [blame] | 28 | let timezones_element = document.getElementById("appointment-timezone"); |
| 29 | let local_timezone = moment.tz.guess(); |
| 30 | window.timezones.forEach((timezone) => { |
| 31 | let opt = document.createElement("option"); |
| 32 | opt.value = timezone; |
| 33 | if (timezone == local_timezone) { |
| 34 | opt.selected = true; |
| 35 | } |
| 36 | opt.innerHTML = timezone; |
| 37 | timezones_element.appendChild(opt); |
| 38 | }); |
pranav nachnekar | 2791054 | 2019-09-03 12:04:52 +0530 | [diff] [blame] | 39 | } |
| 40 | |
Pranav Nachanekar | 10711dd | 2019-09-09 15:41:20 +0530 | [diff] [blame] | 41 | function setup_date_picker() { |
Ankush Menat | ec74a5e | 2024-03-10 19:45:40 +0530 | [diff] [blame] | 42 | let date_picker = document.getElementById("appointment-date"); |
| 43 | let today = new Date(); |
| 44 | date_picker.min = today.toISOString().substr(0, 10); |
| 45 | today.setDate(today.getDate() + window.appointment_settings.advance_booking_days); |
| 46 | date_picker.max = today.toISOString().substr(0, 10); |
pranav nachnekar | 2791054 | 2019-09-03 12:04:52 +0530 | [diff] [blame] | 47 | } |
| 48 | |
Pranav Nachanekar | 91a5649 | 2019-09-17 16:58:41 +0530 | [diff] [blame] | 49 | function hide_next_button() { |
Ankush Menat | ec74a5e | 2024-03-10 19:45:40 +0530 | [diff] [blame] | 50 | let next_button = document.getElementById("next-button"); |
| 51 | next_button.disabled = true; |
| 52 | next_button.onclick = () => frappe.msgprint(__("Please select a date and time")); |
Pranav Nachanekar | 10711dd | 2019-09-09 15:41:20 +0530 | [diff] [blame] | 53 | } |
| 54 | |
Pranav Nachanekar | 91a5649 | 2019-09-17 16:58:41 +0530 | [diff] [blame] | 55 | function show_next_button() { |
Ankush Menat | ec74a5e | 2024-03-10 19:45:40 +0530 | [diff] [blame] | 56 | let next_button = document.getElementById("next-button"); |
| 57 | next_button.disabled = false; |
| 58 | next_button.onclick = setup_details_page; |
Pranav Nachanekar | 10711dd | 2019-09-09 15:41:20 +0530 | [diff] [blame] | 59 | } |
| 60 | |
| 61 | function on_date_or_timezone_select() { |
Ankush Menat | ec74a5e | 2024-03-10 19:45:40 +0530 | [diff] [blame] | 62 | let date_picker = document.getElementById("appointment-date"); |
| 63 | let timezone = document.getElementById("appointment-timezone"); |
| 64 | if (date_picker.value === "") { |
| 65 | clear_time_slots(); |
| 66 | hide_next_button(); |
| 67 | frappe.throw(__("Please select a date")); |
| 68 | } |
| 69 | window.selected_date = date_picker.value; |
| 70 | window.selected_timezone = timezone.value; |
| 71 | update_time_slots(date_picker.value, timezone.value); |
| 72 | let lead_text = document.getElementById("lead-text"); |
| 73 | lead_text.innerHTML = __("Select Time"); |
Pranav Nachanekar | 10711dd | 2019-09-09 15:41:20 +0530 | [diff] [blame] | 74 | } |
| 75 | |
| 76 | async function get_time_slots(date, timezone) { |
Ankush Menat | ec74a5e | 2024-03-10 19:45:40 +0530 | [diff] [blame] | 77 | let slots = ( |
| 78 | await frappe.call({ |
| 79 | method: "erpnext.www.book_appointment.index.get_appointment_slots", |
| 80 | args: { |
| 81 | date: date, |
| 82 | timezone: timezone, |
| 83 | }, |
| 84 | }) |
| 85 | ).message; |
| 86 | return slots; |
Pranav Nachanekar | 10711dd | 2019-09-09 15:41:20 +0530 | [diff] [blame] | 87 | } |
pranav nachnekar | c5b2a58 | 2019-09-03 14:16:47 +0530 | [diff] [blame] | 88 | |
Pranav Nachanekar | 10711dd | 2019-09-09 15:41:20 +0530 | [diff] [blame] | 89 | async function update_time_slots(selected_date, selected_timezone) { |
Ankush Menat | ec74a5e | 2024-03-10 19:45:40 +0530 | [diff] [blame] | 90 | let timeslot_container = document.getElementById("timeslot-container"); |
| 91 | window.slots = await get_time_slots(selected_date, selected_timezone); |
| 92 | clear_time_slots(); |
| 93 | if (window.slots.length <= 0) { |
| 94 | let message_div = document.createElement("p"); |
| 95 | message_div.innerHTML = __("There are no slots available on this date"); |
| 96 | timeslot_container.appendChild(message_div); |
| 97 | return; |
| 98 | } |
| 99 | window.slots.forEach((slot, index) => { |
| 100 | // Get and append timeslot div |
| 101 | let timeslot_div = get_timeslot_div_layout(slot); |
| 102 | timeslot_container.appendChild(timeslot_div); |
| 103 | }); |
| 104 | set_default_timeslot(); |
Pranav Nachanekar | 10711dd | 2019-09-09 15:41:20 +0530 | [diff] [blame] | 105 | } |
| 106 | |
Pranav Nachanekar | 91a5649 | 2019-09-17 16:58:41 +0530 | [diff] [blame] | 107 | function get_timeslot_div_layout(timeslot) { |
Ankush Menat | ec74a5e | 2024-03-10 19:45:40 +0530 | [diff] [blame] | 108 | let start_time = new Date(timeslot.time); |
| 109 | let timeslot_div = document.createElement("div"); |
| 110 | timeslot_div.classList.add("time-slot"); |
| 111 | if (!timeslot.availability) { |
| 112 | timeslot_div.classList.add("unavailable"); |
| 113 | } |
| 114 | timeslot_div.innerHTML = get_slot_layout(start_time); |
| 115 | timeslot_div.id = timeslot.time.substring(11, 19); |
| 116 | timeslot_div.addEventListener("click", select_time); |
| 117 | return timeslot_div; |
Pranav Nachanekar | 91a5649 | 2019-09-17 16:58:41 +0530 | [diff] [blame] | 118 | } |
| 119 | |
Pranav Nachanekar | 10711dd | 2019-09-09 15:41:20 +0530 | [diff] [blame] | 120 | function clear_time_slots() { |
Ankush Menat | ec74a5e | 2024-03-10 19:45:40 +0530 | [diff] [blame] | 121 | // Clear any existing divs in timeslot container |
| 122 | let timeslot_container = document.getElementById("timeslot-container"); |
| 123 | while (timeslot_container.firstChild) { |
| 124 | timeslot_container.removeChild(timeslot_container.firstChild); |
| 125 | } |
Pranav Nachanekar | 10711dd | 2019-09-09 15:41:20 +0530 | [diff] [blame] | 126 | } |
| 127 | |
| 128 | function get_slot_layout(time) { |
Ankush Menat | ec74a5e | 2024-03-10 19:45:40 +0530 | [diff] [blame] | 129 | let timezone = document.getElementById("appointment-timezone").value; |
| 130 | time = new Date(time); |
| 131 | let start_time_string = moment(time).tz(timezone).format("LT"); |
| 132 | let end_time = moment(time).tz(timezone).add(window.appointment_settings.appointment_duration, "minutes"); |
| 133 | let end_time_string = end_time.format("LT"); |
| 134 | return `<span style="font-size: 1.2em;">${start_time_string}</span><br><span class="text-muted small">${__( |
| 135 | "to" |
| 136 | )} ${end_time_string}</span>`; |
pranav nachnekar | 2791054 | 2019-09-03 12:04:52 +0530 | [diff] [blame] | 137 | } |
| 138 | |
| 139 | function select_time() { |
Ankush Menat | ec74a5e | 2024-03-10 19:45:40 +0530 | [diff] [blame] | 140 | if (this.classList.contains("unavailable")) { |
| 141 | return; |
| 142 | } |
| 143 | let selected_element = document.getElementsByClassName("selected"); |
| 144 | if (!(selected_element.length > 0)) { |
| 145 | this.classList.add("selected"); |
| 146 | show_next_button(); |
| 147 | return; |
| 148 | } |
| 149 | selected_element = selected_element[0]; |
| 150 | window.selected_time = this.id; |
| 151 | selected_element.classList.remove("selected"); |
| 152 | this.classList.add("selected"); |
| 153 | show_next_button(); |
pranav nachnekar | 2791054 | 2019-09-03 12:04:52 +0530 | [diff] [blame] | 154 | } |
| 155 | |
| 156 | function set_default_timeslot() { |
Ankush Menat | ec74a5e | 2024-03-10 19:45:40 +0530 | [diff] [blame] | 157 | let timeslots = document.getElementsByClassName("time-slot"); |
| 158 | // Can't use a forEach here since, we need to break the loop after a timeslot is selected |
| 159 | for (let i = 0; i < timeslots.length; i++) { |
| 160 | const timeslot = timeslots[i]; |
| 161 | if (!timeslot.classList.contains("unavailable")) { |
| 162 | timeslot.classList.add("selected"); |
| 163 | break; |
| 164 | } |
| 165 | } |
pranav nachnekar | 2791054 | 2019-09-03 12:04:52 +0530 | [diff] [blame] | 166 | } |
| 167 | |
Pranav Nachanekar | 91a5649 | 2019-09-17 16:58:41 +0530 | [diff] [blame] | 168 | function navigate_to_page(page_number) { |
Ankush Menat | ec74a5e | 2024-03-10 19:45:40 +0530 | [diff] [blame] | 169 | let page1 = document.getElementById("select-date-time"); |
| 170 | let page2 = document.getElementById("enter-details"); |
| 171 | switch (page_number) { |
| 172 | case 1: |
| 173 | page1.style.display = "block"; |
| 174 | page2.style.display = "none"; |
| 175 | break; |
| 176 | case 2: |
| 177 | page1.style.display = "none"; |
| 178 | page2.style.display = "block"; |
| 179 | break; |
| 180 | default: |
| 181 | break; |
| 182 | } |
Pranav Nachanekar | a2dbd39 | 2019-09-12 10:48:26 +0530 | [diff] [blame] | 183 | } |
| 184 | |
Pranav Nachanekar | 91a5649 | 2019-09-17 16:58:41 +0530 | [diff] [blame] | 185 | function setup_details_page() { |
Ankush Menat | ec74a5e | 2024-03-10 19:45:40 +0530 | [diff] [blame] | 186 | navigate_to_page(2); |
| 187 | let date_container = document.getElementsByClassName("date-span")[0]; |
| 188 | let time_container = document.getElementsByClassName("time-span")[0]; |
| 189 | setup_search_params(); |
| 190 | date_container.innerHTML = moment(window.selected_date).format("MMM Do YYYY"); |
| 191 | time_container.innerHTML = moment(window.selected_time, "HH:mm:ss").format("LT"); |
pranav nachnekar | 2791054 | 2019-09-03 12:04:52 +0530 | [diff] [blame] | 192 | } |
| 193 | |
Pranav Nachnekar | c131270 | 2020-01-28 12:20:47 +0000 | [diff] [blame] | 194 | function setup_search_params() { |
Ankush Menat | ec74a5e | 2024-03-10 19:45:40 +0530 | [diff] [blame] | 195 | let search_params = new URLSearchParams(window.location.search); |
| 196 | let customer_name = search_params.get("name"); |
| 197 | let customer_email = search_params.get("email"); |
| 198 | let detail = search_params.get("details"); |
| 199 | if (customer_name) { |
| 200 | let name_input = document.getElementById("customer_name"); |
| 201 | name_input.value = customer_name; |
| 202 | name_input.disabled = true; |
| 203 | } |
| 204 | if (customer_email) { |
| 205 | let email_input = document.getElementById("customer_email"); |
| 206 | email_input.value = customer_email; |
| 207 | email_input.disabled = true; |
| 208 | } |
| 209 | if (detail) { |
| 210 | let detail_input = document.getElementById("customer_notes"); |
| 211 | detail_input.value = detail; |
| 212 | detail_input.disabled = true; |
| 213 | } |
Pranav Nachnekar | c131270 | 2020-01-28 12:20:47 +0000 | [diff] [blame] | 214 | } |
pranav nachnekar | c5b2a58 | 2019-09-03 14:16:47 +0530 | [diff] [blame] | 215 | async function submit() { |
Ankush Menat | ec74a5e | 2024-03-10 19:45:40 +0530 | [diff] [blame] | 216 | let button = document.getElementById("submit-button"); |
| 217 | button.disabled = true; |
| 218 | let form = document.querySelector("#customer-form"); |
| 219 | if (!form.checkValidity()) { |
| 220 | form.reportValidity(); |
| 221 | button.disabled = false; |
| 222 | return; |
| 223 | } |
| 224 | let contact = get_form_data(); |
| 225 | let appointment = frappe.call({ |
| 226 | method: "erpnext.www.book_appointment.index.create_appointment", |
| 227 | args: { |
| 228 | date: window.selected_date, |
| 229 | time: window.selected_time, |
| 230 | contact: contact, |
| 231 | tz: window.selected_timezone, |
| 232 | }, |
| 233 | callback: (response) => { |
| 234 | if (response.message.status == "Unverified") { |
| 235 | frappe.show_alert(__("Please check your email to confirm the appointment")); |
| 236 | } else { |
| 237 | frappe.show_alert(__("Appointment Created Successfully")); |
| 238 | } |
| 239 | setTimeout(() => { |
| 240 | let redirect_url = "/"; |
| 241 | if (window.appointment_settings.success_redirect_url) { |
| 242 | redirect_url += window.appointment_settings.success_redirect_url; |
| 243 | } |
| 244 | window.location.href = redirect_url; |
| 245 | }, 5000); |
| 246 | }, |
| 247 | error: (err) => { |
| 248 | frappe.show_alert(__("Something went wrong please try again")); |
| 249 | button.disabled = false; |
| 250 | }, |
| 251 | }); |
Pranav Nachanekar | 91a5649 | 2019-09-17 16:58:41 +0530 | [diff] [blame] | 252 | } |
Pranav Nachanekar | 10711dd | 2019-09-09 15:41:20 +0530 | [diff] [blame] | 253 | |
Pranav Nachanekar | 91a5649 | 2019-09-17 16:58:41 +0530 | [diff] [blame] | 254 | function get_form_data() { |
Ankush Menat | ec74a5e | 2024-03-10 19:45:40 +0530 | [diff] [blame] | 255 | let contact = {}; |
| 256 | let inputs = ["name", "skype", "number", "notes", "email"]; |
| 257 | inputs.forEach((id) => (contact[id] = document.getElementById(`customer_${id}`).value)); |
| 258 | return contact; |
Pranav Nachanekar | 10711dd | 2019-09-09 15:41:20 +0530 | [diff] [blame] | 259 | } |