PluginProbe ʕ •ᴥ•ʔ
LatePoint – Calendar Booking Plugin for Appointments and Events / 5.4.2
LatePoint – Calendar Booking Plugin for Appointments and Events v5.4.2
5.6.6 5.6.5 5.6.4 5.6.3 5.6.2 5.6.1 5.6.0 5.5.2 5.5.1 5.5.0 5.4.2 trunk 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.1.8 5.1.9 5.1.91 5.1.92 5.1.93 5.1.94 5.2.0 5.2.1 5.2.10 5.2.11 5.2.2 5.2.3 5.2.4 5.2.5 5.2.6 5.2.7 5.2.8 5.2.9 5.3.0 5.3.1 5.3.2 5.4.0 5.4.1
latepoint / lib / assets / javascripts / bin / admin / main.js
latepoint / lib / assets / javascripts / bin / admin Last commit date
_agents.js 1 year ago _calendar.js 3 months ago _chart.js 9 months ago _customers.js 1 year ago _customers_import.js 9 months ago _orders.js 9 months ago _processes.js 1 year ago _steps.js 9 months ago _stripe_connect.js 1 year ago main.js 5 months ago updates.js 3 months ago
main.js
1118 lines
1 /*
2 * Copyright (c) 2022 LatePoint LLC. All rights reserved.
3 */
4
5 function latepoint_init_version5_intro(){
6 if(jQuery('.improvement-install-pro').length){
7 let $install_btn = jQuery('.improvement-install-pro');
8 var data = {
9 action: latepoint_helper.route_action,
10 route_name: $install_btn.data('route-name'),
11 params: {},
12 return_format: 'json'
13 }
14 jQuery.ajax({
15 type : "post",
16 dataType : "json",
17 url : latepoint_timestamped_ajaxurl(),
18 data : data,
19 success: function(response){
20 $install_btn.removeClass('os-loading');
21 if(response.status == 'success'){
22 $install_btn.addClass('is-installed').find('span').html(response.message);
23 }else{
24 $install_btn.addClass('is-not-installed').find('span').html(response.message);
25 }
26 }
27 });
28 }
29 }
30
31
32 function latepoint_settings_customer_authentication_method_changed($select){
33 if($select.val() === 'password_or_otp'){
34 jQuery('#authDefaultMethod').show();
35 }else{
36 jQuery('#authDefaultMethod').hide();
37 }
38 }
39
40 function latepoint_settings_customer_authentication_field_type_changed($select){
41 if($select.val() === 'disabled'){
42 jQuery('#passwordFields, #customerStepSettings').hide();
43 jQuery('#authDefaultMergeBehavior').show();
44 }else{
45 jQuery('#passwordFields, #customerStepSettings').show();
46 jQuery('#authDefaultMergeBehavior').hide();
47 }
48 if($select.val() === 'email_or_phone'){
49 jQuery('#authDefaultContactType').show();
50 }else{
51 jQuery('#authDefaultContactType').hide();
52 }
53 }
54
55 function latepoint_init_sticky_side_nav(){
56 jQuery('.latepoint-page-side-nav a').on('click', function(e) {
57 e.preventDefault();
58 let target = jQuery(this).attr('href');
59 let targetOffset = jQuery(target).offset().top - 20;
60
61 jQuery('html, body').animate({
62 scrollTop: targetOffset
63 }, 400, 'swing');
64 });
65 if(jQuery('.latepoint-page-side-nav').length){
66 jQuery(window).on('scroll', function() {
67 let scrollPos = jQuery(window).scrollTop() + 100; // 100px offset for better UX
68
69 jQuery('.section-anchor').each(function() {
70 let sectionTop = jQuery(this).offset().top;
71 let sectionBottom = sectionTop + jQuery(this).outerHeight();
72 let sectionId = jQuery(this).attr('id');
73
74 // Check if current scroll position is within this section
75 if (scrollPos >= sectionTop && scrollPos < sectionBottom) {
76 // Remove active class from all menu items
77 jQuery('.latepoint-page-side-nav a').removeClass('is-active');
78
79 // Add active class to current section's menu item
80 jQuery('.latepoint-page-side-nav a[href="#' + sectionId + '"]').addClass('is-active');
81 }
82 });
83 });
84 }
85 }
86
87 function latepoint_init_instant_booking_settings(){
88
89 jQuery('.instant-copy-url').on('click', function(e){
90 e.preventDefault();
91 let $this = jQuery(this);
92 jQuery('body').find('.os-click-to-copy-prompt').hide();
93 let text_to_copy = jQuery('.instant-visit-url').prop('href');
94 navigator.clipboard.writeText(text_to_copy);
95
96 let position_info = $this.offset();
97 let position_left = position_info.left;
98 let position_top = position_info.top;
99
100 let $done_prompt = jQuery('<div class="os-click-to-copy-done color-dark" style="top: '+position_top+'px; left: '+position_left+'px;">' + latepoint_helper.click_to_copy_done + '</div>');
101 $done_prompt.appendTo(jQuery('body')).animate({
102 opacity: 0,
103 left: (position_left + 20),
104 }, 600);
105 setTimeout(function(){
106 jQuery('body').find('.os-click-to-copy-done').remove();
107 jQuery('body').find('.os-click-to-copy-prompt').show();
108 }, 800);
109 });
110
111 jQuery('.instant-booking-preview-settings-content').find('select, input').on('change', function(){
112 latepoint_build_url_for_instant_booking_page();
113 })
114 jQuery('.preview-background-option').on('click', function(e){
115 jQuery('.preview-background-option').removeClass('selected');
116 jQuery(this).addClass('selected');
117 jQuery('input[name="instant_booking[background_pattern]"]').val(jQuery(this).data('pattern-key')).trigger('change');
118 });
119
120 jQuery('.latepoint-instant-preview-close-trigger').on('click', function(e){
121 jQuery('.latepoint-full-panel-w').remove();
122 return false;
123 });
124
125 }
126
127 async function latepoint_build_url_for_instant_booking_page(){
128 let data = {
129 action: 'latepoint_route_call',
130 route_name: jQuery('.instant-booking-preview-settings-content').data('route-name'),
131 params: jQuery('.instant-booking-preview-settings-content').find('select, input').serialize(),
132 layout: 'none',
133 return_format: 'json'
134 }
135 try {
136 let response = await jQuery.ajax({
137 type: "post",
138 dataType: "json",
139 url: latepoint_timestamped_ajaxurl(),
140 data: data
141 });
142 if (response.status == 'success') {
143 jQuery('.instant-booking-settings-iframe-wrapper').html('<iframe class="instant-preview-iframe" src="' + response.message + '"/>');
144 jQuery('.instant-visit-url').attr('href', response.message);
145 } else {
146 throw new Error('Error: ' + response.message);
147 }
148 } catch (e) {
149 throw e;
150 }
151 }
152
153 function latepoint_build_and_save_step_order(){
154 const $steps_wrapper = jQuery('.os-ordered-steps');
155 let steps_in_order = [];
156 $steps_wrapper.find('.os-ordered-step').each(function(index){
157 if(jQuery(this).find('.os-ordered-step-children').length){
158 jQuery(this).find('.os-ordered-step-child').each(function(){
159 steps_in_order.push(jQuery(this).data('step-code'));
160 });
161 }else{
162 steps_in_order.push(jQuery(this).data('step-code'));
163 }
164 });
165 const paramsQuery = $steps_wrapper.data('params') || '';
166 const params = Object.fromEntries(new URLSearchParams(paramsQuery));
167 const data = {
168 action: latepoint_helper.route_action,
169 route_name: $steps_wrapper.data('route-name'),
170 params: {
171 ...params,
172 steps_order: steps_in_order.join(','),
173 },
174 return_format: 'json'
175 }
176 jQuery('.latepoint-lightbox-heading').addClass('os-loading');
177 jQuery.ajax({
178 type : "post",
179 dataType : "json",
180 url : latepoint_timestamped_ajaxurl(),
181 data : data,
182 success: function(response){
183 jQuery('.latepoint-lightbox-heading').removeClass('os-loading');
184 latepoint_add_lightbox_notification(response.message, response.status);
185 }
186 });
187 }
188
189 function latepoint_init_step_reordering(){
190 jQuery('.os-ordered-step-expand').on('click', function(){
191 jQuery(this).closest('.os-ordered-step').toggleClass('is-expanded');
192 return false;
193 });
194
195
196 // Steps Order Dragging
197 dragula([jQuery('.os-ordered-steps')[0]], {
198 moves: function (el, container, handle) {
199 return handle.classList.contains('os-ordered-step-drag-handle');
200 },
201 }).on('drop', function(el){
202 latepoint_build_and_save_step_order();
203 });
204
205 jQuery('.os-ordered-step-children').each(function(){
206 let step_holder = jQuery(this)
207 // Child steps Order Dragging
208 dragula([step_holder[0]], {
209 moves: function (el, container, handle) {
210 return handle.classList.contains('os-ordered-step-child-drag-handle');
211 },
212 }).on('drop', function(el){
213 latepoint_build_and_save_step_order();
214 });
215 });
216 }
217
218
219 function latepoint_init_json_view($pre_element = false){
220 if(!$pre_element){
221 // if pre is not provided -search for all unitialised ones
222 $pre_element = jQuery('pre.format-json:not(.json-document)');
223 }
224 if($pre_element.length){
225 $pre_element.each(function(){
226 let json_data = JSON.parse(jQuery(this).html());
227 jQuery(this).jsonViewer(json_data);
228 });
229 }
230 }
231
232 function latepoint_init_accordions(){
233 jQuery('.latepoint-admin').on('click', '.os-accordion-title', function(){
234 jQuery(this).closest('.os-accordion-wrapper').toggleClass('is-open');
235 return false;
236 });
237 }
238
239
240 function latepoint_init_sticky_side_menu(){
241 jQuery('.os-sticky-side-menu a').on('click', function(){
242 jQuery('.os-sticky-side-menu li.os-active').removeClass('os-active');
243 jQuery(this).closest('li').addClass('os-active');
244 let section_anchor = jQuery(this).data('section-anchor');
245 let position = jQuery('.section-anchor#'+section_anchor).offset();
246 jQuery('html').animate({ scrollTop: position.top }, 300);
247 return false;
248 });
249 }
250
251 function latepoint_init_template_library(){
252 jQuery('.os-templates-wrapper .template-type-selector').on('click', function(){
253 jQuery(this).toggleClass('is-selected');
254 let user_type = jQuery(this).data('user-type');
255 jQuery('.os-template-items[data-user-type="'+user_type+'"]').toggleClass('hidden');
256 return false;
257 });
258
259 jQuery('.os-templates-wrapper .os-template-item').on('click', function(){
260 let $this = jQuery(this);
261 $this.closest('.os-templates-list').find('.os-template-item.selected').removeClass('selected');
262 $this.addClass('selected');
263 let templateId = $this.data('id');
264 jQuery('.os-template-preview').hide();
265 jQuery('.os-template-preview[data-id="'+ templateId+'"]').show();
266 jQuery('.os-no-template-selected-message').hide();
267 jQuery('.os-template-use-button-wrapper').removeClass('hidden');
268 return false;
269 });
270
271 jQuery('.latepoint-select-template-btn').on('click', function(){
272 let $btn = jQuery(this);
273 let route_name = $btn.data('route');
274 let action_id = $btn.data('action-id');
275 let process_id = $btn.data('process-id');
276 let action_type = $btn.data('action-type');
277 $btn.addClass('os-loading');
278
279 let data = { action: latepoint_helper.route_action,
280 route_name: route_name,
281 params: {
282 template_id: jQuery('.os-template-item.selected').data('id'),
283 action_id: action_id,
284 process_id: process_id,
285 action_type: action_type
286 },
287 return_format: 'json' }
288 jQuery.ajax({
289 type: 'post',
290 dataType : "json",
291 url : latepoint_timestamped_ajaxurl(),
292 data : data,
293 success: (response) => {
294 $btn.removeClass('os-loading');
295 if(response.status === latepoint_helper.response_status.success){
296 let $action_form = jQuery('.process-action-form[data-id="'+action_id+'"]');
297 $action_form.find('.process-action-settings').html(response.message);
298 latepoint_init_process_action_form($action_form);
299 latepoint_close_side_panel();
300 }else{
301 alert("Error!");
302 }
303 }
304 });
305
306 return false;
307 });
308 }
309
310 function latepoint_init_default_form_fields_settings(){
311
312 if(jQuery('.os-default-fields').length){
313 jQuery('.os-default-field input[type="checkbox"], .os-default-field select').on('change', (event) => {
314 latepoint_update_default_form_fields_settings();
315 });
316
317 jQuery('.os-default-field .os-toggler').on('ostoggler:toggle', (event) => {
318 if(jQuery(event.currentTarget).hasClass('off')){
319 jQuery(event.currentTarget).closest('.os-default-field').addClass('is-disabled');
320 }else{
321 jQuery(event.currentTarget).closest('.os-default-field').removeClass('is-disabled');
322 }
323 latepoint_update_default_form_fields_settings();
324 });
325 }
326 }
327
328 function latepoint_update_default_form_fields_settings(){
329 var $wrapper = jQuery('.os-default-fields');
330
331 var form_data = new FormData($wrapper.find('form')[0]);
332 var data = { action: latepoint_helper.route_action,
333 route_name: $wrapper.data('route'),
334 params: latepoint_formdata_to_url_encoded_string(form_data),
335 return_format: 'json' }
336
337 jQuery.ajax({
338 type : "post",
339 dataType : "json",
340 url : latepoint_timestamped_ajaxurl(),
341 data : data,
342 success: (response) => {
343 latepoint_add_notification(response.message);
344 }
345 });
346 }
347
348 function latepoint_init_side_menu(){
349 jQuery('.menu-toggler').on('click', function(){
350 let $menuToggler = jQuery(this);
351 let layout_style = 'full';
352 if(jQuery('.latepoint-side-menu-w').hasClass('side-menu-full')){
353 layout_style = 'compact';
354 jQuery('.latepoint-side-menu-w').addClass('side-menu-compact').removeClass('side-menu-full');
355 }else{
356 jQuery('.latepoint-side-menu-w').addClass('side-menu-full').removeClass('side-menu-compact');
357 }
358 const paramsQuery = $menuToggler.data('params') || '';
359 const params = Object.fromEntries(new URLSearchParams(paramsQuery));
360 const data = {
361 action: latepoint_helper.route_action,
362 route_name: $menuToggler.data('route'),
363 params: {
364 ...params,
365 menu_layout_style: layout_style,
366 },
367 layout: 'none',
368 return_format: 'json'
369 }
370 jQuery.ajax({
371 type : "post",
372 dataType : "json",
373 url : latepoint_timestamped_ajaxurl(),
374 data : data,
375 success: function(data){
376 }
377 });
378 return false;
379 });
380 }
381
382 function latepoint_init_grouped_bookings_form(){
383
384 }
385
386 function latepoint_quick_order_customer_cleared(){
387 latepoint_init_input_masks(jQuery('.quick-order-form-w .customer-quick-edit-form-w'));
388 }
389
390 function latepoint_quick_order_customer_selected(){
391 latepoint_init_input_masks(jQuery('.quick-order-form-w .customer-quick-edit-form-w'));
392 jQuery('.customer-info-w').removeClass('selecting').addClass('selected');
393 }
394
395 function latepoint_custom_day_removed($elem){
396 $elem.closest('.custom-day-work-period').fadeOut(300, function(){ jQuery(this).remove()});
397 }
398
399
400 function latepoint_count_active_connections($connection_wrapper){
401 var connected_services_count = $connection_wrapper.find('.connection-children-list li.active').length;
402 var all_services_count = $connection_wrapper.find('.connection-children-list li').length;
403 if(connected_services_count == all_services_count){
404 connected_services_count = jQuery('.selected-connections').data('all-text');
405 jQuery('.selected-connections').removeClass('not-all-selected');
406 }else{
407 connected_services_count = connected_services_count + '/' + all_services_count;
408 jQuery('.selected-connections').addClass('not-all-selected');
409 $connection_wrapper.closest('.white-box').find('.os-select-all-toggler').prop('checked', false);
410 }
411 $connection_wrapper.find('.selected-connections strong').text(connected_services_count);
412 }
413
414 function latepoint_custom_field_removed($elem){
415 $elem.closest('.os-form-block').remove();
416 }
417
418 function latepoint_coupon_removed($elem){
419 $elem.closest('.os-coupon-form').remove();
420 }
421
422 function latepoint_reminder_removed($elem){
423 $elem.closest('.os-reminder-form').remove();
424 }
425
426 function latepoint_init_form_blocks(){
427 jQuery('.latepoint-content-w').on('click', '.os-form-block-header', function(){
428 jQuery(this).closest('.os-form-block').toggleClass('os-is-editing');
429 return false;
430 });
431 jQuery('.latepoint-content-w').on('keyup', '.os-form-block-name-input', function(){
432 jQuery(this).closest('.os-form-block').find('.os-form-block-name').text(jQuery(this).val());
433 });
434 }
435
436
437 function latepoint_init_coupons_form(){
438 jQuery('.latepoint-content-w').on('click', '.os-coupon-form-info', function(){
439 jQuery(this).closest('.os-coupon-form').toggleClass('os-is-editing');
440 return false;
441 });
442 jQuery('.latepoint-content-w').on('change', 'select.os-coupon-medium-select', function(){
443 if(jQuery(this).val() == 'email'){
444 jQuery(this).closest('.os-coupon-form').find('.os-coupon-email-subject').show();
445 }else{
446 jQuery(this).closest('.os-coupon-form').find('.os-coupon-email-subject').hide();
447 }
448 });
449 jQuery('.latepoint-content-w').on('keyup', '.os-coupon-name-input', function(){
450 jQuery(this).closest('.os-coupon-form').find('.os-coupon-name').text(jQuery(this).val());
451 });
452 jQuery('.latepoint-content-w').on('keyup', '.os-coupon-code-input', function(){
453 jQuery(this).closest('.os-coupon-form').find('.os-coupon-code').text(jQuery(this).val());
454 });
455 }
456
457 function latepoint_init_reminders_form(){
458 jQuery('.latepoint-content-w').on('click', '.os-reminder-form-info', function(){
459 jQuery(this).closest('.os-reminder-form').toggleClass('os-is-editing');
460 return false;
461 });
462 jQuery('.latepoint-content-w').on('change', 'select.os-reminder-medium-select', function(){
463 if(jQuery(this).val() == 'email'){
464 jQuery(this).closest('.os-reminder-form').find('.os-reminder-email-subject').show();
465 }else{
466 jQuery(this).closest('.os-reminder-form').find('.os-reminder-email-subject').hide();
467 }
468 });
469 jQuery('.latepoint-content-w').on('keyup', '.os-reminder-name-input', function(){
470 jQuery(this).closest('.os-reminder-form').find('.os-reminder-name').text(jQuery(this).val());
471 });
472 }
473
474 function latepoint_custom_field_saved($elem){
475 }
476
477 function latepoint_init_custom_day_schedule(){
478 latepoint_init_input_masks(jQuery('.latepoint-lightbox-w .custom-day-schedule-w'));
479
480 jQuery('.period-type-selector').on('change', function(){
481 jQuery(this).closest('.custom-day-calendar').attr('data-period-type', jQuery(this).val());
482 jQuery('.custom-day-calendar').attr('data-picking', 'start').data('picking', 'start');
483 if(jQuery(this).val() == 'range'){
484 jQuery('.custom-day-calendar-head .calendar-heading').text(jQuery('.custom-day-calendar-head .calendar-heading').data('label-start'));
485 jQuery('.custom-day-calendar #start_custom_date').trigger('focus');
486 }else{
487 jQuery('.custom-day-calendar .os-day.selected').removeClass('selected');
488 jQuery('.latepoint-lightbox-footer').hide();
489 jQuery('.custom-day-calendar-head .calendar-heading').text(jQuery('.custom-day-calendar-head .calendar-heading').data('label-single'));
490 }
491 });
492
493
494 jQuery('#custom_day_calendar_month, #custom_day_calendar_year').on('change', function(){
495 var $calendar = jQuery('.custom-day-calendar-month');
496 var route_name = $calendar.data('route');
497 $calendar.addClass('os-loading');
498 var target_date_string = jQuery('#custom_day_calendar_year').val() + '-' + jQuery('#custom_day_calendar_month').val() + '-01';
499 var data = { action: latepoint_helper.route_action, route_name: route_name, params: { target_date_string: target_date_string }, layout: 'none', return_format: 'json' }
500 jQuery.ajax({
501 type : "post",
502 dataType : "json",
503 url : latepoint_timestamped_ajaxurl(),
504 data : data,
505 success: function(data){
506 $calendar.removeClass('os-loading');
507 if(data.status === "success"){
508 $calendar.html(data.message);
509 }else{
510 // console.log(data.message);
511 }
512 }
513 });
514 });
515
516
517
518 jQuery('.custom-day-calendar').on('focus', '#start_custom_date', function(){
519 jQuery('.custom-day-calendar-head .calendar-heading').text(jQuery('.custom-day-calendar-head .calendar-heading').data('label-start'));
520 jQuery('.custom-day-calendar').attr('data-picking', 'start').data('picking', 'start');
521 });
522
523 jQuery('.custom-day-calendar').on('focus', '#end_custom_date', function(){
524 jQuery('.custom-day-calendar-head .calendar-heading').text(jQuery('.custom-day-calendar-head .calendar-heading').data('label-end'));
525 jQuery('.custom-day-calendar').attr('data-picking', 'end').data('picking', 'end');
526 });
527
528 jQuery('.custom-day-calendar').on('click', '.os-day', function(){
529 var $this = jQuery(this);
530 $this.closest('.custom-day-calendar').find('.os-day.selected').removeClass('selected');
531 $this.addClass('selected');
532
533 if(jQuery('.custom-day-calendar').data('picking') == 'start'){
534 jQuery('.custom-day-settings-w #start_custom_date').val($this.data('date')).trigger('keyup');
535 if(jQuery('.period-type-selector').val() == 'range'){
536 jQuery('.custom-day-calendar #end_custom_date').trigger('focus');
537 if(!jQuery('.custom-day-calendar #end_custom_date').val()) return false;
538 }
539 }else{
540 jQuery('.custom-day-settings-w #end_custom_date').val($this.data('date')).trigger('keyup');
541 }
542 jQuery('.latepoint-lightbox-footer').slideDown(200);
543 if(jQuery('.custom-day-calendar').data('show-schedule') == 'yes') jQuery('.latepoint-lightbox-w').removeClass('hide-schedule');
544 return false;
545 });
546 }
547
548 function latepoint_init_updates_page(){
549
550 }
551
552 function latepoint_calendar_set_month_label(){
553 jQuery('.os-current-month-label .current-month').text(jQuery('.os-monthly-calendar-days-w.active').data('calendar-month-label'));
554 jQuery('.os-current-month-label .current-year').text(jQuery('.os-monthly-calendar-days-w.active').data('calendar-year'));
555 }
556
557
558 function latepoint_init_element_togglers(){
559 jQuery('[data-toggle-element]').on('click', function(){
560 var $this = jQuery(this);
561 $this.closest('.os-form-checkbox-group').toggleClass('is-checked');
562 jQuery($this.data('toggle-element')).toggle();
563 });
564 }
565
566
567 function latepoint_init_color_picker(){
568 if(jQuery('.latepoint-color-picker').length){
569 jQuery('.latepoint-color-picker').each(function(){
570 var color = jQuery(this).data('color');
571 var picker = jQuery(this)[0];
572 var $picker_wrapper = jQuery(this).closest('.latepoint-color-picker-w');
573 Pickr.create({
574 el: picker,
575 default: color,
576 comparison: false,
577 useAsButton: true,
578 components: {
579
580 // Main components
581 preview: false,
582 opacity: false,
583 hue: true,
584
585 // Input / output Options
586 interaction: {
587 input: false,
588 clear: false,
589 save: true
590 }
591 },
592 onChange(hsva, instance) {
593 $picker_wrapper.find('.os-form-control').val(hsva.toHEX().toString());
594 },
595 });
596 });
597 }
598 }
599
600
601 function latepoint_lightbox_close(){
602 jQuery('body').removeClass('latepoint-lightbox-active');
603 jQuery('.latepoint-lightbox-w').remove();
604 }
605
606 function latepoint_reload_select_service_categories(){
607 jQuery('.service-selector-adder-field-w').each(function(){
608 var $trigger_elem = jQuery(this);
609 var route = jQuery('.service-selector-adder-field-w').find('select').data('select-source');
610 var data = { action: latepoint_helper.route_action, route_name: route, params: '', return_format: 'json' }
611 jQuery.ajax({
612 type : "post",
613 dataType : "json",
614 url : latepoint_timestamped_ajaxurl(),
615 data : data,
616 success: function(response){
617 $trigger_elem.removeClass('os-loading');
618 if(response.status === "success"){
619 latepoint_lightbox_close();
620 $trigger_elem.find('select').html(response.message);
621 $trigger_elem.find('select option:last').attr('selected', 'selected');
622 }else{
623 alert(response.message, 'error');
624 }
625 }
626 });
627 });
628 }
629
630 function latepoint_wizard_item_editing_cancelled(response){
631 jQuery('.os-wizard-setup-w').removeClass('is-sub-editing');
632 jQuery('.os-wizard-footer').show();
633 jQuery('.os-wizard-footer .os-wizard-next-btn').show();
634 if(response.show_prev_btn){
635 jQuery('.os-wizard-footer .os-wizard-prev-btn').show();
636 }
637 }
638
639
640 function latepoint_reload_week_view_calendar(start_date = false){
641 var service_id = (jQuery('.cc-availability-toggler #overlay_service_availability').val() == 'on') ? jQuery('.calendar-service-selector').val() : false;
642 var agent_id = jQuery('.calendar-agent-selector').val();
643 var location_id = jQuery('.calendar-location-selector').val();
644 var calendar_start_date = (start_date) ? start_date : jQuery('.calendar-start-date').val();
645 latepoint_load_calendar(calendar_start_date, agent_id, location_id, service_id);
646 }
647
648 function latepoint_init_work_period_form(){
649 latepoint_mask_timefield(jQuery('.os-time-input-w .os-mask-time'));
650 }
651
652 function latepoint_close_side_panel(){
653 latepoint_close_quick_availability_form();
654 jQuery('.latepoint-side-panel-w').remove();
655 }
656
657 function reload_process_jobs_table(){
658 if(jQuery('table.os-reload-on-booking-update').length) latepoint_filter_table(jQuery('table.os-reload-on-booking-update'), jQuery('table.os-reload-on-booking-update'));
659 }
660
661
662 function latepoint_transaction_removed($trigger){
663 $trigger.closest('.quick-add-transaction-box-w').remove();
664 latepoint_reload_balance_and_payments();
665 }
666
667 function latepoint_reload_widget($widget_elem){
668 var form_data = $widget_elem.find('select, input').serialize();
669 var data = { action: latepoint_helper.route_action, route_name: $widget_elem.data('os-reload-action'), params: form_data, return_format: 'json' }
670 $widget_elem.addClass('os-loading');
671 jQuery.ajax({
672 type : "post",
673 dataType : "json",
674 url : latepoint_timestamped_ajaxurl(),
675 data : data,
676 success: function(response){
677 $widget_elem.removeClass('os-loading');
678 if(response.status === "success"){
679 var $updated_widget_elem = jQuery(response.message);
680 $updated_widget_elem.removeClass('os-widget-animated');
681 $widget_elem = $widget_elem.replaceWith($updated_widget_elem);
682 latepoint_init_daterangepicker($updated_widget_elem.find('.os-date-range-picker'));
683 if($widget_elem.hasClass('os-widget-top-agents')) latepoint_init_circles_charts();
684 if($widget_elem.hasClass('os-widget-daily-bookings')){
685 latepoint_init_daily_bookings_chart();
686 latepoint_init_donut_charts();
687 }
688 }else{
689 alert(response.message);
690 }
691 }
692 });
693 }
694
695 function latepoint_load_calendar(target_date, agent_id, location_id = false, service_id = false){
696 var route_name = jQuery('.calendar-week-agent-w').data('calendar-action');
697 jQuery('.calendar-week-agent-w').addClass('os-loading');
698 var params_arr = {target_date: target_date, agent_id: agent_id};
699 if(location_id) params_arr.location_id = location_id;
700 if(service_id) params_arr.service_id = service_id;
701 var data = { action: latepoint_helper.route_action, route_name: route_name, params: jQuery.param(params_arr), return_format: 'json' }
702 jQuery.ajax({
703 type : "post",
704 dataType : "json",
705 url : latepoint_timestamped_ajaxurl(),
706 data : data,
707 success: function(response){
708 if(response.status === "success"){
709 jQuery('.calendar-week-agent-w').html(response.message).removeClass('os-loading');
710 jQuery('.calendar-load-target-date.os-loading').removeClass('os-loading');
711 }else{
712 alert(response.message);
713 }
714 }
715 });
716 }
717
718 function latepoint_init_quick_transaction_form(){
719 latepoint_mask_money(jQuery('.quick-add-transaction-box-w .os-mask-money'));
720 }
721
722 function latepoint_reload_price_breakdown(){
723 var $trigger = jQuery('.reload-price-breakdown');
724 $trigger.addClass('os-loading');
725 var $quick_edit_form = $trigger.closest('form.order-quick-edit-form');
726 var form_data = new FormData($quick_edit_form[0]);
727 var route = $trigger.data('route');
728
729 var data = { action: latepoint_helper.route_action, route_name: route, params: latepoint_formdata_to_url_encoded_string(form_data), return_format: 'json' }
730 jQuery.ajax({
731 type : "post",
732 dataType : "json",
733 url : latepoint_timestamped_ajaxurl(),
734 data : data,
735 success: function(response){
736 $trigger.removeClass('os-loading');
737 if(response.status === "success"){
738 jQuery('.price-breakdown-wrapper').html(response.message);
739 latepoint_mask_money(jQuery('.price-breakdown-wrapper .os-mask-money'));
740 latepoint_reload_balance_and_payments();
741 }else{
742 alert(response.message);
743 }
744 }
745 });
746 }
747
748 function latepoint_complex_selector_select($connection_wrappers, qty = 1){
749 $connection_wrappers.each(function(){
750 jQuery(this).addClass('active');
751 jQuery(this).find('.connection-children-list li').addClass('active');
752 jQuery(this).find('.connection-child-is-connected').val('yes');
753 jQuery(this).find('.item-quantity-selector-input').val(qty);
754 latepoint_count_active_connections(jQuery(this));
755 });
756 }
757
758 function latepoint_complex_selector_deselect($connection_wrappers){
759 $connection_wrappers.each(function(){
760 jQuery(this).removeClass('active');
761 jQuery(this).removeClass('show-customize-box');
762 jQuery(this).find('.connection-children-list li.active').removeClass('active');
763 jQuery(this).find('.connection-child-is-connected').val('no');
764 jQuery(this).find('.item-quantity-selector-input').val(0);
765 latepoint_count_active_connections(jQuery(this));
766 });
767 }
768
769
770
771 function latepoint_is_next_day($form){
772 let field_base_name = 'order_items[' + $form.data('order-item-id') +'][bookings][' + $form.data('booking-id') +']';
773
774 var start_time = $form.find('input[name="' + field_base_name + '[start_time][formatted_value]"]').val();
775 var start_time_ampm = $form.find('input[name="' + field_base_name + '[start_time][ampm]"]').val();
776 var start_time_minutes = latepoint_hours_and_minutes_to_minutes(start_time, start_time_ampm);
777 var end_time = $form.find('input[name="' + field_base_name + '[end_time][formatted_value]"]').val();
778 var end_time_ampm = $form.find('input[name="' + field_base_name + '[end_time][ampm]"]').val();
779 var end_time_minutes = latepoint_hours_and_minutes_to_minutes(end_time, end_time_ampm);
780
781 if(end_time_minutes && (end_time_minutes <= start_time_minutes)){
782 $form.find('.quick-end-time-w').addClass('ending-next-day');
783 }else{
784 $form.find('.quick-end-time-w').removeClass('ending-next-day');
785 }
786 }
787
788 function latepoint_set_booking_end_time($booking_data_form){
789 var booking_duration = 0;
790 var service_duration = Number($booking_data_form.find('.os-service-durations select').val());
791
792 let field_base_name = 'order_items[' + $booking_data_form.data('order-item-id') +'][bookings][' + $booking_data_form.data('booking-id') +']';
793
794 booking_duration = booking_duration + service_duration;
795 if($booking_data_form.find('select[name="temp_service_extras_ids"] option:selected').length){
796 $booking_data_form.find('select[name="temp_service_extras_ids"] option:selected').each(function(){
797 var extra_duration = Number(jQuery(this).data('duration'));
798 var $extra_quantity_input = jQuery(this).closest('.lateselect-w').find('.ls-item[data-value="' + jQuery(this).val() + '"]').find('.os-late-quantity-selector-input');
799 if($extra_quantity_input.length) extra_duration = Number(extra_duration) * Number($extra_quantity_input.val());
800 booking_duration = Number(booking_duration) + Number(extra_duration);
801 });
802 }
803
804 var start_time = $booking_data_form.find('input[name="'+field_base_name+'[start_time][formatted_value]"]').val();
805
806 if(start_time){
807 var start_time_ampm = $booking_data_form.find('input[name="'+field_base_name+'[start_time][ampm]"]').val();
808 var start_time_minutes = latepoint_hours_and_minutes_to_minutes(start_time, start_time_ampm);
809 var end_time_minutes = parseInt(start_time_minutes) + parseInt(booking_duration);
810 if(end_time_minutes >= (24 * 60)) end_time_minutes = (end_time_minutes - 24 * 60);
811 var end_time_ampm = (end_time_minutes >= 720 && end_time_minutes < (24 * 60)) ? 'pm' : 'am';
812 var end_hours_and_minutes = latepoint_minutes_to_hours_and_minutes(end_time_minutes);
813
814 $booking_data_form.find('input[name="'+field_base_name+'[end_time][formatted_value]"]').val(end_hours_and_minutes);
815 $booking_data_form.find('.quick-end-time-w .time-ampm-select.time-' + end_time_ampm).trigger('click');
816 $booking_data_form.find('input[name="'+field_base_name+'[end_time][formatted_value]"]').closest('.os-form-group').addClass('has-value');
817 }
818 latepoint_is_next_day($booking_data_form);
819 }
820
821
822
823 function latepoint_init_sortable_columns(){
824 jQuery('.os-sortable-column').on('click', function(){
825 let current_direction = jQuery(this).hasClass('ordered-desc') ? 'desc' : 'asc';
826 let new_direction = (current_direction == 'desc') ? 'asc' : 'desc';
827 jQuery(this).closest('table').find('.os-sortable-column').removeClass('ordered-desc').removeClass('ordered-asc');
828 jQuery(this).addClass('ordered-' + new_direction);
829
830 jQuery(this).closest('table').find('.records-ordered-by-key').val(jQuery(this).data('order-key'));
831 jQuery(this).closest('table').find('.records-ordered-by-direction').val(new_direction);
832 latepoint_filter_table(jQuery(this).closest('table'), jQuery(this).closest('.os-form-group'));
833 return false;
834 });
835 }
836 function latepoint_random_text(length){
837 var result = '';
838 var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
839 var charactersLength = characters.length;
840 for ( var i = 0; i < length; i++ ) {
841 result += characters.charAt(Math.floor(Math.random() * charactersLength));
842 }
843 return result;
844 }
845
846 function latepoint_get_order_for_service_categories(){
847
848 }
849
850
851 function latepoint_init_daterangepicker($elem){
852 $elem.each(function(){
853 // DATERANGEPICKER
854 var picker_start_time = jQuery(this).find('input[name="date_from"], .os-datepicker-date-from').val();
855 var picker_end_time = jQuery(this).find('input[name="date_to"], .os-datepicker-date-to').val();
856 var locale = {};
857 if(jQuery(this).data('can-be-cleared')) locale = { cancelLabel: jQuery(this).data('clear-btn-label')};
858
859
860 moment.locale(latepoint_helper.wp_locale);
861
862 jQuery(this).daterangepicker({
863 opens: 'center',
864 singleDatePicker: (jQuery(this).data('single-date') == 'yes'),
865 startDate: (picker_start_time) ? moment(picker_start_time) : moment(),
866 endDate: (picker_end_time) ? moment(picker_end_time) : moment(),
867 locale: locale
868 });
869 });
870
871 $elem.on('cancel.daterangepicker', function(ev, picker) {
872 if(picker.element.data('can-be-cleared')){
873 picker.element.find('input[name="date_from"], .os-datepicker-date-from').val('');
874 picker.element.find('input[name="date_to"], .os-datepicker-date-to').val('');
875 picker.element.find('span.range-picker-value').text(picker.element.data('no-value-label'));
876 if(picker.element.hasClass('os-table-filter-datepicker')){
877 latepoint_filter_table(picker.element.closest('table'), picker.element.closest('.os-form-group'));
878 }
879 }
880 });
881
882 $elem.on('apply.daterangepicker', function(ev, picker) {
883 if(picker.element.data('single-date') == 'yes'){
884 picker.element.find('.range-picker-value').text(picker.startDate.format('ll'));
885 }else{
886 picker.element.find('.range-picker-value').text(picker.startDate.format('ll') + ' - ' + picker.endDate.format('ll'));
887 }
888 picker.element.find('input[name="date_from"], .os-datepicker-date-from').attr('value', picker.startDate.format('YYYY-MM-DD'));
889 picker.element.find('input[name="date_to"], .os-datepicker-date-to').attr('value', picker.endDate.format('YYYY-MM-DD'));
890 if(picker.element.closest('.os-widget').length){
891 latepoint_reload_widget(picker.element.closest('.os-widget'));
892 }
893 if(picker.element.hasClass('os-table-filter-datepicker')){
894 latepoint_filter_table(picker.element.closest('table'), picker.element.closest('.os-form-group'));
895 }
896 });
897 }
898
899 function latepoint_recalculate_items_count_in_category(){
900 jQuery('.os-category-items-count').each(function(){
901 var number_of_items = jQuery(this).closest('.os-category-parent-w').find('.item-in-category-w').length;
902 jQuery(this).find('span').text(number_of_items);
903 });
904 }
905
906 function latepoint_remove_agent_box($remove_btn){
907 var $agent_box = $remove_btn.closest('.agent-box-w');
908 $agent_box.fadeOut(300, function(){ jQuery(this).remove(); });
909 }
910
911 function latepoint_remove_service_box($remove_btn){
912 var $service_box = $remove_btn.closest('.service-box-w');
913 $service_box.fadeOut(300, function(){ jQuery(this).remove(); });
914 }
915
916 function latepoint_init_monthly_view(){
917 if(!jQuery('.calendar-month-agents-w').length) return;
918
919 jQuery('.monthly-calendar-headers select').on('change', function(){
920 var $calendar = jQuery('.calendar-month-agents-w');
921 var route_name = $calendar.data('route');
922 $calendar.addClass('os-loading');
923 var params = { month: jQuery('#monthly_calendar_month_select').val(), year: jQuery('#monthly_calendar_year_select').val() };
924 if(jQuery('#monthly_calendar_location_select').length && jQuery('#monthly_calendar_location_select').val()) params.location_id = jQuery('#monthly_calendar_location_select').val();
925 if(jQuery('#monthly_calendar_service_select').length && jQuery('#monthly_calendar_service_select').val()) params.service_id = jQuery('#monthly_calendar_service_select').val();
926 var data = { action: latepoint_helper.route_action, route_name: route_name, params: params, layout: 'none', return_format: 'json' }
927 jQuery.ajax({
928 type : "post",
929 dataType : "json",
930 url : latepoint_timestamped_ajaxurl(),
931 data : data,
932 success: function(data){
933 $calendar.removeClass('os-loading');
934 if(data.status === "success"){
935 $calendar.html(data.message);
936 }else{
937 // console.log(data.message);
938 }
939 }
940 });
941 });
942 }
943
944
945 function latepoint_init_copy_on_click_elements(){
946
947 jQuery('.os-click-to-copy').on('mouseenter', function() {
948 var $this = jQuery(this);
949 var position_info = $this.offset();
950 var width = jQuery(this).outerWidth();
951 var position_left = position_info.left;
952 var position_top = position_info.top - 20 - jQuery(window).scrollTop();
953
954 let color = ($this.data('copy-tooltip-color') == 'dark') ? 'dark' : 'light';
955 if($this.data('copy-tooltip-position') == 'left'){
956 position_left = position_left - width - 5;
957 position_top = position_top + $this.outerHeight() - jQuery(window).scrollTop();
958 }
959 jQuery('body').append('<div class="os-click-to-copy-prompt color-'+color+'" style="top: '+position_top+'px; left: '+position_left+'px;">' + latepoint_helper.click_to_copy_prompt + '</div>');
960 }).on('mouseleave', function() {
961 jQuery('body').find('.os-click-to-copy-prompt').remove();
962 });
963 jQuery('.os-click-to-copy').on('click', function(){
964 var $this = jQuery(this);
965 let color = ($this.data('copy-tooltip-color') == 'dark') ? 'dark' : 'light';
966 jQuery('body').find('.os-click-to-copy-prompt').hide();
967 var text_to_copy = $this.is('input') ? $this.val() : $this.text();
968 navigator.clipboard.writeText(text_to_copy);
969
970 var position_info = $this.offset();
971 var width = $this.outerWidth();
972 var position_left = position_info.left;
973 var position_top = position_info.top - 20 - jQuery(window).scrollTop();
974
975 if($this.data('copy-tooltip-position') == 'left'){
976 position_left = position_left - width - 5;
977 position_top = position_top + $this.outerHeight() - jQuery(window).scrollTop();
978 }
979 var $done_prompt = jQuery('<div class="os-click-to-copy-done color-'+color+'" style="top: '+position_top+'px; left: '+position_left+'px;">' + latepoint_helper.click_to_copy_done + '</div>');
980 $done_prompt.appendTo(jQuery('body')).animate({
981 opacity: 0,
982 left: (position_left + 20),
983 }, 600);
984 setTimeout(function(){
985 jQuery('body').find('.os-click-to-copy-done').remove();
986 jQuery('body').find('.os-click-to-copy-prompt').show();
987 }, 800);
988 });
989 }
990
991 function latepoint_remove_floating_popup(){
992 jQuery('.os-showing-popup').removeClass('os-showing-popup');
993 jQuery('.os-floating-popup').remove();
994 }
995
996 function latepoint_init_clickable_cells(){
997 jQuery('.os-clickable-popup-trigger').on('click', function(){
998 var $this = jQuery(this);
999 var position = $this.offset();
1000 var width = $this.outerWidth();
1001 var $popup = jQuery('<div class="os-floating-popup os-loading"></div>');
1002 if($this.hasClass('os-showing-popup')){
1003 latepoint_remove_floating_popup();
1004 }else{
1005 latepoint_remove_floating_popup();
1006 $popup.offset({top: position.top, left: (position.left + width/2)});
1007 jQuery('body').append($popup);
1008 $this.addClass('os-showing-popup');
1009
1010 var route = $this.data('route');
1011 var params = $this.data('os-params');
1012 var data = { action: latepoint_helper.route_action, route_name: route, params: params, layout: 'none', return_format: 'json' };
1013 jQuery.ajax({
1014 type : "post",
1015 dataType : "json",
1016 url : latepoint_timestamped_ajaxurl(),
1017 data : data,
1018 success: function(response){
1019 if(response.status === latepoint_helper.response_status.success){
1020 jQuery('body').find('.os-floating-popup').html(response.message).removeClass('os-loading');
1021 latepoint_init_customer_donut_chart();
1022 jQuery('.os-floating-popup .os-floating-popup-close').on('click', function(){
1023 latepoint_remove_floating_popup();
1024 return false;
1025 });
1026 }else{
1027
1028 }
1029 }
1030 });
1031 }
1032 return false;
1033 });
1034 }
1035
1036 function latepoint_init_tiny_mce(element_id){
1037 // TODO CHECK IF wp.editor is defined
1038 if(typeof wp !== 'undefined' && typeof wp.editor !== 'undefined' && jQuery('#'+ element_id).length){
1039 wp.editor.remove(element_id);
1040 wp.editor.initialize(element_id,
1041 {
1042 tinymce: {
1043 wpautop: false,
1044 toolbar1: 'formatselect alignjustify forecolor | bold italic underline strikethrough | bullist numlist | blockquote hr | alignleft aligncenter alignright | link unlink | pastetext removeformat | outdent indent | undo redo',
1045 height : "480",
1046 },
1047 quicktags: true,
1048 mediaButtons: true,
1049 }
1050 );
1051 }
1052 }
1053
1054 function latepoint_init_reminder_form(){
1055 latepoint_init_tiny_mce(jQuery('.os-reminder-form:last-child textarea').attr('id'));
1056 }
1057
1058
1059 function latepoint_filter_table($table, $filter_elem, reset_page = true){
1060 $filter_elem.addClass('os-loading');
1061 var filter_params = $table.find('.os-table-filter').serialize();
1062 var $table_w = $table.closest('.table-with-pagination-w');
1063 if(reset_page){
1064 $table_w.find('select.pagination-page-select').val(1);
1065 }else{
1066 filter_params+= '&page_number='+$table_w.find('select.pagination-page-select').val();
1067 }
1068 var route = $table.data('route');
1069 var data = { action: latepoint_helper.route_action, route_name: route, params: filter_params, layout: 'none', return_format: 'json' };
1070 jQuery.ajax({
1071 type : "post",
1072 dataType : "json",
1073 url : latepoint_timestamped_ajaxurl(),
1074 data : data,
1075 success: function(data){
1076 $filter_elem.removeClass('os-loading');
1077 if(data.status === "success"){
1078 $table.find('tbody').html(data.message);
1079 if(data.total_pages && reset_page){
1080 var options = '';
1081 for(var i = 1; i <= data.total_pages; i++){
1082 options+= '<option>'+ i +'</option>';
1083 }
1084 $table_w.find('select.pagination-page-select').html(options);
1085 }
1086 $table_w.find('.os-pagination-from').text(data.showing_from);
1087 $table_w.find('.os-pagination-to').text(data.showing_to);
1088 $table_w.find('.os-pagination-total').text(data.total_records);
1089 latepoint_init_clickable_cells();
1090 }else{
1091 // console.log(data.message);
1092 }
1093 }
1094 });
1095 }
1096
1097 function latepoint_init_service_duration_box($duration_box){
1098 latepoint_init_input_masks(jQuery('.service-duration-box:last-child'));
1099 }
1100
1101 function latepoint_init_wizard_content(){
1102 latepoint_init_input_masks(jQuery('.os-wizard-step-content'));
1103 }
1104
1105 function latepoint_init_input_masks($scoped_element = false){
1106 let $wrapper = $scoped_element ? $scoped_element : jQuery('body');
1107 latepoint_mask_timefield($wrapper.find('.os-mask-time'));
1108
1109 $wrapper.find('.os-mask-phone').each(function(){
1110 latepoint_mask_phone(jQuery(this));
1111 });
1112
1113 latepoint_mask_money($wrapper.find('.os-mask-money'));
1114 latepoint_mask_date($wrapper.find('.os-mask-date'));
1115 latepoint_mask_minutes($wrapper.find('.os-mask-minutes'));
1116
1117 $wrapper.trigger('latepoint:initInputMasks');
1118 }