PluginProbe ʕ •ᴥ•ʔ
LatePoint – Calendar Booking Plugin for Appointments and Events / 5.1.3
LatePoint – Calendar Booking Plugin for Appointments and Events v5.1.3
5.6.6 5.6.5 5.6.4 5.6.3 5.6.2 5.6.1 5.6.0 5.5.2 5.5.1 5.5.0 5.4.2 trunk 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.1.8 5.1.9 5.1.91 5.1.92 5.1.93 5.1.94 5.2.0 5.2.1 5.2.10 5.2.11 5.2.2 5.2.3 5.2.4 5.2.5 5.2.6 5.2.7 5.2.8 5.2.9 5.3.0 5.3.1 5.3.2 5.4.0 5.4.1
latepoint / lib / assets / javascripts / bin / front / main.js
latepoint / lib / assets / javascripts / bin / front Last commit date
_customer.js 1 year ago _events.js 1 year ago _stripe_connect.js 1 year ago main.js 1 year ago
main.js
1839 lines
1 /*
2 * Copyright (c) 2022 LatePoint LLC. All rights reserved.
3 */
4
5
6 function latepoint_init_order_summary_lightbox() {
7
8 }
9
10 function latepoint_init_bundle_scheduling_summary() {
11
12 }
13
14
15 function latepoint_manage_by_key_reload_booking() {
16 let $wrapper = jQuery('.manage-booking-wrapper');
17 $wrapper.addClass('os-loading')
18 let params = {
19 key: $wrapper.data('key')
20 }
21 let data = {
22 action: latepoint_helper.route_action,
23 route_name: $wrapper.data('route-name'),
24 params: params,
25 layout: 'none',
26 return_format: 'json'
27 };
28
29 jQuery.ajax({
30 type: "post",
31 dataType: "json",
32 url: latepoint_timestamped_ajaxurl(),
33 data: data,
34 success: function (data) {
35 $wrapper.removeClass('os-loading')
36 if (data.status === "success") {
37 $wrapper.replaceWith(data.message);
38 } else {
39 latepoint_show_message_inside_element(data.message, $wrapper, 'error');
40 }
41 }
42 });
43 }
44
45 function latepoint_init_manage_booking_by_key() {
46 let $wrapper = jQuery('.manage-booking-wrapper');
47 if (!$wrapper.length) return;
48 jQuery('.latepoint-w').on('change', '.change-booking-status-trigger', function () {
49 $wrapper.addClass('os-loading')
50 let params = {
51 key: $wrapper.data('key'),
52 status: jQuery(this).val()
53 }
54 let data = {
55 action: latepoint_helper.route_action,
56 route_name: jQuery(this).closest('.change-booking-status-trigger-wrapper').data('route-name'),
57 params: params,
58 layout: 'none',
59 return_format: 'json'
60 };
61
62 jQuery.ajax({
63 type: "post",
64 dataType: "json",
65 url: latepoint_timestamped_ajaxurl(),
66 data: data,
67 success: function (data) {
68 $wrapper.removeClass('os-loading')
69 if (data.status === "success") {
70 latepoint_manage_by_key_reload_booking();
71 } else {
72 latepoint_show_message_inside_element(data.message, $wrapper, 'error');
73 }
74 }
75 });
76 return false;
77 });
78
79
80 $wrapper.on('click', '.qr-show-trigger', function () {
81 jQuery(this).closest('.manage-booking-wrapper').find('.qr-code-on-full-summary').addClass('show-vevent-qr-code');
82 return false;
83 });
84 $wrapper.on('click', '.os-item-details-popup-close', function () {
85 var $wrapper = jQuery(this).closest('.manage-booking-wrapper');
86 $wrapper.find('.os-item-details-popup.open').remove();
87 $wrapper.find('.manage-booking-inner, .manage-booking-controls').show();
88 return false;
89 });
90
91 $wrapper.on('click', '.os-trigger-item-details-popup', function () {
92 var $wrapper = jQuery(this).closest('.manage-booking-wrapper');
93 $wrapper.find('.manage-booking-inner, .manage-booking-controls').hide();
94 $wrapper.find('.os-item-details-popup.open').remove();
95 var $popup = $wrapper.find('#' + jQuery(this).data('item-details-popup-id')).clone();
96 $popup.addClass('open').appendTo($wrapper);
97 return false;
98 });
99 }
100
101 function latepoint_init_form_masks() {
102 if (('intlTelInput' in window) && ('intlTelInputGlobals' in window)) {
103 jQuery('.os-mask-phone').each(function () {
104 latepoint_mask_phone(jQuery(this));
105 });
106 }
107 }
108
109 function latepoint_scroll_to_top_of_booking_form($booking_form_element) {
110 // if it's a form shortcode (not lightbox), scroll to top of the form
111 if ($booking_form_element.parent().hasClass('latepoint-inline-form')) {
112 $booking_form_element[0].scrollIntoView({block: "nearest", behavior: 'smooth'}); // SHOULD NOT BE FIRST!! Also need to FIX, scroll only if TOP of the booking form is above the viewport
113 }
114 // if lightbox - scroll body of lightbox to top
115 if ($booking_form_element.parent().hasClass('latepoint-lightbox-i')) {
116 $booking_form_element.find('.latepoint-body').scrollTop(0);
117 }
118 }
119
120 async function latepoint_init_payment_method_actions($booking_form_element, payment_method) {
121 let callbacks_list = [];
122 let is_last_step = $booking_form_element.data('next-submit-is-last') == 'yes';
123 $booking_form_element.trigger('latepoint:initPaymentMethod', [{
124 payment_method: payment_method,
125 callbacks_list: callbacks_list,
126 is_last_step: is_last_step
127 }]);
128 $booking_form_element.removeClass('step-content-loaded').addClass('step-content-loading');
129
130
131 try {
132 for (const callback of callbacks_list) {
133 await callback.action();
134 }
135 $booking_form_element.removeClass('step-content-loading').addClass('step-content-loaded').find('.lp-payment-method-content[data-payment-method="' + payment_method + '"]').show();
136 } catch (error) {
137 latepoint_show_error_and_stop_loading_booking_form(error, $booking_form_element);
138 }
139 }
140
141 function latepoint_lightbox_close() {
142 jQuery('body').removeClass('latepoint-lightbox-active');
143 jQuery('.latepoint-lightbox-w').remove();
144 }
145
146 function latepoint_show_next_btn($booking_form_element) {
147 $booking_form_element.find('.latepoint-next-btn').removeClass('disabled');
148 $booking_form_element.removeClass('hidden-buttons');
149 }
150
151 function clear_step_services($booking_form_element) {
152 }
153
154 function clear_step_service_extras($booking_form_element) {
155 }
156
157 function clear_step_locations($booking_form_element) {
158 }
159
160 function clear_step_agents($booking_form_element) {
161 }
162
163 function clear_step_datepicker($booking_form_element) {
164 }
165
166 function latepoint_hide_next_btn($booking_form_element) {
167 $booking_form_element.find('.latepoint-next-btn').addClass('disabled');
168 if ($booking_form_element.find('.latepoint-prev-btn.disabled').length) $booking_form_element.addClass('hidden-buttons');
169 }
170
171
172 function latepoint_show_prev_btn($booking_form_element) {
173 $booking_form_element.find('.latepoint-prev-btn').removeClass('disabled');
174 $booking_form_element.removeClass('hidden-buttons');
175 }
176
177 function latepoint_hide_prev_btn($booking_form_element) {
178 $booking_form_element.find('.latepoint-prev-btn').addClass('disabled');
179 if ($booking_form_element.find('.latepoint-next-btn.disabled').length) $booking_form_element.addClass('hidden-buttons');
180 }
181
182
183 function latepoint_remove_cart_item($trigger) {
184 let $booking_form_element = $trigger.closest('.latepoint-booking-form-element');
185 let cart_item_id = $trigger.data('cart-item-id');
186
187
188 $trigger.addClass('os-loading');
189 let data = {
190 action: latepoint_helper.route_action,
191 route_name: $trigger.data('route'),
192 params: jQuery.param({cart_item_id: cart_item_id}),
193 layout: 'none',
194 return_format: 'json'
195 }
196 jQuery.ajax({
197 type: "post",
198 dataType: "json",
199 url: latepoint_timestamped_ajaxurl(),
200 data: data,
201 success: function (data) {
202 if (data.status === "success") {
203 if(cart_item_id != $booking_form_element.find('input[name="active_cart_item[id]"]').val()){
204 // cart has other items - just reload the summary/step
205 if ($trigger.closest('.latepoint-summary-w').length) {
206 // removed by clicking on summary side panel
207 latepoint_reload_summary($booking_form_element);
208 } else {
209 // remove by clicking on cart item on verify step
210 latepoint_reload_step($booking_form_element);
211 }
212 }else{
213 // this was a last item, need to go back to the start of a booking process
214 latepoint_restart_booking_process($booking_form_element);
215 }
216 } else {
217 $trigger.removeClass('os-loading');
218 latepoint_show_message_inside_element(data.message, $booking_form_element.find('.latepoint-body'), 'error');
219 }
220 }
221 });
222 }
223
224 function latepoint_apply_coupon($elem) {
225 var $booking_form_element = $elem.closest('.latepoint-booking-form-element');
226
227 var $coupon_input = $elem;
228 $coupon_input.closest('.coupon-code-input-w').addClass('os-loading');
229 var form_data = new FormData($booking_form_element.find('.latepoint-form')[0]);
230 var data = {
231 action: latepoint_helper.route_action,
232 route_name: $elem.data('route'),
233 params: latepoint_formdata_to_url_encoded_string(form_data),
234 layout: 'none',
235 return_format: 'json'
236 }
237 jQuery.ajax({
238 type: "post",
239 dataType: "json",
240 url: latepoint_timestamped_ajaxurl(),
241 data: data,
242 success: function (data) {
243 $coupon_input.closest('.coupon-code-input-w').removeClass('os-loading');
244 if (data.status === "success") {
245 latepoint_show_message_inside_element(data.message, $booking_form_element.find('.latepoint-body'), 'success');
246 $booking_form_element.find('.step-payment-w input[name="cart[payment_method]"]').val('');
247 $booking_form_element.find('input[name="cart[payment_token]"]').val('');
248 $booking_form_element.find('input[name="cart[payment_portion]"]').val('');
249 latepoint_reload_step($booking_form_element);
250 } else {
251 latepoint_show_message_inside_element(data.message, $booking_form_element.find('.latepoint-body'), 'error');
252 }
253 }
254 });
255 }
256
257 function latepoint_remove_coupon($elem) {
258 $elem.closest('.applied-coupon-code-wrapper').fadeOut();
259 var $booking_form_element = $elem.closest('.latepoint-booking-form-element');
260 let $coupon_input = $booking_form_element.find('input[name="coupon_code"]');
261 $coupon_input.val('');
262 latepoint_apply_coupon($coupon_input);
263 }
264
265 function latepoint_restart_booking_process($booking_form_element) {
266 // first first step
267 let first_step_code = $booking_form_element.find('.latepoint-step-content').first().data('step-code');
268 latepoint_reload_step($booking_form_element, first_step_code);
269 return false;
270 }
271
272 function latepoint_reload_step($booking_form_element, step_code = false) {
273
274 if (step_code) {
275 $booking_form_element.find('.latepoint_current_step_code').val(step_code);
276 $booking_form_element.removeClass(function (index, className) {
277 return (className.match(/(^|\s)current-step-\S+/g) || []).join(' ');
278 }).addClass('current-step-' + step_code);
279 if ($booking_form_element.find('.latepoint-step-content[data-step-code="' + step_code + '"]')) {
280 $booking_form_element.find('.latepoint-step-content[data-step-code="' + step_code + '"]').nextAll('.latepoint-step-content').remove();
281 $booking_form_element.find('.latepoint-step-content[data-step-code="' + step_code + '"]').remove();
282 }
283 }
284
285 $booking_form_element.find('.latepoint_step_direction').val('specific');
286 latepoint_submit_booking_form($booking_form_element.find('.latepoint-form'));
287
288 return false;
289 }
290
291
292 function latepoint_reset_password_from_booking_init() {
293 jQuery('.os-step-existing-customer-login-w').hide();
294 jQuery('.os-password-reset-form-holder').on('click', '.password-reset-back-to-login', function () {
295 jQuery('.os-password-reset-form-holder').html('');
296 jQuery('.os-step-existing-customer-login-w').show();
297 return false;
298 });
299 }
300
301 function latepoint_bundle_selected($item) {
302 let $booking_form_element = $item.closest('.latepoint-booking-form-element');
303 $booking_form_element.find('input[name="active_cart_item[variant]"]').val('bundle');
304 $booking_form_element.find('input[name="booking[service_id]"]').val('');
305 }
306
307 function latepoint_service_selected($item) {
308 let $booking_form_element = $item.closest('.latepoint-booking-form-element');
309 $booking_form_element.find('input[name="active_cart_item[variant]"]').val('booking');
310 }
311
312 async function latepoint_reload_summary($booking_form_element) {
313 let $summary_panel = $booking_form_element.closest('.latepoint-with-summary');
314 if (!$summary_panel.length) return;
315
316 let current_step = $booking_form_element.find('.latepoint_current_step_code').val();
317
318 $booking_form_element.find('.latepoint-summary-w').addClass('os-loading');
319 let $booking_form = $booking_form_element.find('.latepoint-form');
320 let form_data = new FormData($booking_form[0]);
321 let data = {
322 action: latepoint_helper.route_action,
323 route_name: latepoint_helper.reload_booking_form_summary_route,
324 params: latepoint_formdata_to_url_encoded_string(form_data),
325 layout: 'none',
326 return_format: 'json'
327 }
328
329 let response = await jQuery.ajax({
330 type: "post",
331 dataType: "json",
332 url: latepoint_timestamped_ajaxurl(),
333 data: data
334 });
335 if(response.status === 'success'){
336 $booking_form_element.find('.os-summary-contents').html(response.message);
337 $booking_form_element.find('.latepoint-summary-w').removeClass('os-loading');
338 // hide on verify and confirmation steps
339 if (current_step && !['verify', 'confirmation'].includes(current_step) && response.message) {
340 $summary_panel.addClass('latepoint-summary-is-open');
341 } else {
342 $summary_panel.removeClass('latepoint-summary-is-open');
343 }
344 latepoint_init_booking_summary_panel($booking_form_element);
345 }else{
346 throw new Error(response.message ? response.message : 'Error reloading summary');
347 }
348 }
349
350 function latepoint_init_booking_summary_panel($booking_form_element) {
351 let $summary_panel = $booking_form_element.find('.latepoint-summary-w');
352 if (!$summary_panel.length) return;
353
354 $summary_panel.find('.price-breakdown-unfold').on('click', function () {
355 jQuery(this).closest('.summary-price-breakdown-wrapper').removeClass('compact-summary');
356 return false;
357 });
358
359 $summary_panel.find('.os-remove-item-from-cart').on('click keydown', function (event) {
360 if(event.type === 'keydown' && event.key !== ' ' && event.key !== 'Enter') return;
361 latepoint_remove_cart_item(jQuery(this));
362 return false;
363 });
364
365 $summary_panel.find('.latepoint-lightbox-summary-trigger').on('click', function () {
366 var $wrapper = jQuery(this).closest('.latepoint-w');
367 $wrapper.toggleClass('show-summary-on-mobile');
368 return false;
369 });
370 }
371
372 function latepoint_password_changed_show_login(response) {
373 jQuery('.os-step-existing-customer-login-w').show();
374 jQuery('.os-password-reset-form-holder').html('');
375 latepoint_show_message_inside_element(response.message, jQuery('.os-step-existing-customer-login-w'), 'success');
376 }
377
378 function latepoint_hide_message_inside_element($elem = jQuery('.latepoint-body')) {
379 if ($elem.length && $elem.find('.latepoint-message').length) {
380 $elem.find('.latepoint-message').remove();
381 }
382 }
383
384 function latepoint_show_message_inside_element(message, $elem = jQuery('.latepoint-body'), message_type = 'error') {
385 message = message || 'Error. Please try again.';
386 if ($elem.length) {
387 if ($elem.find('.latepoint-message').length) {
388 $elem.find('.latepoint-message').removeClass('latepoint-message-success').removeClass('latepoint-message-error').addClass('latepoint-message-' + message_type + '').html(message).show();
389 } else {
390 $elem.prepend('<div class="latepoint-message latepoint-message-' + message_type + '">' + message + '</div>');
391 }
392 // scroll errors into view
393 if (message_type == 'error') $elem.find('.latepoint-message')[0].scrollIntoView();
394 }
395 }
396
397 function latepoint_add_action(callbacks_list, action, priority = 10) {
398 callbacks_list.push({priority: priority, action: action});
399 callbacks_list.sort((a, b) => a.priority - b.priority);
400 return callbacks_list;
401 }
402
403 function latepoint_update_next_btn_label($booking_form_element) {
404 let btn_label = $booking_form_element.find('.latepoint-step-content').last().data('next-btn-label')
405 if (btn_label) {
406 $booking_form_element.find('.latepoint-next-btn span').text(btn_label);
407 }
408 }
409
410 function latepoint_init_step(step_code, $booking_form_element) {
411 latepoint_init_step_selectable_items($booking_form_element);
412 latepoint_init_step_category_items(step_code);
413 switch (step_code) {
414 case 'customer':
415 latepoint_init_step_contact();
416 break;
417 case 'booking__datepicker':
418 latepoint_init_step_datepicker($booking_form_element);
419 break;
420 case 'booking__agents':
421 latepoint_init_step_agents();
422 break;
423 case 'booking__locations':
424 latepoint_init_step_locations();
425 break;
426 case 'booking__services':
427 latepoint_init_step_services();
428 break;
429 case 'payment__methods':
430 latepoint_init_step_payment__methods($booking_form_element);
431 break;
432 case 'payment__times':
433 latepoint_init_step_payment__times($booking_form_element);
434 break;
435 case 'payment__portions':
436 latepoint_init_step_payment__portions($booking_form_element);
437 break;
438 case 'payment__pay':
439 latepoint_init_step_payment__pay($booking_form_element);
440 break;
441 case 'verify':
442 latepoint_init_step_verify($booking_form_element);
443 break;
444 case 'confirmation':
445 latepoint_init_step_confirmation($booking_form_element);
446 break;
447 }
448
449 $booking_form_element.trigger("latepoint:initStep", [{step_code: step_code}]);
450 $booking_form_element.trigger("latepoint:initStep:" + step_code);
451 }
452
453
454 function day_timeslots($day, $wrapper_element = false, $scrollable_wrapper = false) {
455 if (!$wrapper_element) $wrapper_element = $day.closest('.latepoint-booking-form-element');
456 $day.addClass('selected');
457
458 var service_duration = $day.data('service-duration');
459 var interval = $day.data('interval');
460 var work_start_minutes = $day.data('work-start-time');
461 var work_end_minutes = $day.data('work-end-time');
462 var total_work_minutes = $day.data('total-work-minutes');
463 var bookable_minutes = [];
464 var available_capacities_of_bookable_minute = [];
465 if ($day.attr('data-bookable-minutes')) {
466 if ($day.data('bookable-minutes').toString().indexOf(':') > -1) {
467 // has capacity information embedded into bookable minutes string
468 let bookable_minutes_with_capacity = $day.data('bookable-minutes').toString().split(',');
469 for (let i = 0; i < bookable_minutes_with_capacity.length; i++) {
470 bookable_minutes.push(parseInt(bookable_minutes_with_capacity[i].split(':')[0]));
471 available_capacities_of_bookable_minute.push(parseInt(bookable_minutes_with_capacity[i].split(':')[1]));
472 }
473 } else {
474 bookable_minutes = $day.data('bookable-minutes').toString().split(',').map(Number);
475 }
476 }
477 var work_minutes = $day.data('work-minutes').toString().split(',').map(Number);
478
479 var $timeslots = $wrapper_element.find('.timeslots');
480 $timeslots.html('');
481
482 if (total_work_minutes > 0 && bookable_minutes.length && work_minutes.length) {
483 var prev_minutes = false;
484 work_minutes.forEach(function (current_minutes) {
485 var ampm = latepoint_am_or_pm(current_minutes);
486
487 var timeslot_class = 'dp-timepicker-trigger';
488 var timeslot_available_capacity = 0;
489 if (latepoint_helper.time_pick_style == 'timeline') {
490 timeslot_class += ' dp-timeslot';
491 } else {
492 timeslot_class += ' dp-timebox';
493 }
494
495 if (prev_minutes !== false && ((current_minutes - prev_minutes) > service_duration)) {
496 // show interval that is off between two work periods
497 var off_label = latepoint_minutes_to_hours_and_minutes(prev_minutes + service_duration) + ' ' + latepoint_am_or_pm(prev_minutes + service_duration) + ' - ' + latepoint_minutes_to_hours_and_minutes(current_minutes) + ' ' + latepoint_am_or_pm(current_minutes);
498 var off_width = (((current_minutes - prev_minutes - service_duration) / total_work_minutes) * 100);
499 $timeslots.append('<div class="' + timeslot_class + ' is-off" style="max-width:' + off_width + '%; width:' + off_width + '%"><span class="dp-label">' + off_label + '</span></div>');
500 }
501
502 if (!bookable_minutes.includes(current_minutes)) {
503 timeslot_class += ' is-booked';
504 } else {
505 if (available_capacities_of_bookable_minute.length) timeslot_available_capacity = available_capacities_of_bookable_minute[bookable_minutes.indexOf(current_minutes)];
506 }
507 var tick_html = '';
508 var capacity_label = '';
509 var capacity_label_html = '';
510 var capacity_internal_label_html = '';
511
512 if (((current_minutes % 60) == 0) || (interval >= 60)) {
513 timeslot_class += ' with-tick';
514 tick_html = '<span class="dp-tick"><strong>' + latepoint_minutes_to_hours_preferably(current_minutes) + '</strong>' + ' ' + ampm + '</span>';
515 }
516 var timeslot_label = latepoint_minutes_to_hours_and_minutes(current_minutes) + ' ' + ampm;
517 if (latepoint_show_booking_end_time()) {
518 var end_minutes = current_minutes + service_duration;
519 if (end_minutes > 1440) end_minutes = end_minutes - 1440;
520 var end_minutes_ampm = latepoint_am_or_pm(end_minutes);
521 timeslot_label += ' - <span class="dp-label-end-time">' + latepoint_minutes_to_hours_and_minutes(end_minutes) + ' ' + end_minutes_ampm + '</span>';
522 }
523 if (timeslot_available_capacity) {
524 var spaces_message = timeslot_available_capacity > 1 ? latepoint_helper.many_spaces_message : latepoint_helper.single_space_message;
525 capacity_label = timeslot_available_capacity + ' ' + spaces_message;
526 capacity_label_html = '<span class="dp-capacity">' + capacity_label + '</span>';
527 capacity_internal_label_html = '<span class="dp-label-capacity">' + capacity_label + '</span>';
528 }
529 timeslot_label = timeslot_label.trim();
530 $timeslots.removeClass('slots-not-available').append('<div tabindex="0" class="' + timeslot_class + '" data-minutes="' + current_minutes + '"><span class="dp-label">' + capacity_internal_label_html + '<span class="dp-label-time">' + timeslot_label + '</span>' + '</span>' + tick_html + capacity_label_html + '</div>');
531 prev_minutes = current_minutes;
532 });
533 } else {
534 // No working hours this day
535 $timeslots.addClass('slots-not-available').append('<div class="not-working-message">' + latepoint_helper.msg_not_available + "</div>");
536 }
537 jQuery('.times-header-label span').text($day.data('nice-date'));
538 $wrapper_element.find('.time-selector-w').slideDown(200, function () {
539 if (!$scrollable_wrapper) $scrollable_wrapper = $wrapper_element.find('.latepoint-body');
540 $scrollable_wrapper.stop();
541 $wrapper_element.find('.time-selector-w')[0].scrollIntoView({block: "nearest", behavior: 'smooth'});
542 });
543 }
544
545
546 function latepoint_timeslot_clicked(event) {
547 if(event.type === 'keydown' && event.key !== ' ' && event.key !== 'Enter') return;
548 let $booking_form_element = jQuery(this).closest('.latepoint-booking-form-element');
549 if (jQuery(this).hasClass('is-booked') || jQuery(this).hasClass('is-off')) {
550 // Show error message that you cant select a booked period
551 } else {
552 if (jQuery(this).hasClass('selected')) {
553 jQuery(this).removeClass('selected');
554 jQuery(this).find('.dp-success-label').remove();
555 $booking_form_element.find('.latepoint_start_time').val('');
556 latepoint_hide_next_btn($booking_form_element);
557 latepoint_reload_summary($booking_form_element);
558 } else {
559 $booking_form_element.find('.dp-timepicker-trigger.selected').removeClass('selected').find('.dp-success-label').remove();
560 var selected_timeslot_time = jQuery(this).find('.dp-label-time').html();
561 jQuery(this).addClass('selected').find('.dp-label').prepend('<span class="dp-success-label">' + latepoint_helper.datepicker_timeslot_selected_label + '</span>');
562
563 var minutes = parseInt(jQuery(this).data('minutes'));
564 var timeshift_minutes = parseInt($booking_form_element.find('.latepoint_timeshift_minutes').val());
565 // we substract timeshift minutes because its timeshift minutes that the business is running in, in opposite of what we do when we generate a calendar for a client
566 if (timeshift_minutes) minutes = minutes - timeshift_minutes;
567 var start_date = new Date($booking_form_element.find('.os-day.selected').data('date'));
568 if (minutes < 0) {
569 // business minutes are in previous day
570 minutes = 24 * 60 + minutes;
571 // move start date back 1 day
572 start_date.setDate(start_date.getDate() - 1);
573 } else if (minutes >= 24 * 60) {
574 // business minutes are in next day
575 minutes = minutes - 24 * 60;
576 start_date.setDate(start_date.getDate() + 1);
577 }
578 $booking_form_element.find('.latepoint_start_date').val(start_date.toISOString().split('T')[0])
579 $booking_form_element.find('.latepoint_start_time').val(minutes);
580 latepoint_trigger_next_btn($booking_form_element);
581 }
582 }
583 return false;
584 }
585
586 function latepoint_init_timeslots($booking_form_element = false) {
587 if (!$booking_form_element) return;
588 $booking_form_element.off('click', '.dp-timepicker-trigger', latepoint_timeslot_clicked);
589 $booking_form_element.on('click', '.dp-timepicker-trigger', latepoint_timeslot_clicked);
590 $booking_form_element.off('keydown', '.dp-timepicker-trigger', latepoint_timeslot_clicked);
591 $booking_form_element.on('keydown', '.dp-timepicker-trigger', latepoint_timeslot_clicked);
592 }
593
594 async function latepoint_monthly_calendar_load_next_month($booking_form_element){
595 try {
596
597 if ($booking_form_element.find('.os-monthly-calendar-days-w.active + .os-monthly-calendar-days-w').length) {
598 $booking_form_element.find('.os-monthly-calendar-days-w.active').removeClass('active').next('.os-monthly-calendar-days-w').addClass('active');
599 latepoint_calendar_set_month_label($booking_form_element);
600 return true;
601 } else {
602 let $btn = $booking_form_element.find('.os-month-next-btn');
603 let next_month_route_name = $btn.data('route');
604 $btn.addClass('os-loading');
605 let $calendar_element = $booking_form_element.find('.os-monthly-calendar-days-w').last();
606 let calendar_year = $calendar_element.data('calendar-year');
607 let calendar_month = $calendar_element.data('calendar-month');
608 if (calendar_month == 12) {
609 calendar_year = calendar_year + 1;
610 calendar_month = 1;
611 } else {
612 calendar_month = calendar_month + 1;
613 }
614 let form_data = new FormData($booking_form_element.find('.latepoint-form')[0]);
615 form_data.set('target_date_string', `${calendar_year}-${calendar_month}-1`);
616 let params = latepoint_formdata_to_url_encoded_string(form_data);
617 let data = {
618 action: latepoint_helper.route_action,
619 route_name: next_month_route_name,
620 params: params,
621 layout: 'none',
622 return_format: 'json'
623 }
624 let response = await jQuery.ajax({
625 type: "post",
626 dataType: "json",
627 url: latepoint_timestamped_ajaxurl(),
628 data: data,
629 success: function (data) {
630 }
631 });
632 $btn.removeClass('os-loading');
633 if (response.status === "success") {
634 $booking_form_element.find('.os-months').append(response.message);
635 $booking_form_element.find('.os-monthly-calendar-days-w.active').removeClass('active').next('.os-monthly-calendar-days-w').addClass('active');
636 latepoint_calendar_set_month_label($booking_form_element);
637 latepoint_calendar_show_or_hide_prev_next_buttons($booking_form_element);
638 return true;
639 } else {
640 console.log(response.message);
641 return false;
642 }
643
644 }
645 } catch (e) {
646 console.log(e);
647 alert('Error:' + e);
648 return false;
649 }
650 }
651
652 function latepoint_init_monthly_calendar_navigation($booking_form_element = false) {
653 if (!$booking_form_element) return;
654 $booking_form_element.find('.os-month-next-btn').on('click', async function () {
655 let $booking_form_element = jQuery(this).closest('.latepoint-booking-form-element');
656 return latepoint_monthly_calendar_load_next_month($booking_form_element);
657 });
658 $booking_form_element.find('.os-month-prev-btn').on('click', function () {
659 var $booking_form_element = jQuery(this).closest('.latepoint-booking-form-element');
660 if ($booking_form_element.find('.os-monthly-calendar-days-w.active').prev('.os-monthly-calendar-days-w').length) {
661 $booking_form_element.find('.os-monthly-calendar-days-w.active').removeClass('active').prev('.os-monthly-calendar-days-w').addClass('active');
662 latepoint_calendar_set_month_label($booking_form_element);
663 }
664 latepoint_calendar_show_or_hide_prev_next_buttons($booking_form_element);
665 return false;
666 });
667 }
668
669 function latepoint_calendar_set_month_label($booking_form_element) {
670 $booking_form_element.find('.os-current-month-label .current-year').text($booking_form_element.find('.os-monthly-calendar-days-w.active').data('calendar-year'));
671 $booking_form_element.find('.os-current-month-label .current-month').text($booking_form_element.find('.os-monthly-calendar-days-w.active').data('calendar-month-label'));
672 }
673
674
675 function latepoint_calendar_show_or_hide_prev_next_buttons($booking_form_element) {
676 $booking_form_element.find('.os-current-month-label .current-year').text($booking_form_element.find('.os-monthly-calendar-days-w.active .os-monthly-calendar-days').data('calendar-year'));
677 $booking_form_element.find('.os-current-month-label .current-month').text($booking_form_element.find('.os-monthly-calendar-days-w.active .os-monthly-calendar-days').data('calendar-month-label'));
678
679 if ($booking_form_element.find('.os-monthly-calendar-days-w.active').prev('.os-monthly-calendar-days-w').length) {
680 $booking_form_element.find('.os-month-prev-btn').removeClass('disabled');
681 } else {
682 $booking_form_element.find('.os-month-prev-btn').addClass('disabled');
683 }
684 }
685
686 function latepoint_format_minutes_to_time(minutes, service_duration) {
687 var ampm = latepoint_am_or_pm(minutes);
688 var formatted_time = latepoint_minutes_to_hours_and_minutes(minutes) + ' ' + ampm;
689 if (latepoint_show_booking_end_time()) {
690 var end_minutes = minutes + service_duration;
691 var end_minutes_ampm = latepoint_am_or_pm(end_minutes);
692 formatted_time += ' - ' + latepoint_minutes_to_hours_and_minutes(end_minutes) + ' ' + end_minutes_ampm;
693 }
694 formatted_time = formatted_time.trim();
695 return formatted_time;
696 }
697
698 function latepoint_monthly_calendar_day_clicked(event) {
699 if(event.type === 'keydown' && event.key !== ' ' && event.key !== 'Enter') return;
700 if (jQuery(this).hasClass('os-day-passed')) return false;
701 if (jQuery(this).hasClass('os-not-in-allowed-period')) return false;
702 var $booking_form_element = jQuery(this).closest('.latepoint-booking-form-element');
703 if (jQuery(this).closest('.os-monthly-calendar-days-w').hasClass('hide-if-single-slot')) {
704 // HIDE TIMESLOT IF ONLY ONE TIMEPOINT
705 if (jQuery(this).hasClass('os-not-available')) {
706 // clicked on a day that has no available timeslots
707 // do nothing
708 } else {
709 $booking_form_element.find('.os-day.selected').removeClass('selected');
710 jQuery(this).addClass('selected');
711 // set date
712 $booking_form_element.find('.latepoint_start_date').val(jQuery(this).data('date'));
713 if (jQuery(this).hasClass('os-one-slot-only')) {
714 // clicked on a day that has only one slot available
715 var bookable_minutes = jQuery(this).data('bookable-minutes').toString().split(':')[0];
716 var selected_timeslot_time = latepoint_format_minutes_to_time(Number(bookable_minutes), Number(jQuery(this).data('service-duration')));
717 $booking_form_element.find('.latepoint_start_time').val(jQuery(this).data('bookable-minutes'));
718 latepoint_show_next_btn($booking_form_element);
719 $booking_form_element.find('.time-selector-w').slideUp(200);
720 } else {
721 // regular day with more than 1 timeslots available
722 // build timeslots
723 day_timeslots(jQuery(this));
724 // clear time and hide next btn
725 $booking_form_element.find('.latepoint_start_time').val('');
726 latepoint_hide_next_btn($booking_form_element);
727 }
728 latepoint_reload_summary($booking_form_element);
729 }
730 } else {
731
732 // SHOW TIMESLOTS EVEN IF ONLY ONE TIMEPOINT
733 $booking_form_element.find('.latepoint_start_date').val(jQuery(this).data('date'));
734 $booking_form_element.find('.os-day.selected').removeClass('selected');
735 jQuery(this).addClass('selected');
736
737 // build timeslots
738 day_timeslots(jQuery(this));
739 // clear time and hide next btn
740 latepoint_reload_summary($booking_form_element);
741 $booking_form_element.find('.latepoint_start_time').val('');
742 latepoint_hide_next_btn($booking_form_element);
743 }
744
745
746 return false;
747 }
748
749 async function latepoint_init_step_datepicker($booking_form_element = false) {
750 if (!$booking_form_element) return true;
751 latepoint_init_timeslots($booking_form_element);
752 latepoint_init_monthly_calendar_navigation($booking_form_element);
753 $booking_form_element.off('click', '.os-months .os-day', latepoint_monthly_calendar_day_clicked);
754 $booking_form_element.on('click', '.os-months .os-day', latepoint_monthly_calendar_day_clicked);
755 $booking_form_element.off('keydown', '.os-months .os-day', latepoint_monthly_calendar_day_clicked);
756 $booking_form_element.on('keydown', '.os-months .os-day', latepoint_monthly_calendar_day_clicked);
757 if ($booking_form_element.find('input[name="booking[start_date]"]').val()){
758 $booking_form_element.find('.os-day[data-date="' + $booking_form_element.find('input[name="booking[start_date]"]').val() + '"]').trigger('click');
759 }else{
760 let max_number_of_months_to_check = 24;
761 let current_year = new Date().getFullYear();
762 for (let i = 0; i < max_number_of_months_to_check; i++){
763 let $active_month = $booking_form_element.find('.os-monthly-calendar-days-w.active');
764 let searching_month_label = $active_month.data('calendar-month-label');
765 if($active_month.data('calendar-year') != current_year) searching_month_label+= ' '+$active_month.data('calendar-year');
766 $booking_form_element.find('.os-calendar-searching-info span').text(searching_month_label);
767 // check if active month has any days available for booking
768 let $first_available = $active_month.find('.os-day').not('.os-not-available').first();
769 if($first_available.length){
770 break;
771 }else{
772 await latepoint_monthly_calendar_load_next_month($booking_form_element);
773 }
774 }
775 $booking_form_element.find('.os-dates-w').removeClass('is-searching');
776 }
777 return true;
778 }
779
780
781 function latepoint_init_step_verify($booking_form_element = false) {
782 if (!$booking_form_element) return;
783 $booking_form_element.closest('.latepoint-summary-is-open').removeClass('latepoint-summary-is-open');
784
785 $booking_form_element.find('.coupon-code-wrapper-on-verify .coupon-code-trigger-on-verify-w a').on('click', function (e) {
786 jQuery(this).closest('.coupon-code-wrapper-on-verify').addClass('entering-coupon').find('.coupon-code-input').trigger('focus');
787 return false;
788 });
789 $booking_form_element.find('.coupon-code-wrapper-on-verify .coupon-code-input-cancel').on('click', function (e) {
790 jQuery(this).closest('.coupon-code-wrapper-on-verify').removeClass('entering-coupon');
791 return false;
792 });
793
794 $booking_form_element.find('.coupon-code-wrapper-on-verify .coupon-code-input-submit').on('click', function (e) {
795 latepoint_apply_coupon(jQuery(this).closest('.coupon-code-input-w').find('.coupon-code-input'));
796 return false;
797 });
798
799 $booking_form_element.find('.os-remove-item-from-cart').on('click keydown', function (event) {
800 if(event.type === 'keydown' && event.key !== ' ' && event.key !== 'Enter') return;
801 //make sure to clear active cart item so it doesn't add it again on reload!
802 if (confirm(jQuery(this).data('confirm-text'))) {
803 latepoint_remove_cart_item(jQuery(this));
804 }
805 return false;
806 });
807
808 $booking_form_element.find('.coupon-code-wrapper-on-verify .coupon-code-clear').on('click', function (e) {
809 latepoint_remove_coupon(jQuery(this));
810 return false;
811 });
812
813 $booking_form_element.find('.coupon-code-wrapper-on-verify input.coupon-code-input').on('keyup', function (e) {
814 if (e.which === 13) {
815 latepoint_apply_coupon(jQuery(this));
816 return false;
817 }
818 });
819 }
820
821
822 function latepoint_init_step_payment__pay($booking_form_element = false) {
823 var selected_payment_method = $booking_form_element.find('input[name="cart[payment_method]"]').val();
824 latepoint_init_payment_method_actions($booking_form_element, selected_payment_method);
825 }
826
827 function latepoint_init_step_payment__portions($booking_form_element = false) {
828 // Selecting Payment Time
829 $booking_form_element.find('.lp-payment-trigger-payment-portion-selector').on('click keydown', function (event) {
830 if(event.type === 'keydown' && event.key !== ' ' && event.key !== 'Enter') return;
831 var $booking_form_element = jQuery(this).closest('.latepoint-booking-form-element');
832 $booking_form_element.find('input[name="' + jQuery(this).data('holder') + '"]').val(jQuery(this).data('value'));
833 latepoint_show_prev_btn($booking_form_element);
834 latepoint_trigger_next_btn($booking_form_element);
835 return false;
836 });
837 }
838
839 function latepoint_init_step_payment__times($booking_form_element = false) {
840 // Selecting Payment Time
841 $booking_form_element.find('.lp-payment-trigger-payment-time-selector').on('click keydown', function (event) {
842 if(event.type === 'keydown' && event.key !== ' ' && event.key !== 'Enter') return;
843 var $booking_form_element = jQuery(this).closest('.latepoint-booking-form-element');
844 $booking_form_element.find('input[name="' + jQuery(this).data('holder') + '"]').val(jQuery(this).data('value'));
845 latepoint_show_prev_btn($booking_form_element);
846 latepoint_trigger_next_btn($booking_form_element);
847 return false;
848 });
849 }
850
851
852 function latepoint_init_step_payment__methods($booking_form_element = false) {
853 // Selecting Payment Time
854 $booking_form_element.find('.lp-payment-trigger-payment-method-selector').on('click', function (e) {
855 var $booking_form_element = jQuery(this).closest('.latepoint-booking-form-element');
856 $booking_form_element.find('input[name="' + jQuery(this).data('holder') + '"]').val(jQuery(this).data('value'));
857 latepoint_show_prev_btn($booking_form_element);
858 latepoint_trigger_next_btn($booking_form_element);
859 return false;
860 });
861 }
862
863 function latepoint_category_item_clicked(event){
864 if(event.type === 'keydown' && event.key !== ' ' && event.key !== 'Enter') return;
865 let $item = jQuery(event.target);
866
867 let $booking_form_element = $item.closest('.latepoint-booking-form-element');
868 latepoint_show_prev_btn($booking_form_element);
869 $item.closest('.latepoint-step-content').addClass('selecting-item-category');
870 let $category_wrapper = $item.closest('.os-item-category-w');
871 let $main_parent = $item.closest('.os-item-categories-main-parent');
872 if ($category_wrapper.hasClass('selected')) {
873 $category_wrapper.removeClass('selected');
874 if ($category_wrapper.parent().closest('.os-item-category-w').length) {
875 $category_wrapper.parent().closest('.os-item-category-w').addClass('selected');
876 } else {
877 $main_parent.removeClass('show-selected-only');
878 }
879 } else {
880 $main_parent.find('.os-item-category-w.selected').removeClass('selected');
881 $main_parent.addClass('show-selected-only');
882 $category_wrapper.addClass('selected');
883 }
884 return false;
885 }
886
887 function latepoint_init_step_category_items(step_code) {
888 let $category_items = jQuery('.latepoint-step-content[data-step-code="' + step_code + '"] .os-item-category-info');
889 $category_items.on('click', latepoint_category_item_clicked);
890 $category_items.on('keydown', latepoint_category_item_clicked);
891 }
892
893
894 function latepoint_init_step_selectable_items($booking_form_element) {
895 $booking_form_element.off('click', '.os-selectable-items .os-selectable-item', latepoint_selectable_item_clicked);
896 $booking_form_element.on('click', '.os-selectable-items .os-selectable-item', latepoint_selectable_item_clicked);
897
898 $booking_form_element.off('click', '.os-selectable-items .os-selectable-item .item-quantity-selector-input', latepoint_selectable_item_quantity_keyup);
899 $booking_form_element.on('click', '.os-selectable-items .os-selectable-item .item-quantity-selector-input', latepoint_selectable_item_quantity_keyup);
900
901
902 $booking_form_element.off('keydown', '.os-selectable-items .os-selectable-item', latepoint_selectable_item_clicked);
903 $booking_form_element.on('keydown', '.os-selectable-items .os-selectable-item', latepoint_selectable_item_clicked);
904 }
905
906
907 function latepoint_update_quantity_for_selectable_items($item) {
908 var ids = $item.closest('.os-selectable-items')
909 .find('.os-selectable-item.selected')
910 .map(function () {
911 if (jQuery(this).hasClass('has-quantity')) {
912 return jQuery(this).data('item-id') + ':' + jQuery(this).find('input.item-quantity-selector-input').val();
913 } else {
914 return jQuery(this).data('item-id');
915 }
916 }).get();
917 $item.closest('.latepoint-booking-form-element').find($item.data('id-holder')).val(ids);
918 }
919
920 function latepoint_selectable_item_quantity_keyup(event) {
921 var $booking_form_element = jQuery(this).closest('.latepoint-booking-form-element');
922 var $item = jQuery(this).closest('.os-selectable-item');
923 var new_value = jQuery(this).val();
924 if (new_value && new_value.match(/^\d+$/)) {
925 var max_quantity = $item.data('max-quantity');
926 if (max_quantity && (new_value > max_quantity)) new_value = max_quantity;
927 } else {
928 new_value = 0;
929 }
930 jQuery(this).val(new_value);
931
932 if (($item.hasClass('selected') && (new_value > 0)) || (!$item.hasClass('selected') && (new_value == 0))) {
933 latepoint_update_quantity_for_selectable_items($item);
934 latepoint_reload_summary($booking_form_element);
935 return false;
936 } else {
937 $item.trigger('click');
938 }
939 }
940
941 function latepoint_selectable_item_clicked(event) {
942 if(event.type === 'keydown' && event.key !== ' ' && event.key !== 'Enter') return;
943 event.stopPropagation();
944 event.stopImmediatePropagation();
945 var $booking_form_element = jQuery(this).closest('.latepoint-booking-form-element');
946 if (jQuery(this).hasClass('has-quantity')) {
947 if (jQuery(event.target).hasClass('item-quantity-selector')) {
948 var current_value = parseInt(jQuery(this).find('input.item-quantity-selector-input').val());
949 var new_value = (jQuery(event.target).data('sign') == 'minus') ? current_value - 1 : current_value + 1;
950 var max_quantity = jQuery(this).data('max-quantity');
951 if (new_value < 0) new_value = 0;
952 if (max_quantity && (new_value > max_quantity)) new_value = max_quantity;
953 jQuery(this).find('input.item-quantity-selector-input').val(new_value);
954 if ((jQuery(this).hasClass('selected') && (new_value > 0)) || (!jQuery(this).hasClass('selected') && (new_value == 0))) {
955 latepoint_update_quantity_for_selectable_items(jQuery(this));
956 latepoint_reload_summary($booking_form_element);
957 return false;
958 }
959 }
960 if (jQuery(event.target).hasClass('item-quantity-selector-input')) {
961 latepoint_update_quantity_for_selectable_items(jQuery(this));
962 latepoint_reload_summary($booking_form_element);
963 return false;
964 }
965 }
966 var summary_value = '';
967 if (jQuery(this).hasClass('os-allow-multiselect')) {
968 if (jQuery(this).hasClass('selected')) {
969 jQuery(this).removeClass('selected');
970 if (jQuery(this).hasClass('has-quantity')) jQuery(this).find('input.item-quantity-selector-input').val(0);
971 } else {
972 jQuery(this).addClass('selected');
973 if (jQuery(this).hasClass('has-quantity') && !(jQuery(this).find('input.item-quantity-selector-input').val() > 0)) {
974 jQuery(this).find('input.item-quantity-selector-input').val(1);
975 }
976 }
977 latepoint_update_quantity_for_selectable_items(jQuery(this));
978 summary_value = String(jQuery(this).closest('.os-selectable-items').find('.os-selectable-item.selected').map(function () {
979 return (' ' + jQuery(this).data('summary-value'));
980 }).get()).trim();
981 latepoint_show_next_btn($booking_form_element);
982 } else {
983 if (!jQuery(this).hasClass('os-duration-item')) jQuery(this).closest('.os-item-categories-main-parent').find('.os-selectable-item.selected').removeClass('selected');
984 jQuery(this).closest('.os-selectable-items').find('.os-selectable-item.selected').removeClass('selected');
985 jQuery(this).addClass('selected');
986 $booking_form_element.find(jQuery(this).data('id-holder')).val(jQuery(this).data('item-id'));
987 summary_value = jQuery(this).data('summary-value');
988 if (jQuery(this).data('cart-item-item-data-key')) {
989 latepoint_update_active_cart_item_item_data($booking_form_element, jQuery(this).data('cart-item-item-data-key'), jQuery(this).data('item-id'));
990 }
991 if (jQuery(this).data('os-call-func')) {
992 window[jQuery(this).data('os-call-func')](jQuery(this));
993 }
994 if (jQuery(this).data('activate-sub-step')) {
995 window[jQuery(this).data('activate-sub-step')](jQuery(this));
996 } else {
997 latepoint_trigger_next_btn($booking_form_element);
998 }
999 }
1000 return false;
1001 }
1002
1003 function latepoint_update_active_cart_item_item_data($booking_form_element, key, value) {
1004 let item_data_json = $booking_form_element.find('input[name="active_cart_item[item_data]"]').val();
1005 let item_data = item_data_json ? JSON.parse($booking_form_element.find('input[name="active_cart_item[item_data]"]').val()) : {};
1006 item_data[key] = value;
1007 $booking_form_element.find('input[name="active_cart_item[item_data]"]').val(JSON.stringify(item_data));
1008 }
1009
1010 function latepoint_format_price(price) {
1011 // replace default decimal separator dot with comma if it's in settings
1012 if (latepoint_helper.decimal_separator == ',') price = String(price).replace('.', ',');
1013 return latepoint_helper.currency_symbol_before + String(price) + latepoint_helper.currency_symbol_after;
1014 }
1015
1016
1017 function latepoint_init_step_services() {
1018 }
1019
1020
1021 function latepoint_trigger_next_btn($booking_form_element) {
1022 $booking_form_element.find('.latepoint_step_direction').val('next');
1023 latepoint_submit_booking_form($booking_form_element.find('.latepoint-form'));
1024 }
1025
1026 function latepoint_init_step_locations() {
1027 }
1028
1029 function latepoint_init_agent_details_link($booking_form_element) {
1030 $booking_form_element.on('click', '.os-trigger-item-details-popup', function () {
1031 $booking_form_element.find('.os-item-details-popup.open').remove();
1032 var $popup = $booking_form_element.find('#' + jQuery(this).data('item-details-popup-id')).first().clone().attr('id', '');
1033 $booking_form_element.find('.latepoint-form-w').addClass('showing-item-details-popup');
1034 $popup.addClass('open').appendTo($booking_form_element.find('.latepoint-body'));
1035 return false;
1036 });
1037 $booking_form_element.on('click', '.os-item-details-popup.open .os-item-details-popup-close', function () {
1038 $booking_form_element.find('.latepoint-form-w').removeClass('showing-item-details-popup');
1039 jQuery(this).closest('.os-item-details-popup.open').remove();
1040 return false;
1041 });
1042 }
1043
1044 function latepoint_init_step_agents() {
1045 }
1046
1047
1048 function latepoint_init_booking_summary_lightbox() {
1049 jQuery('.customer-dashboard-booking-summary-lightbox').on('click', '.qr-show-trigger', function () {
1050 jQuery(this).closest('.latepoint-lightbox-i').find('.qr-code-on-full-summary').addClass('show-vevent-qr-code');
1051 return false;
1052 });
1053 jQuery('.customer-dashboard-booking-summary-lightbox').on('click', '.os-item-details-popup-close', function () {
1054 var $ligthbox = jQuery(this).closest('.latepoint-lightbox-content');
1055 $ligthbox.find('.os-item-details-popup.open').remove();
1056 $ligthbox.find('.full-summary-wrapper').show();
1057 return false;
1058 });
1059
1060 jQuery('.customer-dashboard-booking-summary-lightbox').on('click', '.os-trigger-item-details-popup', function () {
1061 var $ligthbox = jQuery(this).closest('.latepoint-lightbox-content');
1062 $ligthbox.find('.full-summary-wrapper').hide();
1063 $ligthbox.find('.os-item-details-popup.open').remove();
1064 var $popup = $ligthbox.find('#' + jQuery(this).data('item-details-popup-id')).clone();
1065 $popup.addClass('open').appendTo($ligthbox);
1066 return false;
1067 });
1068 }
1069
1070 function latepoint_init_step_confirmation($booking_form_element = false) {
1071 if (!$booking_form_element) return;
1072 $booking_form_element.on('click', '.set-customer-password-btn', function () {
1073 var $btn = jQuery(this);
1074 var $booking_form_element = jQuery(this).closest('.latepoint-booking-form-element');
1075
1076 $btn.addClass('os-loading');
1077 var params = {
1078 account_nonse: jQuery('input[name="account_nonse"]').val(),
1079 password: jQuery('input[name="customer[password]"]').val(),
1080 password_confirmation: jQuery('input[name="customer[password_confirmation]"]').val()
1081 }
1082 var data = {
1083 action: latepoint_helper.route_action,
1084 route_name: jQuery(this).data('btn-action'),
1085 params: jQuery.param(params),
1086 layout: 'none',
1087 return_format: 'json'
1088 }
1089 jQuery.ajax({
1090 type: "post",
1091 dataType: "json",
1092 url: latepoint_timestamped_ajaxurl(),
1093 data: data,
1094 success: function (data) {
1095 $btn.removeClass('os-loading');
1096 if (data.status === "success") {
1097 $booking_form_element.find('.step-confirmation-set-password').html('').hide();
1098 $booking_form_element.find('.confirmation-cabinet-info').show();
1099 } else {
1100 latepoint_show_message_inside_element(data.message, $booking_form_element.find('.step-confirmation-set-password'), 'error');
1101 }
1102 }
1103 });
1104 return false;
1105 });
1106
1107 $booking_form_element.on('click', '.qr-show-trigger', function () {
1108 var $booking_form_element = jQuery(this).closest('.latepoint-booking-form-element');
1109 $booking_form_element.find('.qr-code-on-full-summary').addClass('show-vevent-qr-code');
1110 return false;
1111 });
1112
1113 $booking_form_element.on('click', '.show-set-password-fields', function () {
1114 var $booking_form_element = jQuery(this).closest('.latepoint-booking-form-element');
1115
1116 $booking_form_element.find('.step-confirmation-set-password').show();
1117 $booking_form_element.find('#customer_password').trigger('focus');
1118 jQuery(this).closest('.info-box').hide();
1119 return false;
1120 });
1121 }
1122
1123 function latepoint_init_customer_dashboard() {
1124 latepoint_init_form_masks();
1125 jQuery('.latepoint-customer-timezone-selector-w select').on('change', function (e) {
1126 var $select_box = jQuery(this);
1127 $select_box.closest('.latepoint-customer-timezone-selector-w').addClass('os-loading');
1128 var data = {
1129 action: latepoint_helper.route_action,
1130 route_name: jQuery(this).closest('.latepoint-customer-timezone-selector-w').data('route-name'),
1131 params: {timezone_name: jQuery(this).val()},
1132 layout: 'none',
1133 return_format: 'json'
1134 }
1135 jQuery.ajax({
1136 type: "post",
1137 dataType: "json",
1138 url: latepoint_timestamped_ajaxurl(),
1139 data: data,
1140 success: function (data) {
1141 $select_box.closest('.latepoint-customer-timezone-selector-w').removeClass('os-loading');
1142 if (data.status === "success") {
1143 location.reload();
1144 } else {
1145
1146 }
1147 }
1148 });
1149 });
1150
1151
1152 jQuery('.latepoint-request-booking-cancellation').on('click', function () {
1153 if (!confirm(latepoint_helper.cancel_booking_prompt)) return false;
1154 var $this = jQuery(this);
1155 var $booking_box = $this.closest('.customer-booking');
1156
1157 var route = jQuery(this).data('route');
1158 var params = {id: $booking_box.data('id')};
1159
1160 var data = {
1161 action: latepoint_helper.route_action,
1162 route_name: route,
1163 params: params,
1164 layout: 'none',
1165 return_format: 'json'
1166 }
1167 $this.addClass('os-loading');
1168 jQuery.ajax({
1169 type: "post",
1170 dataType: "json",
1171 url: latepoint_timestamped_ajaxurl(),
1172 data: data,
1173 success: function (data) {
1174 if (data.status === "success") {
1175 $this.remove();
1176 location.reload();
1177 } else {
1178 $this.removeClass('os-loading');
1179 }
1180 }
1181 });
1182 return false;
1183 });
1184
1185 }
1186
1187
1188 function get_customer_name($wrapper) {
1189 var customer_name = '';
1190 var first_name = $wrapper.find('input[name="customer[first_name]"]').val();
1191 var last_name = $wrapper.find('input[name="customer[last_name]"]').val();
1192 if (first_name) customer_name += first_name;
1193 if (last_name) customer_name += ' ' + last_name;
1194 return customer_name.trim();
1195 }
1196
1197 function latepoint_init_step_contact() {
1198 latepoint_init_form_masks();
1199
1200 // Init Logout button
1201 jQuery('.step-customer-logout-btn').on('click', function () {
1202 var $booking_form_element = jQuery(this).closest('.latepoint-booking-form-element');
1203 var data = {
1204 action: latepoint_helper.route_action,
1205 route_name: jQuery(this).data('btn-action'),
1206 layout: 'none',
1207 return_format: 'json'
1208 }
1209 latepoint_step_content_change_start($booking_form_element);
1210 jQuery.ajax({
1211 type: "post",
1212 dataType: "json",
1213 url: latepoint_timestamped_ajaxurl(),
1214 data: data,
1215 success: function (data) {
1216 latepoint_reload_step($booking_form_element);
1217 }
1218 });
1219 return false;
1220 });
1221
1222 // Init Login Existing Customer Button
1223 jQuery('.step-login-existing-customer-btn').on('click', function () {
1224 var $booking_form_element = jQuery(this).closest('.latepoint-booking-form-element');
1225 var params = {
1226 email: $booking_form_element.find('.os-step-existing-customer-login-w input[name="customer_login[email]"]').val(),
1227 password: $booking_form_element.find('.os-step-existing-customer-login-w input[name="customer_login[password]"]').val()
1228 }
1229 var data = {
1230 action: latepoint_helper.route_action,
1231 route_name: jQuery(this).data('btn-action'),
1232 params: jQuery.param(params),
1233 layout: 'none',
1234 return_format: 'json'
1235 }
1236 latepoint_step_content_change_start($booking_form_element);
1237 jQuery.ajax({
1238 type: "post",
1239 dataType: "json",
1240 url: latepoint_timestamped_ajaxurl(),
1241 data: data,
1242 success: function (data) {
1243 if (data.status === "success") {
1244 latepoint_reload_step($booking_form_element);
1245 } else {
1246 latepoint_show_message_inside_element(data.message, $booking_form_element.find('.os-step-existing-customer-login-w'));
1247 latepoint_step_content_change_end(false, $booking_form_element);
1248 }
1249 }
1250 });
1251 return false;
1252 });
1253 }
1254
1255 function latepoint_step_content_change_start($booking_form_element) {
1256 $booking_form_element.removeClass('step-content-loaded').addClass('step-content-loading');
1257 }
1258
1259 // TODO
1260 function latepoint_step_content_change_end(new_content, $booking_form_element) {
1261 if (new_content) $booking_form_element.find('.latepoint-body .latepoint-step-content').replaceWith(new_content);
1262 $booking_form_element.removeClass('step-content-loading').addClass('step-content-mid-loading');
1263 setTimeout(function () {
1264 $booking_form_element.removeClass('step-content-mid-loading').addClass('step-content-loaded');
1265 }, 50);
1266 }
1267
1268
1269 function latepoint_change_step_desc($booking_form_element, step_code) {
1270 $booking_form_element.removeClass('step-changed').addClass('step-changing');
1271 setTimeout(function () {
1272 // Progress bar
1273 var $step_progress = $booking_form_element.find('.latepoint-progress li[data-step-code="' + step_code + '"]');
1274 $step_progress.addClass('active').addClass('complete').prevAll().addClass('complete').removeClass('active');
1275 $step_progress.nextAll().removeClass('complete').removeClass('active');
1276 // Side panel
1277 var side_panel_desc = $booking_form_element.find('.latepoint-step-desc-library[data-step-code="' + step_code + '"]').html();
1278 $booking_form_element.find('.latepoint-step-desc').html(side_panel_desc);
1279
1280 // Top header
1281 var top_header_desc = $booking_form_element.find('.os-heading-text-library[data-step-code="' + step_code + '"]').html();
1282 $booking_form_element.find('.os-heading-text').html(top_header_desc);
1283 setTimeout(function () {
1284 $booking_form_element.removeClass('step-changing').addClass('step-changed');
1285 }, 50);
1286 }, 500);
1287 }
1288
1289
1290 function latepoint_progress_prev($booking_form_element, step_code) {
1291 var $step_progress = $booking_form_element.find('.latepoint-progress li[data-step-code="' + step_code + '"]');
1292 $step_progress.addClass('active').addClass('complete').prevAll().addClass('complete').removeClass('active');
1293 $step_progress.nextAll().removeClass('complete').removeClass('active');
1294 }
1295
1296
1297 function latepoint_progress_next($booking_form_element, step_code) {
1298 var $step_progress = $booking_form_element.find('.latepoint-progress li[data-step-code="' + step_code + '"]');
1299 $step_progress.addClass('active').addClass('complete').prevAll().addClass('complete').removeClass('active');
1300 $step_progress.nextAll().removeClass('complete').removeClass('active');
1301 }
1302
1303
1304 function latepoint_next_step_description($booking_form_element, step_code) {
1305 $booking_form_element.removeClass('step-changed').addClass('step-changing');
1306 setTimeout(function () {
1307 $booking_form_element.find('.latepoint-step-desc').html($booking_form_element.find('.latepoint-step-desc-library.active').removeClass('active').next('.latepoint-step-desc-library').addClass('active').html());
1308 $booking_form_element.find('.os-heading-text').html($booking_form_element.find('.os-heading-text-library.active').removeClass('active').next('.os-heading-text-library').addClass('active').html());
1309 setTimeout(function () {
1310 $booking_form_element.removeClass('step-changing').addClass('step-changed');
1311 }, 50);
1312 }, 500);
1313 }
1314
1315 function latepoint_prev_step_description($booking_form_element, step_code) {
1316 $booking_form_element.removeClass('step-changed').addClass('step-changing');
1317 setTimeout(function () {
1318 $booking_form_element.find('.latepoint-step-desc').html($booking_form_element.find('.latepoint-step-desc-library.active').removeClass('active').prev('.latepoint-step-desc-library').addClass('active').html());
1319 $booking_form_element.find('.os-heading-text').html($booking_form_element.find('.os-heading-text-library.active').removeClass('active').prev('.os-heading-text-library').addClass('active').html());
1320 setTimeout(function () {
1321 $booking_form_element.removeClass('step-changing').addClass('step-changed');
1322 }, 50);
1323 }, 500);
1324 }
1325
1326
1327 function latepoint_validate_fields($fields) {
1328 var is_valid = true;
1329 $fields.each(function (index) {
1330 if (jQuery(this).val() == '') {
1331 is_valid = false;
1332 return false;
1333 }
1334 });
1335 return is_valid;
1336 }
1337
1338
1339 async function latepoint_submit_booking_form($booking_form) {
1340 let $booking_form_element = $booking_form.closest('.latepoint-booking-form-element');
1341
1342 let current_step = $booking_form_element.find('.latepoint_current_step_code').val();
1343 let callbacks_list = [];
1344 if (latepoint_check_if_booking_form_is_final_submit($booking_form_element)) {
1345 // check if order intent is still bookable
1346 latepoint_add_action(callbacks_list, async () => {
1347 return await latepoint_check_if_order_intent_still_bookable($booking_form_element);
1348 }, 1);
1349 }
1350 $booking_form_element.trigger('latepoint:submitBookingForm', [{
1351 current_step: current_step,
1352 callbacks_list: callbacks_list,
1353 is_final_submit: latepoint_check_if_booking_form_is_final_submit($booking_form_element),
1354 direction: $booking_form_element.find('.latepoint_step_direction').val()
1355 }]);
1356 try {
1357 latepoint_hide_prev_btn($booking_form_element);
1358 await latepoint_process_list_of_callbacks(callbacks_list, $booking_form_element, $booking_form);
1359 } catch (error) {
1360 latepoint_show_prev_btn($booking_form_element);
1361 latepoint_show_error_and_stop_loading_booking_form(error, $booking_form_element);
1362 return false;
1363 }
1364
1365
1366
1367 $booking_form_element.removeClass('step-content-loaded').addClass('step-content-loading');
1368 latepoint_hide_prev_btn($booking_form_element);
1369 try{
1370 latepoint_hide_message_inside_element($booking_form_element.find('.latepoint-body'));
1371 let response = await jQuery.ajax({
1372 type: "post",
1373 dataType: "json",
1374 processData: false,
1375 contentType: false,
1376 url: latepoint_timestamped_ajaxurl(),
1377 data: latepoint_create_form_data($booking_form)
1378 });
1379
1380 $booking_form.find('.latepoint_step_direction').val('next');
1381 if(response.status === 'success'){
1382 if (response.fields_to_update) {
1383 for (const [key, value] of Object.entries(response.fields_to_update)) {
1384 $booking_form_element.find('input[name="' + key + '"]').val(value)
1385 }
1386 }
1387 if ($booking_form_element.data('flash-error')) {
1388 latepoint_show_message_inside_element($booking_form_element.data('flash-error'), $booking_form_element.find('.latepoint-body'));
1389 $booking_form_element.data('flash-error', '');
1390 }
1391 $booking_form_element.find('.latepoint_current_step_code').val(response.step_code);
1392 $booking_form_element.removeClass(function (index, className) {
1393 return (className.match(/(^|\s)current-step-\S+/g) || []).join(' ');
1394 }).addClass('current-step-' + response.step_code);
1395 setTimeout(function () {
1396 $booking_form_element.removeClass('step-content-loading').addClass('step-content-mid-loading');
1397 $booking_form_element.find('.latepoint-body').find('.latepoint-step-content').addClass('is-hidden');
1398 if ($booking_form_element.find('.latepoint-step-content[data-step-code="' + response.step_code + '"]')) {
1399 $booking_form_element.find('.latepoint-step-content[data-step-code="' + response.step_code + '"]').remove();
1400 }
1401 $booking_form_element.find('.latepoint-body').append(response.message);
1402
1403
1404 latepoint_update_next_btn_label($booking_form_element);
1405 latepoint_init_step(response.step_code, $booking_form_element);
1406 setTimeout(function () {
1407 $booking_form_element.removeClass('step-content-mid-loading').addClass('step-content-loaded');
1408 $booking_form_element.find('.latepoint-next-btn, .latepoint-prev-btn').removeClass('os-loading');
1409 latepoint_scroll_to_top_of_booking_form($booking_form_element);
1410 }, 50);
1411 }, 500);
1412
1413 if (response.is_pre_last_step) {
1414 $booking_form_element.data('next-submit-is-last', 'yes');
1415 } else {
1416 $booking_form_element.data('next-submit-is-last', 'no');
1417 }
1418 if (response.is_last_step) {
1419 $booking_form_element.addClass('hidden-buttons').find('.latepoint-footer').remove();
1420 $booking_form_element.find('.latepoint-progress').css('opacity', 0);
1421 $booking_form_element.closest('.latepoint-summary-is-open').removeClass('latepoint-summary-is-open');
1422 $booking_form_element.closest('.latepoint-show-side-panel').removeClass('latepoint-show-side-panel').addClass('latepoint-hide-side-panel');
1423 $booking_form_element.addClass('is-final-step');
1424 } else {
1425 if (response.show_next_btn === true) {
1426 latepoint_show_next_btn($booking_form_element);
1427 } else {
1428 latepoint_hide_next_btn($booking_form_element);
1429 }
1430 if (response.show_prev_btn === true) {
1431 latepoint_show_prev_btn($booking_form_element);
1432 } else {
1433 latepoint_hide_prev_btn($booking_form_element);
1434 }
1435 }
1436 latepoint_change_step_desc($booking_form_element, response.step_code);
1437 latepoint_reload_summary($booking_form_element);
1438 }else{
1439 if(response.send_to_step && response.send_to_step === 'resubmit'){
1440 let current_resubmit_count = parseInt($booking_form.data('resubmit-count')) ? parseInt($booking_form.data('resubmit-count')) : 1;
1441 $booking_form.data('resubmit-count', current_resubmit_count + 1);
1442 if(current_resubmit_count > 6){
1443 latepoint_show_message_inside_element(response.message, $booking_form_element.find('.latepoint-body'));
1444 }else{
1445 // resubmission probably caused by order intent still being processed, since
1446 // order intent is still processing, give it a little more time and try again
1447 await latepoint_sleep(2000);
1448 return latepoint_submit_booking_form($booking_form);
1449 }
1450 }else{
1451 $booking_form_element.removeClass('step-content-loading').addClass('step-content-loaded');
1452 $booking_form_element.find('.latepoint-next-btn, .latepoint-prev-btn').removeClass('os-loading');
1453 if (response.send_to_step && $booking_form_element.find('.latepoint-step-content[data-step-code="' + response.send_to_step + '"]').length) {
1454 $booking_form_element.data('flash-error', response.message);
1455 latepoint_reload_step($booking_form_element, response.send_to_step);
1456 } else {
1457 latepoint_show_message_inside_element(response.message, $booking_form_element.find('.latepoint-body'));
1458 latepoint_show_prev_btn($booking_form_element);
1459 }
1460 }
1461 }
1462 }catch(e){
1463 console.log(e);
1464 alert('Error:' + e);
1465 }
1466 }
1467
1468 function latepoint_sleep(ms) {
1469 return new Promise(resolve => setTimeout(resolve, ms));
1470 }
1471
1472 function latepoint_show_error_and_stop_loading_booking_form(error, $booking_form_element) {
1473 if (error.send_to_step && $booking_form_element.find('.latepoint-step-content[data-step-code="' + error.send_to_step + '"]').length) {
1474 latepoint_reload_step($booking_form_element, error.send_to_step);
1475 $booking_form_element.data('flash-error', error.message);
1476 } else {
1477 latepoint_show_message_inside_element(error.message, $booking_form_element.find('.latepoint-body'), 'error');
1478
1479 if ($booking_form_element.hasClass('step-content-loading')) $booking_form_element.removeClass('step-content-loading').addClass('step-content-loaded');
1480 $booking_form_element.find('.latepoint-next-btn').removeClass('os-loading');
1481
1482 // if previous step exists - show prev button
1483 if ($booking_form_element.find('.latepoint-step-content:last-child').prev('.latepoint-step-content').length) latepoint_show_prev_btn($booking_form_element);
1484 latepoint_scroll_to_top_of_booking_form($booking_form_element);
1485 }
1486 }
1487
1488 function latepoint_reset_active_cart_item($booking_form_element) {
1489 $booking_form_element.find('input[name="active_cart_item[id]"]').val('');
1490 $booking_form_element.find('input[name="active_cart_item[variant]"]').val('');
1491 $booking_form_element.find('input[name="active_cart_item[item_data]"]').val('');
1492 }
1493
1494 function latepoint_check_if_booking_form_is_final_submit($booking_form_element) {
1495 return ($booking_form_element.data('next-submit-is-last') == 'yes');
1496 }
1497
1498
1499 async function latepoint_check_if_order_intent_still_bookable($booking_form_element) {
1500 let response = await jQuery.ajax({
1501 type: "post",
1502 dataType: "json",
1503 processData: false,
1504 contentType: false,
1505 url: latepoint_timestamped_ajaxurl(),
1506 data: latepoint_create_form_data($booking_form_element.find('.latepoint-form'), latepoint_helper.check_order_intent_bookable_route)
1507 });
1508 if(response.status === 'success'){
1509 return true;
1510 }else{
1511 throw new Error(response.message);
1512 }
1513 }
1514
1515 async function latepoint_process_list_of_callbacks(callbacks, $booking_form_element, $booking_form) {
1516 for (const callback of callbacks) {
1517 await callback.action();
1518 }
1519 }
1520
1521 function latepoint_clear_presets($booking_form_element){
1522 $booking_form_element.find('.clear_for_new_item').val('');
1523 }
1524
1525 function latepoint_init_booking_form($booking_form_element) {
1526 $booking_form_element.on('click keydown', '.checkout-from-summary-panel-btn', function (event) {
1527 if(event.type === 'keydown' && event.key !== ' ' && event.key !== 'Enter') return;
1528 latepoint_reload_step($booking_form_element, jQuery(this).data('step'));
1529 jQuery(this).closest('.latepoint-w').removeClass('show-summary-on-mobile');
1530 return false;
1531 });
1532
1533 $booking_form_element.on('click keydown', '.latepoint-add-another-item-trigger', function (event) {
1534 if(event.type === 'keydown' && event.key !== ' ' && event.key !== 'Enter') return;
1535 latepoint_clear_presets($booking_form_element);
1536 latepoint_reset_active_cart_item($booking_form_element);
1537 latepoint_reload_step($booking_form_element, jQuery(this).data('step'));
1538 return false;
1539 });
1540 $booking_form_element.find('.latepoint-form').on('submit', function (e) {
1541 e.preventDefault();
1542 let $booking_form = jQuery(this);
1543 latepoint_submit_booking_form($booking_form);
1544 });
1545
1546 latepoint_init_booking_summary_panel($booking_form_element);
1547
1548 $booking_form_element.find('.latepoint-heading-w .latepoint-lightbox-summary-trigger').on('click', function () {
1549 var $wrapper = jQuery(this).closest('.latepoint-w');
1550 $wrapper.toggleClass('show-summary-on-mobile');
1551 return false;
1552 });
1553
1554 $booking_form_element.find('.latepoint-lightbox-close').on('click', function () {
1555
1556 let params = new URLSearchParams(location.search);
1557 if (params.has('latepoint_order_intent_key')) {
1558 params.delete('latepoint_order_intent_key');
1559 history.replaceState(null, '', '?' + params + location.hash);
1560 }
1561
1562 jQuery('body').removeClass('latepoint-lightbox-active');
1563 jQuery('.latepoint-lightbox-w').remove();
1564 return false;
1565 });
1566
1567
1568 $booking_form_element.find('.latepoint-timezone-selector-w select').on('change', function (e) {
1569 var $select_box = jQuery(this);
1570 $select_box.closest('.latepoint-timezone-selector-w').addClass('os-loading');
1571 var data = {
1572 action: latepoint_helper.route_action,
1573 route_name: jQuery(this).closest('.latepoint-timezone-selector-w').data('route-name'),
1574 params: {timezone_name: jQuery(this).val()},
1575 layout: 'none',
1576 return_format: 'json'
1577 }
1578 $booking_form_element.removeClass('step-content-loaded').addClass('step-content-loading');
1579 jQuery.ajax({
1580 type: "post",
1581 dataType: "json",
1582 url: latepoint_timestamped_ajaxurl(),
1583 data: data,
1584 success: function (data) {
1585 $select_box.closest('.latepoint-timezone-selector-w').removeClass('os-loading');
1586 $booking_form_element.removeClass('step-content-loading');
1587 if (data.status === "success") {
1588 // reload datepicker if its the step
1589 if ($select_box.closest('.latepoint-booking-form-element').hasClass('current-step-booking__datepicker')) {
1590 latepoint_reload_step($select_box.closest('.latepoint-booking-form-element'));
1591 }
1592 } else {
1593
1594 }
1595 }
1596 });
1597 });
1598
1599 if (!latepoint_helper.is_timezone_selected) {
1600 const tzid = Intl.DateTimeFormat().resolvedOptions().timeZone;
1601 if (tzid) {
1602 if (tzid != $booking_form_element.find('.latepoint-timezone-selector-w select').val()) $booking_form_element.find('.latepoint-timezone-selector-w select').val(tzid).trigger('change');
1603 }
1604 }
1605
1606
1607 $booking_form_element.on('click keydown', '.lp-option', function (event) {
1608 if(event.type === 'keydown' && event.key !== ' ' && event.key !== 'Enter') return;
1609 jQuery(this).closest('.lp-options').find('.lp-option.selected').removeClass('selected');
1610 jQuery(this).addClass('selected');
1611 });
1612
1613
1614 // Next Step button Click
1615 $booking_form_element.find('.latepoint-next-btn').on('click', async function (e) {
1616 e.preventDefault();
1617 if (jQuery(this).hasClass('disabled') || jQuery(this).hasClass('os-loading')) return false;
1618 var $next_btn = jQuery(this);
1619 $next_btn.addClass('os-loading');
1620 var $booking_form = jQuery(this).closest('.latepoint-form');
1621
1622 var current_step = $booking_form_element.find('.latepoint_current_step_code').val();
1623
1624 $booking_form.find('.latepoint_step_direction').val('next');
1625 var callbacks_list = [];
1626
1627 $booking_form_element.trigger('latepoint:nextStepClicked', [{
1628 current_step: current_step,
1629 callbacks_list: callbacks_list
1630 }]);
1631 latepoint_hide_prev_btn($booking_form_element);
1632
1633 try{
1634 await latepoint_process_list_of_callbacks(callbacks_list, $booking_form_element, $booking_form );
1635 await latepoint_submit_booking_form($booking_form);
1636 }catch(error){
1637 latepoint_show_error_and_stop_loading_booking_form(error, $booking_form_element);
1638 }
1639 return false;
1640 });
1641
1642
1643 // Previous Step button Click
1644 $booking_form_element.find('.latepoint-prev-btn').on('click', function (e) {
1645 if (jQuery(this).hasClass('disabled') || jQuery(this).hasClass('os-loading')) return false;
1646
1647 let $current_step = $booking_form_element.find('.latepoint-step-content:last-child');
1648
1649
1650 // handle categories
1651 if ($current_step.hasClass('selecting-item-category')) {
1652 if ($current_step.find('.os-item-category-w .os-item-category-w.selected').length) {
1653 $current_step.find('.os-item-category-w .os-item-category-w.selected').parents('.os-item-category-w').addClass('selected').find('.os-item-category-w.selected').removeClass('selected');
1654 } else {
1655 $current_step.removeClass('selecting-item-category').find('.os-item-category-w.selected').removeClass('selected');
1656 $current_step.removeClass('selecting-item-category').find('.os-item-categories-holder.show-selected-only').removeClass('show-selected-only');
1657 }
1658 if (($booking_form_element.find('.latepoint-step-content').length <= 1) && !$current_step.hasClass('selecting-item-category')) {
1659 latepoint_hide_prev_btn($booking_form_element);
1660 }
1661 latepoint_reload_summary($booking_form_element);
1662 return false;
1663 }
1664
1665 if ($current_step.data('clear-action')) {
1666 window[$current_step.data('clear-action')]($booking_form_element);
1667 }
1668
1669 let $back_btn = jQuery(this);
1670 $back_btn.addClass('os-loading');
1671 $booking_form_element.removeClass('step-content-loaded').addClass('step-content-loading');
1672 let $new_current_step = $booking_form_element.find('.latepoint-step-content.is-hidden').last();
1673 let new_current_step_code = $new_current_step.data('step-code');
1674 let current_step_code = $current_step.data('step-code');
1675
1676
1677 let current_parent_code_name = current_step_code.split('__')[0];
1678 let new_parent_code_name = new_current_step_code.split('__')[0];
1679
1680 let active_cart_item_id = $booking_form_element.find('input[name="active_cart_item[id]"]').val();
1681
1682 latepoint_change_step_desc($booking_form_element, new_current_step_code);
1683 setTimeout(function () {
1684 $new_current_step.removeClass('is-hidden');
1685 $current_step.remove();
1686 $booking_form_element.find('.latepoint_current_step_code').val(new_current_step_code);
1687 $booking_form_element.removeClass(function (index, className) {
1688 return (className.match(/(^|\s)current-step-\S+/g) || []).join(' ');
1689 }).addClass('current-step-' + new_current_step_code);
1690 $booking_form_element.find('.latepoint-next-btn span').text($booking_form_element.find('.latepoint-next-btn').data('label'));
1691 $booking_form_element.data('next-submit-is-last', 'no');
1692
1693 latepoint_update_next_btn_label($booking_form_element);
1694 latepoint_show_next_btn($booking_form_element);
1695 $back_btn.removeClass('os-loading');
1696 if ($booking_form_element.find('.latepoint-step-content').length <= 1) {
1697 if ($new_current_step.hasClass('selecting-item-category')) {
1698
1699 }
1700 if (new_current_step_code == 'booking__services') {
1701 var $services_step = $booking_form_element.find('.step-services-w');
1702 if ($services_step.hasClass('selecting-item-category')) {
1703 if ($services_step.find('.os-services > .os-item.selected').hasClass('is-preselected')) {
1704 // if service is preselected check if there are both multiple durations and quantity selector and only then show prev button
1705 } else {
1706 latepoint_show_prev_btn($booking_form_element);
1707 }
1708 } else {
1709 latepoint_hide_prev_btn($booking_form_element);
1710 }
1711 } else {
1712 if (!$new_current_step.hasClass('selecting-item-category')) {
1713 latepoint_hide_prev_btn($booking_form_element);
1714 }
1715 }
1716 }
1717 $booking_form_element.removeClass('step-content-loading').addClass('step-content-mid-loading');
1718
1719
1720 if(new_parent_code_name == 'booking' && current_parent_code_name != 'booking' && active_cart_item_id){
1721
1722 // we are going back to one of the steps of a booking process, we need to remove the item that was just added to the cart and start over
1723 $booking_form_element.find('.latepoint-summary-w').addClass('os-loading');
1724 let data = {
1725 action: latepoint_helper.route_action,
1726 route_name: latepoint_helper.remove_cart_item_route,
1727 params: jQuery.param({cart_item_id: active_cart_item_id}),
1728 layout: 'none',
1729 return_format: 'json'
1730 }
1731 jQuery.ajax({
1732 type: "post",
1733 dataType: "json",
1734 url: latepoint_timestamped_ajaxurl(),
1735 data: data,
1736 success: function (data) {
1737 if (data.status === "success") {
1738 $booking_form_element.find('input[name="active_cart_item[id]"]').val('');
1739 if($booking_form_element.find('input[name="active_cart_item[variant]"]').val() == 'bundle'){
1740 latepoint_update_active_cart_item_item_data($booking_form_element, 'bundle_id', '');
1741 $booking_form_element.find('input[name="active_cart_item[variant]"]').val('');
1742 }
1743 latepoint_reload_summary($booking_form_element);
1744 } else {
1745 $booking_form_element.find('.latepoint-summary-w').removeClass('os-loading');
1746 latepoint_show_message_inside_element(data.message, $booking_form_element.find('.latepoint-body'), 'error');
1747 }
1748 }
1749 });
1750 }else{
1751 latepoint_reload_summary($booking_form_element);
1752 }
1753 setTimeout(function () {
1754 $booking_form_element.removeClass('step-content-mid-loading').addClass('step-content-loaded');
1755 latepoint_hide_message_inside_element($booking_form_element.find('.latepoint-body'));
1756 latepoint_scroll_to_top_of_booking_form($booking_form_element);
1757 }, 150);
1758 }, 700);
1759 return false;
1760 });
1761
1762 latepoint_init_agent_details_link($booking_form_element);
1763 }
1764
1765
1766 function latepoint_init_booking_form_by_trigger($trigger) {
1767 let route = latepoint_helper.booking_button_route;
1768 let params = {};
1769 let restrictions = {};
1770 let presets = {};
1771 let booking_element_styles = {};
1772 if ($trigger.data('show-service-categories')) restrictions.show_service_categories = $trigger.data('show-service-categories');
1773 if ($trigger.data('show-locations')) restrictions.show_locations = $trigger.data('show-locations');
1774 if ($trigger.data('show-services')) restrictions.show_services = $trigger.data('show-services');
1775 if ($trigger.data('show-agents')) restrictions.show_agents = $trigger.data('show-agents');
1776 if ($trigger.data('calendar-start-date')) restrictions.calendar_start_date = $trigger.data('calendar-start-date');
1777
1778 if ($trigger.data('selected-location')) presets.selected_location = $trigger.data('selected-location');
1779 if ($trigger.data('selected-agent')) presets.selected_agent = $trigger.data('selected-agent');
1780 if ($trigger.data('selected-service')) presets.selected_service = $trigger.data('selected-service');
1781 if ($trigger.data('selected-bundle')) presets.selected_bundle = $trigger.data('selected-bundle');
1782 if ($trigger.data('selected-duration')) presets.selected_duration = $trigger.data('selected-duration');
1783 if ($trigger.data('selected-total-attendees')) presets.selected_total_attendees = $trigger.data('selected-total-attendees');
1784 if ($trigger.data('selected-service-category')) presets.selected_service_category = $trigger.data('selected-service-category');
1785 if ($trigger.data('selected-start-date')) presets.selected_start_date = $trigger.data('selected-start-date');
1786 if ($trigger.data('selected-start-time')) presets.selected_start_time = $trigger.data('selected-start-time');
1787 if ($trigger.data('order-item-id')) presets.order_item_id = $trigger.data('order-item-id');
1788 if ($trigger.data('source-id')) presets.source_id = $trigger.data('source-id');
1789
1790 if ($trigger.data('hide-summary') == 'yes') booking_element_styles.hide_summary = true;
1791 if ($trigger.data('hide-side-panel') == 'yes') booking_element_styles.hide_side_panel = true;
1792
1793
1794 if (jQuery.isEmptyObject(restrictions) == false) params.restrictions = restrictions;
1795 if (jQuery.isEmptyObject(presets) == false) params.presets = presets;
1796 if (jQuery.isEmptyObject(booking_element_styles) == false) params.booking_element_styles = booking_element_styles;
1797
1798 let data = {
1799 action: latepoint_helper.route_action,
1800 route_name: route,
1801 params: params,
1802 layout: 'none',
1803 return_format: 'json'
1804 }
1805
1806 let is_inline_form = $trigger.hasClass('latepoint-book-form-wrapper');
1807 if(is_inline_form){
1808 data.params.booking_element_type = 'inline_form';
1809 }
1810
1811 $trigger.addClass('os-loading');
1812 jQuery.ajax({
1813 type: "post",
1814 dataType: "json",
1815 url: latepoint_timestamped_ajaxurl(),
1816 data: data,
1817 success: (data) => {
1818 if (data.status === "success") {
1819 let $booking_form_element = false;
1820 if(is_inline_form){
1821 $trigger.html(data.message);
1822 $booking_form_element = $trigger.find('.latepoint-booking-form-element');
1823 }else{
1824 let lightbox_class = 'booking-form-in-lightbox';
1825 latepoint_show_data_in_lightbox(data.message, lightbox_class, false);
1826 $booking_form_element = jQuery('.latepoint-lightbox-w .latepoint-booking-form-element');
1827 jQuery('body').addClass('latepoint-lightbox-active');
1828 }
1829 latepoint_init_booking_form($booking_form_element);
1830 latepoint_init_step(data.step, $booking_form_element);
1831 $trigger.removeClass('os-loading');
1832 } else {
1833 $trigger.removeClass('os-loading');
1834 // console.log(data.message);
1835 }
1836 }
1837 });
1838 }
1839