https://tirtaayuspa.com.ng/lekki/wp-content/plugins/latepoint/public/javascripts/front.js?ver=5.1.93
1function latepoint_is_timeframe_in_periods(timeframe_start, timeframe_end, periods_arr) { 2 var is_inside = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; 3 4 for (var i = 0; i < periods_arr.length; i++) { 5 6 var period_start = 0; 7 var period_end = 0; 8 var buffer_before = 0; 9 var buffer_after = 0; 10 11 var period_info = periods_arr[i].split(':'); 12 if (period_info.length == 2) { 13 period_start = period_info[0]; 14 period_end = period_info[1]; 15 } else { 16 buffer_before = period_info[2]; 17 buffer_after = period_info[3]; 18 period_start = parseFloat(period_info[0]) - parseFloat(buffer_before); 19 period_end = parseFloat(period_info[1]) + parseFloat(buffer_after); 20 } 21 if (is_inside) { 22 if (latepoint_is_period_inside_another(timeframe_start, timeframe_end, period_start, period_end)) { 23 return true; 24 } 25 } else { 26 if (latepoint_is_period_overlapping(timeframe_start, timeframe_end, period_start, period_end)) { 27 return true; 28 } 29 } 30 } 31 return false; 32} 33 34function latepoint_is_period_overlapping(period_one_start, period_one_end, period_two_start, period_two_end) { 35 // https://stackoverflow.com/questions/325933/determine-whether-two-date-ranges-overlap/ 36 return period_one_start < period_two_end && period_two_start < period_one_end; 37} 38 39function latepoint_is_period_inside_another(period_one_start, period_one_end, period_two_start, period_two_end) { 40 return period_one_start >= period_two_start && period_one_end <= period_two_end; 41} 42 43 44// Converts time in minutes to hours if possible, if minutes also exists - shows minutes too 45function latepoint_minutes_to_hours_preferably(time) { 46 var army_clock = latepoint_is_army_clock(); 47 48 var hours = Math.floor(time / 60); 49 if (!army_clock && hours > 12) hours = hours - 12; 50 51 var minutes = time % 60; 52 if (minutes > 0) hours = hours + ':' + minutes; 53 return hours; 54} 55 56 57function latepoint_minutes_to_hours(time) { 58 var army_clock = latepoint_is_army_clock(); 59 60 var hours = Math.floor(time / 60); 61 if (!army_clock && hours > 12) hours = hours - 12; 62 return hours; 63} 64 65 66function latepoint_am_or_pm(minutes) { 67 if (latepoint_is_army_clock()) return ''; 68 return (minutes < 720 || minutes == 1440) ? 'am' : 'pm'; 69} 70 71function latepoint_hours_and_minutes_to_minutes(hours_and_minutes, ampm) { 72 var hours_and_minutes_arr = hours_and_minutes.split(':'); 73 var hours = hours_and_minutes_arr[0]; 74 var minutes = hours_and_minutes_arr[1]; 75 if (ampm == "pm" && hours < 12) hours = parseInt(hours) + 12; 76 if (ampm == "am" && hours == 12) hours = 0; 77 minutes = parseInt(minutes) + (hours * 60); 78 return minutes; 79} 80 81function latepoint_get_time_system() { 82 return latepoint_helper.time_system; 83} 84 85function latepoint_is_army_clock() { 86 return (latepoint_get_time_system() == '24'); 87} 88 89function latepoint_minutes_to_hours_and_minutes(minutes) { 90 var army_clock = latepoint_is_army_clock(); 91 var format = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '%02d:%02d'; 92 93 var hours = Math.floor(minutes / 60); 94 if (!army_clock && (hours > 12)) hours = hours - 12; 95 if (!army_clock && hours == 0) hours = 12; 96 minutes = minutes % 60; 97 // Check if sprintf is available (either native or from a library) 98 if (typeof sprintf === 'function') { 99 return sprintf(format, hours, minutes); 100 } else { 101 return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`; 102 } 103} 104 105 106function latepoint_timestamped_ajaxurl(){ 107 let url = latepoint_helper.ajaxurl; 108 let timestamp = Date.now(); 109 110 // Check if the URL already has GET parameters 111 if (url.includes('?')) { 112 return `${url}&t=${timestamp}`; 113 } else { 114 return `${url}?t=${timestamp}`; 115 } 116} 117 118function latepoint_random_generator() { 119 var S4 = function () { 120 return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1); 121 }; 122 return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4()); 123} 124 125function latepoint_validate_form($form) { 126 let errors = []; 127 $form.find('select[data-os-validate], input[data-os-validate], textarea[data-os-validate]').each(function () { 128 let validations = jQuery(this).data('os-validate').split(' '); 129 let $input = jQuery(this); 130 let label = $input.closest('.os-form-group').find('label').text(); 131 let field_has_errors = false;
132 if (validations) { 133 for (let i = 0; i < validations.length; i++) { 134 switch (validations[i]) { 135 case 'presence': 136 if($input.is(':checkbox')){ 137 if (!$input.is(':checked')) { 138 errors.push({message: label + ' ' + latepoint_helper.msg_validation_presence_checkbox}); 139 field_has_errors = true; 140 } 141 }else{ 142 if (!$input.val()) { 143 errors.push({message: label + ' ' + latepoint_helper.msg_validation_presence}); 144 field_has_errors = true; 145 } 146 } 147 break; 148 case 'phone': 149 if (!window.lp_intlTelInputGlobals.getInstance($input[0]).isValidNumber()) { 150 errors.push({message: label + ' ' + latepoint_helper.msg_validation_invalid}); 151 field_has_errors = true; 152 } 153 break; 154 } 155 } 156 } 157 if (field_has_errors) { 158 $input.closest('.os-form-group').addClass('os-invalid'); 159 } else { 160 $input.closest('.os-form-group').removeClass('os-invalid'); 161 } 162 }); 163 return errors; 164} 165 166function latepoint_create_form_data_from_non_form_element($elem) { 167 let formData = new FormData(); 168 // create objecte from all input fields that are inside of the element 169 let fields = $elem.find('select, input, textarea').serializeArray(); 170 if (fields) { 171 fields.forEach(field => formData.append(field.name, field.value)); 172 } 173 return formData; 174} 175 176function latepoint_create_form_data($form, route_name = false, extra_params = false) { 177 let form_data = new FormData(); 178 let params = new FormData($form[0]); 179 180 if (extra_params) { 181 Object.keys(extra_params).forEach(key => { 182 params.set(key, extra_params[key]); 183 }); 184 } 185 186 // get values from phone number fields 187 if (('lp_intlTelInputGlobals' in window) && ('lp_intlTelInputUtils' in window)) { 188 $form.find('input.os-mask-phone').each(function () { 189 const phoneInputName = this.getAttribute('name'); 190 const phoneInputValue = window.lp_intlTelInputGlobals.getInstance(this).getNumber(window.lp_intlTelInputUtils.numberFormat.E164); 191 // override value generated automatically by formdata with a formatted value of a phone field with country code 192 params.set(phoneInputName, phoneInputValue); 193 }); 194 } 195 196 form_data.append('params', latepoint_formdata_to_url_encoded_string(params)); 197 form_data.append('action', latepoint_helper.route_action); 198 form_data.append('route_name', route_name ? route_name : $form.data('route-name')); 199 form_data.append('layout', 'none'); 200 form_data.append('return_format', 'json'); 201 202 let file_data; 203 // put file data into main form_data object, since we can't send them in "params" string 204 $form.find('input[type="file"]').each(function () { 205 file_data = this.files; // get multiple files from input file 206 let file_name = this.getAttribute("name"); 207 for (let i = 0; i < file_data.length; i++) { 208 form_data.append(file_name + '[]', file_data[i]); 209 } 210 }); 211 return form_data; 212} 213 214function latepoint_mask_timefield($elem) { 215 if (jQuery().inputmask) { 216 $elem.inputmask({ 217 'mask': '99:99', 218 'placeholder': 'HH:MM' 219 }); 220 } 221} 222 223function latepoint_formdata_to_url_encoded_string(form_data) { 224 let filtered_form_data = new FormData(); 225 // remove file fields from params, so we can serialize it into string, 226 // !important, this will not include file fields into the form_data, so you have to include them manually, see latepoint_create_form_data() that does it 227 // note: we don't use form_data.remove(key) on original object because we might want to preserve it 228 for (const [key, value] of form_data) { 229 if (value instanceof File) continue; 230 if (key.slice(-2) === '[]') { 231 // expecting array, append 232 filtered_form_data.append(key, value); 233 } else { 234 filtered_form_data.set(key, value); 235 } 236 } 237 return new URLSearchParams(filtered_form_data).toString(); 238} 239 240function latepoint_mask_percent($elem) { 241 if (jQuery().inputmask) { 242 $elem.inputmask({ 243 'alias': 'decimal', 244 'radixPoint': latepoint_helper.decimal_separator, 245 'digits': 4, 246 'digitsOptional': false, 247 'suffix': '%', 248 'placeholder': '0', 249 'rightAlign': false 250 }); 251 } 252} 253 254function latepoint_mask_minutes($elem) { 255 if (jQuery().inputmask) { 256 $elem.inputmask({ 257 'removeMaskOnSubmit': true, 258 'alias': 'numeric', 259 'digits': 0, 260 'suffix': latepoint_helper.msg_minutes_suffix, 261 'placeholder': '0', 262 'rightAlign': false 263 }); 264 } 265} 266 267 268function latepoint_mask_money($elem) { 269 if (jQuery().inputmask) { 270 $elem.inputmask({ 271 'alias': 'currency', 272 'groupSeparator': latepoint_helper.thousand_separator, 273 'radixPoint': latepoint_helper.decimal_separator, 274 'digits': latepoint_helper.number_of_decimals, 275 'digitsOptional': false, 276 'prefix': latepoint_helper.currency_symbol_before ? latepoint_helper.currency_symbol_before + ' ' : '', 277 'suffix': latepoint_helper.currency_symbol_after ? ' ' + latepoint_helper.currency_symbol_after : '', 278 'placeholder': '0', 279 'rightAlign': false 280 }); 281 } 282} 283 284function latepoint_mask_date($elem) { 285 if (jQuery().inputmask) { 286 $elem.inputmask({ 287 'alias': 'datetime', 288 'inputFormat': latepoint_helper.date_format_for_js 289 }); 290 } 291} 292 293function latepoint_init_phone_masking_from_placeholder($input) { 294 if (!latepoint_helper.mask_phone_number_fields) return; 295 let format = $input.attr('placeholder'); 296 if (format && jQuery().inputmask) { 297 $input.inputmask(format.replace(/[0-9]/g, 9)); 298 } 299} 300 301function latepoint_mask_phone($elem) { 302 let jsElem = $elem[0]; 303 304 // First priority is to prevent duplicates (common in non-document.body contexts) 305 if (jsElem && !window.lp_intlTelInputGlobals.getInstance(jsElem)) { 306 let dropdownContainer = document.body; 307 308 let onlyCountries = JSON.parse(latepoint_helper.included_phone_countries); 309 // Remedy a quirk with json_encode(EMPTY_ARRAY) 310 if (onlyCountries.length === 1 && onlyCountries[0] === "") { 311 onlyCountries = []; 312 } 313 const preferredCountries = onlyCountries.length ? [] : window.lp_intlTelInputGlobals.defaults.preferredCountries; 314 315 // remove country name in english and only use names in country language 316 var countryData = window.lp_intlTelInputGlobals.getCountryData(); 317 318 for (var i = 0; i < countryData.length; i++) { 319 var country = countryData[i]; 320 country.name = country.name.replace(/ *\([^)]*\) */g, ""); 321 } 322 323 let defaultCountryCode = latepoint_helper.default_phone_country; 324 if (onlyCountries.length && !onlyCountries.includes(defaultCountryCode)) { 325 defaultCountryCode = onlyCountries[0]; 326 } 327 328 329 let iti = window.lp_intlTelInput(jsElem, { 330 dropdownContainer: dropdownContainer, 331 formatOnDisplay: true, 332 nationalMode: true, 333 autoPlaceholder: 'aggressive', 334 initialCountry: defaultCountryCode, 335 geoIpLookup: function (callback) { 336 const cookieName = 'latepoint_phone_country'; 337 338 if (latepoint_has_cookie(cookieName)) { 339 callback(latepoint_get_cookie(cookieName)); 340 } else { 341 jQuery.get('https://ipinfo.io', function () { 342 }, 'jsonp').always(function (response) { 343 // Sensible default 344 let countryCode = defaultCountryCode; 345 346 if (response && response.country) { 347 countryCode = response.country.toLowerCase(); 348 latepoint_set_cookie(cookieName, countryCode); 349 } 350 callback(countryCode); 351 }) 352 } 353 }, 354 allowDropdown: onlyCountries.length != 1, 355 onlyCountries: onlyCountries, 356 preferredCountries: preferredCountries, 357 separateDialCode: latepoint_helper.is_enabled_show_dial_code_with_flag 358 }); 359 360 iti.promise.then(function () { 361 latepoint_init_phone_masking_from_placeholder($elem); 362 }); 363 364 365 $elem.on("countrychange", function (event) { 366 latepoint_init_phone_masking_from_placeholder(jQuery(this)); 367 }); 368 } 369} 370 371function latepoint_show_booking_end_time() { 372 return (latepoint_helper.show_booking_end_time == 'yes'); 373} 374 375function latepoint_set_cookie(name, value, days) { 376 let date = new Date; 377 date.setTime(date.getTime() + 24 * 60 * 60 * 1000 * days); 378 document.cookie = name + "=" + value + ";path=/;expires=" + date.toGMTString(); 379} 380 381function latepoint_get_cookie(name) { 382 let cookie = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)'); 383 return cookie ? cookie[2] : null; 384} 385 386function latepoint_has_cookie(name) { 387 return latepoint_get_cookie(name) !== null; 388} 389 390function latepoint_delete_cookie(name) { 391 latepoint_set_cookie(name, '', -1); 392} 393 394function latepoint_add_notification(message, message_type = 'success'){ 395 var wrapper = jQuery('body').find('.os-notifications'); 396 if(!wrapper.length){ 397 jQuery('body').append('<div class="os-notifications"></div>'); 398 wrapper = jQuery('body').find('.os-notifications'); 399 } 400 if(wrapper.find('.item').length > 0) wrapper.find('.item:first-child').remove(); 401 wrapper.append('<div class="item item-type-'+ message_type +'">' + message + '<span class="os-notification-close"><i class="latepoint-icon latepoint-icon-x"></i></span></div>'); 402} 403 404function latepoint_add_lightbox_notification(message, message_type = 'success'){ 405 var wrapper = jQuery('.latepoint-lightbox-content').find('.os-notifications'); 406 if(!wrapper.length){ 407 jQuery('.latepoint-lightbox-content').prepend('<div class="os-notifications"></div>'); 408 wrapper = jQuery('.latepoint-lightbox-content').find('.os-notifications'); 409 } 410 if(wrapper.find('.item').length > 0) wrapper.find('.item:first-child').remove(); 411 wrapper.append('<div class="item item-type-'+ message_type +'">' + message + '<span class="os-notification-close"><i class="latepoint-icon latepoint-icon-x"></i></span></div>'); 412} 413 414function latepoint_generate_form_message_html(messages, status){ 415 var message_html = '<div class="os-form-message-w status-' + status + '"><ul>'; 416 if(Array.isArray(messages)){
417 messages.forEach(function(message){ 418 message_html+= '<li>' + message + '</li>'; 419 }); 420 }else{ 421 message_html+= '<li>' + messages + '</li>'; 422 } 423 message_html+= '</ul></div>'; 424 return message_html; 425} 426 427function latepoint_display_in_side_sub_panel(html){ 428 if(!jQuery('.latepoint-side-panel-w').length) latepoint_show_data_in_side_panel(''); 429 jQuery('.latepoint-side-panel-w .latepoint-side-panels .side-sub-panel-wrapper').remove(); 430 jQuery('.latepoint-side-panel-w .latepoint-side-panels').append(html); 431} 432 433function latepoint_clear_form_messages($form){ 434 $form.find('.os-form-message-w').remove(); 435} 436 437function latepoint_show_data_in_side_panel(message, extra_classes = '', close_btn = true){ 438 jQuery('.latepoint-side-panel-w').remove(); 439 jQuery('body').append('<div class="latepoint-side-panel-w ' + extra_classes + ' os-loading"><div class="latepoint-side-panel-shadow"></div><div class="latepoint-side-panels"><div class="latepoint-side-panel-i"></div></div></div>'); 440 jQuery('.latepoint-side-panel-i').html(message); 441 if(close_btn){ 442 jQuery('.latepoint-side-panel-i').find('.os-form-header .latepoint-side-panel-close').remove(); 443 jQuery('.latepoint-side-panel-i').find('.os-form-header').append('<a href="#" class="latepoint-side-panel-close latepoint-side-panel-close-trigger"><i class="latepoint-icon latepoint-icon-x"></i></a>'); 444 } 445 setTimeout(function(){ 446 jQuery('.latepoint-side-panel-w').removeClass('os-loading'); 447 }, 100); 448} 449 450function latepoint_show_data_in_lightbox(message, extra_classes = '', close_btn = true, tag = 'div', inner_extra_classes = '', inner_tag = 'div'){ 451 jQuery('.latepoint-lightbox-w').remove(); 452 let lightbox_css_classes = 'latepoint-lightbox-w latepoint-w latepoint-border-radius-' + latepoint_helper.style_border_radius+ ' '; 453 if(extra_classes) lightbox_css_classes+= extra_classes; 454 let lightbox_css_inner_classes = 'latepoint-lightbox-i '; 455 if(inner_extra_classes) lightbox_css_inner_classes += inner_extra_classes; 456 457 let close_btn_html = close_btn ? '<a href="#" class="latepoint-lightbox-close" tabindex="0"><i class="latepoint-icon latepoint-icon-x"></i></a>' : ''; 458 jQuery('body').append('<'+tag+' class="'+ lightbox_css_classes +'"><'+inner_tag+' class="'+ lightbox_css_inner_classes +'">' + message + close_btn_html + '</'+inner_tag+'><div class="latepoint-lightbox-shadow"></div></'+tag+'>'); 459 460 jQuery('body').addClass('latepoint-lightbox-active'); 461} 462 463 464 465// DOCUMENT READY 466jQuery(function( $ ) { 467 468 if($('.latepoint').find('[data-os-action-onload]').length){ 469 $('.latepoint').find('[data-os-action-onload]').each(function(){ 470 var $this = jQuery(this); 471 $this.addClass('os-loading'); 472 var params = $this.data('os-params'); 473 var return_format = $this.data('os-return-format') ? $this.data('os-return-format') : 'json' 474 var data = { action: 'latepoint_route_call', route_name: $this.data('os-action-onload'), params: params, return_format: return_format } 475 jQuery.ajax({ 476 type : "post", 477 dataType : "json", 478 url : latepoint_timestamped_ajaxurl(), 479 data : data, 480 success: function(response) { 481 $this.removeClass('os-loading'); 482 if (response.status === "success") { 483 if($this.data('os-output-target') == 'self'){ 484 $this.html(response.message); 485 } 486 } 487 } 488 }); 489 }); 490 } 491 492 /* 493 Ajax buttons action 494 */ 495 $('.latepoint').on('click', 'button[data-os-action], a[data-os-action], div[data-os-action], span[data-os-action], tr[data-os-action]', function(e){ 496 var $this = jQuery(this); 497 if($this.data('os-prompt') && !confirm($this.data('os-prompt'))) return false; 498 var params = $this.data('os-params'); 499 if($this.data('os-source-of-params')){ 500 var form_data = latepoint_create_form_data_from_non_form_element($($this.data('os-source-of-params'))); 501 params = latepoint_formdata_to_url_encoded_string(form_data); 502 } 503 var return_format = $this.data('os-return-format') ? $this.data('os-return-format') : 'json' 504 var data = { action: 'latepoint_route_call', route_name: $this.data('os-action'), params: params, return_format: return_format } 505 $this.addClass('os-loading'); 506 if($this.data('os-output-target') == 'side-panel'){ 507 $('.latepoint-side-panel-w').remove();
508 let css_classes = $this.data('os-lightbox-classes') ? $this.data('os-lightbox-classes') : ''; 509 $('body').append('<div class="latepoint-side-panel-w ' + css_classes + ' os-loading"><div class="latepoint-side-panel-shadow"></div><div class="latepoint-side-panels"><div class="latepoint-side-panel-i"></div></div></div>'); 510 }else if($this.data('os-output-target') == 'full-panel'){ 511 $('.latepoint-full-panel-w').remove(); 512 $('body').append('<div class="latepoint-full-panel-w os-loading"></div>'); 513 } 514 $.ajax({ 515 type : "post", 516 dataType : "json", 517 url : latepoint_timestamped_ajaxurl(), 518 data : data, 519 success: function(response){ 520 if(response.status === "success"){ 521 if($this.data('os-output-target') == 'lightbox'){ 522 latepoint_show_data_in_lightbox(response.message, $this.data('os-lightbox-classes'), ($this.data('os-lightbox-no-close-button') !== 'yes'), $this.data('os-lightbox-tag'), $this.data('os-lightbox-inner-classes'), $this.data('os-lightbox-inner-tag')); 523 }else if($this.data('os-output-target') == 'side-panel'){ 524 $('.latepoint-side-panel-i').html(response.message); 525 jQuery('.latepoint-side-panel-i').find('.os-form-header .latepoint-side-panel-close').remove(); 526 jQuery('.latepoint-side-panel-i').find('.os-form-header').append('<a href="#" class="latepoint-side-panel-close latepoint-side-panel-close-trigger"><i class="latepoint-icon latepoint-icon-x"></i></a>'); 527 setTimeout(function(){ 528 $('.latepoint-side-panel-w').removeClass('os-loading'); 529 }, 100); 530 }else if($this.data('os-output-target') == 'full-panel'){ 531 $('.latepoint-full-panel-w').html(response.message); 532 setTimeout(function(){ 533 $('.latepoint-full-panel-w').removeClass('os-loading'); 534 }, 100); 535 }else if($this.data('os-success-action') == 'reload'){ 536 latepoint_add_notification(response.message); 537 location.reload(); 538 return; 539 }else if($this.data('os-success-action') == 'redirect'){ 540 if($this.data('os-redirect-to')){ 541 latepoint_add_notification(response.message); 542 window.location.replace($this.data('os-redirect-to')); 543 }else{ 544 window.location.replace(response.message); 545 } 546 return; 547 }else if($this.data('os-output-target') && $($this.data('os-output-target')).length){ 548 if($this.data('os-output-target-do') == 'append') { 549 $($this.data('os-output-target')).append(response.message); 550 }else if($this.data('os-output-target-do') == 'prepend'){ 551 $($this.data('os-output-target')).prepend(response.message); 552 }else{ 553 $($this.data('os-output-target')).html(response.message); 554 } 555 }else{ 556 switch($this.data('os-before-after')){ 557 case 'before': 558 $this.before(response.message); 559 break; 560 case 'after': 561 $this.after(response.message); 562 break; 563 case 'replace': 564 $this.replaceWith(response.message); 565 break; 566 case 'none': 567 break; 568 default: 569 latepoint_add_notification(response.message); 570 } 571 } 572 if($this.data('os-after-call')){ 573 var func_name = $this.data('os-after-call'); 574 var callback = false; 575 if(func_name.includes('.')){ 576 var func_arr = func_name.split('.'); 577 if(typeof window[func_arr[0]][func_arr[1]] !== 'function'){ 578 console.log(func_name + ' is undefined'); 579 } 580 if($this.data('os-pass-this') && $this.data('os-pass-response')){ 581 window[func_arr[0]][func_arr[1]]($this, response); 582 }else if($this.data('os-pass-this')){ 583 window[func_arr[0]][func_arr[1]]($this); 584 }else if($this.data('os-pass-response')){ 585 window[func_arr[0]][func_arr[1]](response); 586 }else{ 587 window[func_arr[0]][func_arr[1]](); 588 } 589 }else{ 590 if(typeof window[func_name] !== 'function'){ 591 console.log(func_name + ' is undefined'); 592 } 593 if($this.data('os-pass-this') && $this.data('os-pass-response')){ 594 window[func_name]($this, response); 595 }else if($this.data('os-pass-this')){ 596 window[func_name]($this); 597 }else if($this.data('os-pass-response')){ 598 window[func_name](response); 599 }else{ 600 window[func_name](); 601 } 602 } 603 } 604 $this.removeClass('os-loading'); 605 }else{ 606 $this.removeClass('os-loading'); 607 if($this.data('os-output-target') && $($this.data('os-output-target')).length){ 608 $($this.data('os-output-target')).prepend(latepoint_generate_form_message_html(response.message, 'error')); 609 }else{ 610 alert(response.message); 611 } 612 if($this.data('os-after-call-error')){ 613 var func_name = $this.data('os-after-call-error'); 614 var callback = false;
615 if(func_name.includes('.')){ 616 var func_arr = func_name.split('.'); 617 if(typeof window[func_arr[0]][func_arr[1]] !== 'function'){ 618 console.log(func_name + ' is undefined'); 619 } 620 if($this.data('os-pass-this') && $this.data('os-pass-response')){ 621 window[func_arr[0]][func_arr[1]]($this, response); 622 }else if($this.data('os-pass-this')){ 623 window[func_arr[0]][func_arr[1]]($this); 624 }else if($this.data('os-pass-response')){ 625 window[func_arr[0]][func_arr[1]](response); 626 }else{ 627 window[func_arr[0]][func_arr[1]](); 628 } 629 }else{ 630 if(typeof window[func_name] !== 'function'){ 631 console.log(func_name + ' is undefined'); 632 } 633 if($this.data('os-pass-this') && $this.data('os-pass-response')){ 634 window[func_name]($this, response); 635 }else if($this.data('os-pass-this')){ 636 window[func_name]($this); 637 }else if($this.data('os-pass-response')){ 638 window[func_name](response); 639 }else{ 640 window[func_name](); 641 } 642 } 643 } 644 } 645 } 646 }); 647 return false; 648 }); 649 650 651 $('.latepoint').on('click', 'form[data-os-action] button[type="submit"]', function(e){ 652 $(this).addClass('os-loading'); 653 }); 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 /* 672 Form ajax submit action 673 */ 674 $('.latepoint').on('submit', 'form[data-os-action]', function(e){ 675 e.preventDefault(); // prevent native submit 676 var $form = $(this); 677 var form_data = new FormData($form[0]); 678 679 if (('lp_intlTelInputGlobals' in window) && ('lp_intlTelInputUtils' in window)) { 680 // Get e164 formatted number from phone fields when form is submitted 681 $form.find('input.os-mask-phone').each(function () { 682 let telInstance = window.lp_intlTelInputGlobals.getInstance(this); 683 if(telInstance){ 684 const phoneInputName = this.getAttribute('name'); 685 const phoneInputValue = window.lp_intlTelInputGlobals.getInstance(this).getNumber(window.lp_intlTelInputUtils.numberFormat.E164); 686 form_data.set(phoneInputName, phoneInputValue); 687 } 688 }); 689 } 690 691 let data = latepoint_create_form_data($form, $(this).data('os-action')); 692 693 // var data = { action: 'latepoint_route_call', route_name: $(this).data('os-action'), params: latepoint_formdata_to_url_encoded_string(form_data), return_format: 'json' } 694 $form.find('button[type="submit"]').addClass('os-loading'); 695 $.ajax({ 696 type : "post", 697 dataType : "json", 698 processData: false, 699 contentType: false, 700 url : latepoint_timestamped_ajaxurl(), 701 data : data, 702 success: function(response){ 703 $form.find('button[type="submit"].os-loading').removeClass('os-loading'); 704 latepoint_clear_form_messages($form); 705 if(response.status === "success"){ 706 if($form.data('os-success-action') == 'reload'){ 707 latepoint_add_notification(response.message); 708 location.reload(); 709 return; 710 }else if($form.data('os-success-action') == 'redirect'){ 711 if($form.data('os-redirect-to')){ 712 latepoint_add_notification(response.message); 713 window.location.replace($form.data('os-redirect-to')); 714 }else{ 715 window.location.replace(response.message); 716 } 717 return; 718 }else if($form.data('os-output-target') && $($form.data('os-output-target')).length){ 719 $($form.data('os-output-target')).html(response.message); 720 }else{ 721 if(response.message == 'redirect'){ 722 window.location.replace(response.url); 723 }else{ 724 latepoint_add_notification(response.message); 725 } 726 } 727 if($form.data('os-record-id-holder') && response.record_id){ 728 $form.find('[name="' + $form.data('os-record-id-holder') + '"]').val(response.record_id) 729 } 730 if($form.data('os-after-call')){ 731 732 var func_name = $form.data('os-after-call'); 733 var callback = false;
734 if(func_name.includes('.')){ 735 var func_arr = func_name.split('.'); 736 if(typeof window[func_arr[0]][func_arr[1]] !== 'function'){ 737 console.log(func_name + ' is undefined'); 738 } 739 if($form.data('os-pass-this') && $form.data('os-pass-response')){ 740 window[func_arr[0]][func_arr[1]]($form, response); 741 }else if($form.data('os-pass-this')){ 742 window[func_arr[0]][func_arr[1]]($form); 743 }else if($form.data('os-pass-response')){ 744 window[func_arr[0]][func_arr[1]](response); 745 }else{ 746 window[func_arr[0]][func_arr[1]](); 747 } 748 }else{ 749 if(typeof window[func_name] !== 'function'){ 750 console.log(func_name + ' is undefined'); 751 } 752 if($form.data('os-pass-this') && $form.data('os-pass-response')){ 753 window[func_name]($form, response); 754 }else if($form.data('os-pass-this')){ 755 window[func_name]($form); 756 }else if($form.data('os-pass-response')){ 757 window[func_name](response); 758 }else{ 759 window[func_name](); 760 } 761 } 762 } 763 $('button.os-loading').removeClass('os-loading'); 764 }else{ 765 $('button.os-loading').removeClass('os-loading'); 766 if($form.data('os-show-errors-as-notification')){ 767 latepoint_add_notification(response.message, 'error'); 768 }else{ 769 latepoint_add_notification(response.message, 'error'); 770 $([document.documentElement, document.body]).animate({ 771 scrollTop: ($form.find(".os-form-message-w").offset().top - 30) 772 }, 200); 773 } 774 } 775 if(response.form_values_to_update){ 776 $.each(response.form_values_to_update, function(name, value){ 777 $form.find('[name="'+ name +'"]').val(value); 778 }); 779 } 780 } 781 }); 782 return false; 783 }); 784}); 785 786/* 787 * Copyright (c) 2022 LatePoint LLC. All rights reserved. 788 */ 789 790 791function latepoint_init_order_summary_lightbox() { 792 let $lightbox = jQuery('.customer-dashboard-order-summary-lightbox'); 793 latepoint_init_qr_trigger($lightbox); 794 latepoint_init_item_details_popup($lightbox); 795} 796 797function latepoint_init_qr_trigger($lightbox){ 798 $lightbox.on('click', '.qr-show-trigger', function () { 799 jQuery(this).closest('.summary-box-wrapper').find('.qr-code-on-full-summary').toggleClass('show-vevent-qr-code'); 800 return false; 801 }); 802} 803 804function latepoint_init_item_details_popup($lightbox){ 805 806 $lightbox.on('click', '.os-item-details-popup-close', function () { 807 var $ligthbox = jQuery(this).closest('.latepoint-lightbox-content'); 808 $ligthbox.find('.os-item-details-popup.open').remove(); 809 $ligthbox.find('.full-summary-wrapper').show(); 810 $ligthbox.find('.booking-status-info-wrapper').show(); 811 return false; 812 }); 813 814 $lightbox.on('click', '.os-trigger-item-details-popup', function () { 815 var $ligthbox = jQuery(this).closest('.latepoint-lightbox-content'); 816 $ligthbox.find('.full-summary-wrapper').hide(); 817 $ligthbox.find('.booking-status-info-wrapper').hide(); 818 $ligthbox.find('.os-item-details-popup.open').remove(); 819 var $popup = $ligthbox.find('#' + jQuery(this).data('item-details-popup-id')).clone(); 820 $popup.addClass('open').appendTo($ligthbox); 821 return false; 822 }); 823} 824 825function latepoint_init_bundle_scheduling_summary() { 826 827} 828 829 830function latepoint_manage_by_key_reload_booking() { 831 let $wrapper = jQuery('.manage-booking-wrapper'); 832 $wrapper.addClass('os-loading') 833 let params = { 834 key: $wrapper.data('key') 835 } 836 let data = { 837 action: latepoint_helper.route_action, 838 route_name: $wrapper.data('route-name'), 839 params: params, 840 layout: 'none', 841 return_format: 'json' 842 }; 843 844 jQuery.ajax({ 845 type: "post", 846 dataType: "json", 847 url: latepoint_timestamped_ajaxurl(), 848 data: data, 849 success: function (data) { 850 $wrapper.removeClass('os-loading') 851 if (data.status === "success") { 852 $wrapper.replaceWith(data.message); 853 } else {
854 latepoint_show_message_inside_element(data.message, $wrapper, 'error'); 855 } 856 } 857 }); 858} 859 860function latepoint_init_manage_booking_by_key() { 861 let $wrapper = jQuery('.manage-booking-wrapper'); 862 if (!$wrapper.length) return; 863 jQuery('.latepoint-w').on('change', '.change-booking-status-trigger', function () { 864 $wrapper.addClass('os-loading') 865 let params = { 866 key: $wrapper.data('key'), 867 status: jQuery(this).val() 868 } 869 let data = { 870 action: latepoint_helper.route_action, 871 route_name: jQuery(this).closest('.change-booking-status-trigger-wrapper').data('route-name'), 872 params: params, 873 layout: 'none', 874 return_format: 'json' 875 }; 876 877 jQuery.ajax({ 878 type: "post", 879 dataType: "json", 880 url: latepoint_timestamped_ajaxurl(), 881 data: data, 882 success: function (data) { 883 $wrapper.removeClass('os-loading') 884 if (data.status === "success") { 885 latepoint_manage_by_key_reload_booking(); 886 } else { 887 latepoint_show_message_inside_element(data.message, $wrapper, 'error'); 888 } 889 } 890 }); 891 return false; 892 }); 893 894 895 $wrapper.on('click', '.qr-show-trigger', function () { 896 jQuery(this).closest('.manage-booking-wrapper').find('.qr-code-on-full-summary').addClass('show-vevent-qr-code'); 897 return false; 898 }); 899 $wrapper.on('click', '.os-item-details-popup-close', function () { 900 var $wrapper = jQuery(this).closest('.manage-booking-wrapper'); 901 $wrapper.find('.os-item-details-popup.open').remove(); 902 $wrapper.find('.manage-booking-inner, .manage-booking-controls').show(); 903 return false; 904 }); 905 906 $wrapper.on('click', '.os-trigger-item-details-popup', function () { 907 var $wrapper = jQuery(this).closest('.manage-booking-wrapper'); 908 $wrapper.find('.manage-booking-inner, .manage-booking-controls').hide(); 909 $wrapper.find('.os-item-details-popup.open').remove(); 910 var $popup = $wrapper.find('#' + jQuery(this).data('item-details-popup-id')).clone(); 911 $popup.addClass('open').appendTo($wrapper); 912 return false; 913 }); 914} 915 916function latepoint_init_form_masks() { 917 if (('lp_intlTelInput' in window) && ('lp_intlTelInputGlobals' in window)) { 918 jQuery('.os-mask-phone').each(function () { 919 latepoint_mask_phone(jQuery(this)); 920 }); 921 } 922} 923 924function latepoint_scroll_to_top_of_booking_form($booking_form_element) { 925 // if it's a form shortcode (not lightbox), scroll to top of the form 926 if ($booking_form_element.parent().hasClass('latepoint-inline-form')) { 927 $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 928 } 929 // if lightbox - scroll body of lightbox to top 930 if ($booking_form_element.parent().hasClass('latepoint-lightbox-i')) { 931 $booking_form_element.find('.latepoint-body').scrollTop(0); 932 } 933} 934 935async function latepoint_init_payment_method_actions($booking_form_element, payment_method) {
936 let callbacks_list = []; 937 let is_last_step = $booking_form_element.data('next-submit-is-last') == 'yes'; 938 $booking_form_element.trigger('latepoint:initPaymentMethod', [{ 939 payment_method: payment_method, 940 callbacks_list: callbacks_list, 941 is_last_step: is_last_step 942 }]); 943 $booking_form_element.removeClass('step-content-loaded').addClass('step-content-loading'); 944 945 946 try { 947 for (const callback of callbacks_list) { 948 await callback.action(); 949 } 950 $booking_form_element.removeClass('step-content-loading').addClass('step-content-loaded').find('.lp-payment-method-content[data-payment-method="' + payment_method + '"]').show(); 951 } catch (error) { 952 latepoint_show_error_and_stop_loading_booking_form(error, $booking_form_element); 953 } 954} 955 956function latepoint_lightbox_close() { 957 jQuery('body').removeClass('latepoint-lightbox-active'); 958 jQuery('.latepoint-lightbox-w').remove(); 959} 960 961function latepoint_show_next_btn($booking_form_element) { 962 $booking_form_element.find('.latepoint-next-btn').removeClass('disabled'); 963 $booking_form_element.removeClass('hidden-buttons'); 964} 965 966function clear_step_services($booking_form_element) { 967} 968 969function clear_step_service_extras($booking_form_element) { 970} 971 972function clear_step_locations($booking_form_element) { 973} 974 975function clear_step_agents($booking_form_element) { 976} 977 978function clear_step_datepicker($booking_form_element) { 979} 980 981function latepoint_hide_next_btn($booking_form_element) { 982 $booking_form_element.find('.latepoint-next-btn').addClass('disabled'); 983 if ($booking_form_element.find('.latepoint-prev-btn.disabled').length) $booking_form_element.addClass('hidden-buttons'); 984} 985 986 987function latepoint_show_prev_btn($booking_form_element) { 988 $booking_form_element.find('.latepoint-prev-btn').removeClass('disabled'); 989 $booking_form_element.removeClass('hidden-buttons'); 990} 991 992function latepoint_hide_prev_btn($booking_form_element) { 993 $booking_form_element.find('.latepoint-prev-btn').addClass('disabled'); 994 if ($booking_form_element.find('.latepoint-next-btn.disabled').length) $booking_form_element.addClass('hidden-buttons'); 995} 996 997 998function latepoint_remove_cart_item($trigger) { 999 let $booking_form_element = $trigger.closest('.latepoint-booking-form-element'); 1000 let cart_item_id = $trigger.data('cart-item-id'); 1001 1002 1003 $trigger.addClass('os-loading'); 1004 let data = { 1005 action: latepoint_helper.route_action, 1006 route_name: $trigger.data('route'), 1007 params: jQuery.param({cart_item_id: cart_item_id}), 1008 layout: 'none', 1009 return_format: 'json' 1010 } 1011 jQuery.ajax({ 1012 type: "post", 1013 dataType: "json", 1014 url: latepoint_timestamped_ajaxurl(), 1015 data: data, 1016 success: function (data) { 1017 if (data.status === "success") { 1018 if (cart_item_id != $booking_form_element.find('input[name="active_cart_item[id]"]').val()) { 1019 // cart has other items - just reload the summary/step 1020 if ($trigger.closest('.latepoint-summary-w').length) { 1021 // removed by clicking on summary side panel 1022 latepoint_reload_summary($booking_form_element); 1023 } else { 1024 // remove by clicking on cart item on verify step 1025 latepoint_reload_step($booking_form_element); 1026 } 1027 } else { 1028 // this was a last item, need to go back to the start of a booking process 1029 latepoint_restart_booking_process($booking_form_element); 1030 } 1031 } else { 1032 $trigger.removeClass('os-loading'); 1033 latepoint_show_message_inside_element(data.message, $booking_form_element.find('.latepoint-body'), 'error'); 1034 } 1035 } 1036 }); 1037} 1038 1039function latepoint_apply_coupon($elem) { 1040 var $booking_form_element = $elem.closest('.latepoint-booking-form-element'); 1041 1042 var $coupon_input = $elem; 1043 $coupon_input.closest('.coupon-code-input-w').addClass('os-loading'); 1044 var form_data = new FormData($booking_form_element.find('.latepoint-form')[0]); 1045 var data = { 1046 action: latepoint_helper.route_action, 1047 route_name: $elem.data('route'), 1048 params: latepoint_formdata_to_url_encoded_string(form_data), 1049 layout: 'none', 1050 return_format: 'json' 1051 } 1052 jQuery.ajax({ 1053 type: "post", 1054 dataType: "json", 1055 url: latepoint_timestamped_ajaxurl(), 1056 data: data, 1057 success: function (data) { 1058 $coupon_input.closest('.coupon-code-input-w').removeClass('os-loading'); 1059 if (data.status === "success") {
1060 latepoint_show_message_inside_element(data.message, $booking_form_element.find('.latepoint-body'), 'success'); 1061 $booking_form_element.find('.step-payment-w input[name="cart[payment_method]"]').val(''); 1062 $booking_form_element.find('input[name="cart[payment_token]"]').val(''); 1063 $booking_form_element.find('input[name="cart[payment_portion]"]').val(''); 1064 latepoint_reload_step($booking_form_element); 1065 } else { 1066 latepoint_show_message_inside_element(data.message, $booking_form_element.find('.latepoint-body'), 'error'); 1067 } 1068 } 1069 }); 1070} 1071 1072function latepoint_remove_coupon($elem) { 1073 $elem.closest('.applied-coupon-code-wrapper').fadeOut(); 1074 var $booking_form_element = $elem.closest('.latepoint-booking-form-element'); 1075 let $coupon_input = $booking_form_element.find('input[name="coupon_code"]'); 1076 $coupon_input.val(''); 1077 latepoint_apply_coupon($coupon_input); 1078} 1079 1080function latepoint_restart_booking_process($booking_form_element) { 1081 // first first step 1082 let first_step_code = $booking_form_element.find('.latepoint-step-content').first().data('step-code'); 1083 latepoint_reload_step($booking_form_element, first_step_code); 1084 return false; 1085} 1086 1087function latepoint_reload_step($booking_form_element, step_code = false) { 1088 1089 if (step_code) { 1090 $booking_form_element.find('.latepoint_current_step_code').val(step_code); 1091 $booking_form_element.removeClass(function (index, className) { 1092 return (className.match(/(^|\s)current-step-\S+/g) || []).join(' '); 1093 }).addClass('current-step-' + step_code); 1094 if ($booking_form_element.find('.latepoint-step-content[data-step-code="' + step_code + '"]')) { 1095 $booking_form_element.find('.latepoint-step-content[data-step-code="' + step_code + '"]').nextAll('.latepoint-step-content').remove(); 1096 $booking_form_element.find('.latepoint-step-content[data-step-code="' + step_code + '"]').remove(); 1097 } 1098 } 1099 1100 $booking_form_element.find('.latepoint_step_direction').val('specific'); 1101 latepoint_submit_booking_form($booking_form_element.find('.latepoint-form')); 1102 1103 return false; 1104} 1105 1106 1107function latepoint_reset_password_from_booking_init() { 1108 jQuery('.os-step-existing-customer-login-w').hide(); 1109 jQuery('.os-password-reset-form-holder').on('click', '.password-reset-back-to-login', function () { 1110 jQuery('.os-password-reset-form-holder').html(''); 1111 jQuery('.os-step-existing-customer-login-w').show(); 1112 return false; 1113 }); 1114} 1115 1116function latepoint_bundle_selected($item) { 1117 let $booking_form_element = $item.closest('.latepoint-booking-form-element'); 1118 $booking_form_element.find('input[name="active_cart_item[variant]"]').val('bundle'); 1119 $booking_form_element.find('input[name="booking[service_id]"]').val(''); 1120} 1121 1122function latepoint_service_selected($item) { 1123 let $booking_form_element = $item.closest('.latepoint-booking-form-element'); 1124 $booking_form_element.find('input[name="active_cart_item[variant]"]').val('booking'); 1125} 1126 1127async function latepoint_reload_summary($booking_form_element) { 1128 let $summary_panel = $booking_form_element.closest('.latepoint-with-summary'); 1129 if (!$summary_panel.length) return; 1130 1131 if ($booking_form_element.hasClass('is-bundle-scheduling')) { 1132 return; 1133 } 1134 1135 let current_step = $booking_form_element.find('.latepoint_current_step_code').val(); 1136 1137 $booking_form_element.find('.latepoint-summary-w').addClass('os-loading'); 1138 let $booking_form = $booking_form_element.find('.latepoint-form'); 1139 let form_data = new FormData($booking_form[0]); 1140 let data = { 1141 action: latepoint_helper.route_action, 1142 route_name: latepoint_helper.reload_booking_form_summary_route, 1143 params: latepoint_formdata_to_url_encoded_string(form_data), 1144 layout: 'none', 1145 return_format: 'json' 1146 } 1147 1148 let response = await jQuery.ajax({ 1149 type: "post", 1150 dataType: "json", 1151 url: latepoint_timestamped_ajaxurl(), 1152 data: data 1153 }); 1154 if (response.status === 'success') { 1155 $booking_form_element.find('.os-summary-contents').html(response.message); 1156 $booking_form_element.find('.latepoint-summary-w').removeClass('os-loading'); 1157 // hide on verify and confirmation steps 1158 if (current_step && !['verify', 'confirmation'].includes(current_step) && response.message) { 1159 $summary_panel.addClass('latepoint-summary-is-open'); 1160 } else { 1161 $summary_panel.removeClass('latepoint-summary-is-open'); 1162 } 1163 latepoint_init_booking_summary_panel($booking_form_element); 1164 } else { 1165 throw new Error(response.message ? response.message : 'Error reloading summary'); 1166 } 1167} 1168 1169function latepoint_init_booking_summary_panel($booking_form_element) { 1170 let $summary_panel = $booking_form_element.find('.latepoint-summary-w'); 1171 if (!$summary_panel.length) return; 1172 1173 $summary_panel.find('.price-breakdown-unfold').on('click', function () { 1174 jQuery(this).closest('.summary-price-breakdown-wrapper').removeClass('compact-summary'); 1175 return false;
1176 }); 1177 1178 $summary_panel.find('.os-remove-item-from-cart').on('click keydown', function (event) { 1179 if (event.type === 'keydown' && event.key !== ' ' && event.key !== 'Enter') return; 1180 latepoint_remove_cart_item(jQuery(this)); 1181 return false; 1182 }); 1183} 1184 1185function latepoint_password_changed_show_login(response) { 1186 jQuery('.os-step-existing-customer-login-w').show(); 1187 jQuery('.os-password-reset-form-holder').html(''); 1188 latepoint_show_message_inside_element(response.message, jQuery('.os-step-existing-customer-login-w'), 'success'); 1189} 1190 1191function latepoint_hide_message_inside_element($elem = jQuery('.latepoint-body')) { 1192 if ($elem.length && $elem.find('.latepoint-message').length) { 1193 $elem.find('.latepoint-message').remove(); 1194 } 1195} 1196 1197function latepoint_show_message_inside_element(message, $elem = jQuery('.latepoint-body'), message_type = 'error') { 1198 message = message || 'Error. Please try again.'; 1199 if ($elem.length) { 1200 if ($elem.find('.latepoint-message').length) { 1201 $elem.find('.latepoint-message').removeClass('latepoint-message-success').removeClass('latepoint-message-error').addClass('latepoint-message-' + message_type + '').html(message).show(); 1202 } else { 1203 $elem.prepend('<div class="latepoint-message latepoint-message-' + message_type + '">' + message + '</div>'); 1204 } 1205 // scroll errors into view 1206 if (message_type == 'error') $elem.find('.latepoint-message')[0].scrollIntoView(); 1207 } 1208} 1209 1210function latepoint_add_action(callbacks_list, action, priority = 10) { 1211 callbacks_list.push({priority: priority, action: action}); 1212 callbacks_list.sort((a, b) => a.priority - b.priority); 1213 return callbacks_list; 1214} 1215 1216function latepoint_update_next_btn_label($booking_form_element) { 1217 let btn_label = $booking_form_element.find('.latepoint-step-content').last().data('next-btn-label') 1218 if (btn_label) { 1219 $booking_form_element.find('.latepoint-next-btn span').text(btn_label); 1220 } 1221} 1222 1223function latepoint_init_step(step_code, $booking_form_element) { 1224 latepoint_init_step_selectable_items($booking_form_element); 1225 latepoint_init_step_category_items(step_code); 1226 switch (step_code) { 1227 case 'customer': 1228 latepoint_init_step_contact(); 1229 break; 1230 case 'booking__datepicker': 1231 latepoint_init_step_datepicker($booking_form_element); 1232 break; 1233 case 'booking__agents': 1234 latepoint_init_step_agents(); 1235 break; 1236 case 'booking__locations': 1237 latepoint_init_step_locations(); 1238 break; 1239 case 'booking__services': 1240 latepoint_init_step_services(); 1241 break; 1242 case 'payment__methods': 1243 latepoint_init_step_payment__methods($booking_form_element); 1244 break; 1245 case 'payment__times': 1246 latepoint_init_step_payment__times($booking_form_element); 1247 break; 1248 case 'payment__portions': 1249 latepoint_init_step_payment__portions($booking_form_element); 1250 break; 1251 case 'payment__pay': 1252 latepoint_init_step_payment__pay($booking_form_element); 1253 break; 1254 case 'verify': 1255 latepoint_init_step_verify($booking_form_element); 1256 break; 1257 case 'confirmation': 1258 latepoint_init_step_confirmation($booking_form_element); 1259 break; 1260 } 1261 1262 $booking_form_element.trigger("latepoint:initStep", [{step_code: step_code}]); 1263 $booking_form_element.trigger("latepoint:initStep:" + step_code); 1264} 1265 1266 1267async function latepoint_generate_day_timeslots($day, $wrapper_element = false, $scrollable_wrapper = false) { 1268 if (!$wrapper_element) $wrapper_element = $day.closest('.latepoint-booking-form-element'); 1269 1270 $day.addClass('selected'); 1271 1272 var service_duration = $day.data('service-duration'); 1273 var interval = $day.data('interval'); 1274 var work_start_minutes = $day.data('work-start-time'); 1275 var work_end_minutes = $day.data('work-end-time'); 1276 var total_work_minutes = $day.data('total-work-minutes'); 1277 var bookable_minutes = []; 1278 var available_capacities_of_bookable_minute = []; 1279 if ($day.attr('data-bookable-minutes')) { 1280 if ($day.data('bookable-minutes').toString().indexOf(':') > -1) { 1281 // has capacity information embedded into bookable minutes string 1282 let bookable_minutes_with_capacity = $day.data('bookable-minutes').toString().split(','); 1283 for (let i = 0; i < bookable_minutes_with_capacity.length; i++) { 1284 bookable_minutes.push(parseInt(bookable_minutes_with_capacity[i].split(':')[0])); 1285 available_capacities_of_bookable_minute.push(parseInt(bookable_minutes_with_capacity[i].split(':')[1])); 1286 } 1287 } else { 1288 bookable_minutes = $day.data('bookable-minutes').toString().split(',').map(Number); 1289 } 1290 } 1291 var work_minutes = $day.data('work-minutes').toString().split(',').map(Number); 1292 1293 var $timeslots = $wrapper_element.find('.timeslots'); 1294 $timeslots.html(''); 1295 1296 if (total_work_minutes > 0 && bookable_minutes.length && work_minutes.length) { 1297 var prev_minutes = false;
1298 work_minutes.forEach(function (current_minutes) { 1299 var ampm = latepoint_am_or_pm(current_minutes); 1300 1301 var timeslot_class = 'dp-timepicker-trigger'; 1302 var timeslot_available_capacity = 0; 1303 if (latepoint_helper.time_pick_style == 'timeline') { 1304 timeslot_class += ' dp-timeslot'; 1305 } else { 1306 timeslot_class += ' dp-timebox'; 1307 } 1308 1309 if (prev_minutes !== false && ((current_minutes - prev_minutes) > service_duration)) { 1310 // show interval that is off between two work periods 1311 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); 1312 var off_width = (((current_minutes - prev_minutes - service_duration) / total_work_minutes) * 100); 1313 $timeslots.append('<div class="' + timeslot_class + ' is-off" style="max-width:' + off_width + '%; width:' + off_width + '%"><span class="dp-label">' + off_label + '</span></div>'); 1314 } 1315 1316 if (!bookable_minutes.includes(current_minutes)) { 1317 timeslot_class += ' is-booked'; 1318 } else { 1319 if (available_capacities_of_bookable_minute.length) timeslot_available_capacity = available_capacities_of_bookable_minute[bookable_minutes.indexOf(current_minutes)]; 1320 } 1321 var tick_html = ''; 1322 var capacity_label = ''; 1323 var capacity_label_html = ''; 1324 var capacity_internal_label_html = ''; 1325 1326 if (((current_minutes % 60) == 0) || (interval >= 60)) { 1327 timeslot_class += ' with-tick'; 1328 tick_html = '<span class="dp-tick"><strong>' + latepoint_minutes_to_hours_preferably(current_minutes) + '</strong>' + ' ' + ampm + '</span>'; 1329 } 1330 var timeslot_label = latepoint_minutes_to_hours_and_minutes(current_minutes) + ' ' + ampm; 1331 if (latepoint_show_booking_end_time()) { 1332 var end_minutes = current_minutes + service_duration; 1333 if (end_minutes > 1440) end_minutes = end_minutes - 1440; 1334 var end_minutes_ampm = latepoint_am_or_pm(end_minutes); 1335 timeslot_label += ' - <span class="dp-label-end-time">' + latepoint_minutes_to_hours_and_minutes(end_minutes) + ' ' + end_minutes_ampm + '</span>'; 1336 } 1337 if (timeslot_available_capacity) { 1338 var spaces_message = timeslot_available_capacity > 1 ? latepoint_helper.many_spaces_message : latepoint_helper.single_space_message; 1339 capacity_label = timeslot_available_capacity + ' ' + spaces_message; 1340 capacity_label_html = '<span class="dp-capacity">' + capacity_label + '</span>'; 1341 capacity_internal_label_html = '<span class="dp-label-capacity">' + capacity_label + '</span>'; 1342 } 1343 timeslot_label = timeslot_label.trim(); 1344 $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>'); 1345 prev_minutes = current_minutes; 1346 }); 1347 } else { 1348 // No working hours this day 1349 $timeslots.addClass('slots-not-available').append('<div class="not-working-message">' + latepoint_helper.msg_not_available + "</div>"); 1350 } 1351 jQuery('.times-header-label span').text($day.data('nice-date')); 1352 $wrapper_element.find('.time-selector-w').slideDown(200, function () { 1353 if (!$scrollable_wrapper) $scrollable_wrapper = $wrapper_element.find('.latepoint-body'); 1354 $scrollable_wrapper.stop(); 1355 $wrapper_element.find('.time-selector-w')[0].scrollIntoView({block: "nearest", behavior: 'smooth'}); 1356 }); 1357} 1358 1359 1360function latepoint_recurring_option_clicked(event) { 1361 if (event.type === 'keydown' && event.key !== ' ' && event.key !== 'Enter') return; 1362 let $btn = jQuery(this); 1363 let $booking_form_element = $btn.closest('.latepoint-booking-form-element'); 1364 $booking_form_element.find('.latepoint_is_recurring').val($btn.data('value')); 1365 latepoint_trigger_next_btn($booking_form_element); 1366 $booking_form_element.find('.step-datepicker-w').removeClass('show-recurring-prompt'); 1367 return false;
1368} 1369 1370function latepoint_timeslot_clicked(event) { 1371 if (event.type === 'keydown' && event.key !== ' ' && event.key !== 'Enter') return; 1372 event.preventDefault(); 1373 let $booking_form_element = jQuery(this).closest('.latepoint-booking-form-element'); 1374 let $trigger = jQuery(this); 1375 if ($trigger.hasClass('is-booked') || jQuery(this).hasClass('is-off')) { 1376 // Show error message that you cant select a booked period 1377 } else { 1378 if ($trigger.hasClass('selected')) { 1379 $trigger.removeClass('selected'); 1380 $trigger.find('.dp-success-label').remove(); 1381 $booking_form_element.find('.latepoint_start_time').val(''); 1382 latepoint_hide_next_btn($booking_form_element); 1383 latepoint_reload_summary($booking_form_element); 1384 } else { 1385 $booking_form_element.find('.dp-timepicker-trigger.selected').removeClass('selected').find('.dp-success-label').remove(); 1386 let selected_timeslot_time = $trigger.find('.dp-label-time').html(); 1387 $trigger.addClass('selected').find('.dp-label').prepend('<span class="dp-success-label">' + latepoint_helper.datepicker_timeslot_selected_label + '</span>'); 1388 1389 let start_minutes = parseInt($trigger.data('minutes')); 1390 let start_date = $trigger.closest('.os-dates-and-times-w').find('.os-day.selected').data('date'); 1391 1392 if ($booking_form_element.find('.recurring-bookings-preview-wrapper').length && $booking_form_element.find('.os-recurrence-rules').length) { 1393 // recurring datepicker 1394 if ($booking_form_element.find('.recurring-bookings-preview-wrapper .recurring-booking-preview.is-editing').length) { 1395 // editing one of timeslots, not the recurrence settings 1396 let $recurring_bookings_fields = $booking_form_element.find('.os-recurrence-selection-fields-wrapper'); 1397 let $edited_booking = $booking_form_element.find('.recurring-bookings-preview-wrapper .recurring-booking-preview.is-editing'); 1398 1399 $recurring_bookings_fields.find('input[name="recurrence[overrides][' + $edited_booking.data('stamp') + '][custom_day]"]').val(start_date); 1400 $recurring_bookings_fields.find('input[name="recurrence[overrides][' + $edited_booking.data('stamp') + '][custom_minutes]"]').val(start_minutes); 1401 1402 return window.latepointRecurringBookingsFrontFeature.reload_recurrence_rules($booking_form_element, false); 1403 } else { 1404 // editing recurrence start date/time 1405 $booking_form_element.find('.latepoint_start_date').val(start_date); 1406 $booking_form_element.find('.latepoint_start_time').val(start_minutes); 1407 return window.latepointRecurringBookingsFrontFeature.reload_recurrence_rules($booking_form_element, true); 1408 } 1409 } else { 1410 $booking_form_element.find('.latepoint_start_date').val(start_date); 1411 $booking_form_element.find('.latepoint_start_time').val(start_minutes); 1412 if ($trigger.closest('.os-dates-and-times-w').data('allow-recurring') === 'yes') { 1413 $booking_form_element.find('.step-datepicker-w').addClass('show-recurring-prompt'); 1414 $booking_form_element.find('.os-recurring-suggestion-wrapper')[0].scrollIntoView({block: "nearest", behavior: 'smooth'}); 1415 latepoint_hide_next_btn($booking_form_element); 1416 latepoint_hide_prev_btn($booking_form_element); 1417 } else { 1418 latepoint_trigger_next_btn($booking_form_element); 1419 } 1420 } 1421 } 1422 } 1423 return false; 1424} 1425 1426function latepoint_init_timeslots($booking_form_element = false) { 1427 if (!$booking_form_element) return; 1428 $booking_form_element.off('click', '.dp-timepicker-trigger', latepoint_timeslot_clicked); 1429 $booking_form_element.on('click', '.dp-timepicker-trigger', latepoint_timeslot_clicked); 1430 $booking_form_element.off('keydown', '.dp-timepicker-trigger', latepoint_timeslot_clicked); 1431 $booking_form_element.on('keydown', '.dp-timepicker-trigger', latepoint_timeslot_clicked); 1432 1433 $booking_form_element.off('click', '.os-recurring-suggestion-option', latepoint_recurring_option_clicked); 1434 $booking_form_element.on('click', '.os-recurring-suggestion-option', latepoint_recurring_option_clicked); 1435 $booking_form_element.off('keydown', '.os-recurring-suggestion-option', latepoint_recurring_option_clicked); 1436 $booking_form_element.on('keydown', '.os-recurring-suggestion-option', latepoint_recurring_option_clicked); 1437} 1438 1439async function latepoint_monthly_calendar_load_next_month($booking_form_element) { 1440 try { 1441 1442 if ($booking_form_element.find('.os-monthly-calendar-days-w.active + .os-monthly-calendar-days-w').length) { 1443 $booking_form_element.find('.os-monthly-calendar-days-w.active').removeClass('active').next('.os-monthly-calendar-days-w').addClass('active'); 1444 $booking_form_element.find('.os-month-prev-btn').removeClass('disabled'); 1445 latepoint_calendar_set_month_label($booking_form_element); 1446 return true; 1447 } else { 1448 let $btn = $booking_form_element.find('.os-month-next-btn'); 1449 let next_month_route_name = $btn.data('route'); 1450 $btn.addClass('os-loading'); 1451 let $calendar_element = $booking_form_element.find('.os-monthly-calendar-days-w').last(); 1452 let calendar_year = $calendar_element.data('calendar-year');
1453 let calendar_month = $calendar_element.data('calendar-month'); 1454 if (calendar_month == 12) { 1455 calendar_year = calendar_year + 1; 1456 calendar_month = 1; 1457 } else { 1458 calendar_month = calendar_month + 1; 1459 } 1460 let form_data = new FormData($booking_form_element.find('.latepoint-form')[0]); 1461 form_data.set('target_date_string', `${calendar_year}-${calendar_month}-1`); 1462 let params = latepoint_formdata_to_url_encoded_string(form_data); 1463 let data = { 1464 action: latepoint_helper.route_action, 1465 route_name: next_month_route_name, 1466 params: params, 1467 layout: 'none', 1468 return_format: 'json' 1469 } 1470 let response = await jQuery.ajax({ 1471 type: "post", 1472 dataType: "json", 1473 url: latepoint_timestamped_ajaxurl(), 1474 data: data, 1475 success: function (data) { 1476 } 1477 }); 1478 $btn.removeClass('os-loading'); 1479 if (response.status === "success") { 1480 $booking_form_element.find('.os-months').append(response.message); 1481 $booking_form_element.find('.os-monthly-calendar-days-w.active').removeClass('active').next('.os-monthly-calendar-days-w').addClass('active'); 1482 latepoint_calendar_set_month_label($booking_form_element); 1483 latepoint_calendar_show_or_hide_prev_next_buttons($booking_form_element); 1484 return true; 1485 } else { 1486 console.log(response.message); 1487 return false; 1488 } 1489 1490 } 1491 } catch (e) { 1492 console.log(e); 1493 alert('Error:' + e); 1494 return false; 1495 } 1496} 1497 1498function latepoint_init_monthly_calendar_navigation($booking_form_element = false) { 1499 if (!$booking_form_element) return; 1500 $booking_form_element.find('.os-month-next-btn').on('click', async function () { 1501 let $booking_form_element = jQuery(this).closest('.latepoint-booking-form-element'); 1502 return latepoint_monthly_calendar_load_next_month($booking_form_element); 1503 }); 1504 $booking_form_element.find('.os-month-prev-btn').on('click', function () { 1505 var $booking_form_element = jQuery(this).closest('.latepoint-booking-form-element'); 1506 if ($booking_form_element.find('.os-monthly-calendar-days-w.active').prev('.os-monthly-calendar-days-w').length) { 1507 $booking_form_element.find('.os-monthly-calendar-days-w.active').removeClass('active').prev('.os-monthly-calendar-days-w').addClass('active'); 1508 latepoint_calendar_set_month_label($booking_form_element); 1509 } 1510 latepoint_calendar_show_or_hide_prev_next_buttons($booking_form_element); 1511 return false; 1512 }); 1513} 1514 1515function latepoint_calendar_set_month_label($booking_form_element) { 1516 $booking_form_element.find('.os-current-month-label .current-year').text($booking_form_element.find('.os-monthly-calendar-days-w.active').data('calendar-year')); 1517 $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')); 1518} 1519 1520 1521function latepoint_calendar_show_or_hide_prev_next_buttons($booking_form_element) { 1522 $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')); 1523 $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')); 1524 1525 if ($booking_form_element.find('.os-monthly-calendar-days-w.active').prev('.os-monthly-calendar-days-w').length) { 1526 $booking_form_element.find('.os-month-prev-btn').removeClass('disabled'); 1527 } else { 1528 $booking_form_element.find('.os-month-prev-btn').addClass('disabled'); 1529 } 1530} 1531 1532function latepoint_format_minutes_to_time(minutes, service_duration) { 1533 var ampm = latepoint_am_or_pm(minutes); 1534 var formatted_time = latepoint_minutes_to_hours_and_minutes(minutes) + ' ' + ampm; 1535 if (latepoint_show_booking_end_time()) { 1536 var end_minutes = minutes + service_duration; 1537 var end_minutes_ampm = latepoint_am_or_pm(end_minutes); 1538 formatted_time += ' - ' + latepoint_minutes_to_hours_and_minutes(end_minutes) + ' ' + end_minutes_ampm; 1539 } 1540 formatted_time = formatted_time.trim(); 1541 return formatted_time; 1542} 1543 1544function latepoint_monthly_calendar_day_clicked(event) { 1545 if (event.type === 'keydown' && event.key !== ' ' && event.key !== 'Enter') return; 1546 let $day = jQuery(this); 1547 if ($day.hasClass('os-day-passed')) return false;
1548 if ($day.hasClass('os-not-in-allowed-period')) return false; 1549 if($day.closest('.os-dates-and-times-w').hasClass('calendar-style-modern')) { 1550 if ($day.hasClass('os-month-prev')) return false; 1551 if ($day.hasClass('os-month-next')) return false; 1552 } 1553 var $booking_form_element = jQuery(this).closest('.latepoint-booking-form-element'); 1554 if ($day.closest('.os-recurrence-datepicker-wrapper').length) { 1555 // recurrent datepicker 1556 $day.closest('.os-recurrence-datepicker-wrapper').find('.os-day.selected').removeClass('selected'); 1557 $day.addClass('selected'); 1558 if ($day.closest('.os-dates-and-times-w').hasClass('days-only')) { 1559 $day.closest('.step-recurring-bookings-w').find('input[name="recurrence[rules][repeat_end_date]"]').val($day.data('date')); 1560 window.latepointRecurringBookingsFrontFeature.reload_recurrence_rules($booking_form_element, true); 1561 } else { 1562 latepoint_generate_day_timeslots($day); 1563 $day.closest('.os-recurrence-datepicker-wrapper').find('.time-selector-w')[0].scrollIntoView({block: "nearest", behavior: 'smooth'}); 1564 } 1565 } else { 1566 // regular datepicker 1567 if ($day.closest('.os-monthly-calendar-days-w').hasClass('hide-if-single-slot')) { 1568 // HIDE TIMESLOT IF ONLY ONE TIMEPOINT 1569 if ($day.hasClass('os-not-available')) { 1570 // clicked on a day that has no available timeslots 1571 // do nothing 1572 } else { 1573 $booking_form_element.find('.os-day.selected').removeClass('selected'); 1574 $day.addClass('selected'); 1575 // set date 1576 $booking_form_element.find('.latepoint_start_date').val($day.data('date')); 1577 if ($day.hasClass('os-one-slot-only')) { 1578 // clicked on a day that has only one slot available 1579 var bookable_minutes = $day.data('bookable-minutes').toString().split(':')[0]; 1580 var selected_timeslot_time = latepoint_format_minutes_to_time(Number(bookable_minutes), Number($day.data('service-duration'))); 1581 $booking_form_element.find('.latepoint_start_time').val($day.data('bookable-minutes')); 1582 latepoint_show_next_btn($booking_form_element); 1583 $booking_form_element.find('.time-selector-w').slideUp(200); 1584 } else { 1585 // regular day with more than 1 timeslots available 1586 // build timeslots 1587 latepoint_generate_day_timeslots($day); 1588 // clear time and hide next btn 1589 $booking_form_element.find('.latepoint_start_time').val(''); 1590 latepoint_hide_next_btn($booking_form_element); 1591 } 1592 latepoint_reload_summary($booking_form_element); 1593 } 1594 } else { 1595 1596 // SHOW TIMESLOTS EVEN IF ONLY ONE TIMEPOINT 1597 $booking_form_element.find('.latepoint_start_date').val($day.data('date')); 1598 $booking_form_element.find('.os-day.selected').removeClass('selected'); 1599 $day.addClass('selected'); 1600 1601 // build timeslots 1602 latepoint_generate_day_timeslots($day); 1603 // clear time and hide next btn 1604 latepoint_reload_summary($booking_form_element); 1605 $booking_form_element.find('.latepoint_start_time').val(''); 1606 latepoint_hide_next_btn($booking_form_element); 1607 } 1608 } 1609 1610 1611 return false; 1612} 1613 1614async function latepoint_init_step_datepicker($booking_form_element = false) { 1615 if (!$booking_form_element) return true; 1616 latepoint_init_timeslots($booking_form_element); 1617 latepoint_init_monthly_calendar_navigation($booking_form_element); 1618 $booking_form_element.off('click', '.os-months .os-day', latepoint_monthly_calendar_day_clicked); 1619 $booking_form_element.on('click', '.os-months .os-day', latepoint_monthly_calendar_day_clicked); 1620 $booking_form_element.off('keydown', '.os-months .os-day', latepoint_monthly_calendar_day_clicked); 1621 $booking_form_element.on('keydown', '.os-months .os-day', latepoint_monthly_calendar_day_clicked); 1622 1623 if ($booking_form_element.find('input[name="booking[start_date]"]').val()) { 1624 $booking_form_element.find('.os-day[data-date="' + $booking_form_element.find('input[name="booking[start_date]"]').val() + '"]').trigger('click'); 1625 } else { 1626 if($booking_form_element.find('.os-dates-and-times-w').hasClass('auto-search')){ 1627 let max_number_of_months_to_check = 24; 1628 let current_year = new Date().getFullYear(); 1629 for (let i = 0; i < max_number_of_months_to_check; i++) {
1630 let $active_month = $booking_form_element.find('.os-monthly-calendar-days-w.active'); 1631 let searching_month_label = $active_month.data('calendar-month-label'); 1632 if ($active_month.data('calendar-year') != current_year) searching_month_label += ' ' + $active_month.data('calendar-year'); 1633 $booking_form_element.find('.os-calendar-searching-info span').text(searching_month_label); 1634 // check if active month has any days available for booking 1635 let $first_available = $active_month.find('.os-day').not('.os-not-available').first(); 1636 if ($first_available.length) { 1637 break; 1638 } else { 1639 await latepoint_monthly_calendar_load_next_month($booking_form_element); 1640 } 1641 } 1642 } 1643 } 1644 $booking_form_element.find('.os-dates-and-times-w').removeClass('is-searching'); 1645 return true; 1646} 1647 1648 1649function latepoint_init_step_verify($booking_form_element = false) { 1650 if (!$booking_form_element) return; 1651 $booking_form_element.closest('.latepoint-summary-is-open').removeClass('latepoint-summary-is-open'); 1652 1653 $booking_form_element.find('.coupon-code-wrapper-on-verify .coupon-code-trigger-on-verify-w a').on('click', function (e) { 1654 jQuery(this).closest('.coupon-code-wrapper-on-verify').addClass('entering-coupon').find('.coupon-code-input').trigger('focus'); 1655 return false; 1656 }); 1657 $booking_form_element.find('.coupon-code-wrapper-on-verify .coupon-code-input-cancel').on('click', function (e) { 1658 jQuery(this).closest('.coupon-code-wrapper-on-verify').removeClass('entering-coupon'); 1659 return false; 1660 }); 1661 1662 $booking_form_element.find('.coupon-code-wrapper-on-verify .coupon-code-input-submit').on('click', function (e) { 1663 latepoint_apply_coupon(jQuery(this).closest('.coupon-code-input-w').find('.coupon-code-input')); 1664 return false; 1665 }); 1666 1667 $booking_form_element.find('.os-remove-item-from-cart').on('click keydown', function (event) { 1668 if (event.type === 'keydown' && event.key !== ' ' && event.key !== 'Enter') return; 1669 //make sure to clear active cart item so it doesn't add it again on reload! 1670 if (confirm(jQuery(this).data('confirm-text'))) { 1671 latepoint_remove_cart_item(jQuery(this)); 1672 } 1673 return false; 1674 }); 1675 1676 $booking_form_element.find('.coupon-code-wrapper-on-verify .coupon-code-clear').on('click', function (e) { 1677 latepoint_remove_coupon(jQuery(this)); 1678 return false; 1679 }); 1680 1681 $booking_form_element.find('.coupon-code-wrapper-on-verify input.coupon-code-input').on('keyup', function (e) { 1682 if (e.which === 13) { 1683 latepoint_apply_coupon(jQuery(this)); 1684 return false; 1685 } 1686 }); 1687} 1688 1689 1690function latepoint_init_step_payment__pay($booking_form_element = false) { 1691 var selected_payment_method = $booking_form_element.find('input[name="cart[payment_method]"]').val(); 1692 latepoint_init_payment_method_actions($booking_form_element, selected_payment_method); 1693} 1694 1695function latepoint_init_step_payment__portions($booking_form_element = false) { 1696 // Selecting Payment Time 1697 $booking_form_element.find('.lp-payment-trigger-payment-portion-selector').on('click keydown', function (event) { 1698 if (event.type === 'keydown' && event.key !== ' ' && event.key !== 'Enter') return; 1699 var $booking_form_element = jQuery(this).closest('.latepoint-booking-form-element'); 1700 $booking_form_element.find('input[name="' + jQuery(this).data('holder') + '"]').val(jQuery(this).data('value')); 1701 latepoint_show_prev_btn($booking_form_element); 1702 latepoint_trigger_next_btn($booking_form_element); 1703 return false; 1704 }); 1705} 1706 1707function latepoint_init_step_payment__times($booking_form_element = false) { 1708 // Selecting Payment Time 1709 $booking_form_element.find('.lp-payment-trigger-payment-time-selector').on('click keydown', function (event) { 1710 if (event.type === 'keydown' && event.key !== ' ' && event.key !== 'Enter') return; 1711 var $booking_form_element = jQuery(this).closest('.latepoint-booking-form-element'); 1712 $booking_form_element.find('input[name="' + jQuery(this).data('holder') + '"]').val(jQuery(this).data('value')); 1713 latepoint_show_prev_btn($booking_form_element); 1714 latepoint_trigger_next_btn($booking_form_element); 1715 return false;
1716 }); 1717} 1718 1719 1720function latepoint_init_step_payment__methods($booking_form_element = false) { 1721 // Selecting Payment Time 1722 $booking_form_element.find('.lp-payment-trigger-payment-method-selector').on('click', function (e) { 1723 var $booking_form_element = jQuery(this).closest('.latepoint-booking-form-element'); 1724 $booking_form_element.find('input[name="' + jQuery(this).data('holder') + '"]').val(jQuery(this).data('value')); 1725 latepoint_show_prev_btn($booking_form_element); 1726 latepoint_trigger_next_btn($booking_form_element); 1727 return false; 1728 }); 1729} 1730 1731function latepoint_category_item_clicked(event) { 1732 if (event.type === 'keydown' && event.key !== ' ' && event.key !== 'Enter') return; 1733 let $item = jQuery(event.target); 1734 1735 let $booking_form_element = $item.closest('.latepoint-booking-form-element'); 1736 latepoint_show_prev_btn($booking_form_element); 1737 $item.closest('.latepoint-step-content').addClass('selecting-item-category'); 1738 let $category_wrapper = $item.closest('.os-item-category-w'); 1739 let $main_parent = $item.closest('.os-item-categories-main-parent'); 1740 if ($category_wrapper.hasClass('selected')) { 1741 $category_wrapper.removeClass('selected'); 1742 if ($category_wrapper.parent().closest('.os-item-category-w').length) { 1743 $category_wrapper.parent().closest('.os-item-category-w').addClass('selected'); 1744 } else { 1745 $main_parent.removeClass('show-selected-only'); 1746 } 1747 } else { 1748 $main_parent.find('.os-item-category-w.selected').removeClass('selected'); 1749 $main_parent.addClass('show-selected-only'); 1750 $category_wrapper.addClass('selected'); 1751 } 1752 return false; 1753} 1754 1755function latepoint_init_step_category_items(step_code) { 1756 let $category_items = jQuery('.latepoint-step-content[data-step-code="' + step_code + '"] .os-item-category-info'); 1757 $category_items.on('click', latepoint_category_item_clicked); 1758 $category_items.on('keydown', latepoint_category_item_clicked); 1759} 1760 1761 1762function latepoint_init_step_selectable_items($booking_form_element) { 1763 $booking_form_element.off('click', '.os-selectable-items .os-selectable-item', latepoint_selectable_item_clicked); 1764 $booking_form_element.on('click', '.os-selectable-items .os-selectable-item', latepoint_selectable_item_clicked); 1765 1766 $booking_form_element.off('click', '.os-selectable-items .os-selectable-item .item-quantity-selector-input', latepoint_selectable_item_quantity_keyup); 1767 $booking_form_element.on('click', '.os-selectable-items .os-selectable-item .item-quantity-selector-input', latepoint_selectable_item_quantity_keyup); 1768 1769 1770 $booking_form_element.off('keydown', '.os-selectable-items .os-selectable-item', latepoint_selectable_item_clicked); 1771 $booking_form_element.on('keydown', '.os-selectable-items .os-selectable-item', latepoint_selectable_item_clicked); 1772} 1773 1774 1775function latepoint_update_quantity_for_selectable_items($item) { 1776 var ids = $item.closest('.os-selectable-items') 1777 .find('.os-selectable-item.selected') 1778 .map(function () { 1779 if (jQuery(this).hasClass('has-quantity')) { 1780 return jQuery(this).data('item-id') + ':' + jQuery(this).find('input.item-quantity-selector-input').val(); 1781 } else { 1782 return jQuery(this).data('item-id'); 1783 } 1784 }).get(); 1785 $item.closest('.latepoint-booking-form-element').find($item.data('id-holder')).val(ids); 1786} 1787 1788function latepoint_selectable_item_quantity_keyup(event) { 1789 var $booking_form_element = jQuery(this).closest('.latepoint-booking-form-element'); 1790 var $item = jQuery(this).closest('.os-selectable-item'); 1791 var new_value = jQuery(this).val(); 1792 if (new_value && new_value.match(/^\d+$/)) { 1793 var max_quantity = $item.data('max-quantity'); 1794 if (max_quantity && (new_value > max_quantity)) new_value = max_quantity; 1795 } else { 1796 new_value = 0; 1797 } 1798 jQuery(this).val(new_value); 1799 1800 if (($item.hasClass('selected') && (new_value > 0)) || (!$item.hasClass('selected') && (new_value == 0))) { 1801 latepoint_update_quantity_for_selectable_items($item); 1802 latepoint_reload_summary($booking_form_element); 1803 return false;
1804 } else { 1805 $item.trigger('click'); 1806 } 1807} 1808 1809function latepoint_selectable_item_clicked(event) { 1810 if (event.type === 'keydown' && event.key !== ' ' && event.key !== 'Enter') return; 1811 event.stopPropagation(); 1812 event.stopImmediatePropagation(); 1813 var $booking_form_element = jQuery(this).closest('.latepoint-booking-form-element'); 1814 if (jQuery(this).hasClass('has-quantity')) { 1815 if (jQuery(event.target).hasClass('item-quantity-selector')) { 1816 var current_value = parseInt(jQuery(this).find('input.item-quantity-selector-input').val()); 1817 var new_value = (jQuery(event.target).data('sign') == 'minus') ? current_value - 1 : current_value + 1; 1818 var max_quantity = jQuery(this).data('max-quantity'); 1819 if (new_value < 0) new_value = 0; 1820 if (max_quantity && (new_value > max_quantity)) new_value = max_quantity; 1821 jQuery(this).find('input.item-quantity-selector-input').val(new_value); 1822 if ((jQuery(this).hasClass('selected') && (new_value > 0)) || (!jQuery(this).hasClass('selected') && (new_value == 0))) { 1823 latepoint_update_quantity_for_selectable_items(jQuery(this)); 1824 latepoint_reload_summary($booking_form_element); 1825 return false; 1826 } 1827 } 1828 if (jQuery(event.target).hasClass('item-quantity-selector-input')) { 1829 latepoint_update_quantity_for_selectable_items(jQuery(this)); 1830 latepoint_reload_summary($booking_form_element); 1831 return false; 1832 } 1833 } 1834 var summary_value = ''; 1835 if (jQuery(this).hasClass('os-allow-multiselect')) { 1836 if (jQuery(this).hasClass('selected')) { 1837 jQuery(this).removeClass('selected'); 1838 if (jQuery(this).hasClass('has-quantity')) jQuery(this).find('input.item-quantity-selector-input').val(0); 1839 } else { 1840 jQuery(this).addClass('selected'); 1841 if (jQuery(this).hasClass('has-quantity') && !(jQuery(this).find('input.item-quantity-selector-input').val() > 0)) { 1842 jQuery(this).find('input.item-quantity-selector-input').val(1); 1843 } 1844 } 1845 latepoint_update_quantity_for_selectable_items(jQuery(this)); 1846 latepoint_reload_summary($booking_form_element); 1847 latepoint_show_next_btn($booking_form_element); 1848 } else { 1849 if (!jQuery(this).hasClass('os-duration-item')) jQuery(this).closest('.os-item-categories-main-parent').find('.os-selectable-item.selected').removeClass('selected'); 1850 jQuery(this).closest('.os-selectable-items').find('.os-selectable-item.selected').removeClass('selected'); 1851 jQuery(this).addClass('selected'); 1852 $booking_form_element.find(jQuery(this).data('id-holder')).val(jQuery(this).data('item-id')); 1853 if (jQuery(this).data('cart-item-item-data-key')) { 1854 latepoint_update_active_cart_item_item_data($booking_form_element, jQuery(this).data('cart-item-item-data-key'), jQuery(this).data('item-id')); 1855 } 1856 if (jQuery(this).data('os-call-func')) { 1857 window[jQuery(this).data('os-call-func')](jQuery(this)); 1858 } 1859 if (jQuery(this).data('activate-sub-step')) { 1860 window[jQuery(this).data('activate-sub-step')](jQuery(this)); 1861 } else { 1862 latepoint_trigger_next_btn($booking_form_element); 1863 } 1864 } 1865 return false; 1866} 1867 1868function latepoint_update_active_cart_item_item_data($booking_form_element, key, value) { 1869 let item_data_json = $booking_form_element.find('input[name="active_cart_item[item_data]"]').val(); 1870 let item_data = item_data_json ? JSON.parse($booking_form_element.find('input[name="active_cart_item[item_data]"]').val()) : {}; 1871 item_data[key] = value; 1872 $booking_form_element.find('input[name="active_cart_item[item_data]"]').val(JSON.stringify(item_data)); 1873} 1874 1875function latepoint_format_price(price) { 1876 // replace default decimal separator dot with comma if it's in settings 1877 if (latepoint_helper.decimal_separator == ',') price = String(price).replace('.', ','); 1878 return latepoint_helper.currency_symbol_before + String(price) + latepoint_helper.currency_symbol_after; 1879} 1880 1881 1882function latepoint_init_step_services() { 1883} 1884 1885 1886function latepoint_trigger_next_btn($booking_form_element) { 1887 $booking_form_element.find('.latepoint_step_direction').val('next'); 1888 latepoint_submit_booking_form($booking_form_element.find('.latepoint-form')); 1889} 1890 1891function latepoint_init_step_locations() { 1892} 1893 1894function latepoint_init_agent_details_link($booking_form_element) { 1895 $booking_form_element.on('click', '.os-trigger-item-details-popup', function () { 1896 $booking_form_element.find('.os-item-details-popup.open').remove(); 1897 var $popup = $booking_form_element.find('#' + jQuery(this).data('item-details-popup-id')).first().clone().attr('id', ''); 1898 $booking_form_element.find('.latepoint-form-w').addClass('showing-item-details-popup'); 1899 $popup.addClass('open').appendTo($booking_form_element.find('.latepoint-body')); 1900 return false;
1901 }); 1902 $booking_form_element.on('click', '.os-item-details-popup.open .os-item-details-popup-close', function () { 1903 $booking_form_element.find('.latepoint-form-w').removeClass('showing-item-details-popup'); 1904 jQuery(this).closest('.os-item-details-popup.open').remove(); 1905 return false; 1906 }); 1907} 1908 1909function latepoint_init_step_agents() { 1910} 1911 1912 1913function latepoint_init_booking_summary_lightbox() { 1914 let $lightbox = jQuery('.customer-dashboard-booking-summary-lightbox'); 1915 latepoint_init_qr_trigger($lightbox); 1916 latepoint_init_item_details_popup($lightbox); 1917} 1918 1919function latepoint_init_step_confirmation($booking_form_element = false) { 1920 if (!$booking_form_element) return; 1921 $booking_form_element.on('click', '.set-customer-password-btn', function () { 1922 var $btn = jQuery(this); 1923 var $booking_form_element = jQuery(this).closest('.latepoint-booking-form-element'); 1924 1925 $btn.addClass('os-loading'); 1926 var params = { 1927 account_nonse: jQuery('input[name="account_nonse"]').val(), 1928 password: jQuery('input[name="customer[password]"]').val(), 1929 password_confirmation: jQuery('input[name="customer[password_confirmation]"]').val() 1930 } 1931 var data = { 1932 action: latepoint_helper.route_action, 1933 route_name: jQuery(this).data('btn-action'), 1934 params: jQuery.param(params), 1935 layout: 'none', 1936 return_format: 'json' 1937 } 1938 jQuery.ajax({ 1939 type: "post", 1940 dataType: "json", 1941 url: latepoint_timestamped_ajaxurl(), 1942 data: data, 1943 success: function (data) { 1944 $btn.removeClass('os-loading'); 1945 if (data.status === "success") { 1946 $booking_form_element.find('.step-confirmation-set-password').html('').hide(); 1947 $booking_form_element.find('.confirmation-cabinet-info').show(); 1948 } else { 1949 latepoint_show_message_inside_element(data.message, $booking_form_element.find('.step-confirmation-set-password'), 'error'); 1950 } 1951 } 1952 }); 1953 return false; 1954 }); 1955 1956 $booking_form_element.on('click', '.qr-show-trigger', function () { 1957 var $booking_form_element = jQuery(this).closest('.latepoint-booking-form-element'); 1958 $booking_form_element.find('.qr-code-on-full-summary').addClass('show-vevent-qr-code'); 1959 return false; 1960 }); 1961 1962 $booking_form_element.on('click', '.show-set-password-fields', function () { 1963 var $booking_form_element = jQuery(this).closest('.latepoint-booking-form-element'); 1964 1965 $booking_form_element.find('.step-confirmation-set-password').show(); 1966 $booking_form_element.find('#customer_password').trigger('focus'); 1967 jQuery(this).closest('.info-box').hide(); 1968 return false; 1969 }); 1970} 1971 1972function latepoint_init_customer_dashboard() { 1973 latepoint_init_form_masks(); 1974 jQuery('.latepoint-customer-timezone-selector-w select').on('change', function (e) { 1975 var $select_box = jQuery(this); 1976 $select_box.closest('.latepoint-customer-timezone-selector-w').addClass('os-loading'); 1977 var data = { 1978 action: latepoint_helper.route_action, 1979 route_name: jQuery(this).closest('.latepoint-customer-timezone-selector-w').data('route-name'), 1980 params: {timezone_name: jQuery(this).val()}, 1981 layout: 'none', 1982 return_format: 'json' 1983 } 1984 jQuery.ajax({ 1985 type: "post", 1986 dataType: "json", 1987 url: latepoint_timestamped_ajaxurl(), 1988 data: data, 1989 success: function (data) { 1990 $select_box.closest('.latepoint-customer-timezone-selector-w').removeClass('os-loading'); 1991 if (data.status === "success") { 1992 location.reload(); 1993 } else { 1994 1995 } 1996 } 1997 }); 1998 }); 1999 2000 2001 jQuery('.latepoint-request-booking-cancellation').on('click', function () { 2002 if (!confirm(latepoint_helper.cancel_booking_prompt)) return false;
2003 var $this = jQuery(this); 2004 var $booking_box = $this.closest('.customer-booking'); 2005 2006 var route = jQuery(this).data('route'); 2007 var params = {id: $booking_box.data('id')}; 2008 2009 var data = { 2010 action: latepoint_helper.route_action, 2011 route_name: route, 2012 params: params, 2013 layout: 'none', 2014 return_format: 'json' 2015 } 2016 $this.addClass('os-loading'); 2017 jQuery.ajax({ 2018 type: "post", 2019 dataType: "json", 2020 url: latepoint_timestamped_ajaxurl(), 2021 data: data, 2022 success: function (data) { 2023 if (data.status === "success") { 2024 $this.remove(); 2025 location.reload(); 2026 } else { 2027 $this.removeClass('os-loading'); 2028 } 2029 } 2030 }); 2031 return false; 2032 }); 2033 2034} 2035 2036 2037function get_customer_name($wrapper) { 2038 var customer_name = ''; 2039 var first_name = $wrapper.find('input[name="customer[first_name]"]').val(); 2040 var last_name = $wrapper.find('input[name="customer[last_name]"]').val(); 2041 if (first_name) customer_name += first_name; 2042 if (last_name) customer_name += ' ' + last_name; 2043 return customer_name.trim(); 2044} 2045 2046function latepoint_init_step_contact() { 2047 latepoint_init_form_masks(); 2048 2049 // Init Logout button 2050 jQuery('.step-customer-logout-btn').on('click', function () { 2051 var $booking_form_element = jQuery(this).closest('.latepoint-booking-form-element'); 2052 var data = { 2053 action: latepoint_helper.route_action, 2054 route_name: jQuery(this).data('btn-action'), 2055 layout: 'none', 2056 return_format: 'json' 2057 } 2058 latepoint_step_content_change_start($booking_form_element); 2059 jQuery.ajax({ 2060 type: "post", 2061 dataType: "json", 2062 url: latepoint_timestamped_ajaxurl(), 2063 data: data, 2064 success: function (data) { 2065 latepoint_reload_step($booking_form_element); 2066 } 2067 }); 2068 return false; 2069 }); 2070 2071 // Init Login Existing Customer Button 2072 jQuery('.step-login-existing-customer-btn').on('click', function () { 2073 var $booking_form_element = jQuery(this).closest('.latepoint-booking-form-element'); 2074 var params = { 2075 email: $booking_form_element.find('.os-step-existing-customer-login-w input[name="customer_login[email]"]').val(), 2076 password: $booking_form_element.find('.os-step-existing-customer-login-w input[name="customer_login[password]"]').val() 2077 } 2078 var data = { 2079 action: latepoint_helper.route_action, 2080 route_name: jQuery(this).data('btn-action'), 2081 params: jQuery.param(params), 2082 layout: 'none', 2083 return_format: 'json' 2084 } 2085 latepoint_step_content_change_start($booking_form_element); 2086 jQuery.ajax({ 2087 type: "post", 2088 dataType: "json", 2089 url: latepoint_timestamped_ajaxurl(), 2090 data: data, 2091 success: function (data) { 2092 if (data.status === "success") { 2093 latepoint_reload_step($booking_form_element); 2094 } else { 2095 latepoint_show_message_inside_element(data.message, $booking_form_element.find('.os-step-existing-customer-login-w')); 2096 latepoint_step_content_change_end(false, $booking_form_element); 2097 } 2098 } 2099 }); 2100 return false; 2101 }); 2102} 2103 2104function latepoint_step_content_change_start($booking_form_element) { 2105 $booking_form_element.removeClass('step-content-loaded').addClass('step-content-loading'); 2106} 2107 2108// TODO 2109function latepoint_step_content_change_end(new_content, $booking_form_element) { 2110 if (new_content) $booking_form_element.find('.latepoint-body .latepoint-step-content').replaceWith(new_content); 2111 $booking_form_element.removeClass('step-content-loading').addClass('step-content-mid-loading'); 2112 setTimeout(function () { 2113 $booking_form_element.removeClass('step-content-mid-loading').addClass('step-content-loaded'); 2114 }, 50); 2115} 2116 2117 2118function latepoint_change_step_desc($booking_form_element, step_code) { 2119 $booking_form_element.removeClass('step-changed').addClass('step-changing'); 2120 setTimeout(function () { 2121 // Progress bar 2122 var $step_progress = $booking_form_element.find('.latepoint-progress li[data-step-code="' + step_code + '"]'); 2123 $step_progress.addClass('active').addClass('complete').prevAll().addClass('complete').removeClass('active'); 2124 $step_progress.nextAll().removeClass('complete').removeClass('active'); 2125 // Side panel 2126 var side_panel_desc = $booking_form_element.find('.latepoint-step-desc-library[data-step-code="' + step_code + '"]').html(); 2127 $booking_form_element.find('.latepoint-step-desc').html(side_panel_desc); 2128 2129 // Top header 2130 var top_header_desc = $booking_form_element.find('.os-heading-text-library[data-step-code="' + step_code + '"]').html(); 2131 $booking_form_element.find('.os-heading-text').html(top_header_desc); 2132 setTimeout(function () { 2133 $booking_form_element.removeClass('step-changing').addClass('step-changed'); 2134 }, 50); 2135 }, 500); 2136} 2137 2138 2139function latepoint_progress_prev($booking_form_element, step_code) { 2140 var $step_progress = $booking_form_element.find('.latepoint-progress li[data-step-code="' + step_code + '"]'); 2141 $step_progress.addClass('active').addClass('complete').prevAll().addClass('complete').removeClass('active'); 2142 $step_progress.nextAll().removeClass('complete').removeClass('active'); 2143} 2144 2145 2146function latepoint_progress_next($booking_form_element, step_code) { 2147 var $step_progress = $booking_form_element.find('.latepoint-progress li[data-step-code="' + step_code + '"]'); 2148 $step_progress.addClass('active').addClass('complete').prevAll().addClass('complete').removeClass('active'); 2149 $step_progress.nextAll().removeClass('complete').removeClass('active'); 2150} 2151 2152 2153function latepoint_next_step_description($booking_form_element, step_code) { 2154 $booking_form_element.removeClass('step-changed').addClass('step-changing'); 2155 setTimeout(function () { 2156 $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()); 2157 $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()); 2158 setTimeout(function () { 2159 $booking_form_element.removeClass('step-changing').addClass('step-changed'); 2160 }, 50); 2161 }, 500); 2162} 2163 2164function latepoint_prev_step_description($booking_form_element, step_code) { 2165 $booking_form_element.removeClass('step-changed').addClass('step-changing'); 2166 setTimeout(function () { 2167 $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()); 2168 $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()); 2169 setTimeout(function () { 2170 $booking_form_element.removeClass('step-changing').addClass('step-changed'); 2171 }, 50); 2172 }, 500); 2173} 2174 2175 2176function latepoint_validate_fields($fields) { 2177 var is_valid = true; 2178 $fields.each(function (index) { 2179 if (jQuery(this).val() == '') { 2180 is_valid = false;
2181 return false; 2182 } 2183 }); 2184 return is_valid; 2185} 2186 2187 2188async function latepoint_submit_booking_form($booking_form) { 2189 let $booking_form_element = $booking_form.closest('.latepoint-booking-form-element'); 2190 2191 let current_step = $booking_form_element.find('.latepoint_current_step_code').val(); 2192 let callbacks_list = []; 2193 if (latepoint_check_if_booking_form_is_final_submit($booking_form_element)) { 2194 // check if order intent is still bookable 2195 latepoint_add_action(callbacks_list, async () => { 2196 return await latepoint_check_if_order_intent_still_bookable($booking_form_element); 2197 }, 1); 2198 } 2199 $booking_form_element.trigger('latepoint:submitBookingForm', [{ 2200 current_step: current_step, 2201 callbacks_list: callbacks_list, 2202 is_final_submit: latepoint_check_if_booking_form_is_final_submit($booking_form_element), 2203 direction: $booking_form_element.find('.latepoint_step_direction').val() 2204 }]); 2205 try { 2206 latepoint_hide_prev_btn($booking_form_element); 2207 await latepoint_process_list_of_callbacks(callbacks_list, $booking_form_element, $booking_form); 2208 } catch (error) { 2209 latepoint_show_prev_btn($booking_form_element); 2210 latepoint_show_error_and_stop_loading_booking_form(error, $booking_form_element); 2211 return false; 2212 } 2213 2214 2215 $booking_form_element.removeClass('step-content-loaded').addClass('step-content-loading'); 2216 latepoint_hide_prev_btn($booking_form_element); 2217 try { 2218 latepoint_hide_message_inside_element($booking_form_element.find('.latepoint-body')); 2219 let response = await jQuery.ajax({ 2220 type: "post", 2221 dataType: "json", 2222 processData: false, 2223 contentType: false, 2224 url: latepoint_timestamped_ajaxurl(), 2225 data: latepoint_create_form_data($booking_form) 2226 }); 2227 2228 $booking_form.find('.latepoint_step_direction').val('next'); 2229 if (response.status === 'success') { 2230 if (response.fields_to_update) { 2231 for (const [key, value] of Object.entries(response.fields_to_update)) { 2232 $booking_form_element.find('input[name="' + key + '"]').val(value) 2233 } 2234 } 2235 if ($booking_form_element.data('flash-error')) { 2236 latepoint_show_message_inside_element($booking_form_element.data('flash-error'), $booking_form_element.find('.latepoint-body')); 2237 $booking_form_element.data('flash-error', ''); 2238 } 2239 $booking_form_element.find('.latepoint_current_step_code').val(response.step_code); 2240 $booking_form_element.removeClass(function (index, className) { 2241 return (className.match(/(^|\s)current-step-\S+/g) || []).join(' '); 2242 }).addClass('current-step-' + response.step_code); 2243 setTimeout(function () { 2244 $booking_form_element.removeClass('step-content-loading').addClass('step-content-mid-loading'); 2245 $booking_form_element.find('.latepoint-body').find('.latepoint-step-content').addClass('is-hidden'); 2246 if ($booking_form_element.find('.latepoint-step-content[data-step-code="' + response.step_code + '"]')) { 2247 $booking_form_element.find('.latepoint-step-content[data-step-code="' + response.step_code + '"]').remove(); 2248 } 2249 $booking_form_element.find('.latepoint-body').append(response.message); 2250 2251 2252 latepoint_update_next_btn_label($booking_form_element); 2253 latepoint_init_step(response.step_code, $booking_form_element); 2254 setTimeout(function () { 2255 $booking_form_element.removeClass('step-content-mid-loading').addClass('step-content-loaded'); 2256 $booking_form_element.find('.latepoint-next-btn, .latepoint-prev-btn').removeClass('os-loading'); 2257 latepoint_scroll_to_top_of_booking_form($booking_form_element); 2258 }, 50); 2259 }, 500); 2260 2261 if (response.is_pre_last_step) { 2262 $booking_form_element.data('next-submit-is-last', 'yes'); 2263 } else { 2264 $booking_form_element.data('next-submit-is-last', 'no'); 2265 } 2266 if (response.is_last_step) { 2267 $booking_form_element.addClass('hidden-buttons').find('.latepoint-footer').remove(); 2268 $booking_form_element.find('.latepoint-progress').css('opacity', 0); 2269 $booking_form_element.closest('.latepoint-summary-is-open').removeClass('latepoint-summary-is-open'); 2270 $booking_form_element.closest('.latepoint-show-side-panel').removeClass('latepoint-show-side-panel').addClass('latepoint-hide-side-panel'); 2271 $booking_form_element.addClass('is-final-step'); 2272 } else { 2273 if (response.show_next_btn === true) { 2274 latepoint_show_next_btn($booking_form_element); 2275 } else { 2276 latepoint_hide_next_btn($booking_form_element); 2277 } 2278 if (response.show_prev_btn === true) { 2279 latepoint_show_prev_btn($booking_form_element); 2280 } else { 2281 latepoint_hide_prev_btn($booking_form_element); 2282 } 2283 } 2284 latepoint_change_step_desc($booking_form_element, response.step_code); 2285 latepoint_reload_summary($booking_form_element); 2286 } else { 2287 if (response.send_to_step && response.send_to_step === 'resubmit') { 2288 let current_resubmit_count = parseInt($booking_form.data('resubmit-count')) ? parseInt($booking_form.data('resubmit-count')) : 1; 2289 $booking_form.data('resubmit-count', current_resubmit_count + 1); 2290 if (current_resubmit_count > 6) {
2291 latepoint_show_message_inside_element(response.message, $booking_form_element.find('.latepoint-body')); 2292 } else { 2293 // resubmission probably caused by order intent still being processed, since 2294 // order intent is still processing, give it a little more time and try again 2295 await latepoint_sleep(2000); 2296 return latepoint_submit_booking_form($booking_form); 2297 } 2298 } else { 2299 $booking_form_element.removeClass('step-content-loading').addClass('step-content-loaded'); 2300 $booking_form_element.find('.latepoint-next-btn, .latepoint-prev-btn').removeClass('os-loading'); 2301 if (response.send_to_step && $booking_form_element.find('.latepoint-step-content[data-step-code="' + response.send_to_step + '"]').length) { 2302 $booking_form_element.data('flash-error', response.message); 2303 latepoint_reload_step($booking_form_element, response.send_to_step); 2304 } else { 2305 latepoint_show_message_inside_element(response.message, $booking_form_element.find('.latepoint-body')); 2306 latepoint_show_prev_btn($booking_form_element); 2307 } 2308 } 2309 } 2310 } catch (e) { 2311 console.log(e); 2312 alert('Error:' + e); 2313 } 2314} 2315 2316function latepoint_sleep(ms) { 2317 return new Promise(resolve => setTimeout(resolve, ms)); 2318} 2319 2320function latepoint_show_error_and_stop_loading_booking_form(error, $booking_form_element) { 2321 if (error.send_to_step && $booking_form_element.find('.latepoint-step-content[data-step-code="' + error.send_to_step + '"]').length) { 2322 latepoint_reload_step($booking_form_element, error.send_to_step); 2323 $booking_form_element.data('flash-error', error.message); 2324 } else { 2325 latepoint_show_message_inside_element(error.message, $booking_form_element.find('.latepoint-body'), 'error'); 2326 2327 if ($booking_form_element.hasClass('step-content-loading')) $booking_form_element.removeClass('step-content-loading').addClass('step-content-loaded'); 2328 $booking_form_element.find('.latepoint-next-btn').removeClass('os-loading'); 2329 2330 // if previous step exists - show prev button 2331 if ($booking_form_element.find('.latepoint-step-content:last-child').prev('.latepoint-step-content').length) latepoint_show_prev_btn($booking_form_element); 2332 latepoint_scroll_to_top_of_booking_form($booking_form_element); 2333 } 2334} 2335 2336function latepoint_reset_active_cart_item($booking_form_element) { 2337 $booking_form_element.find('input[name="active_cart_item[id]"]').val(''); 2338 $booking_form_element.find('input[name="active_cart_item[variant]"]').val(''); 2339 $booking_form_element.find('input[name="active_cart_item[item_data]"]').val(''); 2340} 2341 2342function latepoint_check_if_booking_form_is_final_submit($booking_form_element) { 2343 return ($booking_form_element.data('next-submit-is-last') == 'yes'); 2344} 2345 2346 2347async function latepoint_check_if_order_intent_still_bookable($booking_form_element) { 2348 let response = await jQuery.ajax({ 2349 type: "post", 2350 dataType: "json", 2351 processData: false, 2352 contentType: false, 2353 url: latepoint_timestamped_ajaxurl(), 2354 data: latepoint_create_form_data($booking_form_element.find('.latepoint-form'), latepoint_helper.check_order_intent_bookable_route) 2355 }); 2356 if (response.status === 'success') { 2357 return true; 2358 } else { 2359 throw new Error(response.message); 2360 } 2361} 2362 2363async function latepoint_process_list_of_callbacks(callbacks, $booking_form_element, $booking_form) { 2364 for (const callback of callbacks) { 2365 await callback.action(); 2366 } 2367} 2368 2369function latepoint_clear_presets($booking_form_element) { 2370 $booking_form_element.find('.clear_for_new_item').val(''); 2371} 2372 2373function latepoint_init_booking_form($booking_form_element) { 2374 $booking_form_element.on('click keydown', '.checkout-from-summary-panel-btn', function (event) { 2375 if (event.type === 'keydown' && event.key !== ' ' && event.key !== 'Enter') return; 2376 latepoint_reload_step($booking_form_element, jQuery(this).data('step')); 2377 jQuery(this).closest('.latepoint-w').removeClass('show-summary-on-mobile'); 2378 return false;
2379 }); 2380 2381 $booking_form_element.on('click keydown', '.latepoint-add-another-item-trigger', function (event) { 2382 if(event.type === 'keydown' && event.key !== ' ' && event.key !== 'Enter') return; 2383 2384 if (latepoint_helper.reset_presets_when_adding_new_item){ 2385 latepoint_clear_presets($booking_form_element); 2386 } 2387 latepoint_reset_active_cart_item($booking_form_element); 2388 latepoint_reload_step($booking_form_element, jQuery(this).data('step')); 2389 return false; 2390 }); 2391 $booking_form_element.find('.latepoint-form').on('submit', function (e) { 2392 e.preventDefault(); 2393 let $booking_form = jQuery(this); 2394 latepoint_submit_booking_form($booking_form); 2395 }); 2396 2397 latepoint_init_booking_summary_panel($booking_form_element); 2398 2399 $booking_form_element.on('click keydown', '.latepoint-lightbox-summary-trigger', function (event) { 2400 event.preventDefault(); 2401 if (event.type === 'keydown' && event.key !== ' ' && event.key !== 'Enter') return; 2402 let $wrapper = jQuery(this).closest('.latepoint-w'); 2403 $wrapper.toggleClass('show-summary-on-mobile'); 2404 return false; 2405 }); 2406 2407 $booking_form_element.find('.latepoint-lightbox-close').on('click', function () { 2408 2409 let params = new URLSearchParams(location.search); 2410 if (params.has('latepoint_order_intent_key')) { 2411 params.delete('latepoint_order_intent_key'); 2412 history.replaceState(null, '', '?' + params + location.hash); 2413 } 2414 2415 jQuery('body').removeClass('latepoint-lightbox-active'); 2416 jQuery('.latepoint-lightbox-w').remove(); 2417 return false; 2418 }); 2419 2420 2421 $booking_form_element.on('click keydown', '.lp-option', function (event) { 2422 if (event.type === 'keydown' && event.key !== ' ' && event.key !== 'Enter') return; 2423 jQuery(this).closest('.lp-options').find('.lp-option.selected').removeClass('selected'); 2424 jQuery(this).addClass('selected'); 2425 }); 2426 2427 2428 // Next Step button Click 2429 $booking_form_element.find('.latepoint-next-btn').on('click', async function (e) { 2430 e.preventDefault(); 2431 if (jQuery(this).hasClass('disabled') || jQuery(this).hasClass('os-loading')) return false; 2432 var $next_btn = jQuery(this); 2433 $next_btn.addClass('os-loading'); 2434 var $booking_form = jQuery(this).closest('.latepoint-form'); 2435 2436 var current_step = $booking_form_element.find('.latepoint_current_step_code').val(); 2437 2438 $booking_form.find('.latepoint_step_direction').val('next'); 2439 var callbacks_list = []; 2440 2441 $booking_form_element.trigger('latepoint:nextStepClicked', [{ 2442 current_step: current_step, 2443 callbacks_list: callbacks_list 2444 }]); 2445 latepoint_hide_prev_btn($booking_form_element); 2446 2447 try { 2448 await latepoint_process_list_of_callbacks(callbacks_list, $booking_form_element, $booking_form); 2449 await latepoint_submit_booking_form($booking_form); 2450 } catch (error) { 2451 latepoint_show_error_and_stop_loading_booking_form(error, $booking_form_element); 2452 } 2453 return false; 2454 }); 2455 2456 2457 // Previous Step button Click 2458 $booking_form_element.find('.latepoint-prev-btn').on('click', function (e) { 2459 if (jQuery(this).hasClass('disabled') || jQuery(this).hasClass('os-loading')) return false; 2460 2461 let $current_step = $booking_form_element.find('.latepoint-step-content:last-child'); 2462 2463 2464 // handle categories 2465 if ($current_step.hasClass('selecting-item-category')) { 2466 if ($current_step.find('.os-item-category-w .os-item-category-w.selected').length) { 2467 $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'); 2468 } else { 2469 $current_step.removeClass('selecting-item-category').find('.os-item-category-w.selected').removeClass('selected'); 2470 $current_step.removeClass('selecting-item-category').find('.os-item-categories-holder.show-selected-only').removeClass('show-selected-only'); 2471 } 2472 if (($booking_form_element.find('.latepoint-step-content').length <= 1) && !$current_step.hasClass('selecting-item-category')) { 2473 latepoint_hide_prev_btn($booking_form_element); 2474 } 2475 latepoint_reload_summary($booking_form_element); 2476 return false;
2477 } 2478 2479 if ($current_step.data('clear-action')) { 2480 window[$current_step.data('clear-action')]($booking_form_element); 2481 } 2482 2483 let $back_btn = jQuery(this); 2484 $back_btn.addClass('os-loading'); 2485 $booking_form_element.removeClass('step-content-loaded').addClass('step-content-loading'); 2486 let $new_current_step = $booking_form_element.find('.latepoint-step-content.is-hidden').last(); 2487 let new_current_step_code = $new_current_step.data('step-code'); 2488 let current_step_code = $current_step.data('step-code'); 2489 2490 2491 let current_parent_code_name = current_step_code.split('__')[0]; 2492 let new_parent_code_name = new_current_step_code.split('__')[0]; 2493 2494 let active_cart_item_id = $booking_form_element.find('input[name="active_cart_item[id]"]').val(); 2495 2496 latepoint_change_step_desc($booking_form_element, new_current_step_code); 2497 setTimeout(function () { 2498 $new_current_step.removeClass('is-hidden'); 2499 $current_step.remove(); 2500 $booking_form_element.find('.latepoint_current_step_code').val(new_current_step_code); 2501 $booking_form_element.removeClass(function (index, className) { 2502 return (className.match(/(^|\s)current-step-\S+/g) || []).join(' '); 2503 }).addClass('current-step-' + new_current_step_code); 2504 $booking_form_element.find('.latepoint-next-btn span').text($booking_form_element.find('.latepoint-next-btn').data('label')); 2505 $booking_form_element.data('next-submit-is-last', 'no'); 2506 2507 latepoint_update_next_btn_label($booking_form_element); 2508 latepoint_show_next_btn($booking_form_element); 2509 $back_btn.removeClass('os-loading'); 2510 if ($booking_form_element.find('.latepoint-step-content').length <= 1) { 2511 if ($new_current_step.hasClass('selecting-item-category')) { 2512 2513 } 2514 if (new_current_step_code == 'booking__services') { 2515 var $services_step = $booking_form_element.find('.step-services-w'); 2516 if ($services_step.hasClass('selecting-item-category')) { 2517 if ($services_step.find('.os-services > .os-item.selected').hasClass('is-preselected')) { 2518 // if service is preselected check if there are both multiple durations and quantity selector and only then show prev button 2519 } else { 2520 latepoint_show_prev_btn($booking_form_element); 2521 } 2522 } else { 2523 latepoint_hide_prev_btn($booking_form_element); 2524 } 2525 } else { 2526 if (!$new_current_step.hasClass('selecting-item-category')) { 2527 latepoint_hide_prev_btn($booking_form_element); 2528 } 2529 } 2530 } 2531 $booking_form_element.removeClass('step-content-loading').addClass('step-content-mid-loading'); 2532 2533 2534 if (new_parent_code_name == 'booking' && current_parent_code_name != 'booking' && active_cart_item_id) { 2535 2536 // 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 2537 $booking_form_element.find('.latepoint-summary-w').addClass('os-loading'); 2538 let data = { 2539 action: latepoint_helper.route_action, 2540 route_name: latepoint_helper.remove_cart_item_route, 2541 params: jQuery.param({cart_item_id: active_cart_item_id}), 2542 layout: 'none', 2543 return_format: 'json' 2544 } 2545 jQuery.ajax({ 2546 type: "post", 2547 dataType: "json", 2548 url: latepoint_timestamped_ajaxurl(), 2549 data: data, 2550 success: function (data) { 2551 if (data.status === "success") { 2552 $booking_form_element.find('input[name="active_cart_item[id]"]').val(''); 2553 if ($booking_form_element.find('input[name="active_cart_item[variant]"]').val() == 'bundle') { 2554 latepoint_update_active_cart_item_item_data($booking_form_element, 'bundle_id', ''); 2555 $booking_form_element.find('input[name="active_cart_item[variant]"]').val(''); 2556 } 2557 latepoint_reload_summary($booking_form_element); 2558 } else { 2559 $booking_form_element.find('.latepoint-summary-w').removeClass('os-loading'); 2560 latepoint_show_message_inside_element
2560(data.message, $booking_form_element.find('.latepoint-body'), 'error'); 2561 } 2562 } 2563 }); 2564 } else { 2565 latepoint_reload_summary($booking_form_element); 2566 } 2567 setTimeout(function () { 2568 $booking_form_element.removeClass('step-content-mid-loading').addClass('step-content-loaded'); 2569 latepoint_hide_message_inside_element($booking_form_element.find('.latepoint-body')); 2570 latepoint_scroll_to_top_of_booking_form($booking_form_element); 2571 }, 150); 2572 }, 700); 2573 return false; 2574 }); 2575 2576 latepoint_init_agent_details_link($booking_form_element); 2577 $booking_form_element.trigger('latepoint:initBookingForm'); 2578} 2579 2580 2581function latepoint_init_booking_form_by_trigger($trigger) { 2582 let route = latepoint_helper.booking_button_route; 2583 let params = {}; 2584 let restrictions = {}; 2585 let presets = {}; 2586 let booking_element_styles = {}; 2587 if ($trigger.data('show-service-categories')) restrictions.show_service_categories = $trigger.data('show-service-categories'); 2588 if ($trigger.data('show-locations')) restrictions.show_locations = $trigger.data('show-locations'); 2589 if ($trigger.data('show-services')) restrictions.show_services = $trigger.data('show-services'); 2590 if ($trigger.data('show-agents')) restrictions.show_agents = $trigger.data('show-agents'); 2591 if ($trigger.data('calendar-start-date')) restrictions.calendar_start_date = $trigger.data('calendar-start-date'); 2592 2593 if ($trigger.data('selected-location')) presets.selected_location = $trigger.data('selected-location'); 2594 if ($trigger.data('selected-agent')) presets.selected_agent = $trigger.data('selected-agent'); 2595 if ($trigger.data('selected-service')) presets.selected_service = $trigger.data('selected-service'); 2596 if ($trigger.data('selected-bundle')) presets.selected_bundle = $trigger.data('selected-bundle'); 2597 if ($trigger.data('selected-duration')) presets.selected_duration = $trigger.data('selected-duration'); 2598 if ($trigger.data('selected-total-attendees')) presets.selected_total_attendees = $trigger.data('selected-total-attendees'); 2599 if ($trigger.data('selected-service-category')) presets.selected_service_category = $trigger.data('selected-service-category'); 2600 if ($trigger.data('selected-start-date')) presets.selected_start_date = $trigger.data('selected-start-date'); 2601 if ($trigger.data('selected-start-time')) presets.selected_start_time = $trigger.data('selected-start-time'); 2602 if ($trigger.data('order-item-id')) presets.order_item_id = $trigger.data('order-item-id'); 2603 if ($trigger.data('source-id')) presets.source_id = $trigger.data('source-id'); 2604 2605 if ($trigger.data('hide-summary') == 'yes') booking_element_styles.hide_summary = true; 2606 if ($trigger.data('hide-side-panel') == 'yes') booking_element_styles.hide_side_panel = true; 2607 2608 2609 if (jQuery.isEmptyObject(restrictions) == false) params.restrictions = restrictions; 2610 if (jQuery.isEmptyObject(presets) == false) params.presets = presets; 2611 if (jQuery.isEmptyObject(booking_element_styles) == false) params.booking_element_styles = booking_element_styles; 2612 2613 let data = { 2614 action: latepoint_helper.route_action, 2615 route_name: route, 2616 params: params, 2617 layout: 'none', 2618 return_format: 'json' 2619 } 2620 2621 let is_inline_form = $trigger.hasClass('latepoint-book-form-wrapper'); 2622 if (is_inline_form) { 2623 data.params.booking_element_type = 'inline_form'; 2624 } 2625 2626 $trigger.addClass('os-loading'); 2627 jQuery.ajax({ 2628 type: "post", 2629 dataType: "json", 2630 url: latepoint_timestamped_ajaxurl(), 2631 data: data, 2632 success: (data) => { 2633 if (data.status === "success") { 2634 let $booking_form_element = false; 2635 if (is_inline_form) { 2636 $trigger.html(data.message); 2637 $booking_form_element = $trigger.find('.latepoint-booking-form-element'); 2638 } else { 2639 let lightbox_class = 'booking-form-in-lightbox'; 2640 latepoint_show_data_in_lightbox(data.message, lightbox_class, false); 2641 $booking_form_element = jQuery('.latepoint-lightbox-w .latepoint-booking-form-element'); 2642 jQuery('body').addClass('latepoint-lightbox-active'); 2643 } 2644 latepoint_init_booking_form($booking_form_element); 2645 latepoint_init_step(data.step, $booking_form_element); 2646 $trigger.removeClass('os-loading'); 2647 } else { 2648 $trigger.removeClass('os-loading'); 2649 // console.log(data.message); 2650 } 2651 } 2652 }); 2653} 2654 2655 2656/* 2657 * Copyright (c) 2023 LatePoint LLC. All rights reserved. 2658 */ 2659 2660async function latepoint_init_transaction_payment_form() {
2661 let callbacks_list = []; 2662 let $transaction_payment_form = jQuery('.latepoint-transaction-payment-form'); 2663 let current_step = $transaction_payment_form.find('input[name="current_step"]').val(); 2664 2665 $transaction_payment_form.on('click keydown', '.lp-option', (e) => { 2666 let $option = jQuery(e.currentTarget); 2667 if(e.type === 'keydown' && e.key !== ' ' && e.key !== 'Enter') return; 2668 $option.closest('.lp-options').find('.lp-option.selected').removeClass('selected'); 2669 $option.addClass('selected'); 2670 $transaction_payment_form.find('input[name="' + $option.data('holder') + '"]').val($option.data('value')); 2671 $transaction_payment_form.trigger('submit'); 2672 return false; 2673 }); 2674 2675 2676 switch (current_step) { 2677 case 'methods': 2678 break; 2679 case 'processors': 2680 break; 2681 case 'pay': 2682 $transaction_payment_form.trigger('latepoint:initOrderPaymentMethod', [{ 2683 callbacks_list: callbacks_list, 2684 payment_method: $transaction_payment_form.find('input[name="payment_method"]').val(), 2685 payment_processor: $transaction_payment_form.find('input[name="payment_processor"]').val(), 2686 }]); 2687 $transaction_payment_form.addClass('os-loading'); 2688 2689 try { 2690 for (const callback of callbacks_list) { 2691 await callback.action(); 2692 } 2693 $transaction_payment_form.removeClass('os-loading'); 2694 } catch (error) { 2695 latepoint_show_error_and_stop_loading_booking_form(error, $transaction_payment_form); 2696 } 2697 break; 2698 case 'confirmation': 2699 break; 2700 } 2701 2702 $transaction_payment_form.on('submit', async function (e) { 2703 e.preventDefault(); 2704 await latepoint_submit_transaction_payment_form(jQuery(e.target)); 2705 }); 2706} 2707 2708async function latepoint_submit_transaction_payment_form($transaction_payment_form) { 2709 2710 if($transaction_payment_form.hasClass('os-loading')) return false; 2711 let callbacks_list = []; 2712 2713 $transaction_payment_form.find('.latepoint-message').remove(); 2714 $transaction_payment_form.addClass('os-loading'); 2715 $transaction_payment_form.find('.latepoint-btn').addClass('os-loading'); 2716 2717 $transaction_payment_form.trigger('latepoint:submitTransactionPaymentForm', [{ 2718 callbacks_list: callbacks_list, 2719 payment_method: $transaction_payment_form.find('input[name="payment_method"]').val(), 2720 payment_processor: $transaction_payment_form.find('input[name="payment_processor"]').val(), 2721 current_step: $transaction_payment_form.find('input[name="current_step"]').val(), 2722 }]); 2723 2724 try { 2725 for (const callback of callbacks_list) { 2726 await callback.action(); 2727 } 2728 } catch (error) { 2729 $transaction_payment_form.removeClass('os-loading').find('.os-loading').removeClass('os-loading'); 2730 latepoint_show_message_inside_element(error.message, $transaction_payment_form.find('.lp-payment-method-content'), 'error'); 2731 return false; 2732 } 2733 2734 2735 try { 2736 let response = await jQuery.ajax({ 2737 type: "post", 2738 dataType: "json", 2739 processData: false, 2740 contentType: false, 2741 url: latepoint_timestamped_ajaxurl(), 2742 data: latepoint_create_form_data($transaction_payment_form, latepoint_helper.invoices_payment_form_route) 2743 }); 2744 2745 $transaction_payment_form.removeClass('os-loading').find('.os-loading').removeClass('os-loading'); 2746 2747 if (response.status === 'success') { 2748 $transaction_payment_form.html(response.message); 2749 return await latepoint_init_transaction_payment_form(); 2750 2751 } else { 2752 latepoint_show_message_inside_element(response.message, $transaction_payment_form.find('.lp-payment-method-content'), 'error'); 2753 return false; 2754 } 2755 } catch (e) { 2756 2757 $transaction_payment_form.removeClass('os-loading').find('.os-loading').removeClass('os-loading'); 2758 console.log(e); 2759 alert('Error:' + e); 2760 } 2761 2762} 2763 2764function latepoint_hide_reschedule_button() { 2765 jQuery('.reschedule-confirmation-button-wrapper').hide(); 2766} 2767 2768function latepoint_show_reschedule_button() { 2769 jQuery('.reschedule-confirmation-button-wrapper').show(); 2770} 2771 2772function latepoint_customer_cabinet_reload_booking_tile($booking_tile) { 2773 $booking_tile.addClass('os-loading'); 2774 let params = { 2775 booking_id: $booking_tile.data('id'), 2776 } 2777 let data = { 2778 action: latepoint_helper.route_action, 2779 route_name: $booking_tile.data('route-name'), 2780 params: params, 2781 layout: 'none', 2782 return_format: 'json' 2783 }; 2784 jQuery.ajax({ 2785 type: "post", 2786 dataType: "json", 2787 url: latepoint_timestamped_ajaxurl(), 2788 data: data, 2789 success: function (data) { 2790 $booking_tile.removeClass('os-loading') 2791 if (data.status === "success") { 2792 $booking_tile.replaceWith(data.message); 2793 } else { 2794 alert(data.message); 2795 } 2796 } 2797 }); 2798} 2799 2800// show invoices -> summary_before_payment in modal 2801function show_summary_before_payment($access_key) { 2802 let data = { 2803 action: latepoint_helper.route_action, 2804 route_name: latepoint_helper.invoices_summary_before_payment_route, 2805 params: {key: $access_key}, 2806 layout: 'none', 2807 return_format: 'json' 2808 } 2809 2810 jQuery.ajax({ 2811 type: "post", 2812 dataType: "json", 2813 url: latepoint_timestamped_ajaxurl(), 2814 data: data, 2815 success: function (data) { 2816 latepoint_show_data_in_lightbox(data.message, 'width-500'); 2817 } 2818 }); 2819} 2820 2821function latepoint_reload_reschedule_calendar($reschedule_calendar_wrapper) { 2822 $reschedule_calendar_wrapper.addClass('os-loading'); 2823 let $calendar_element = $reschedule_calendar_wrapper.find('.os-monthly-calendar-days-w.active').last();
2824 let calendar_year = $calendar_element.data('calendar-year'); 2825 let calendar_month = $calendar_element.data('calendar-month'); 2826 2827 let data = { 2828 action: latepoint_helper.route_action, 2829 route_name: $reschedule_calendar_wrapper.data('route'), 2830 params: { 2831 timezone_name: $reschedule_calendar_wrapper.find('input[type="hidden"].latepoint_timezone_name').val(), 2832 key: $reschedule_calendar_wrapper.find('input[type="hidden"].latepoint_manage_booking_key').val(), 2833 target_date_string: `${calendar_year}-${calendar_month}-1`, 2834 booking_id: $reschedule_calendar_wrapper.find('input[type="hidden"].latepoint_booking_id').val() 2835 }, 2836 layout: 'none', 2837 return_format: 'json' 2838 } 2839 jQuery.ajax({ 2840 type: "post", 2841 dataType: "json", 2842 url: latepoint_timestamped_ajaxurl(), 2843 data: data, 2844 success: function (data) { 2845 $reschedule_calendar_wrapper.removeClass('os-loading'); 2846 if (data.status === "success") { 2847 jQuery('.latepoint-lightbox-i').html(data.message); 2848 } else { 2849 // console.log(data.message); 2850 } 2851 } 2852 }); 2853 latepoint_calendar_show_or_hide_prev_next_buttons($reschedule_calendar_wrapper); 2854 return false; 2855} 2856 2857function latepoint_init_reschedule() { 2858 2859 let $reschedule_wrapper = jQuery('.reschedule-calendar-wrapper'); 2860 2861 latepoint_init_timezone_picker($reschedule_wrapper); 2862 2863 $reschedule_wrapper.on('click', '.latepoint-request-reschedule-trigger', function () { 2864 let $trigger = jQuery(this) 2865 let $wrapper = $trigger.closest('.reschedule-calendar-wrapper') 2866 let booking_id = $wrapper.find('input[type="hidden"].latepoint_booking_id').val() 2867 2868 $trigger.addClass('os-loading') 2869 let params = { 2870 booking_id: booking_id, 2871 key: $wrapper.find('input[type="hidden"].latepoint_manage_booking_key').val(), 2872 start_date: $wrapper.find('input[type="hidden"].latepoint_start_date').val(), 2873 start_time: $wrapper.find('input[type="hidden"].latepoint_start_time').val(), 2874 timezone_name: $wrapper.find('input[type="hidden"].latepoint_timezone_name').val(), 2875 } 2876 let data = { 2877 action: latepoint_helper.route_action, 2878 route_name: $trigger.data('route-name'), 2879 params: params, 2880 layout: 'none', 2881 return_format: 'json' 2882 }; 2883 jQuery.ajax({ 2884 type: "post", 2885 dataType: "json", 2886 url: latepoint_timestamped_ajaxurl(), 2887 data: data, 2888 success: function (data) { 2889 $trigger.removeClass('os-loading') 2890 if (data.status === "success") { 2891 jQuery('.latepoint-lightbox-content').html(data.message); 2892 jQuery('.latepoint-lightbox-footer, .latepoint-lightbox-heading').remove(); 2893 if (jQuery('.customer-bookings-tiles').length) { 2894 // called from customer cabinet 2895 latepoint_customer_cabinet_reload_booking_tile(jQuery('.customer-bookings-tiles .customer-booking[data-id="' + booking_id + '"]')); 2896 } else { 2897 // called from manage by key 2898 latepoint_manage_by_key_reload_booking(); 2899 } 2900 } else { 2901 latepoint_show_message_inside_element(data.message, jQuery('.latepoint-lightbox-content'), 'error'); 2902 jQuery('.latepoint-lightbox-content').animate({scrollTop: 0}, 300); 2903 } 2904 } 2905 }); 2906 return false; 2907 }); 2908 2909 $reschedule_wrapper.on('click keydown', '.dp-timepicker-trigger', function (event) { 2910 if (event.type === 'keydown' && event.key !== ' ' && event.key !== 'Enter') return; 2911 var $reschedule_calendar_wrapper = jQuery(this).closest('.reschedule-calendar-wrapper'); 2912 if (jQuery(this).hasClass('is-booked') || jQuery(this).hasClass('is-off')) { 2913 // Show error message that you cant select a booked period 2914 } else { 2915 if (jQuery(this).hasClass('selected')) { 2916 jQuery(this).removeClass('selected'); 2917 jQuery(this).find('.dp-success-label').remove(); 2918 $reschedule_calendar_wrapper.find('.latepoint_start_time').val(''); 2919 latepoint_hide_reschedule_button(); 2920 } else { 2921 $reschedule_calendar_wrapper.find('.dp-timepicker-trigger.selected').removeClass('selected').find('.dp-success-label').remove(); 2922 var selected_timeslot_time = jQuery(this).find('.dp-label-time').html(); 2923 jQuery(this).addClass('selected').find('.dp-label').prepend('<span class="dp-success-label">' + latepoint_helper.datepicker_timeslot_selected_label + '</span>'); 2924
2925 var minutes = parseInt(jQuery(this).data('minutes')); 2926 var start_date = new Date($reschedule_calendar_wrapper.find('.os-day.selected').data('date')); 2927 2928 $reschedule_calendar_wrapper.find('.latepoint_start_date').val(start_date.toISOString().split('T')[0]) 2929 $reschedule_calendar_wrapper.find('.latepoint_start_time').val(minutes); 2930 latepoint_show_reschedule_button(); 2931 } 2932 } 2933 return false; 2934 }); 2935 2936 2937 $reschedule_wrapper.on('click', '.os-month-next-btn', function () { 2938 var $reschedule_calendar_wrapper = jQuery(this).closest('.reschedule-calendar-wrapper'); 2939 var next_month_route_name = jQuery(this).data('route'); 2940 if ($reschedule_calendar_wrapper.find('.os-monthly-calendar-days-w.active + .os-monthly-calendar-days-w').length) { 2941 $reschedule_calendar_wrapper.find('.os-monthly-calendar-days-w.active').removeClass('active').next('.os-monthly-calendar-days-w').addClass('active'); 2942 latepoint_calendar_set_month_label($reschedule_calendar_wrapper); 2943 } else { 2944 // TODO add condition to check maximum number months to call into the future 2945 if (true) { 2946 var $btn = jQuery(this); 2947 $btn.addClass('os-loading'); 2948 var $calendar_element = $reschedule_calendar_wrapper.find('.os-monthly-calendar-days-w').last(); 2949 var calendar_year = $calendar_element.data('calendar-year'); 2950 var calendar_month = $calendar_element.data('calendar-month'); 2951 if (calendar_month == 12) { 2952 calendar_year = calendar_year + 1; 2953 calendar_month = 1; 2954 } else { 2955 calendar_month = calendar_month + 1; 2956 } 2957 var data = { 2958 action: latepoint_helper.route_action, 2959 route_name: next_month_route_name, 2960 params: { 2961 timezone_name: $reschedule_calendar_wrapper.find('input[type="hidden"].latepoint_timezone_name').val(), 2962 key: $reschedule_calendar_wrapper.find('input[type="hidden"].latepoint_manage_booking_key').val(), 2963 target_date_string: `${calendar_year}-${calendar_month}-1`, 2964 booking: { 2965 id: $reschedule_calendar_wrapper.find('input[type="hidden"].latepoint_booking_id').val() 2966 } 2967 }, 2968 layout: 'none', 2969 return_format: 'json' 2970 } 2971 jQuery.ajax({ 2972 type: "post", 2973 dataType: "json", 2974 url: latepoint_timestamped_ajaxurl(), 2975 data: data, 2976 success: function (data) { 2977 $btn.removeClass('os-loading'); 2978 if (data.status === "success") { 2979 $reschedule_calendar_wrapper.find('.os-months').append(data.message); 2980 $reschedule_calendar_wrapper.find('.os-monthly-calendar-days-w.active').removeClass('active').next('.os-monthly-calendar-days-w').addClass('active'); 2981 latepoint_calendar_set_month_label($reschedule_calendar_wrapper); 2982 } else { 2983 // console.log(data.message); 2984 } 2985 } 2986 }); 2987 } 2988 } 2989 latepoint_calendar_show_or_hide_prev_next_buttons($reschedule_calendar_wrapper); 2990 return false; 2991 }); 2992 2993 $reschedule_wrapper.on('click', '.os-month-prev-btn', function () { 2994 var $reschedule_calendar_wrapper = jQuery(this).closest('.reschedule-calendar-wrapper'); 2995 if ($reschedule_calendar_wrapper.find('.os-monthly-calendar-days-w.active').prev('.os-monthly-calendar-days-w').length) { 2996 $reschedule_calendar_wrapper.find('.os-monthly-calendar-days-w.active').removeClass('active').prev('.os-monthly-calendar-days-w').addClass('active'); 2997 latepoint_calendar_set_month_label($reschedule_calendar_wrapper); 2998 } 2999 latepoint_calendar_show_or_hide_prev_next_buttons($reschedule_calendar_wrapper); 3000 return false;
3001 }); 3002 3003 $reschedule_wrapper.on('click', '.os-day', function () { 3004 if (jQuery(this).hasClass('os-day-passed')) return false; 3005 if (jQuery(this).hasClass('os-not-in-allowed-period')) return false; 3006 if(jQuery(this).closest('.os-dates-and-times-w').hasClass('calendar-style-modern')){ 3007 if(jQuery(this).hasClass('os-month-prev')) return false; 3008 if(jQuery(this).hasClass('os-month-next')) return false; 3009 } 3010 var $reschedule_calendar_wrapper = jQuery(this).closest('.reschedule-calendar-wrapper'); 3011 if (jQuery(this).closest('.os-monthly-calendar-days-w').hasClass('hide-if-single-slot')) { 3012 3013 // HIDE TIMESLOT IF ONLY ONE TIMEPOINT 3014 if (jQuery(this).hasClass('os-not-available')) { 3015 // clicked on a day that has no available timeslots 3016 // do nothing 3017 } else { 3018 $reschedule_calendar_wrapper.find('.os-day.selected').removeClass('selected'); 3019 jQuery(this).addClass('selected'); 3020 // set date 3021 $reschedule_calendar_wrapper.find('.latepoint_start_date').val(jQuery(this).data('date')); 3022 if (jQuery(this).hasClass('os-one-slot-only')) { 3023 // clicked on a day that has only one slot available 3024 var bookable_minutes = jQuery(this).data('bookable-minutes').toString().split(':')[0]; 3025 var selected_timeslot_time = latepoint_format_minutes_to_time(Number(bookable_minutes), Number(jQuery(this).data('service-duration'))); 3026 $reschedule_calendar_wrapper.find('.latepoint_start_time').val(jQuery(this).data('bookable-minutes')); 3027 $reschedule_calendar_wrapper.find('.time-selector-w').slideUp(200); 3028 latepoint_show_reschedule_button() 3029 } else { 3030 // regular day with more than 1 timeslots available 3031 // build timeslots 3032 latepoint_generate_day_timeslots(jQuery(this), $reschedule_calendar_wrapper, $reschedule_calendar_wrapper.find('.latepoint-lightbox-content')); 3033 // initialize timeslots events 3034 // clear time and hide next btn 3035 $reschedule_calendar_wrapper.find('.latepoint_start_time').val(''); 3036 } 3037 } 3038 } else { 3039 3040 // SHOW TIMESLOTS EVEN IF ONLY ONE TIMEPOINT 3041 $reschedule_calendar_wrapper.find('.latepoint_start_date').val(jQuery(this).data('date')); 3042 $reschedule_calendar_wrapper.find('.os-day.selected').removeClass('selected'); 3043 jQuery(this).addClass('selected'); 3044 3045 // build timeslots 3046 latepoint_generate_day_timeslots(jQuery(this), $reschedule_calendar_wrapper, $reschedule_calendar_wrapper.find('.latepoint-lightbox-content')); 3047 // initialize timeslots events 3048 // clear time and hide next btn 3049 let $booking_form_element = jQuery(this).closest('.latepoint-booking-form-element'); 3050 if ($booking_form_element.length) latepoint_reload_summary($booking_form_element); 3051 $reschedule_calendar_wrapper.find('.latepoint_start_time').val(''); 3052 latepoint_hide_next_btn($reschedule_calendar_wrapper); 3053 } 3054 3055 return false; 3056 }); 3057} 3058 3059 3060/* 3061 * Copyright (c) 2024 LatePoint LLC. All rights reserved. 3062 */ 3063 3064function latepoint_reload_day_schedule($day_view){ 3065 $day_view.addClass('os-loading'); 3066 let data = { 3067 action: latepoint_helper.route_action, 3068 route_name: $day_view.data('route-name'), 3069 params: $day_view.find("select, textarea, input").serialize(), 3070 layout: 'none', 3071 return_format: 'json' 3072 } 3073 3074 jQuery.ajax({ 3075 type: "post", 3076 dataType: "json", 3077 url: latepoint_timestamped_ajaxurl(), 3078 data: data, 3079 success: function (data) { 3080 if (data.status === "success") { 3081 $day_view.replaceWith(data.message); 3082 } 3083 } 3084 }); 3085} 3086 3087function latepoint_reload_events_calendar($events_calendar){ 3088 $events_calendar.addClass('os-loading'); 3089 let data = { 3090 action: latepoint_helper.route_action, 3091 route_name: $events_calendar.data('route-name'), 3092 params: $events_calendar.find("select, textarea, input").serialize(), 3093 layout: 'none', 3094 return_format: 'json' 3095 } 3096 3097 jQuery.ajax({ 3098 type: "post", 3099 dataType: "json", 3100 url: latepoint_timestamped_ajaxurl(), 3101 data: data, 3102 success: function (data) { 3103 if (data.status === "success") { 3104 $events_calendar.replaceWith(data.message); 3105 } 3106 } 3107 }); 3108 3109} 3110 3111/* 3112 * Copyright (c) 2024 LatePoint LLC. All rights reserved. 3113 */ 3114 3115class LatepointStripeConnectFront { 3116 3117 // Init 3118 constructor(stripeKey) { 3119 this.stripeKey = stripeKey; 3120 this.stripeElements = null; 3121 this.stripeCore = null; 3122 this.stripePaymentMethod = null; 3123 this.stripeContinueOrderIntentURL = null; 3124 this.stripeContinueTransactionIntentURL = null; 3125 this.stripePaymentIntentSecret = null; 3126 this.stripePaymentElement = null; 3127 this.ready(); 3128 } 3129 3130 ready() { 3131 jQuery(document).ready(() => { 3132 jQuery('body').on('latepoint:submitBookingForm', '.latepoint-booking-form-element', (e, data) => { 3133 if (!latepoint_helper.demo_mode && data.is_final_submit && data.direction == 'next') { 3134 let payment_method = jQuery(e.currentTarget).find('input[name="cart[payment_method]"]').val(); 3135 switch (payment_method) { 3136 case 'payment_element': 3137 latepoint_add_action(data.callbacks_list, async () => { 3138 if (this.stripePaymentIntentSecret && this.stripeCore) { 3139 return await this.confirmPaymentElementPayment(jQuery(e.currentTarget)); 3140 } 3141 }); 3142 break; 3143 } 3144 } 3145 }); 3146 jQuery('body').on('latepoint:submitTransactionPaymentForm', '.latepoint-transaction-payment-form', (e, data) => { 3147 if (data.current_step === 'pay' && data.payment_processor === 'stripe_connect' && data.payment_method === 'payment_element') { 3148 latepoint_add_action(data.callbacks_list, async () => { 3149 if (this.stripePaymentIntentSecret && this.stripeCore) { 3150 return await this.confirmPaymentElementPaymentForTransaction(jQuery(e.currentTarget)); 3151 } 3152 }); 3153 } 3154 }); 3155 3156 // INITIALIZE PAYMENT METHOD 3157 jQuery('body').on('latepoint:initPaymentMethod', '.latepoint-booking-form-element', (e, data) => { 3158 if (!latepoint_helper.demo_mode) { 3159 switch (data.payment_method) { 3160 case 'payment_element': 3161 latepoint_add_action(data.callbacks_list, async () => { 3162 return await this.createPaymentIntent(jQuery(e.currentTarget), data.payment_method); 3163 }); 3164 break; 3165 } 3166 } else { 3167 latepoint_show_next_btn(jQuery(e.currentTarget)); 3168 } 3169 }); 3170 // INITIALIZE PAYMENT METHOD on order payment form 3171 jQuery('body').on('latepoint:initOrderPaymentMethod', '.latepoint-transaction-payment-form', (e, data) => { 3172 if (data.payment_processor === 'stripe_connect') { 3173 switch (data.payment_method) { 3174 case 'payment_element': 3175 latepoint_add_action(data.callbacks_list, async () => { 3176 return await this.createPaymentIntentForTransaction(jQuery(e.currentTarget)); 3177 }); 3178 break; 3179 } 3180 } 3181 }); 3182 }); 3183 } 3184 3185 3186 async createPaymentIntentForTransaction($transaction_intent_form) { 3187 3188 try { 3189 this.stripeCore = Stripe(this.stripeKey, {stripeAccount: latepoint_helper.stripe_connected_account_id}); 3190 this.stripeElements = this.stripeCore.elements(); 3191 }catch(e){ 3192 console.log(e); 3193 alert(e); 3194 } 3195 3196 let data = latepoint_create_form_data($transaction_intent_form, latepoint_helper.stripe_connect_route_create_payment_intent_for_transaction_intent); 3197 3198 let response = await jQuery.ajax({ 3199 type: "post", 3200 dataType: "json", 3201 processData: false, 3202 contentType: false, 3203 url: latepoint_timestamped_ajaxurl(), 3204 data: data 3205 }); 3206 3207 if (response.status === "success") { 3208 $transaction_intent_form.find('input[name="payment_token"]').val(response.payment_intent_id); 3209 this.stripePaymentIntentSecret = response.payment_intent_secret; 3210 this.stripeContinueTransactionIntentURL = response.continue_transaction_intent_url; 3211 latepoint_show_next_btn($transaction_intent_form); 3212 3213 if ($transaction_intent_form.find('.stripe-payment-element').length) { 3214 return this.initPaymentElement($transaction_intent_form); 3215 } 3216 } else { 3217 alert(response.message); 3218 throw new Error(response.message); 3219 } 3220 } 3221 3222 async createPaymentIntent($booking_form_element, payment_method) { 3223 this.stripeCore = Stripe(this.stripeKey, {stripeAccount: latepoint_helper.stripe_connected_account_id}); 3224 this.stripeElements = this.stripeCore.elements(); 3225 3226 let data = latepoint_create_form_data($booking_form_element.find('.latepoint-form'), latepoint_helper.stripe_connect_route_create_payment_intent, {booking_form_page_url: window.location.href}); 3227 3228 let response = await jQuery.ajax({ 3229 type: "post", 3230 dataType: "json", 3231 processData: false, 3232 contentType: false, 3233 url: latepoint_timestamped_ajaxurl(), 3234 data: data 3235 }); 3236 3237 if (response.status === "success") { 3238 $booking_form_element.find('input[name="cart[payment_token]"]').val(response.payment_intent_id); 3239 this.stripePaymentIntentSecret = response.payment_intent_secret; 3240 this.stripeContinueOrderIntentURL = response.continue_order_intent_url; 3241 latepoint_show_next_btn($booking_form_element); 3242 3243 if ($booking_form_element.find('.stripe-payment-element').length) { 3244 return this.initPaymentElement($booking_form_element); 3245 } 3246 } else { 3247 alert(response.message); 3248 throw new Error(response.message); 3249 } 3250 } 3251 3252 async confirmPaymentElementPaymentForTransaction($transaction_intent_form) { 3253 let elements = this.stripeElements; 3254 let continue_transaction_intent_url = this.stripeContinueTransactionIntentURL; 3255 let result = await this.stripeCore.confirmPayment({ 3256 elements, 3257 confirmParams: { 3258 // Return URL where the customer should be redirected after the PaymentIntent is confirmed. 3259 return_url: continue_transaction_intent_url, 3260 }, 3261 redirect: "if_required", 3262 }); 3263 if (result.error) { 3264 throw new Error(result.error.message); 3265 } else { 3266 $transaction_intent_form.find('input[name="payment_token"]').val(result.paymentIntent.i
3266d); 3267 return result.paymentIntent.id; 3268 } 3269 } 3270 3271 async confirmPaymentElementPayment($booking_form_element) { 3272 let elements = this.stripeElements; 3273 let continue_order_intent_url = this.stripeContinueOrderIntentURL; 3274 let result = await this.stripeCore.confirmPayment({ 3275 elements, 3276 confirmParams: { 3277 // Return URL where the customer should be redirected after the PaymentIntent is confirmed. 3278 return_url: continue_order_intent_url, 3279 }, 3280 redirect: "if_required", 3281 }); 3282 if (result.error) { 3283 throw new Error(result.error.message); 3284 } else { 3285 $booking_form_element.find('input[name="cart[payment_token]"]').val(result.paymentIntent.id); 3286 return result.paymentIntent.id; 3287 } 3288 } 3289 3290 initPaymentElement($booking_form_element) { 3291 let appearance = { 3292 theme: 'stripe', 3293 variables: { 3294 fontFamily: 'Overpass', 3295 colorPrimary: '#1d7bff' 3296 }, 3297 rules: { 3298 '.Tab': { 3299 border: '1px solid #E0E6EB', 3300 boxShadow: 'none', 3301 borderRadius: '0', 3302 marginBottom: '10px' 3303 }, 3304 '.Input': { 3305 boxShadow: 'none', 3306 borderRadius: '0' 3307 }, 3308 3309 '.Tab:hover': { 3310 color: 'var(--colorText)', 3311 }, 3312 3313 '.Tab--selected': { 3314 borderColor: 'var(--colorPrimary)', 3315 boxShadow: `0 0 0 1px var(--colorPrimary)`, 3316 }, 3317 3318 '.Input--invalid': { 3319 boxShadow: '0 1px 1px 0 rgba(0, 0, 0, 0.07), 0 0 0 2px var(--colorPrimary)', 3320 }, 3321 3322 // See all supported class names and selector syntax below 3323 } 3324 }; 3325 3326 3327 // Create an instance of the Payment Element 3328 this.stripeElements = this.stripeCore.elements({ 3329 clientSecret: this.stripePaymentIntentSecret, 3330 appearance, 3331 fonts: [{cssSrc: 'https://fonts.googleapis.com/css2?family=Overpass&display=swap'}], 3332 }); 3333 3334 let options = { 3335 layout: { 3336 type: 'tabs', 3337 defaultCollapsed: false, 3338 }, 3339 }; 3340 this.stripePaymentElement = this.stripeElements.create('payment', options); 3341 3342 return this.stripePaymentElement.mount($booking_form_element.find('.stripe-payment-element')[0]); 3343 } 3344 3345 3346} 3347 3348 3349if (latepoint_helper.is_stripe_connect_enabled) window.latepointStripeConnectFront = new LatepointStripeConnectFront(latepoint_helper.stripe_connect_key); 3350 3351/* 3352 * Copyright (c) 2022 LatePoint LLC. All rights reserved. 3353 */ 3354// @codekit-prepend "bin/time.js" 3355// @codekit-prepend "bin/shared.js" 3356// @codekit-prepend "bin/notifications.js"; 3357// @codekit-prepend "bin/actions.js" 3358// @codekit-prepend "bin/front/main.js" 3359// @codekit-prepend "bin/front/_customer.js" 3360// @codekit-prepend "bin/front/_events.js" 3361// @codekit-prepend "bin/front/_stripe_connect.js" 3362 3363 3364// DOCUMENT READY 3365jQuery(document).ready(function ($) { 3366 3367 latepoint_init_customer_dashboard(); 3368 latepoint_init_manage_booking_by_key(); 3369 3370 3371 jQuery('body').on('click', '.le-filter-trigger', function () { 3372 let $events_calendar = jQuery(this).closest('.latepoint-calendar-wrapper'); 3373 if ($events_calendar.hasClass('show-filters')) { 3374 $events_calendar.removeClass('show-filters'); 3375 $events_calendar.find('.latepoint-calendar-filters select').val(''); 3376 latepoint_reload_events_calendar($events_calendar); 3377 } else { 3378 $events_calendar.addClass('show-filters'); 3379 } 3380 return false; 3381 }); 3382 3383 jQuery('body').on('click', '.le-navigation-trigger', function () { 3384 let $trigger = jQuery(this); 3385 let $events_calendar = $trigger.closest('.latepoint-calendar-wrapper'); 3386 $events_calendar.find('input[name="target_date_string"]').val($trigger.data('target-date')); 3387 $trigger.addClass('os-loading'); 3388 latepoint_reload_events_calendar($events_calendar); 3389 return false;
3390 }); 3391 3392 jQuery('body').on('change', '.le-day-filters select', function () { 3393 let $trigger = jQuery(this); 3394 let $day_view = $trigger.closest('.le-day-view-wrapper'); 3395 latepoint_reload_day_schedule($day_view); 3396 return false; 3397 }); 3398 3399 jQuery('body').on('change', '.latepoint-calendar-filters select, .le-range-selector select', function () { 3400 let $trigger = jQuery(this); 3401 let $events_calendar = $trigger.closest('.latepoint-calendar-wrapper'); 3402 $events_calendar.find('.le-filter').addClass('os-loading'); 3403 latepoint_reload_events_calendar($events_calendar); 3404 return false; 3405 }); 3406 3407 jQuery('body').on('click', '.close-calendar-types', function () { 3408 jQuery(this).closest('.add-to-calendar-wrapper').removeClass('show-types'); 3409 return false; 3410 }); 3411 jQuery('body').on('click', '.open-calendar-types', function () { 3412 jQuery(this).closest('.add-to-calendar-wrapper').addClass('show-types'); 3413 return false; 3414 }); 3415 3416 jQuery('body').on('latepoint:nextStepClicked', '.latepoint-booking-form-element', (e, data) => { 3417 3418 latepoint_add_action(data.callbacks_list, async () => { 3419 let $booking_form = jQuery(e.currentTarget).find('.latepoint-form'); 3420 let errors = latepoint_validate_form($booking_form); 3421 if (errors.length) { 3422 let error_messages = errors.map(error => error.message).join(', '); 3423 throw new Error(error_messages); 3424 } else { 3425 return true; 3426 } 3427 }, 1); 3428 3429 }); 3430 3431 if (latepoint_helper.start_from_order_intent_key) { 3432 $('body').append('<div class="latepoint-continue-intent-loading"></div>'); 3433 3434 var data = { 3435 action: latepoint_helper.route_action, 3436 route_name: latepoint_helper.start_from_order_intent_route, 3437 params: {order_intent_key: latepoint_helper.start_from_order_intent_key}, 3438 layout: 'none', 3439 return_format: 'json' 3440 } 3441 3442 $.ajax({ 3443 type: "post", 3444 dataType: "json", 3445 url: latepoint_timestamped_ajaxurl(), 3446 data: data, 3447 success: function (data) { 3448 $('.latepoint-continue-intent-loading').remove(); 3449 if (data.status === "success") { 3450 var lightbox_class = ''; 3451 latepoint_show_data_in_lightbox(data.message, data.lightbox_class); 3452 var $booking_form_element = jQuery('.latepoint-lightbox-w .latepoint-booking-form-element'); 3453 latepoint_init_booking_form($booking_form_element); 3454 $booking_form_element.find('.latepoint-step-content').addClass('is-hidden').last().removeClass('is-hidden'); 3455 if ($booking_form_element.find('.latepoint-step-content').length > 1) latepoint_show_prev_btn($booking_form_element); 3456 var $booking_form_element = jQuery('.latepoint-lightbox-w .latepoint-booking-form-element'); 3457 $booking_form_element.find('.latepoint-step-content').each(function () { 3458 latepoint_init_step($(this).data('step-code'), $booking_form_element); 3459 }); 3460 $('body').addClass('latepoint-lightbox-active'); 3461 } else { 3462 // console.log(data.message); 3463 } 3464 } 3465 }); 3466 } 3467 3468 if (latepoint_helper.start_from_transaction_access_key) { 3469 const invoice_access_key = latepoint_helper.start_from_transaction_access_key; 3470 show_summary_before_payment(invoice_access_key); 3471 } 3472 3473 3474 jQuery('body').on('click', '.latepoint-lightbox-close', function () { 3475 latepoint_lightbox_close(); 3476 return false; 3477 }); 3478 3479 3480 jQuery('body').on('click', '.os-step-tabs .os-step-tab', function () { 3481 jQuery(this).closest('.os-step-tabs').find('.os-step-tab').removeClass('active'); 3482 jQuery(this).addClass('active'); 3483 var target = jQuery(this).data('target'); 3484 jQuery(this).closest('.os-step-tabs-w').find('.os-step-tab-content').hide(); 3485 jQuery(target).show(); 3486 }); 3487 3488 jQuery('body').on('keyup', '.os-form-group .os-form-control', function () { 3489 if (jQuery(this).val()) { 3490 jQuery(this).closest('.os-form-group').addClass('has-value'); 3491 } else { 3492 jQuery(this).closest('.os-form-group').removeClass('has-value'); 3493 } 3494 }); 3495 3496 jQuery('.latepoint-tab-triggers').on('click', '.latepoint-tab-trigger', function () { 3497 var $tabs_wrapper = jQuery(this).closest('.latepoint-tabs-w') 3498 $tabs_wrapper.find('.latepoint-tab-trigger.active').removeClass('active'); 3499 $tabs_wrapper.find('.latepoint-tab-content').removeClass('active'); 3500 jQuery(this).addClass('active'); 3501 $tabs_wrapper.find('.latepoint-tab-content' + jQuery(this).data('tab-target')).addClass('active'); 3502 return false;
3503 }); 3504 3505 3506 // Main Button to trigger lightbox opening 3507 if(jQuery('.latepoint-book-form-wrapper').length){ 3508 jQuery('.latepoint-book-form-wrapper').each(function(){ 3509 latepoint_init_booking_form_by_trigger(jQuery(this)); 3510 }); 3511 } 3512 3513 jQuery('body').on('click', '.latepoint-book-button, .os_trigger_booking', function () { 3514 latepoint_init_booking_form_by_trigger(jQuery(this)); 3515 return false; 3516 }); 3517 3518});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.