1(function($) { 2"use strict"; 3 4var $owl = []; 5var ajax_request = {}; 6var timer = {}; 7var sticky_sidebar; 8var sticky_cart; 9const $timeout = 80000; 10const $content_type = { 11 'form':'application/x-www-form-urlencoded; charset=UTF-8', 12 'json':'application/json' 13}; 14var $instance_lazy; 15 16const map_style =[ 17 { 18 "featureType": "administrative.country", 19 "elementType": "geometry", 20 "stylers": [ 21 { 22 "visibility": "off" 23 } 24 ] 25 } 26]; 27 28const api_location = site_url + "/apilocations"; 29const StoreName = 'store'; 30//const StoreMapName = 'Mapstore'; 31window.StoreMapName = 'Mapstore'; 32 33var dump = function(data) 34{ 35 console.debug(data); 36} 37 38var dump2 = function(data) { 39 alert(JSON.stringify(data)); 40}; 41 42var setStorage = function(key,value) 43{ 44 localStorage.setItem(key,value); 45} 46 47var getStorage = function(key) 48{ 49 return localStorage.getItem(key); 50} 51 52var removeStorage = function(key) 53{ 54 localStorage.removeItem(key); 55} 56 57 58function setInLocalStorageStore(storeKey, key, value) { 59 let store = JSON.parse(localStorage.getItem(storeKey)); 60 if (!store) { 61 store = {}; 62 } 63 store[key] = value; 64 localStorage.setItem(storeKey, JSON.stringify(store)); 65} 66 67// function getFromLocalStorageStore(storeKey, key) { 68// const store = JSON.parse(localStorage.getItem(storeKey)); 69// return store ? store[key] : undefined; 70// } 71 72window.getFromLocalStorageStore = function(storeKey, key) { 73 const store = JSON.parse(localStorage.getItem(storeKey)); 74 return store ? store[key] : undefined; 75}; 76 77function removeFromLocalStorageStore(storeKey, key) { 78 let store = JSON.parse(localStorage.getItem(storeKey)); 79 if (!store) { 80 return; 81 } 82 delete store[key]; 83 localStorage.setItem(storeKey, JSON.stringify(store)); 84} 85 86/** 87 * Reorder address to move UK postcode from start to end 88 * Input: "BN1 5HF, Westdene Drive, Brighton and Hove, Brighton, UK" 89 * Output: "Westdene Drive, Brighton and Hove, Brighton, BN1 5HF" 90 */ 91function reorderAddressPostcode(address, postcodeToAppend = null) { 92 if (!address || typeof address !== 'string') return address; 93 94 // UK postcode regex pattern (matches postcodes like BN1 5HF, SW1A 1AA, EC1A 1BB, etc.) 95 const ukPostcodeRegex = /^([A-Z]{1,2}\d[A-Z\d]?\s*\d[A-Z]{2}),\s*/i; 96 const match = address.match(ukPostcodeRegex); 97 98 if (match) { 99 const postcode = match[1].toUpperCase(); 100 // Remove postcode from beginning 101 let rest = address.substring(match[0].length); 102 // Remove UK/United Kingdom from end 103 rest = rest.replace(/,\s*(UK|United Kingdom|England|Scotland|Wales|Northern Ireland)\s*$/i, ''); 104 // Add postcode at the end 105 return rest + ', ' + postcode; 106 } 107 108 // If no postcode at start, just remove UK from end 109 let result = address.replace(/,\s*(UK|United Kingdom|England|Scotland|Wales|Northern Ireland)\s*$/i, ''); 110 111 // Check if address already contains a UK postcode anywhere 112 const hasPostcode = /[A-Z]{1,2}\d[A-Z\d]?\s*\d[A-Z]{2}/i.test(result); 113 114 // If no postcode found and we have one to append, add it at the end 115 if (!hasPostcode && postcodeToAppend && postcodeToAppend.trim()) { 116 result = result + ', ' + postcodeToAppend.trim().toUpperCase(); 117 } 118 119 return result; 120} 121 122const INCOMPLETE_ADDRESS_CONFIRM_MESSAGE = 123 'The address appears to be incomplete. Are you sure you want to save?'; 124const MISSING_DOOR_OR_FLAT_CONFIRM_MESSAGE = 125 'Door or Flat number is missing. Are you sure you want to save?'; 126const MISSING_POSTCODE_CONFIRM_MESSAGE = 127 'Postcode appears to be missing or incomplete. Are you sure you want to save?'; 128 129const UK_FULL_POSTCODE_REGEX = /\b([A-Z]{1,2}\d[A-Z\d]?|GIR)\s*(\d[A-Z]{2})\b/i; 130const UK_PLUS_CODE_REGEX = /\b[A-Z0-9]{4,8}\+[A-Z0-9]{2,3}\b/i; 131const UK_STREET_WORDS = [ 132 'street', 'st', 'road', 'rd', 'avenue', 'ave', 'lane', 'ln', 133 'close', 'court', 'ct', 'drive', 'dr', 'way', 'place', 'terrace', 134 'crescent', 'cres', 'gardens', 'grove', 'walk', 'row', 'parade', 135 'square', 'mews', 'yard', 'wharf', 'quay', 'path', 'approach', 136 'chase', 'estate', 'hill', 'rise', 'end', 'gate', 'green', 'park',
137 'view', 'vale', 'mead', 'meadow', 'orchard', 'wood', 'woods', 'croft', 138 'mount', 'broadway', 'circus', 'bank', 'bridge', 'cross', 'common', 139 'heath', 'lea', 'fold', 'nook', 'dale', 'dene', 'row', 'causeway', 140 'embankment', 'promenade', 'esplanade' 141]; 142const UK_COMPOUND_STREET_SUFFIXES = [ 143 'street', 'road', 'lane', 'avenue', 'drive', 'way', 'close', 'court', 144 'walk', 'grove', 'hill', 'gate', 'park', 'green', 'view', 'vale', 145 'croft', 'mead', 'rise', 'end', 'bank', 'mount', 'row', 'place', 'path' 146]; 147const UK_BUILDING_WORDS = [ 148 'house', 'farm', 'cottage', 'cottages', 'vicarage', 'lodge', 149 'manor', 'barn', 'barns' 150]; 151 152/** 153 * Warn on incomplete UK delivery addresses, with a specific message 154 * when the door/flat number or postcode is the missing part. 155 */ 156function extractUkPostcode(text) { 157 const match = String(text || '').toUpperCase().match(UK_FULL_POSTCODE_REGEX); 158 return match ? (match[1] + ' ' + match[2]) : ''; 159} 160 161function hasPlusCode(text) { 162 return UK_PLUS_CODE_REGEX.test(String(text || '')); 163} 164 165function isAdminAreaToken(token) { 166 const value = String(token || '').toLowerCase().replace(/[^a-z]/g, ''); 167 if (!value) { 168 return true; 169 } 170 const adminAreas = [ 171 'uk', 'gb', 'unitedkingdom', 'greatbritain', 'britain', 172 'england', 'scotland', 'wales', 'northernireland', 173 'bedfordshire', 'berkshire', 'buckinghamshire', 'cambridgeshire', 174 'cheshire', 'cheshireeast', 'cheshirewestandchester', 'cornwall', 'cumbria', 'derbyshire', 'devon', 'dorset', 'durham', 175 'essex', 'gloucestershire', 'hampshire', 'herefordshire', 'hertfordshire', 176 'kent', 'lancashire', 'leicestershire', 'lincolnshire', 'merseyside', 177 'norfolk', 'northamptonshire', 'northumberland', 'nottinghamshire', 178 'oxfordshire', 'rutland', 'shropshire', 'somerset', 'staffordshire', 179 'suffolk', 'surrey', 'sussex', 'eastsussex', 'westsussex', 180 'warwickshire', 'wiltshire', 'worcestershire', 'yorkshire', 181 'eastyorkshire', 'westyorkshire', 'southyorkshire', 'northyorkshire', 182 'greatermanchester', 'westmidlands', 'tyneandwear', 'isleofwight' 183 ]; 184 return adminAreas.indexOf(value) !== -1; 185} 186 187function hasAnyWord(text, words) { 188 const haystack = String(text || '').toLowerCase().trim(); 189 if (!haystack) { 190 return false; 191 } 192 return words.some((word) => new RegExp('\\b' + word + '\\b', 'i').test(haystack)); 193} 194 195function hasStreetName(text) { 196 if (hasAnyWord(text, UK_STREET_WORDS)) { 197 return true; 198 } 199 const tokens = String(text || '').toLowerCase().split(/\s+/); 200 return tokens.some((token) => { 201 if (!token || token.length < 6) { 202 return false; 203 } 204 return UK_COMPOUND_STREET_SUFFIXES.some((suffix) => { 205 return token.length > suffix.length + 2 && token.slice(-suffix.length) === suffix; 206 }); 207 }); 208} 209 210function stripPostcodeAndAdmin(text) { 211 let rest = String(text || '').replace(/\b([A-Z]{1,2}\d[A-Z\d]?|GIR)\s*(\d[A-Z]{2})\b/gi, ' '); 212 rest = rest.replace(/\b(UK|United Kingdom|Great Britain|England|Scotland|Wales|Northern Ireland)\b/gi, ' '); 213 rest = rest.replace(/\b(Lincolnshire|Cheshire East|Cheshire West and Chester|Cheshire|Cornwall|Devon|Dorset|Essex|Hampshire|Kent|Lancashire|Norfolk|Suffolk|Surrey|Sussex|Yorkshire|Somerset|Staffordshire|Warwickshire|Wiltshire|Worcestershire|Derbyshire|Nottinghamshire|Leicestershire|Northamptonshire|Cambridgeshire|Oxfordshire|Berkshire|Buckinghamshire|Hertfordshire|Bedfordshire|Gloucestershire|Herefordshire|Shropshire|Cumbria|Durham|Northumberland|Merseyside|Greater Manchester|Greater London|West Midlands|Tyne and Wear|Isle of Wight|East Sussex|West Sussex|Brighton and Hove)\b/gi, ' '); 214 rest = rest.replace(/\b([A-Z]{1,2}\d[A-Z\d]?)\b/g, ' '); 215 rest = rest.replace(/[^a-z0-9\s]/gi, ' ').replace(/\s+/g, ' ').trim(); 216 return rest; 217} 218 219function hasHouseOrFlatNumber(text) { 220 const rest = stripPostcodeAndAdmin(text); 221 if (!rest) { 222 return false; 223 } 224 if (/\b(flat|unit|apartment|apt|suite|plot|room)\s*\d+/i.test(rest)) { 225 return true; 226 } 227 return /\b\d+[a-z]?\b/i.test(rest); 228} 229 230function significantAddressTokens(rest) { 231 return String(rest || '').split(/\s+/).filter((token) => { 232 if (!token || token.length < 2) { 233 return false; 234 } 235 if (/^(the|and|of|at|in|to)$/i.test(token)) { 236 return false;
237 } 238 if (/^\d[a-z]{2}$/i.test(token)) { 239 return false; 240 } 241 return !isAdminAreaToken(token); 242 }); 243} 244 245function collectAddressText(payload) { 246 payload = payload || {}; 247 // Use the visible Delivery Address line, not leftover Google/DB fields. 248 // On edit, formatted_address and postal_code often still hold the previous 249 // saved values even after the customer deletes them from the form. 250 const mainAddress = String(payload.formattedAddress || payload.formatted_address || '').trim(); 251 return [ 252 mainAddress, 253 payload.address1, 254 payload.location_name 255 ].filter((part) => part && String(part).trim() !== '').join(' '); 256} 257 258function visibleUkPostcode(payload) { 259 return extractUkPostcode(collectAddressText(payload)); 260} 261 262/** 263 * @returns {''|'door'|'postcode'|'generic'} Empty string means save with no popup. 264 */ 265function getIncompleteAddressWarning(payload) { 266 const combined = collectAddressText(payload).replace(/\s+/g, ' ').trim(); 267 if (!combined) { 268 return 'generic'; 269 } 270 if (hasPlusCode(combined)) { 271 return 'generic'; 272 } 273 274 const fullPostcode = extractUkPostcode(combined); 275 const rest = stripPostcodeAndAdmin(combined); 276 const hasNumber = hasHouseOrFlatNumber(combined); 277 const hasStreet = hasStreetName(rest); 278 const hasBuilding = hasAnyWord(rest, UK_BUILDING_WORDS); 279 const tokens = significantAddressTokens(rest); 280 281 if (hasStreet && hasNumber && fullPostcode) { 282 return ''; 283 } 284 if (hasBuilding && fullPostcode) { 285 return ''; 286 } 287 if (!hasStreet && fullPostcode && tokens.length >= 2) { 288 return ''; 289 } 290 291 if ((hasStreet || hasBuilding) && hasNumber && !fullPostcode) { 292 return 'postcode'; 293 } 294 if (hasBuilding && !fullPostcode) { 295 return 'postcode'; 296 } 297 if (!hasStreet && tokens.length >= 2 && !fullPostcode) { 298 return 'postcode'; 299 } 300 if (hasStreet && fullPostcode && !hasNumber) { 301 return 'door'; 302 } 303 304 return 'generic'; 305} 306 307function confirmIncompleteAddressSave(payload, onConfirm) { 308 if (typeof onConfirm !== 'function') { 309 return; 310 } 311 const warning = getIncompleteAddressWarning(payload); 312 if (!warning) { 313 onConfirm(); 314 return; 315 } 316 317 let words = {}; 318 try { 319 if (typeof some_words !== 'undefined' && some_words) { 320 words = JSON.parse(some_words); 321 } 322 } catch (e) { 323 words = {}; 324 } 325 326 let message = words.incomplete_address_confirm || INCOMPLETE_ADDRESS_CONFIRM_MESSAGE; 327 if (warning === 'door') { 328 message = words.missing_door_or_flat_confirm || MISSING_DOOR_OR_FLAT_CONFIRM_MESSAGE; 329 } else if (warning === 'postcode') { 330 message = words.missing_postcode_confirm || MISSING_POSTCODE_CONFIRM_MESSAGE; 331 } 332 333 ElementPlus.ElMessageBox.confirm( 334 message, 335 '', 336 { 337 confirmButtonText: words.yes || 'Yes', 338 cancelButtonText: words.no || 'No', 339 type: 'warning', 340 closeOnClickModal: false, 341 distinguishCancelAndClose: true, 342 zIndex: 4000 343 } 344 ).then(() => { 345 onConfirm(); 346 }).catch(() => { 347 // User chose No or closed the dialog â stay on the form. 348 }); 349} 350 351window.getLocation = function() 352{ 353 const city_id = getFromLocalStorageStore(StoreName,"selectedCityId"); 354 const area_id = getFromLocalStorageStore(StoreName,"selectedAreaId"); 355 const state_id = getFromLocalStorageStore(StoreName,"selectedStateId"); 356 const postal_id = getFromLocalStorageStore(StoreName,"selectedPostalId"); 357 return { city_id, area_id , state_id , postal_id}; 358} 359 360jQuery.fn.exists = function(){return this.length>0;} 361 362window.empty = function(data){ 363 if (typeof data === "undefined" || data==null || data=="" || data=="null" || data=="undefined" ) { 364 return true; 365 } 366 return false; 367}; 368 369jQuery(document).ready(function() { 370 371 if( $('.sidebar-panel').exists() ) { 372 $('.sidebar-panel').slideAndSwipe(); 373 } 374 375 if( $('.headroom').exists() ) { 376 var myElement = document.querySelector(".headroom"); 377 dump(myElement); 378 var headroom = new Headroom(myElement); 379 headroom.init(); 380 } 381 382 $( document ).ready( function() { 383 $( '.dropdown' ).on( 'show.bs.dropdown', function() { 384 $( this ).find( '.dropdown-menu' ).first().stop( true, true ).slideDown( 150 ); 385 } ); 386 $('.dropdown').on( 'hide.bs.dropdown', function(){ 387 $( this ).find( '.dropdown-menu' ).first().stop( true, true ).slide
387Up( 150 ); 388 } ); 389 }); 390 391 392 /*if( $('.owl-carousel').exists() ) { 393 $owl = $(".owl-carousel").owlCarousel({ 394 items:5, 395 lazyLoad:true, 396 loop:true, 397 margin:15 398 }); 399 }*/ 400 401 if( $('.star-rating').exists() ) { 402 initStarRating(); 403 } 404 405 $( document ).on( "change", "#min_range_slider", function() { 406 $(".min-selected-range").html( $(this).val()); 407 }); 408 409 $('.collapse').on('show.bs.collapse', function(){ 410 $(this).parent().find("a").removeClass("closed").addClass("opened"); 411 }).on('hidden.bs.collapse', function(){ 412 $(this).parent().find("a").removeClass("opened").addClass("closed"); 413 }); 414 415 /*$( document ).on( "click", ".quantity-add-cart", function() { 416 var $_this = $(this); 417 var $_this_qty = $(this).closest('.quantity-wrapper').find('.qty'); 418 $_this_qty.html(1); 419 $_this.hide().parent().find(".quantity-parent").show(); 420 }); */ 421 422 /*$( document ).on( "click", ".qty-btn", function() { 423 var $_this_qty = $(this).parent().parent().find(".qty"); 424 var $_add_to_cart = $(this).closest('.quantity-wrapper').find('.quantity-add-cart'); 425 var $_qty_parent = $(this).closest('.quantity-parent'); 426 427 var $cart_do = $(this).data("id"); 428 var $qty = parseInt( $_this_qty.html() ); 429 430 switch($cart_do){ 431 case "plus": 432 $qty = $qty+1; 433 break 434 435 case "less": 436 $qty = $qty-1; 437 break 438 } 439 440 if($qty<=0){ 441 $_qty_parent.hide(); 442 $_add_to_cart.show(); 443 } 444 $_this_qty.html( $qty ); 445 446 });*/ 447 448 /*STICKY SIDEBAR*/ 449 /*sticky_sidebar = $('.sticky-sidebar').stickySidebar({ 450 topSpacing: 20, 451 });*/ 452 453 if( $('.sticky-sidebar').exists() ) { 454 sticky_sidebar = new StickySidebar('.sticky-sidebar', {topSpacing: 20}); 455 } 456 if( $('.sticky-cart').exists() ) { 457 sticky_cart = new StickySidebar('.sticky-cart', {topSpacing: 20}); 458 } 459 460 /*STICKY*/ 461 $(".category-nav").sticky({topSpacing:0}); 462 463 /*GALLERY*/ 464 $('.gallery_magnific').magnificPopup({ 465 delegate: 'a', 466 type: 'image', 467 gallery: { 468 enabled: true 469 }, 470 removalDelay: 300, 471 mainClass: 'mfp-fade' 472 }); 473 474 475 /*$( document ).on( "click", ".list-selection li, .single-select", function(event) { 476 var $input = $(this).find('input'); 477 478 if( $(event.target).hasClass('qty-btn') || $(event.target).hasClass('zmdi') ){ 479 return; 480 } 481 482 if ( $input.attr("type")=="checkbox"){ 483 $input.prop('checked', !($input.is(':checked'))); 484 } else $input.prop('checked',true); 485 486 var $parent = $(this).parent().parent().find("a"); 487 $parent.each(function(index, $obj){ 488 $($obj).removeClass("active"); 489 }); 490 $(this).addClass("active"); 491 });*/ 492 493 $( document ).on( "click", ".toogle-radio", function() { 494 var $_this = $(this).find('input'); 495 if($_this.prop('checked')==false){ 496 $_this.prop('checked',true); 497 } else { 498 $_this.prop('checked',false); 499 } 500 }); 501 502 $( document ).on( "click", ".desired_delivery", function() { 503 HideandShow( $(this).find("input").val() ,{ 504 'now':'hide', 505 'schedule':'show' 506 }, '.schedule-section' ); 507 }); 508 509 /*$( document ).on( "click", ".add_tips", function() { 510 HideandShow( $(this).find("input").val() ,{ 511 '10':'hide', 512 '20':'hide', 513 '30':'hide', 514 'other':'show' 515 }, '.tips-other-section' ); 516 });*/ 517 518 $( document ).on( "click", ".a-account", function() { 519 $(".login-wrap,.signup-wrap,.account-section").hide(); 520 $( "."+$(this).data("id") ).show(); 521 }); 522 523 $( document ).on( "click", ".close-modal", function() { 524 closeModal( $(this).data('id') ); 525 }); 526 527 528 /*TYPEEHEAD*/ 529 if( $('.auto_typehead').exists() ) { 530 var $typehead_settings = {}; 531 $('.auto_typehead').each(function(index, $obj){ 532 var $_this = $(this); 533 var $api = $_this.data("api"); 534 var $display = $_this.data("display"); 535 536 var $temp_settings = parseQuery( $_this.data("settings") ); 537 538 $.each($temp_settings,function(key, val) { 539 if(val=="true"){ 540 $typehead_settings[key]=true; 541 } else if ( val=="false"){ 542 $typehead_settings[key]=false; 543 } else { 544 $typehead_settings[key]=val; 545 } 546 }); 547 548 $typehead_settings['input'] = $_this; 549 550 $typehead_settings['source'] = { 551 user: { 552 display: $display.split(","), 553 ajax: { 554 method: "POST", 555 url: ajaxurl +"/"+$api, 556 path: "details.data", 557 data: { 558 q: "{{query}}", 559 'YII_CSRF_TOKEN': $('meta[name=YII_CSRF_TOKEN]').attr('content') 560 }, 561 beforeSend: function (jqXHR, options) { 562 dump('before send'); 563 //$(".typhead-error").remove(); 564 565 if($api=="getlocation_autocomplete"){ 566 if( $('.change-address-modal').exists() ) {
567 $(".change-address-modal").find(".modal-content").addClass("opened"); 568 } 569 } 570 571 }, 572 callback: { 573 done: function (data) { 574 /*if(data.code==2){ 575 var $found_err = $_this.parent().find(".typhead-error"); 576 if($found_err.length<=0){ 577 $_this.after('<p class="typhead-error m-0 text-danger">'+ data.msg+'</p>'); 578 } else { 579 $found_err.html( data.msg ); 580 } 581 $(".typeahead__container").removeClass("loading"); 582 return false; 583 }*/ 584 return data; 585 }, 586 fail: function (jqXHR, textStatus, errorThrown) {}, 587 always :function (data, textStatus, jqXHR) { 588 dump("always"); 589 }, 590 then: function (jqXHR, textStatus) {} 591 } 592 } 593 } 594 }; 595 596 $typehead_settings['template'] = function (query, item) { 597 return $_this.data("template"); 598 }; 599 600 $typehead_settings['emptyTemplate'] = $_this.data("emptytemplate"); 601 602 $typehead_settings['callback'] = { 603 onClickAfter: function (node, a, item, event) { 604 605 var $method = node.data("api"); 606 607 switch($method){ 608 case "getlocation_autocomplete": 609 610 var $services = getServiceSelected(); 611 var $params ='id='+ item.id + "&addressLine1="+ item.addressLine1 + "&addressLine2="+item.addressLine2; 612 613 if(item.provider=="google.maps"){ 614 if ((typeof item.place_type !== "undefined") && ( item.place_type !== null)) { 615 $params+="&place_type=" + item.place_type; 616 } 617 } else if( item.provider=="mapbox" ) { 618 if ((typeof item.latitude !== "undefined") && ( item.latitude !== null)) { 619 $params+="&latitude=" + item.latitude; 620 $params+="&longitude=" + item.longitude; 621 $params+="&place_type=" + item.place_type; 622 } 623 } 624 625 $params+="&services="+$services; 626 processAjax('getLocationDetails',$params,'typeahead_loader',1); 627 628 break; 629 630 case "getSearchSuggestion": 631 window.location.href = item.url; 632 break; 633 634 } //end switch 635 636 // onClickAfter 637 }, 638 onCancel: function (node, item, event) { 639 640 if($api=="getlocation_autocomplete"){ 641 if( $('.change-address-modal').exists() ) { 642 $(".change-address-modal").find(".modal-content").removeClass("opened"); 643 } 644 } 645 // onCancel 646 } 647 // 648 }; 649 650 $typehead_settings['selector'] = { 651 list: "typeahead__list list-unstyled", 652 }; 653 654 //dump($typehead_settings); 655 $.typeahead($typehead_settings); 656 }); 657 } 658 /*END TYPEEHEAD*/ 659 660 $( document ).on( "click", ".get_current_location", function() { 661 getCurrentLocation('get_place_details'); 662 }); 663 664 665 /*SHOW FILTER*/ 666 if( $('.load-ajax').exists() ) { 667 $('.load-ajax').each(function(index, $obj){ 668 var $ajax_method = $($obj).data("action"); 669 var $params = $($obj).data("params"); 670 var $loader_type = $($obj).data("loader_type"); 671 var $single_call = $($obj).data("single_call"); 672 var $silent = $($obj).data("silent"); 673 var $method = $($obj).data("method");
674 var $content_type = $($obj).data("content_type"); 675 var $data = parseQuery($params); 676 if($content_type=="json"){ 677 if($ajax_method=="getFeed"){ 678 var $services = $data.services; 679 $params = { 680 'local_id':$data.local_id, 681 'target':$data.target, 682 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 683 'filters':{ 684 'services':$services.split(",") 685 } 686 }; 687 } 688 $params = JSON.stringify($params); 689 } 690 processAjax($ajax_method,$params,$loader_type,$single_call,$silent,$method,$content_type); 691 }); 692 } 693 694 /*if( $('.list-loader').exists() ) { 695 $('.list-loader').each(function(index, $obj){ 696 listPlaceholder($(this) , $obj); 697 }); 698 }*/ 699 700 $( document ).on( "click", ".show-more", function($obj) { 701 var $ajax_method = $(this).data("action"); 702 var $params = $(this).data("params"); 703 var $loader_type = $(this).data("loader_type"); 704 var $single_call = $(this).data("single_call"); 705 var $data = parseQuery($params); 706 var $filters = $data.filters; 707 $filters = $filters.replace(/\\/g, ''); 708 $filters = JSON.parse( $filters ); 709 710 $params = { 711 'local_id':$data.local_id, 712 'page': $data.page, 713 'target':$data.target, 714 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 715 'filters': $filters 716 }; 717 $params = JSON.stringify($params); 718 processAjax($ajax_method,$params,$loader_type,$single_call,null,'PUT','json'); 719 }); 720 721 $( document ).on( "click", ".restaurants-filter", function($obj) { 722 var $local_id = $("#local_id").val(); 723 var $target = $("#target").val(); 724 var $params=''; 725 var $sort = $(".sort:checked").val(); 726 var $price_range = $(".price_range:checked").val(); 727 var $max_fee = $("#min_range_slider").val(); 728 var $ratings = $(".ratings_selected").val(); 729 var $services = []; var $cuisine=[]; 730 731 $(".services:checked").each(function() { 732 $services.push( $(this).val() ); 733 }); 734 $(".cuisine:checked").each(function() { 735 $cuisine.push( $(this).val() ); 736 }); 737 738 if ((typeof $sort !== "undefined") && ( $sort !== null)) { 739 // 740 } else $sort=''; 741 742 $params = { 743 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 744 'local_id':$local_id, 745 'target':$target, 746 'filters': { 747 'services':$services, 748 'cuisine':$cuisine, 749 'price_range':$price_range, 750 'max_fee':parseInt($max_fee), 751 'ratings':parseInt($ratings), 752 'sort':$sort 753 } 754 }; 755 $params = JSON.stringify($params); 756 processAjax('getFeed',$params,'restaurants_filter',1,1,'PUT','json'); 757 }); 758 759 760 // init lazy load 761 $(function(){ 762 initLazyImage(); 763 }); 764 765 $('#changeAddress').on('shown.bs.modal', function (e) { 766 $(".auto_typehead").val(''); 767 $(".auto_typehead").focus(); 768 }); 769 $('#changeAddress').on('hidden.bs.modal', function (e) { 770 $(".change-address-modal").find(".modal-content").removeClass("opened"); 771 }); 772 773 $( document ).on( "click", ".get-item-details", function($obj) { 774 var $item_uuid = $(this).data("item_uuid"); 775 var $cat_id = $(this).closest('section').data("cat_id"); 776 processAjax("getMenuItem","&merchant_id="+ merchant_id + "&item_uuid=" + $item_uuid + "&cat_id="+ $cat_id ); 777 }); 778 779 780 $( document ).on( "click", ".choose-size", function() { 781 var $item_size_id = $(this).find('input:checked').val(); 782 if ((typeof $item_size_id !== "undefined") && ( $item_size_id !== null)) { 783 AddonCategoryRows($item_size_id); 784 } 785 }); 786 787 $( document ).on( "click", ".addon-items", function(event) { 788 /*var $parent = $(this).closest("ul"); 789 var $addon_multi_option = $parent.data("multi_option"); 790 var $addon_multi_option_value = $parent.data("multi_option_value"); 791 792 dump("$addon_multi_option=>"+$addon_multi_option); 793 794 switch($addon_multi_option){ 795 case "custom": 796 var $inputs = $parent.find("input:checked"); 797 var $total_selected = $inputs.length; 798 dump($total_selected+"=>"+$addon_multi_option_value); 799 if($total_selected>=$addon_multi_option_value){ 800 $parent.find("input:checkbox:not(:checked)").attr("disabled",true); 801 } else {
802 $parent.find("input:disabled").attr("disabled",false); 803 } 804 break; 805 }*/ 806 /*setTimeout(function() { 807 ItemSummary(); 808 }, 1); */ 809 }); 810 811 /*$( document ).on( "click", ".multiple_qty", function(event) { 812 setTimeout(function() { 813 ItemSummary(); 814 }, 1); 815 });*/ 816 817 /*$( document ).on( "click", ".add_to_cart", function(event) { 818 addToCart(); 819 });*/ 820 821}); 822/*end doc ready*/ 823 824var listPlaceholder = function($_this){ 825 var $html=''; 826 var $itemlimit = parseInt( list_limit ); 827 dump("$itemlimit=>"+$itemlimit); 828 for (let i = 0; i < $itemlimit; i++) { 829 $html+='<div class="col-lg-3 col-md-3 mb-4 mb-lg-3">'; 830 $html+='<div class="position-relative skeleton-height">'; 831 $html+='<div class="skeleton-placeholder"></div>'; 832 $html+='</div>'; 833 $html+='</div>'; 834 } 835 $_this.html( $html ); 836}; 837 838var getCurrentLocation = function(next_steps){ 839 840 var options = { 841 enableHighAccuracy: true, 842 timeout: 5000, 843 maximumAge: 0 844 }; 845 846 if (navigator.geolocation) { 847 initLoader('typeahead_loader',1); 848 navigator.geolocation.getCurrentPosition(function(position){ 849 850 var $services = getServiceSelected(); 851 852 processAjax("reverseGeocoding","lat="+ position.coords.latitude + "&lng=" + position.coords.longitude + "&services=" + $services + "&next_steps="+next_steps ,'typeahead_loader',1); 853 854 }, function(err){ 855 initLoader('typeahead_loader',false); 856 notify( err.message ); 857 }, options); 858 } else { 859 notify( t("Error: Your browser doesn't support geolocation.") ); 860 initLoader('typeahead_loader',false); 861 } 862}; 863 864var getServiceSelected = function(){ 865 var $services =''; 866 if( $('#services').exists() ) { 867 $("#services option:selected").each(function(){ 868 $services+=$(this).val()+','; 869 }); 870 } 871 return $services; 872}; 873 874function parseQuery(str) 875{ 876 if(typeof str != "string" || str.length == 0) return {}; 877 var s = str.split("&"); 878 var s_length = s.length; 879 var bit, query = {}, first, second; 880 for(var i = 0; i < s_length; i++) 881 { 882 bit = s[i].split("="); 883 first = decodeURIComponent(bit[0]); 884 if(first.length == 0) continue; 885 second = decodeURIComponent(bit[1]); 886 if(typeof query[first] == "undefined") query[first] = second; 887 else if(query[first] instanceof Array) query[first].push(second); 888 else query[first] = [query[first], second]; 889 } 890 return query; 891} 892 893var HideandShow = function($value, $data , $target){ 894 $.each($data,function(key, val) { 895 dump(key+"=>"+val +"=>"+$value); 896 if($value==key){ 897 if(val=="show"){ 898 $($target).show(); 899 } else { 900 $($target).hide(); 901 } 902 } 903 }); 904}; 905 906var closeModal = function($modal_id){ 907 $('#'+$modal_id).modal('hide') 908}; 909 910var initLazyImage = function(){ 911 $instance_lazy = $(".lazy").Lazy({ 912 chainable: false, 913 beforeLoad: function(element) { 914 //dump('before load'); 915 }, 916 afterLoad: function(element) { 917 /*dump('after load'); 918 dump(element);*/ 919 element.parent().parent().addClass("image-loaded"); 920 //element.parent().addClass("image-loaded"); 921 }, 922 onError: function(element) { 923 //dump('error loading image'); 924 }, 925 onFinishedAll: function() { 926 //dump('finish loading all image'); 927 } 928 }); 929}; 930 931var updateLazyImage = function(){ 932 933 setTimeout(() => { 934 /*$instance_lazy.addItems( $('.lazy') ); 935 $instance_lazy.loadAll(); */ 936 initLazyImage(); 937 }, 500); 938}; 939 940var t = function(words){ 941 return words; 942}; 943 944/*var notify = function($message, $message_type){ 945 dump2($message); 946};*/ 947 948const notyf = new Notyf({ 949 'duration':1000*4 950}); 951 952var notify = function($message, $message_type){ 953 switch($message_type){ 954 case "error": 955 notyf.error($message); 956 break; 957 958 default: 959 notyf.success($message); 960 break; 961 } 962}; 963 964const DEMO_notyf = new Notyf({ 965 'duration':10000*6, 966 'dismissible':true, 967 'icon':'', 968 }); 969 970var helpNotify = function(message){ 971 DEMO_notyf.success(message); 972}; 973 974var getTimeNow = function(){ 975 /*var d = new Date(); 976 var n = d.getTime(); 977 n = parseInt(n) + parseInt(d.getMilliseconds()); 978 return n;*/ 979 var n = Date.now() + ( (Math.random()*100000).toFixed()); 980 return n; 981}; 982 983window.addValidationRequest = function(){ 984 var params=''; 985 var yii_token = $('meta[name=YII_CSRF_TOKEN]').attr('content'); 986 params+="&YII_CSRF_TOKEN="+yii_token; 987 return params; 988} 989 990/*mycall*/ 991var processAjax = function(action , data , loader_type, single_c
991all, silent, method , content_type){ 992 993 var timenow = getTimeNow(); 994 if(!empty(single_call)){ 995 timenow = single_call; 996 } 997 998 //dump("timenow=>"+ timenow); 999 1000 if(empty(silent)){ 1001 silent = null; 1002 } 1003 1004 var $content_type =''; 1005 1006 if(empty(method)){ 1007 method="POST"; 1008 } 1009 if(empty(content_type)){ 1010 $content_type = 'application/x-www-form-urlencoded; charset=UTF-8'; 1011 data+=addValidationRequest(); 1012 } else { 1013 $content_type = 'application/json'; 1014 } 1015 1016 ajax_request[timenow] = $.ajax({ 1017 url: ajaxurl+"/"+action, 1018 method: method, 1019 data: data , 1020 dataType: "json", 1021 contentType : $content_type , 1022 timeout: $timeout, 1023 crossDomain: true, 1024 beforeSend: function( xhr ) { 1025 //dump("is silent=>"+silent); 1026 //if ((typeof silent !== "undefined") && ( silent !== null)) { 1027 if(silent==null){ 1028 //dump("ok silent => " + action); 1029 } else { 1030 //dump("show loader_type=> "+ loader_type); 1031 initLoader(loader_type,true); 1032 } 1033 if(ajax_request[timenow] != null) { 1034 //dump("request aborted"); 1035 ajax_request[timenow].abort(); 1036 clearTimeout( timer[timenow] ); 1037 } else { 1038 timer[timenow] = setTimeout(function() { 1039 ajax_request[timenow].abort(); 1040 //notify( t('Request taking lot of time. Please try again') ); 1041 }, $timeout); 1042 } 1043 } 1044 }); 1045 1046 1047 ajax_request[timenow].done(function( data ) { 1048 //dump('done'); 1049 var next_action=''; 1050 if ((typeof data.details !== "undefined") && ( data.details !== null)) { 1051 if ((typeof data.details.next_action !== "undefined") && ( data.details.next_action !== null)) { 1052 next_action = data.details.next_action; 1053 } 1054 } 1055 1056 if(data.code==1){ 1057 switch(next_action){ 1058 case "redirect": 1059 window.location.href = data.details.redirect_url; 1060 break; 1061 1062 case "get_place_details": 1063 var $data = data.details.data; 1064 $(".auto_typehead").val( $data.address.address1 ); 1065 var $params ='id='+ $data.place_id + "&addressLine1="+ $data.address.address1 + "&addressLine2="+$data.address.address2; 1066 if(data.details.provider=="google.maps"){ 1067 if ((typeof $data.place_type !== "undefined") && ( $data.place_type !== null)) { 1068 $params+="&place_type=" + $data.place_type; 1069 } 1070 } else if( data.details.provider=="mapbox" ) { 1071 if ((typeof $data.latitude !== "undefined") && ( $data.latitude !== null)) { 1072 $params+="&latitude=" + $data.latitude; 1073 $params+="&longitude=" + $data.longitude; 1074 $params+="&place_type=" + $data.place_type; 1075 } 1076 } 1077 1078 $params+="&services="+data.details.services; 1079 processAjax('getLocationDetails',$params,'typeahead_loader',1); 1080 break; 1081 1082 case "sidebar_filter": 1083 $(".sidenav-filter").html( data.details.data ); 1084 $(".min-selected-range").html( $("#min_range_slider").val()); 1085 initStarRating(); 1086 1087 $('#moreCuisine').on('shown.bs.collapse', function () { 1088 $(".more-cuisine u").html( t("View less") ); 1089 }); 1090 $('#moreCuisine').on('hidden.bs.collapse', function () { 1091 $(".more-cuisine u").html( t("Show more +") ); 1092 }); 1093 1094 break; 1095 1096 case "fill_feed": 1097 1098 fillFeed({ 1099 'action': data.details.action, 1100 'title':data.details.total_message, 1101 'data': data.details.data , 1102 'target':data.details.target , 1103 'append': data.details.append , 1104 'show_next_page': data.details.show_next_page, 1105 'next_page_data': data.details.next_page_data 1106 }); 1107 break; 1108 1109 case "merchant_menu": 1110 1111 /*MerchantMenu({ 1112 'data':data.details.data, 1113 'target':data.details.target , 1114 });*/ 1115 1116 MerchantMenu({ 1117 'data':data.details.data, 1118 }); 1119 1120 break; 1121 1122 case "show_item_details": 1123 $('#itemModal').modal('show'); 1124 ItemDetails( data.details.data ); 1125 break; 1126 1127 case "fill_price_format": 1128 $(data.details.data.target).html( data.details.data.pretty_price ); 1129 break; 1130 1131 } 1132 } else { 1133 switch(next_action){ 1134 case "location_details_no_results": 1135 notify( data.msg ); 1136 $(".typeahead__container").removeClass("loading") 1137 break; 1138 1139 case "clear_restaurant_results": 1140 var $target = data.details.target; 1141 var $html=''; 1142 $html+='<div class="list-items mt-4 row hover01 list-loader load-ajax"></div>'; 1143 $html+=data.details.data; 1144 $($target).html($html); 1145 break; 1146 1147 default: 1148 notify( data.msg ); 1149 break; 1150 } 1151 } 1152 1153 }); 1154 1155 /*ALWAYS*/ 1156 ajax_request[timenow].always(function() { 1157 //dump("ajax always"); 1158 initLoader(loader_type,false); 1159 ajax_request[timenow]=null; 1160 clearTimeout(timer[timenow]); 1161 }); 1162 1163 /*FAIL*/ 1164 ajax_request[timenow].fail(function( jqXHR, textStatus ) { 1165 clearTimeout(timer[timenow]); 1166 //notify( t("Failed") + ": " + textStatus ,'danger' ); 1167 }); 1168 1169}; 1170/*end mycall*/ 1171 1172var fillFeed = function($data){ 1173 //dump( $data ); 1174 1175 var $html=''; var $items =''; var $bgcolor; var $fncolor; var $attrs=''; 1176 var $append = parseInt($data.append); 1177 var $target = $data.target; 1178 var $show_next_page = $data.show_next_page; 1179 1180 $html+='<h4 class="total_message title">'; 1181 $html+= '<span>'+ $data.title +'</span>' ; 1182 $html+='<div class="skeleton-placeholder"></div>'; 1183 $html+='</h4>'; 1184 1185 $html+='<div class="list-items mt-4 row hover01 list-loader load-ajax">'; 1186 1187 $.each($data.data, function(key, val){ 1188 1189 $items+='<div class="col-lg-3 col-md-3 mb-4 mb-lg-3">'; 1190 $items+='<a href="'+ val.url +'">'; 1191 $items+='<div class="position-relative">'; 1192 $items+='<div class="skeleton-placeholder"></div>'; 1193 $items+='<figure><img class="rounded lazy" data-src="'+ val.url_logo +'"/></figure>'; 1194 $items+='<h6 class="mt-2">'+ val.restaurant_name +'</h6>'; 1195 1196 $items+='<div class="row">'; 1197 $items+='<div class="col d-flex justify-content-start align-items-center"> '; 1198 $items+='<p class="m-0"><i class="zmdi zmdi-time"></i> '+ val.delivery_estimation +'</p>'; 1199 $items+='</div>'; 1200 $items+='<div class="col d-flex justify-content-end align-items-center">'; 1201 if(val.delivery_fee_raw>0){ 1202 $items+='<p class="m-0"><i class="zmdi zmdi-car"></i> '+ val.delivery_fee +'</p>'; 1203 } 1204 $items+='</div>'; 1205 $items+='</div>'; 1206 1207 $items+='<div class="position-top">'; 1208 1209 if ((typeof val.cuisine !== "undefined") && ( val.cuisine !== null)) { 1210 if(val.cuisine.length>0){ 1211 $bgcolor = val.cuisine[0].bgcolor; 1212 $fncolor = val.cuisine[0].fncolor; 1213 $items+='<span class="badge" style="background:'+ $bgcolor +';font-color:'+ $fncolor +';">'+ val.cuisine[0].cuisine_name +'</span>'; 1214 } 1215 } 1216 1217 $items+='<span class="badge rounded-pill float-right" style="background:'+ $bgcolor +';font-color:'+ $fncolor +';" >'+ val.ratings +'</span>'; 1218 $items+='</div>'; 1219 1220 $items+='</div>'; 1221 $items+='</a>'; 1222 $items+='</div>'; 1223 }); 1224 1225 if($append<=0){ 1226 $html+=$items; 1227 } 1228 1229 $html+='</div>'; 1230 1231 if($show_next_page==true){ 1232 dump("SHOW NEXT"); 1233 $.each($data.next_page_data, function(key, val){ 1234 if(key=="filters"){ 1235 $attrs+="&filters="+ addslashes(JSON.stringify(val)); 1236 } else $attrs+=key+"="+val+"&"; 1237 }); 1238 1239 dump("ATTRIBUTES"); 1240 dump($attrs); 1241 1242 $html+='<div class="text-center show_more_section mt-5">'; 1243 $html+='<a href="javascript:;" class="btn btn-black show-more" ';
1244 $html+='data-action='+$data.action+' data-params='+$attrs ; 1245 $html+='\n'; 1246 $html+='data-loader_type='+ 'show_more' +' data-single_call="1"' ; 1247 $html+='data-silent=""' ; 1248 $html+='>'+ t("Show more") +'</a>'; 1249 $html+='<div class="m-auto circle-loader medium" data-loader="circle-side"></div>'; 1250 $html+='</div>'; 1251 } else { 1252 $(".show_more_section").hide(); 1253 } 1254 1255 1256 if($append>0){ 1257 $(".list-items").append( $items ); 1258 } else { 1259 $($target).html( $html ); 1260 } 1261 1262 updateLazyImage(); 1263}; 1264 1265var addslashes = function(str) 1266{ 1267 return (str + '') 1268 .replace(/[\\"']/g, '\\$&') 1269 .replace(/\u0000/g, '\\0') 1270}; 1271 1272/*myloader*/ 1273var initLoader = function(loader_type,is_show){ 1274 //dump("loader_type=>"+loader_type + " =>" + is_show); 1275 switch(loader_type){ 1276 case "getLocationDetails": 1277 case "typeahead_loader": 1278 if(is_show){ 1279 $(".typeahead__container").addClass("loading"); 1280 } else { 1281 setTimeout(function() { 1282 $(".typeahead__container").removeClass("loading") 1283 }, 1000); 1284 } 1285 break; 1286 1287 case "show_more": 1288 if(is_show){ 1289 $(".show_more_section").addClass("loading"); 1290 } else { 1291 $(".show_more_section").removeClass("loading"); 1292 } 1293 break; 1294 1295 case "results_loader": 1296 if(is_show){ 1297 listPlaceholder( $('.list-loader') ); 1298 } else { 1299 // 1300 } 1301 break; 1302 1303 case "restaurants_filter": 1304 if(is_show){ 1305 listPlaceholder( $('.list-loader') ); 1306 $(".restaurants-filter").addClass("loading"); 1307 $(".total_message").addClass("loading"); 1308 $(".show_more_section").hide(); 1309 } else { 1310 $(".restaurants-filter").removeClass("loading"); 1311 $(".total_message").removeClass("loading"); 1312 } 1313 break; 1314 1315 case "add_to_cart": 1316 if(is_show){ 1317 $(".add_to_cart").addClass("loading"); 1318 } else { 1319 $(".add_to_cart").removeClass("loading"); 1320 } 1321 break; 1322 1323 default: 1324 break; 1325 } 1326}; 1327 1328var initStarRating = function(){ 1329 1330 var $star_settings = {}; 1331 $('.star-rating').each(function(index, $obj){ 1332 var $_this = $(this); 1333 var $totalstars = $(this).data("totalstars"); 1334 var $initialrating = $(this).data("initialrating"); 1335 var $strokecolor = $(this).data("strokecolor"); 1336 var $ratedcolor = $(this).data("ratedcolor"); 1337 var $strokewidth = parseInt($(this).data("strokewidth")); 1338 var $starsize = parseInt($(this).data("starsize")); 1339 var $readonly = $(this).data("readonly"); 1340 var $minrating = $(this).data("minrating"); 1341 var $disableafterrate = $(this).data("disableafterrate"); 1342 var $usefullstars = $(this).data("usefullstars"); 1343 var $hovercolor = $(this).data("hovercolor"); 1344 1345 $star_settings['totalStars'] = !empty($totalstars)?$totalstars:''; 1346 $star_settings['initialRating'] = !empty($initialrating)?$initialrating:''; 1347 $star_settings['minRating'] = !empty($minrating)?$minrating:''; 1348 $star_settings['strokeColor'] = !empty($strokecolor)?$strokecolor:''; 1349 $star_settings['ratedColor'] = !empty($ratedcolor)?$ratedcolor:''; 1350 $star_settings['hoverColor'] = !empty($hovercolor)?$hovercolor:''; 1351 $star_settings['strokeWidth'] = !empty($strokewidth)?$strokewidth:''; 1352 $star_settings['starSize'] = !empty($starsize)?$starsize:''; 1353 $star_settings['readOnly'] = !empty($readonly)?$readonly:''; 1354 $star_settings['disableAfterRate'] = $disableafterrate; 1355 $star_settings['useFullStars'] = !empty($usefullstars)?$usefullstars:''; 1356 1357 $star_settings['callback'] = function(currentRating, $el){ 1358 $el.parent().find(".ratings_selected").val(currentRating); 1359 //vue_app_review.rating_value = currentRating; 1360 vm_my_order.$refs.ReviewRef.rating_value = currentRating; 1361 }; 1362 1363 //dump($star_settings); 1364 $(this).starRating($star_settings); 1365 }); /*end each*/ 1366 1367}; 1368 1369var updateStickySibader = function(){ 1370 setTimeout(function() { 1371 sticky_sidebar.updateSticky(); 1372 }, 1); 1373}; 1374 1375var updateStickyCart = function(){ 1376 setTimeout(function() { 1377 if ((typeof sticky_cart !== "undefined") && ( sticky_cart !== null)) { 1378 sticky_cart.updateSticky(); 1379 } 1380 }, 1); 1381}; 1382 1383var MerchantMenux = function($results){ 1384 1385 $(".menu-left").removeClass("loading"); 1386 $("#merchant-menu").removeClass("loading"); 1387 1388 var $category = $results.data.category; 1389 var $items = $results.data.items; 1390 1391 /*FILL CATEGORY*/ 1392 Vue.createApp({ 1393 data(){ 1394 return $results.data 1395 } 1396 }).mount('#menu-category'); 1397 var $new_category = []; var $new_items = []; 1398 1399 /*FILL ITEMS*/
1400 if($category.length>0){ 1401 $.each($category, function(key, val){ 1402 1403 $.each(val.items, function(items_key, $item_id){ 1404 $new_items.push( $items[$item_id] ); 1405 }); // loop 1406 1407 $new_category.push({ 1408 'cat_id': val.cat_id, 1409 'category_name': val.category_name, 1410 'category_uiid': val.category_uiid, 1411 'items':$new_items 1412 }); 1413 1414 $new_items = []; 1415 }); // loop 1416 } 1417 1418 var $new_category = {"category":$new_category}; 1419 Vue.createApp({ 1420 data(){ 1421 return $new_category 1422 } 1423 }).mount('#merchant-menu'); 1424 1425 updateStickySibader(); 1426}; 1427 1428 1429var $items; 1430var $addons; 1431var $addon_items; 1432//var vm; 1433 1434var ItemDetails = function($data){ 1435 $items = $data.items; 1436 $addons = $data.addons; 1437 $addon_items = $data.addon_items; 1438 1439 var $new_data = {"items":$items}; 1440 1441 if ((typeof vm !== "undefined") && ( vm !== null)) { 1442 vm.$data.items = $items; 1443 $("#item-details .lazy").attr("src", $items.url_image ); 1444 } else { 1445 vm = Vue.createApp({ 1446 data(){ 1447 return $new_data 1448 }, 1449 created () { 1450 // 1451 }, 1452 // 1453 }).mount('#item-details'); 1454 } 1455}; 1456 1457var ItemDetailsx = function($data){ 1458 1459 var $target = $("#itemModal .modal-body"); 1460 $items = $data.items; 1461 $addons = $data.addons; 1462 $addon_items = $data.addon_items; 1463 1464 var $html=''; 1465 1466 $html+='<div class="item_s" data-item_token="'+ $items.item_token +'" >'; 1467 1468 $html+='<div class="list-items">'; 1469 $html+='<div class="position-relative">'; 1470 $html+='<div class="skeleton-placeholder"></div>'; 1471 $html+='<img class="rounded lazy" data-src="'+ $items.url_image +'"/>'; 1472 $html+='</div>'; 1473 $html+='</div>'; 1474 1475 $html+='</div>'; 1476 1477 $html+='<h4 class="m-0 mt-2 mb-2">'+ $items.item_name +'</h4>'; 1478 if(!empty($items.item_description)){ 1479 $html+='<p>'+ $items.item_description +'</p>'; 1480 } 1481 1482 /*PRICE*/ 1483 var $item_price_count = 0; 1484 if ((typeof $items.price !== "undefined") && ( $items.price !== null)) { 1485 $item_price_count = Object.keys($items.price).length; 1486 } 1487 if($item_price_count>0){ 1488 $html+='<div class="mb-4 btn-group btn-group-toggle input-group-small choose-size flex-wrap" data-toggle="buttons">'; 1489 var $price_x = 1; 1490 $.each( $items.price , function($pkey,$prices){ 1491 var $active = $price_x==1?"active":''; 1492 var $checked = $price_x==1?"checked='checked'":''; 1493 $html+='<label class="btn '+ $active +' ">'; 1494 $html+='<input value="'+ $prices.item_size_id +'" name="size_uuid" id="size_uuid" class="size_uuid" type="radio" '+ $checked +'> '; 1495 1496 if ( $prices.discount<=0){ 1497 $html+= $prices.size_name+" "+$prices.pretty_price; 1498 } else { 1499 $html+= $prices.size_name+' <del>'+ $prices.pretty_price +'</del> ' + $prices.pretty_price_after_discount; 1500 } 1501 1502 $html+='</label>'; 1503 $price_x++; 1504 }); 1505 $html+='</div>'; 1506 } 1507 /*PRICE*/ 1508 1509 $html+='<div class="addon-list"></div>'; 1510 1511 $target.html($html); 1512 1513 $html=''; 1514 1515 var $item_size_id = $('input[name="size_uuid"]:checked').val(); 1516 //dump("=>"+ $item_size_id); 1517 1518 AddonCategoryRows($item_size_id); 1519}; 1520 1521var AddonCategoryRows = function( $item_size_id ){ 1522 1523 var $html=''; 1524 var $target = $("#itemModal .addon-list"); 1525 1526 if ((typeof $items.item_addons !== "undefined") && ( $items.item_addons !== null)) { 1527 if ((typeof $items.item_addons[$item_size_id] !== "undefined") && ( $items.item_addons[$item_size_id] !== null)) { 1528 $.each( $items.item_addons[$item_size_id] , function($key,$addon_category_id){ 1529 1530 if ((typeof $addons[$addon_category_id] !== "undefined") && ( $addons[$addon_category_id] !== null)) { 1531 1532 var $multi_options = { 1533 'multi_option':$addons[$addon_category_id].multi_option, 1534 'multi_option_value':$addons[$addon_category_id].multi_option_value, 1535 'require_addon':$addons[$addon_category_id].require_addon, 1536 'pre_selected':$addons[$addon_category_id].pre_selected, 1537 'sub_items':$addons[$addon_category_id].sub_items, 1538 }; 1539 1540 $html+='<DIV class="addon-rows">'; 1541 1542 $html+='<div class="d-flex align-items-center heads">'; 1543 $html+='<div class="flexcol flex-grow-1">'; 1544 $html+='<h5 class="m-0">'+ $addons[$addon_category_id].subcategory_name +'</h5>';
1545 $html+='<p class="text-grey m-0 mb-1">'+ AddonCategoryMultiOption( $multi_options ) +'</p>'; 1546 $html+='</div>'; 1547 $html+='<div class="flexcol">'; 1548 $html+='<h6 class="m-0">'+ AddonCategoryRequired($addons[$addon_category_id].require_addon) +'</h6>'; 1549 $html+='</div>'; 1550 $html+='</div>'; 1551 1552 var $sub_items = $addons[$addon_category_id].sub_items; 1553 if($sub_items.length>0){ 1554 $html+='<ul class="list-unstyled list-selection list-addon no-hover m-0 p-0"'; 1555 $html+='data-subcat_id="'+ $addon_category_id +'" '; 1556 $html+='data-multi_option="'+ $multi_options.multi_option +'" data-multi_option_value="'+ $multi_options.multi_option_value +'" '; 1557 $html+='data-require_addon="'+ $multi_options.require_addon +'" data-pre_selected="'+ $multi_options.pre_selected +'" '; 1558 $html+='>'; 1559 1560 $.each( $sub_items , function($key,$addon_items_id){ 1561 if ((typeof $addon_items[$addon_items_id] !== "undefined") && ( $addon_items[$addon_items_id] !== null)) { 1562 $html+=AddonItemsRows( $addon_items[$addon_items_id] , $addon_category_id , $multi_options ); 1563 } 1564 }); 1565 $html+='</ul>'; 1566 } 1567 1568 $html+='</DIV>'; 1569 1570 } 1571 1572 }); 1573 } 1574 } 1575 1576 $target.html($html); 1577 ItemSummary(); 1578}; 1579 1580var AddonItemsRows = function($data, $addon_category_id , $multi_options){ 1581 1582 dump("AddonItemsRows"); 1583 dump($multi_options); 1584 var $multi_option= !empty($multi_options.multi_option)?$multi_options.multi_option:''; 1585 var $multi_option_value= !empty($multi_options.multi_option_value)?$multi_options.multi_option_value:''; 1586 dump("multi_option=>"+ $multi_option); 1587 dump("multi_option_value=>"+ $multi_option_value); 1588 1589 var $html=''; 1590 $html+='<li class="d-flex align-items-center" >'; 1591 //$html+='<div class="flexcol mr-2">'; 1592 1593 switch($multi_option){ 1594 1595 case "custom": 1596 $html+='<div class="custom-control custom-checkbox flex-grow-1">'; 1597 $html+='<input type="checkbox" id="sub_item_id'+ $data.sub_item_id +'" name="sub_item_id_'+ $addon_category_id +'" value="'+ $data.sub_item_id +'" class="addon-items custom-control-input">'; 1598 $html+='<label class="custom-control-label font14 bold" for="sub_item_id'+ $data.sub_item_id +'">'; 1599 $html+='<h6 class="m-0">'+ $data.sub_item_name +'</h6>'; 1600 $html+='</label>'; 1601 $html+='</div>'; 1602 $html+='<p class="m-0">+'+ $data.pretty_price +'</p>'; 1603 break; 1604 1605 case "multiple": 1606 1607 $html+='<div class="position-relative quantity-wrapper ">'; 1608 $html+='<div class="quantity-parent">'; 1609 $html+='<div class="quantity d-flex justify-content-between m-auto">'; 1610 $html+='<div><a href="javascript:;" class="rounded-pill qty-btn multiple_qty" data-id="less"><i class="zmdi zmdi-minus"></i></a></div>'; 1611 $html+='<div class="qty" data-id="'+ $data.sub_item_id +'">0</div>'; 1612 $html+='<div><a href="javascript:;" class="rounded-pill qty-btn multiple_qty" data-id="plus"><i class="zmdi zmdi-plus"></i></a></div>'; 1613 $html+='</div>'; 1614 $html+='</div> '; 1615 1616 $html+='<a href="javascript:;" class="btn quantity-add-cart multiple_qty">'; 1617 $html+='<i class="zmdi zmdi-plus"></i>'; 1618 $html+='</a>'; 1619 $html+='</div>'; 1620 1621 $html+='<div class="flexcol ml-3">'; 1622 $html+='<h6 class="m-0">'+ $data.sub_item_name +'</h6>'; 1623 $html+='<p class="m-0 text-grey">+'+ $data.pretty_price +'</p>'; 1624 $html+='</div>'; 1625 1626 break; 1627 1628 default: 1629 $html+='<div class="custom-control custom-radio flex-grow-1">'; 1630 $html+='<input type="radio" id="sub_item_id'+ $data.sub_item_id +'" name="sub_item_id_'+ $addon_category_id +'" value="'+ $data.sub_item_id +'" class="addon-items custom-control-input">'; 1631 $html+='<label class="custom-control-label font14 bold" for="sub_item_id'+ $data.sub_item_id +'">'; 1632 $html+='<h6 class="m-0">'+ $data.sub_item_name +'</h6>'; 1633 $html+='</label>'; 1634 $html+='</div>'; 1635 $html+='<p class="m-0">+'+ $data.pretty_price +'</p>'; 1636 break; 1637 } 1638 1639 //$html+='</div>'; 1640 1641 /*if($multi_option=="multiple"){ 1642 $html+='<div class="flexcol">'; 1643 $html+='<h6 class="m-0">'+ $data.sub_item_name +'</h6>'; 1644 $html+='<p class="m-0 text-grey">+'+ $data.pretty_price +'</p>'; 1645 $html+='</div>'; 1646 } else { 1647 $html+='<div class="flexcol flex-grow-1">'; 1648 $html+='<h6 class="m-0">'+ $data.sub_item_name +'</h6>'; 1649 $html+='</div>'; 1650 1651 $html+='<div class="flexcol ">'; 1652 $html+='<p class="m-0">+'+ $data.pretty_price +'</p>'; 1653 $html+='</div>'; 1654 }*/ 1655 1656 $html+='</li>'; 1657 return $html; 1658 1659}; 1660 1661var AddonCategoryMultiOption = function($data){ 1662 var $display_msg = ''; 1663 var $multi_option= !empty($data.multi_option)?$data.multi_option:''; 1664 var $sub_items= !empty($data.sub_items)?$data.sub_items:''; 1665 var $multi_option_value= !empty($data.multi_option_value)?$data.multi_option_value:''; 1666 1667 switch($multi_option){ 1668 case "one": 1669 $display_msg = t("Select 1"); 1670 break; 1671 1672 case "multiple":
1673 $display_msg = t("Choose up to ") + $multi_option_value; 1674 break; 1675 1676 case "two_flavor": 1677 $display_msg = t("Select flavor " + $multi_option_value); 1678 break; 1679 1680 case "custom": 1681 $display_msg = t("Choose up to ") + $multi_option_value; 1682 break; 1683 1684 default: 1685 break; 1686 } 1687 return $display_msg; 1688}; 1689 1690var AddonCategoryRequired = function($data){ 1691 if($data>0){ 1692 return t("Required"); 1693 } else return t("Optional"); 1694}; 1695 1696var $sub_item_id = 0; 1697var $sub_item_qty = 0; 1698var $addon_price = 0; 1699var $item_size_id = 0; 1700var $item_token = ''; 1701var $item_total = 0; 1702var $item_price = 0; 1703var $addon_multi_option; 1704var $addon_child; 1705var $subcat_id = 0; 1706var $addons_category = []; 1707var $addons_items = []; 1708var $require_addon=0; 1709var $addon_multi_option_value=0; 1710 1711var ItemSummaryx = function(){ 1712 dump("ItemSummary"); 1713 $item_total = 0; 1714 $sub_item_id = 0; 1715 $addon_price = 0; 1716 $sub_item_qty = 0; 1717 $item_size_id = vm.size_id; 1718 $item_price = 0; 1719 1720 $items = $global_items; 1721 $addon_items = $global_addon_items; 1722 1723 if(!empty($items.price[$item_size_id])){ 1724 if( $items.price[$item_size_id].discount>0 ){ 1725 $item_price = !empty($items.price[$item_size_id]) ? parseFloat($items.price[$item_size_id].price_after_discount) : 0; 1726 } else $item_price = !empty($items.price[$item_size_id]) ? parseFloat($items.price[$item_size_id].price) : 0; 1727 } 1728 1729 //dump("price=>" + $item_price); 1730 1731 $item_total+=$item_price; 1732 var $added = []; 1733 var $required_addon = []; 1734 1735 $('.list-addon').each(function(index, $obj){ 1736 $addon_multi_option = $($obj).attr("data-multi_option"); 1737 $require_addon = $($obj).attr("data-require_addon"); 1738 $subcat_id = $($obj).attr("data-subcat_id"); 1739 $addon_multi_option_value = $($obj).attr("data-multi_option_value"); 1740 1741 if($addon_multi_option=="custom" || $addon_multi_option=="one"){ 1742 $addon_child = $($obj).find(".addon-items:checked"); 1743 } else if ( $addon_multi_option=="multiple"){ 1744 $addon_child = $($obj).find(".qty"); 1745 } 1746 1747 if($require_addon==1){ 1748 $required_addon.push($subcat_id); 1749 } 1750 1751 if($addon_multi_option_value>0){ 1752 var $inputs = $($obj).find("input:checked"); 1753 var $total_selected = $inputs.length; 1754 if($total_selected>=$addon_multi_option_value){ 1755 $($obj).find("input:checkbox:not(:checked)").attr("disabled",true); 1756 } else { 1757 $($obj).find("input:disabled").attr("disabled",false); 1758 } 1759 } 1760 1761 if ((typeof $addon_child !== "undefined") && ( $addon_child !== null)) { 1762 $addon_child.each(function(child_index, child_object){ 1763 if($addon_multi_option=="multiple"){ 1764 //dump("==>x"+$addon_multi_option_value); 1765 $sub_item_id = $(child_object).data("id"); 1766 $sub_item_qty = parseInt( $(child_object).html() ) ; 1767 $addon_price = !empty($addon_items[$sub_item_id])? parseFloat($addon_items[$sub_item_id].price) : 0; 1768 $item_total+= ($sub_item_qty*$addon_price); 1769 if($sub_item_qty>0){ 1770 $added.push($subcat_id); 1771 } 1772 } else { 1773 $sub_item_id = $(child_object).val(); 1774 $addon_price = !empty($addon_items[$sub_item_id])? parseFloat($addon_items[$sub_item_id].price) : 0; 1775 $item_total+=$addon_price; 1776 $added.push($subcat_id); 1777 } 1778 }); //loop 1779 } 1780 1781 }); //loop 1782 1783 dump("REQUIRED"); 1784 dump($required_addon); 1785 dump($added); 1786 dump("END REQUIRED"); 1787 1788 var $required_meet=true; 1789 if($required_addon.length>0){ 1790 $.each($required_addon, function(i, val){ 1791 if($added.includes(val)===false){ 1792 $required_meet = false; 1793 return false; 1794 } 1795 }); 1796 } 1797 1798 dump("$required_meet=>"+$required_meet); 1799 1800 if($required_meet==false){ 1801 $(".add_to_cart").attr("disabled",true); 1802 } else $(".add_to_cart").attr("disabled",false); 1803 1804 processAjax('priceFormat','price='+$item_total + "&target=.item-summary",''); 1805}; 1806 1807var addToCart = function(){ 1808 $item_size_id = $('input[name="size_uuid"]:checked').val(); 1809 $item_token = $(".item_s").attr("data-item_token"); 1810 $sub_item_id = 0; 1811 $sub_item_qty = 0; 1812 $addon_price = 0; 1813 $addons_category = []; 1814 $addons_items = ''; 1815 var $addon_rows = ''; 1816 1817 $('.list-addon').each(function(index, $obj){ 1818 1819 $addon_multi_option = $($obj).attr("data-multi_option"); 1820 $subcat_id = $($obj).attr("data-subcat_id"); 1821 1822 if($addon_multi_option=="custom" || $addon_multi_option=="one"){ 1823 $addon_child = $($obj).find(".addon-items:checked"); 1824 } else if ( $addon_multi_option=="multiple"){ 1825 $addon_child = $($obj).find(".qty"); 1826 } 1827 1828 /*$addons_category.push({ 1829 'subcat_id':$subcat_id, 1830 'multi_option':$addon_multi_option, 1831 'multi_option_value' : $($obj).data("multi_option_value") 1832 }); */ 1833 1834 var $x = 0; 1835 if ((typeof $addon_child !== "undefined") && ( $addon_child !== null)) { 1836 //$addon_rows = ''; 1837 $addon_child.each(function(child_index, child_object){ 1838 if($addon_multi_option=="multiple"){ 1839 $sub_item_id = $(child_object).attr("data-id"); 1840 $sub_item_qty = parseInt( $(child_object).html() ) ; 1841 $addon_price = !empty($global_addon_items[$sub_item_id])? parseFloat($global_addon_items[$sub_item_id].price) : 0; 1842 } else { 1843 $sub_item_id = $(child_object).val(); 1844 $addon_price = !empty($global_addon_items[$sub_item_id])? parseFloat($global_addon_items[$sub_item_id].price) : 0; 1845 $sub_item_qty = 1; 1846 } 1847 1848 if($sub_item_qty>0){ 1849 $addon_rows+='{"sub_item_id":'+$sub_item_id+', "sub_item_qty":'+$sub_item_qty+'},'; 1850 } 1851 1852 }); // loop 1853 1854 1855 } 1856 1857 if(!empty($addon_rows)){ 1858 $addon_rows = $addon_rows.slice(0, -1); 1859 $addons_items+= '"'+$subcat_id+'":['+$addon_rows+'],'; 1860 $addon_rows = ''; 1861 1862 $addons_category.push({ 1863 'subcat_id':$subcat_id, 1864 'multi_option':$addon_multi_option, 1865 'multi_option_value' : $($obj).attr("data-multi_option_value") 1866 }); 1867 1868 } 1869 1870 }); // loop 1871 1872 $addons_items = $addons_items.slice(0, -1); 1873 $addons_items = '{'+$addons_items+'}'; 1874 $addons_items = JSON.parse( $addons_items ); 1875 dump($addons_items); 1876 1877 var $params = { 1878 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 1879 'item_token':$item_token, 1880 'item_size_id':$item_size_id, 1881 'addons_category':$addons_category, 1882 'addons_items':$addons_items 1883 }; 1884 $params = JSON.stringify($params); 1885 processAjax('addCartItems',$params,'add_to_cart',1,1,'PUT','json'); 1886}; 1887 1888 1889window.setCookie = function(cname, cvalue, exdays){ 1890 const d = new Date(); 1891 d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000)); 1892 let expires = "expires="+d.toUTCString(); 1893 document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/"; 1894} 1895 1896window.getCookie = function(cname, cvalue, exdays){ 1897 let name = cname + "="; 1898 let ca = document.cookie.split(';'); 1899 for(let i = 0; i < ca.length; i++) {
1900 let c = ca[i]; 1901 while (c.charAt(0) == ' ') { 1902 c = c.substring(1); 1903 } 1904 if (c.indexOf(name) == 0) { 1905 return c.substring(name.length, c.length); 1906 } 1907 } 1908 return ""; 1909} 1910 1911/* 1912 VUE STARTS HERE 1913*/ 1914 1915/* 1916=============================================================================== 1917 START COMPONENTS HERE 1918=============================================================================== 1919*/ 1920 1921const loadingBox = { 1922 props: ['message','donnot_close'], 1923 data(){ 1924 return { 1925 new_message : '' 1926 } 1927 }, 1928 methods :{ 1929 show(){ 1930 $('#loadingBox').modal('show'); 1931 }, 1932 close(){ 1933 $('#loadingBox').modal('hide'); 1934 }, 1935 setMessage(new_message){ 1936 this.new_message = new_message; 1937 }, 1938 }, 1939 template:` 1940 <div class="modal" id="loadingBox" tabindex="-1" role="dialog" aria-labelledby="loadingBox" aria-hidden="true" 1941 data-backdrop="static" data-keyboard="false" 1942 > 1943 <div class="modal-dialog modal-dialog-centered modal-loadingbox" role="document"> 1944 <div class="modal-content"> 1945 <div class="modal-body"> 1946 <div class="loading mt-2"> 1947 <div class="m-auto circle-loader medium" data-loader="circle-side"></div> 1948 </div> 1949 <p class="text-center mt-2"> 1950 <div v-if="!new_message">{{message}}</div> 1951 <div v-if="new_message">{{new_message}}</div> 1952 <div>{{donnot_close}}</div> 1953 </p> 1954 </div> 1955 </div> <!--content--> 1956 </div> <!--dialog--> 1957 </div> <!--modal--> 1958 ` 1959}; 1960 1961/* 1962 COMPONENTS SEARCH 1963*/ 1964const ComponentsSearch = { 1965 props: ['title','label','next_url','auto_generate_uuid','enabled_auto_detect_address'], 1966 components : { 1967 'loading-box' : loadingBox 1968 }, 1969 data(){ 1970 return { 1971 q: '', 1972 awaitingSearch : false, 1973 show_list : false, 1974 data : [], 1975 error : [], 1976 autosaved_addres : true, 1977 }; 1978 }, 1979 created() { 1980 if(this.enabled_auto_detect_address){ 1981 this.detectLocation(); 1982 } 1983 }, 1984 watch: { 1985 q(newsearch,oldsearch){ 1986 if (!this.awaitingSearch) { 1987 1988 if(empty(newsearch)){ 1989 return false; 1990 } 1991 1992 this.show_list = true; 1993 1994 setTimeout(() => { 1995 1996 var $params; var timenow = 2; 1997 $params="q=" + this.q; 1998 $params+=addValidationRequest(); 1999 ajax_request[timenow] = $.ajax({ 2000 url: ajaxurl+"/getlocation_autocomplete", 2001 method: "POST", 2002 dataType: "json", 2003 data: $params, 2004 contentType : $content_type.form , 2005 timeout: $timeout, 2006 crossDomain: true, 2007 beforeSend: data => { 2008 if(ajax_request[timenow] != null) { 2009 ajax_request[timenow].abort(); 2010 } 2011 } 2012 }); 2013 2014 ajax_request[timenow].done( data => { 2015 if ( data.code==1){ 2016 this.data = data.details.data; 2017 } else { 2018 this.data = []; 2019 } 2020 }); // ajax done 2021 2022 ajax_request[timenow].always( data => { 2023 this.awaitingSearch = false; 2024 }); 2025 2026 }, 1000); // 1 sec delay 2027 } 2028 2029 this.data = []; 2030 this.awaitingSearch = true; 2031 }, 2032 }, 2033 methods: { 2034 detectLocation(){ 2035 if (navigator.geolocation) { 2036 navigator.geolocation.getCurrentPosition( 2037 (data) => { 2038 this.reverseGeocoding(data.coords.latitude,data.coords.longitude); 2039 }, 2040 (error) => { 2041 ElementPlus.ElNotification({ 2042 title: "", 2043 message: error.message, 2044 position: 'bottom-right', 2045 type: 'warning', 2046 }); 2047 } 2048 ); 2049 } else { 2050 // 2051 } 2052 }, 2053 reverseGeocoding(lat,lng){ 2054 axios({ 2055 method: 'POST', 2056 url: ajaxurl+"/reverseGeocoding" , 2057 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&lat=" + lat + "&lng=" + lng, 2058 timeout: $timeout, 2059 }).then( response => { 2060 if(response.data.code==1){ 2061 let $auto_address = { 2062 id : response.data.details.data.place_id, 2063 country : response.data.details.data.address.country, 2064 country_code : response.data.details.data.address.country_code 2065 }; 2066 2067 let $some_words = JSON.parse(some_words); 2068 let $we_detected = $some_words.we_detected; 2069 // Use long-form address (formattedAddress has long street names like "Ravey Street") 2070 const longFormAddr = response.data.details.data.address?.formattedAddress 2071 || response.data.details.data.parsed_address?.formatted_address_long 2072 || response.data.details.data.address?.formatted_address 2073 || ''; 2074 $we_detected = $we_detected.replace("{address}", longFormAddr); 2075 2076 ElementPlus.ElMessageBox.confirm( 2077 $we_detected, 2078 $some_words.address_detected, 2079 { 2080 confirmButtonText: $some_words.yes, 2081 cancelButtonText: $some_words.no, 2082 type: 'info', 2083 } 2084 ) 2085 .then(() => {
2086 this.getLocationDetails($auto_address); 2087 }) 2088 .catch(() => { 2089 // 2090 }); 2091 2092 } 2093 }).catch(error => { 2094 // 2095 }).then(data => { 2096 // 2097 }); 2098 }, 2099 showList(){ 2100 this.show_list = true; 2101 }, 2102 clearData(){ 2103 this.data = []; 2104 this.q = ''; 2105 }, 2106 getLocationDetails(items){ 2107 2108 this.show_list = false; 2109 var $params; var timenow = 3; 2110 $params="id=" + items.id; 2111 $params+="&country=" + items.country; 2112 $params+="&country_code=" + items.country_code; 2113 $params+="&description=" + items.description; 2114 $params+="&autosaved_addres=" + this.autosaved_addres; 2115 $params+="&auto_generate_uuid=" + this.auto_generate_uuid; 2116 $params+="&cart_uuid=" + getCookie('cart_uuid'); 2117 2118 $params+=addValidationRequest(); 2119 ajax_request[timenow] = $.ajax({ 2120 url: ajaxurl+"/getLocationDetails", 2121 method: "POST", 2122 dataType: "json", 2123 data: $params, 2124 contentType : $content_type.form , 2125 timeout: $timeout, 2126 crossDomain: true, 2127 beforeSend: data => { 2128 this.awaitingSearch = true; 2129 if(ajax_request[timenow] != null) { 2130 ajax_request[timenow].abort(); 2131 } 2132 } 2133 }); 2134 2135 ajax_request[timenow].done( data => { 2136 if ( data.code==1){ 2137 // Keep the long-form description that user selected from dropdown 2138 // items.description already has the long form (e.g., "Westdene Drive") 2139 this.q = items.description || data.details.data.address.formatted_address; 2140 if(this.auto_generate_uuid==true || this.auto_generate_uuid=="true"){ 2141 setCookie('cart_uuid',data.details.cart_uuid,30); 2142 } 2143 window.location.href = this.next_url; 2144 } else { 2145 this.error[0] = data.msg; 2146 } 2147 }); // ajax done 2148 2149 ajax_request[timenow].always( data => { 2150 this.awaitingSearch = false; 2151 }); 2152 2153 }, 2154 }, 2155 computed: { 2156 hasData(){ 2157 if(this.data.length>0){ 2158 return true; 2159 } 2160 return false; 2161 }, 2162 }, 2163 template: ` 2164 <loading-box ref="loading_box" message="Getting address" donnot_close="do not close this window" ></loading-box> 2165 <div class="position-relative search-geocomplete"> 2166 <div v-if="!awaitingSearch" class="img-20 m-auto pin_placeholder icon"></div> 2167 <div v-if="awaitingSearch" class="icon" data-loader="circle"></div> 2168 2169 <input @click="showList" v-model="q" class="form-control form-control-text" 2170 :placeholder="label.enter_address" > 2171 2172 <div v-if="hasData" @click="clearData" class="icon-remove"><i class="zmdi zmdi-close"></i></div> 2173 <div v-if="!hasData" class="search_placeholder pos-right img-20"></div> 2174 </div> 2175 2176 <div class="search-geocomplete-results" v-if="show_list"> 2177 <ul class="list-unstyled m-0 border"> 2178 <li v-for="items in data"> 2179 <a href="javascript:;" @click="getLocationDetails(items)" > 2180 <h6 class="m-0">{{items.addressLine1}}</h6> 2181 <p class="m-0 text-grey">{{items.addressLine2}}</p> 2182 </a> 2183 </li> 2184 </ul> 2185 </div> 2186 ` 2187}; 2188/*END COMPONENTS SEARCH*/ 2189 2190 2191/* 2192COMPONENTS CHANGE ADDRESS 2193*/ 2194const changeAddressComponent = { 2195 props: ['label','addresses','location_data','saveplace'], 2196 data(){ 2197 return { 2198 q: '', 2199 awaitingSearch : false, 2200 show_list : false, 2201 data : [], 2202 error : [], 2203 autosaved_addres : true, 2204 is_fullwidth : false, 2205 visible : false 2206 }; 2207 }, 2208 mounted() { 2209 if ((typeof is_mobile !== "undefined") && ( is_mobile !== null)) { 2210 if(is_mobile){ 2211 this.is_fullwidth = true; 2212 } 2213 } 2214 }, 2215 computed: { 2216 hasAddress(){ 2217 if(!empty(this.addresses)){ 2218 if (Object.keys(this.addresses).length > 0) { 2219 return true; 2220 } 2221 } 2222 return false; 2223 }, 2224 hasData(){ 2225 if(this.data.length>0){ 2226 return true; 2227 } 2228 return false; 2229 }, 2230 }, 2231 methods: { 2232 showList(){ 2233 this.show_list = true; 2234 }, 2235 clearData(){ 2236 this.data = []; 2237 this.q = ''; 2238 }, 2239 showModal(){ 2240 //$( this.$refs.change_address_modal ).modal('show'); 2241 this.visible = true; 2242 }, 2243 closeModal(){ 2244 //$( this.$refs.change_address_modal ).modal('hide'); 2245 this.visible = false;
2246 this.$emit('afterClose'); 2247 }, 2248 close(){ 2249 //$( this.$refs.change_address_modal ).modal('hide'); 2250 this.visible = false; 2251 }, 2252 getLocationDetails(items){ 2253 2254 const provider = items?.provider ?? null; 2255 console.debug("provider",provider); 2256 console.debug("getLocationDetails",items); 2257 this.show_list = false; 2258 var $params; var timenow = 3; 2259 if(provider=="mapbox"){ 2260 $params="id=" + `${items.longitude},${items.latitude}`; 2261 } else { 2262 $params="id=" + items.id; 2263 } 2264 $params+="&country=" + items.country; 2265 $params+="&country_code=" + items.country_code; 2266 $params+="&autosaved_addres=" + this.autosaved_addres; 2267 $params+="&saveplace=" + this.saveplace; 2268 $params+="&description=" + items.description; 2269 2270 $params+=addValidationRequest(); 2271 ajax_request[timenow] = $.ajax({ 2272 url: ajaxurl+"/getLocationDetails", 2273 method: "POST", 2274 dataType: "json", 2275 data: $params, 2276 contentType : $content_type.form , 2277 timeout: $timeout, 2278 crossDomain: true, 2279 beforeSend: data => { 2280 this.awaitingSearch = true; 2281 if(ajax_request[timenow] != null) { 2282 ajax_request[timenow].abort(); 2283 } 2284 } 2285 }); 2286 2287 ajax_request[timenow].done( data => { 2288 if ( data.code==1){ 2289 this.q=''; 2290 this.closeModal(); 2291 this.$emit('setLocation',data.details.data); 2292 } else { 2293 this.error[0] = data.msg; 2294 } 2295 }); // ajax done 2296 2297 ajax_request[timenow].always( data => { 2298 this.awaitingSearch = false; 2299 }); 2300 2301 }, 2302 setPlaceID(place_id){ 2303 var $params; var timenow = 4; 2304 $params="place_id=" + place_id; 2305 $params+=addValidationRequest(); 2306 ajax_request[timenow] = $.ajax({ 2307 url: ajaxurl+"/setPlaceID", 2308 method: "POST", 2309 dataType: "json", 2310 data: $params, 2311 contentType : $content_type.form , 2312 timeout: $timeout, 2313 crossDomain: true, 2314 beforeSend: data => { 2315 if(ajax_request[timenow] != null) { 2316 ajax_request[timenow].abort(); 2317 } 2318 } 2319 }); 2320 2321 ajax_request[timenow].done( data => { 2322 if ( data.code==1){ 2323 this.$emit('setPlaceid'); 2324 } else { 2325 this.error[0] = data.msg; 2326 } 2327 }); // ajax done 2328 2329 ajax_request[timenow].always( data => { 2330 }); 2331 2332 }, 2333 editAddress(address_data){ 2334 //this.$emit('setLocation',address_data); 2335 this.$emit('setEdit',address_data); 2336 }, 2337 deleteAddress(address_uuid){ 2338 2339 var $params; var timenow = 5; 2340 $params="address_uuid=" + address_uuid; 2341 $params+=addValidationRequest(); 2342 ajax_request[timenow] = $.ajax({ 2343 url: ajaxurl+"/deleteAddress", 2344 method: "POST", 2345 dataType: "json", 2346 data: $params, 2347 contentType : $content_type.form , 2348 timeout: $timeout, 2349 crossDomain: true, 2350 beforeSend: data => { 2351 if(ajax_request[timenow] != null) { 2352 ajax_request[timenow].abort(); 2353 } 2354 } 2355 }); 2356 2357 ajax_request[timenow].done( data => { 2358 if ( data.code==1){ 2359 this.$emit('loadData'); 2360 this.$emit('afterDelete',data); 2361 } else { 2362 this.error[0] = data.msg; 2363 } 2364 }); // ajax done 2365 2366 ajax_request[timenow].always( data => { 2367 }); 2368 2369 }, 2370 locateLocation(){ 2371 this.awaitingSearch = true; 2372 if (navigator.geolocation) { 2373 navigator.geolocation.getCurrentPosition( 2374 (data) => { 2375 this.reverseGeocoding(data.coords.latitude,data.coords.longitude); 2376 }, 2377 (error) => { 2378 this.awaitingSearch = false; 2379 ElementPlus.ElNotification({ 2380 title: "", 2381 message: error.message, 2382 position: 'bottom-right', 2383 type: 'warning', 2384 }); 2385 } 2386 ); 2387 } else { 2388 this.awaitingSearch = false;
2389 ElementPlus.ElNotification({ 2390 title: "", 2391 message: "Your browser doesn't support geolocation.", 2392 position: 'bottom-right', 2393 type: 'warning', 2394 }); 2395 } 2396 }, 2397 reverseGeocoding(lat,lng){ 2398 axios({ 2399 method: 'POST', 2400 url: ajaxurl+"/reverseGeocoding" , 2401 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&lat="+ lat+ "&lng="+lng, 2402 timeout: $timeout, 2403 }).then( response => { 2404 if(response.data.code==1){ 2405 let data_items = []; 2406 data_items.id = response.data.details.data.place_id; 2407 data_items.country = response.data.details.data.address.country; 2408 data_items.country_code = response.data.details.data.address.country_code; 2409 this.getLocationDetails(data_items); 2410 } else { 2411 ElementPlus.ElNotification({ 2412 title: "", 2413 message: response.data.msg, 2414 position: 'bottom-right', 2415 type: 'warning', 2416 }); 2417 } 2418 }).catch(error => { 2419 // 2420 }).then(data => { 2421 this.awaitingSearch = false; 2422 }); 2423 }, 2424searchLocation(queryString,cb){ 2425 let data = []; 2426 axios({ 2427 method: 'POST', 2428 url: ajaxurl+"/getlocationAutocomplete" , 2429 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content')+"&q="+queryString, 2430 timeout: $timeout, 2431 }).then( response => { 2432 if(response.data.code==1){ 2433 data = response.data.details.data; 2434 // Build display name from addressLine1 + addressLine2 (uses full names like "Westdene Drive") 2435 // instead of description (which has abbreviated forms like "Westdene Dr") 2436 data = data.map(item => { 2437 if(item.addressLine1 && item.addressLine2){ 2438 item.description = item.addressLine1 + ', ' + item.addressLine2; 2439 } 2440 return item; 2441 }); 2442 } else { 2443 data = [] 2444 } 2445 cb(data); 2446 }).catch(error => { 2447 // 2448 }).then(data => { 2449 }); 2450 }, 2451 // 2452 }, 2453 template: ` 2454 <el-dialog v-model="visible" :close-on-click-modal="false" :show-close="true" :title="label.title" > 2455 2456 <div v-cloak v-if="error.length>0" class="alert alert-warning mb-2" role="alert"> 2457 <p v-cloak v-for="err in error" class="m-0">{{err}}</p> 2458 </div> 2459 2460 <div class="position-relative search-geocomplete" v-loading="awaitingSearch" > 2461 <el-autocomplete 2462 v-model="q" 2463 :placeholder="label.enter_address" 2464 size="large" 2465 class="w-100" 2466 :trigger-on-focus="false" 2467 value-key="description" 2468 :fit-input-width="is_fullwidth" 2469 clearable 2470 :fetch-suggestions="searchLocation" 2471 @select="getLocationDetails" 2472 > 2473 <template #suffix> 2474 <button @click="locateLocation" type="button" class="btn btn-link"> 2475 <i class="zmdi zmdi-my-location font20" style="color:#000;"></i> 2476 </button> 2477 </template> 2478 </el-autocomplete> 2479 </div> 2480 2481 <template v-if="hasAddress"> 2482 <div class="p-2"></div> 2483 <el-scrollbar max-height="200px" class="w-100"> 2484 <ul class="m-0 list-unstyled w-100 list-with-icon-button" > 2485 <li v-for="valadd in addresses" class="row align-items-center no-gutters" > 2486 2487 <div class="col-1" @click="setPlaceID(valadd.place_id)" ><i class="zmdi zmdi-pin icon-25"></i></div> 2488 <div class="col-9" @click="setPlaceID(valadd.place_id)" > 2489 <h5 class="m-0">{{valadd.address.complete_delivery_address}}</h5> 2490 </div> 2491 2492 <div class="col-2 "> 2493 <div class="float-right"> 2494 <a href="javascript:;" @click="editAddress(valadd)" class="rounded-pill rounded-button-icon d-inline-block mr-2"> 2495 <i class="zmdi zmdi-edit"></i> 2496 </a> 2497 2498 <a href="javascript:;" v-if="location_data.address_uuid != valadd.address_uuid " @click="deleteAddress(valadd.address_uuid)" 2499 class="rounded-pill rounded-button-icon d-inline-block"> 2500 <i class="zmdi zmdi-close"></i> 2501 </a> 2502 2503 </div> 2504 </div> 2505 </li> 2506 </ul> 2507 </el-scrollbar> 2508 </template> 2509 2510 </el-dialog> 2511 ` 2512}; 2513 2514/* 2515END COMPONENTS CHANGE ADDRESS 2516*/ 2517 2518 2519/* 2520 COMPONENTS ADDRESS FORM 2521*/ 2522const ComponentsAddress = { 2523 props: ['label','set_place_id','cmaps_config'], 2524 data(){ 2525 return { 2526 data:[], 2527 is_loading : false, 2528 error:[], 2529 cmaps : undefined, 2530 cmaps_full : false, 2531 //cmaps_config : [], 2532 location_name : '', 2533 delivery_options : '', 2534 address_label : '', 2535 delivery_instructions : '', 2536 delivery_options_data : [], 2537 address_label_data : [], 2538 address1 : '', 2539 formatted_address : '', 2540 new_coordinates : [], 2541 inline_edit : false, 2542 address2 : '', 2543 postal_code :'', 2544 company : '', 2545 custom_field_enabled : false, 2546 custom_field1 : '', 2547 custom_field2 : '', 2548 custom_field1_data : [], 2549 formattedAddress : null, 2550 }; 2551 }, 2552 mounted() { 2553 autosize( document.getElementById("delivery_instructions") ); 2554 this.getAddressAttributes(); 2555 }, 2556 computed: { 2557 DataValid(){ 2558 if(Object.keys(this.data).length>0){ 2559 return true; 2560 } 2561 return false;
2562 }, 2563 DataValidNew(){ 2564 if(Object.keys(this.new_coordinates).length>0){ 2565 return true; 2566 } 2567 return false; 2568 }, 2569 }, 2570 methods :{ 2571 show( address_uuid ){ 2572 this.cmaps_full = false; 2573 this.getAdddress( address_uuid ); 2574 $( this.$refs.modal_address ).modal('show'); 2575 }, 2576 clearForms(){ 2577 this.data = []; 2578 this.location_name = ''; 2579 this.delivery_options =''; 2580 this.address_label = ''; 2581 this.delivery_instructions = ''; 2582 this.address1 = ''; 2583 this.formatted_address = ''; 2584 this.address2 = ''; 2585 this.postal_code = ''; 2586 this.company = ''; 2587 }, 2588 showWithData(data){ 2589 console.debug("showWithData",data); 2590 this.clearForms(); 2591 $( this.$refs.modal_address ).modal('show'); 2592 2593 this.data = data; 2594 this.address1 = data?.parsed_address.street_number ?? data.address.address1; 2595 this.formatted_address = data?.parsed_address.street_name ?? data.address.formatted_address; 2596 // Remove UK and ensure postcode is at end 2597 // Get postcode from data to append if missing 2598 const showPostcode = data?.address?.postal_code || data?.parsed_address?.postal_code || ''; 2599 this.formattedAddress = reorderAddressPostcode(data?.parsed_address?.formatted_address ?? '', showPostcode); 2600 console.debug("this.formattedAddress",this.formattedAddress); 2601 this.loadMap(); 2602 }, 2603 close(){ 2604 //$('#ModalAddress').modal('hide'); 2605 $( this.$refs.modal_address ).modal('hide'); 2606 }, 2607 closeModal(){ 2608 //$('#ModalAddress').modal('hide'); 2609 $( this.$refs.modal_address ).modal('hide'); 2610 this.$emit('afterClose'); 2611 }, 2612 getAddressAttributes(){ 2613 2614 var $params = { 2615 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 2616 }; 2617 var timenow = getTimeNow(); 2618 $params = JSON.stringify($params); 2619 2620 ajax_request[timenow] = $.ajax({ 2621 url: ajaxurl+"/getAddressAttributes", 2622 method: "PUT", 2623 dataType: "json", 2624 data: $params , 2625 contentType : $content_type.json , 2626 timeout: $timeout, 2627 crossDomain: true, 2628 beforeSend: data => { 2629 this.is_loading = true; 2630 if(ajax_request[timenow] != null) { 2631 ajax_request[timenow].abort(); 2632 } 2633 } 2634 }); 2635 2636 ajax_request[timenow].done( data => { 2637 if ( data.code==1){ 2638 this.delivery_options_data = data.details.delivery_option; 2639 this.address_label_data = data.details.address_label; 2640 this.delivery_options = data.details.default_atts.delivery_options; 2641 this.address_label = data.details.default_atts.address_label; 2642 this.custom_field_enabled = data.details.custom_field_enabled; 2643 this.custom_field1_data = data.details.custom_field1_data; 2644 this.custom_field1 = Object.keys(this.custom_field1_data)[0]; 2645 } else { 2646 this.delivery_options_data = []; 2647 this.address_label_data = []; 2648 this.delivery_options = ''; 2649 this.address_label = ''; 2650 this.custom_field1_data = []; 2651 this.custom_field_enabled = false; 2652 } 2653 }); 2654 2655 ajax_request[timenow].always( data => { 2656 this.is_loading = false; 2657 }); 2658 2659 }, 2660 getAdddress(address_uuid){ 2661 2662 var $params = { 2663 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 2664 'address_uuid': address_uuid, 2665 }; 2666 var timenow = getTimeNow(); 2667 $params = JSON.stringify($params); 2668 2669 ajax_request[timenow] = $.ajax({ 2670 url: ajaxurl+"/getAdddress", 2671 method: "PUT", 2672 dataType: "json", 2673 data: $params , 2674 contentType : $content_type.json , 2675 timeout: $timeout, 2676 crossDomain: true, 2677 beforeSend: data => { 2678 this.is_loading = true; 2679 if(ajax_request[timenow] != null) { 2680 ajax_request[timenow].abort(); 2681 } 2682 } 2683 }); 2684 2685 ajax_request[timenow].done( data => { 2686 if ( data.code==1){ 2687 this.data = data.details.data; 2688 this.location_name = data.details.data.attributes.location_name; 2689 this.delivery_options = data.details.data.attributes.delivery_options; 2690 this.address_label = data.details.data.attributes.address_label; 2691 this.delivery_instructions = data.details.data.attributes.delivery_instructions; 2692 this.address1 = data.details.data.address.address1; 2693 this.formatted_address = data.details.data.address.formatted_address; 2694 // Remove UK and ensure postcode is at end 2695 let detailRawAddr = data?.details?.data?.address?.formattedAddress ?? this.formatted_address; 2696 // Get postcode from data to append if missing 2697 const detailPostcode = data?.details?.data?.address?.postal_code || ''; 2698 this.formattedAddress = reorderAddressPostcode(detailRawAddr, detailPostcode); 2699 2700 this.address2 = data.details.data.address.address2; 2701 this.postal_code = data.details.data.address.postal_code;
2702 this.company = data.details.data.address.company; 2703 2704 this.custom_field1 = data.details.data.attributes.custom_field1; 2705 this.custom_field2 = data.details.data.attributes.custom_field2; 2706 2707 this.loadMap(); 2708 } else { 2709 this.clearForms(); 2710 } 2711 }); 2712 2713 ajax_request[timenow].always( data => { 2714 this.is_loading = false; 2715 }); 2716 }, 2717 loadMap(){ 2718 this.renderMap(); 2719 }, 2720 renderMap(){ 2721 switch(this.cmaps_config.provider){ 2722 case "google.maps": 2723 if ((typeof this.cmaps !== "undefined") && ( this.cmaps !== null)) { 2724 this.removeMarker(); 2725 } else { 2726 dump('render map here'); 2727 this.cmaps = new google.maps.Map( this.$refs.cmaps , { 2728 center: { lat: parseFloat(this.data.latitude), lng: parseFloat(this.data.longitude) }, 2729 zoom: parseInt(this.cmaps_config.zoom) , 2730 disableDefaultUI: true, 2731 }); 2732 } 2733 2734 this.addMarker({ 2735 position: { lat: parseFloat(this.data.latitude) , lng: parseFloat(this.data.longitude) }, 2736 map: this.cmaps, 2737 //icon : this.cmaps_config.icon, 2738 animation: google.maps.Animation.DROP, 2739 }); 2740 break; 2741 2742 case "mapbox": 2743 mapboxgl.accessToken = this.cmaps_config.key; 2744 this.cmaps = new mapboxgl.Map({ 2745 container: this.$refs.cmaps , 2746 style: 'mapbox://styles/mapbox/streets-v12', 2747 center: [ parseFloat(this.data.longitude) , parseFloat(this.data.latitude)], 2748 zoom: 14 2749 }); 2750 this.addMarker({ 2751 position: { lat: parseFloat(this.data.latitude) , lng: parseFloat(this.data.longitude) }, 2752 map: this.cmaps, 2753 icon : this.cmaps_config.icon, 2754 animation: null 2755 }); 2756 break; 2757 2758 case "yandex": 2759 this.initYandexAddress(); 2760 break; 2761 } 2762 }, 2763 async initYandexAddress(){ 2764 console.debug("initYandexAddress"); 2765 await ymaps3.ready; 2766 const {YMap, YMapDefaultSchemeLayer,YMapMarker,YMapDefaultFeaturesLayer,YMapListener,YMapControls } = ymaps3; 2767 const {YMapDefaultMarker} = await ymaps3.import('@yandex/[email protected]'); 2768 const {YMapZoomControl,YMapGeolocationControl} = await ymaps3.import('@yandex/[email protected]'); 2769 2770 const LOCATION = { 2771 center: [ parseFloat(this.data.longitude), parseFloat(this.data.latitude) ], 2772 zoom: yandex_zoom 2773 }; 2774 2775 if(yandex_map){ 2776 yandex_map.destroy(); 2777 yandex_map = null; 2778 } 2779 2780 if (!yandex_map) { 2781 yandex_map = new YMap( 2782 this.$refs.cmaps, 2783 { 2784 location: LOCATION, 2785 showScaleInCopyrights: false, 2786 behaviors: ['drag','scrollZoom'] 2787 }, 2788 [ 2789 new YMapDefaultSchemeLayer({}), 2790 new YMapDefaultFeaturesLayer({}) 2791 ] 2792 ); 2793 2794 cmaps_marker = new YMapDefaultMarker({ 2795 coordinates: LOCATION.center, 2796 }); 2797 yandex_map.addChild(cmaps_marker); 2798 } 2799 }, 2800 addMarker(properties){ 2801 switch(this.cmaps_config.provider){ 2802 case "google.maps": 2803 cmaps_marker = new google.maps.Marker(properties); 2804 this.cmaps.panTo(new google.maps.LatLng(properties.position.lat,properties.position.lng)); 2805 break; 2806 case "mapbox": 2807 let markerProperties = {}; 2808 if(properties.draggable){ 2809 markerProperties = {draggable: true}; 2810 } 2811 cmaps_marker = new mapboxgl.Marker(markerProperties) 2812 .setLngLat([properties.position.lng, properties.position.lat]) 2813 .addTo(this.cmaps); 2814 break; 2815 } 2816 }, 2817 removeMarker(){ 2818 switch(this.cmaps_config.provider){ 2819 case "google.maps": 2820 cmaps_marker.setMap(null); 2821 break; 2822 case "mapbox": 2823 dump("remove marker"); 2824 cmaps_marker.remove(); 2825 break; 2826 } 2827 }, 2828 adjustPin(){ 2829 console.debug("adjustPin"); 2830 this.new_coordinates = []; 2831 this.cmaps_full = true; 2832 try { 2833 this.removeMarker(); 2834 } catch(err) { 2835 dump(err); 2836 } 2837 2838 this.addMarker({ 2839 position: { lat: parseFloat(this.data.latitude) , lng: parseFloat(this.data.longitude) }, 2840 map: this.cmaps, 2841 //icon : this.cmaps_config.icon, 2842 animation: this.cmaps_config.provider=="google.maps" ? google.maps.Animation.DROP : null, 2843 draggable:true, 2844 }); 2845 2846 if(this.cmaps_config.provider=="google.maps"){ 2847 cmaps_marker.addListener('dragend', event => {
2848 this.new_coordinates = { 2849 'lat': event.latLng.lat(), 2850 'lng': event.latLng.lng(), 2851 }; 2852 }); 2853 } else if ( this.cmaps_config.provider=="mapbox" ) { 2854 cmaps_marker.on('dragend', (event)=>{ 2855 const lngLat = cmaps_marker.getLngLat(); 2856 this.new_coordinates = { 2857 'lat': lngLat.lat, 2858 'lng': lngLat.lng, 2859 }; 2860 }); 2861 this.mapBoxResize(); 2862 } else if ( this.cmaps_config.provider=="yandex" ) { 2863 const LOCATION = { 2864 center: [ parseFloat(this.data.longitude), parseFloat(this.data.latitude) ], 2865 zoom: yandex_zoom 2866 }; 2867 cmaps_marker.update({ 2868 coordinates : LOCATION.center, 2869 draggable: true, 2870 onDragEnd: (coordinates)=>{ 2871 this.new_coordinates = { 2872 'lat': coordinates[1], 2873 'lng': coordinates[0], 2874 }; 2875 } 2876 }); 2877 } 2878 2879 }, 2880 mapBoxResize(){ 2881 if(this.cmaps_config.provider=="mapbox"){ 2882 setTimeout(()=>{ 2883 this.cmaps.resize(); 2884 }, 500); 2885 } 2886 }, 2887 cancelPin(){ 2888 this.error = []; 2889 this.cmaps_full=false; 2890 2891 if(this.cmaps_config.provider=="yandex"){ 2892 const LOCATION = { 2893 center: [ parseFloat(this.data.longitude), parseFloat(this.data.latitude) ], 2894 zoom: yandex_zoom 2895 }; 2896 cmaps_marker.update({ 2897 coordinates : LOCATION.center, 2898 draggable: false 2899 }); 2900 } else { 2901 this.removeMarker(); 2902 this.addMarker({ 2903 position: { lat: parseFloat(this.data.latitude) , lng: parseFloat(this.data.longitude) }, 2904 map: this.cmaps, 2905 //icon : this.cmaps_config.icon, 2906 animation: this.cmaps_config.provider=="google.maps" ? google.maps.Animation.DROP : null, 2907 }); 2908 this.mapBoxResize(); 2909 } 2910 }, 2911 setNewCoordinates(){ 2912 2913 var $params = { 2914 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 2915 'lat' : this.data.latitude, 2916 'lng' : this.data.longitude, 2917 'new_lat' : this.new_coordinates.lat, 2918 'new_lng' : this.new_coordinates.lng, 2919 }; 2920 2921 var timenow = 1; 2922 $params = JSON.stringify($params); 2923 2924 ajax_request[timenow] = $.ajax({ 2925 url: ajaxurl+"/checkoutValidateCoordinates", 2926 method: "PUT", 2927 dataType: "json", 2928 data: $params , 2929 contentType : $content_type.json , 2930 timeout: $timeout, 2931 crossDomain: true, 2932 beforeSend: data => { 2933 this.is_loading = true; 2934 this.error = []; 2935 if(ajax_request[timenow] != null) { 2936 ajax_request[timenow].abort(); 2937 } 2938 } 2939 }); 2940 2941 ajax_request[timenow].done( data => { 2942 if ( data.code==1){ 2943 this.data.latitude = this.new_coordinates.lat; 2944 this.data.longitude = this.new_coordinates.lng; 2945 this.cmaps_full=false; 2946 2947 if(this.cmaps_config.provider=="yandex"){ 2948 } else { 2949 this.removeMarker(); 2950 this.addMarker({ 2951 position: { lat: parseFloat(this.data.latitude) , lng: parseFloat(this.data.longitude) }, 2952 map: this.cmaps, 2953 //icon : this.cmaps_config.icon, 2954 }); 2955 } 2956 } else { 2957 this.error = data.msg; 2958 setTimeout(function() { 2959 location.href = "#error_message"; 2960 }, 1); 2961 } 2962 }); 2963 2964 ajax_request[timenow].always( data => { 2965 this.is_loading = false; 2966 }); 2967 }, 2968 save(){ 2969 confirmIncompleteAddressSave({ 2970 formattedAddress: this.formattedAddress, 2971 formatted_address: this.formatted_address, 2972 address1: this.address1, 2973 address2: this.address2, 2974 location_name: this.location_name, 2975 postal_code: this.postal_code 2976 }, () => { 2977 var $params = { 2978 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 2979 'address_uuid': this.data.address_uuid, 2980 'location_name' : this.location_name, 2981 'delivery_instructions' : this.delivery_instructions, 2982 'delivery_options' : this.delivery_options, 2983 'address_label' : this.address_label, 2984 'latitude' : this.data.latitude, 2985 'longitude' : this.data.longitude, 2986 'address1' : this.address1, 2987 'formatted_address' : this.formatted_address, 2988 'formattedAddress' : this.formattedAddress, 2989 'set_place_id' : this.set_place_id, 2990 'address2' : this.address2, 2991 'postal_code' : this.postal_code, 2992 'company' : this.company, 2993 'data': this.data, 2994 'address_format_use': this.cmaps_config.address_format_use, 2995 'custom_field1': this.custom_field1, 2996 'custom_field2': this.custom_field2 2997 }; 2998 2999 var timenow = 1; 3000 $params = JSON.stringify($params); 3001 3002 ajax_request[timenow] = $.ajax({ 3003 url: ajaxurl+"/SaveAddress", 3004 method: "PUT", 3005 dataType: "json", 3006 data: $params , 3007 contentType : $content_type.json , 3008 timeout: $timeout, 3009 crossDomain: true, 3010 beforeSend: data => { 3011 this.is_loading = true; 3012 this.error = [] ; 3013 if(ajax_request[timenow] != null) { 3014 ajax_request[timenow].abort(); 3015 } 3016 } 3017 }); 3018 3019 ajax_request[timenow].done( data => { 3020 if ( data.code==1){ 3021 this.close(); 3022 this.$emit('afterSave',true); 3023 } else { 3024 this.error = data.msg; 3025 setTimeout(function() { 3026 location.href = "#error_message"; 3027 }, 1); 3028 } 3029 }); 3030 3031 ajax_request[timenow].always( data => { 3032 this.is_loading = false;
3033 }); 3034 }); 3035 }, 3036 ConfirmDelete(address_uuid){ 3037 vm_bootbox.confirm().then((result) => { 3038 if(result){ 3039 this.deleteAddress(address_uuid); 3040 } 3041 }); 3042 }, 3043 deleteAddress(address_uuid){ 3044 var $params; var timenow = 5; 3045 $params="address_uuid=" + address_uuid; 3046 $params+=addValidationRequest(); 3047 ajax_request[timenow] = $.ajax({ 3048 url: ajaxurl+"/deleteAddress", 3049 method: "POST", 3050 dataType: "json", 3051 data: $params, 3052 contentType : $content_type.form , 3053 timeout: $timeout, 3054 crossDomain: true, 3055 beforeSend: data => { 3056 if(ajax_request[timenow] != null) { 3057 ajax_request[timenow].abort(); 3058 } 3059 } 3060 }); 3061 3062 ajax_request[timenow].done( data => { 3063 if ( data.code==1){ 3064 this.close(); 3065 this.$emit('afterDelete',true); 3066 } else { 3067 this.error[0] = data.msg; 3068 } 3069 }); // ajax done 3070 3071 ajax_request[timenow].always( data => { 3072 }); 3073 }, 3074 }, 3075 template: ` 3076 <div class="modal" ref="modal_address" id="ModalAddress" tabindex="-1" role="dialog" 3077 aria-labelledby="ModalAddress" aria-hidden="true" data-backdrop="static" data-keyboard="false" > 3078 <div class="modal-dialog modal-lg" role="document"> 3079 <div class="modal-content"> 3080 3081 <div class="modal-header border-bottom-0" style="padding-bottom:0px !important;"> 3082 <h5 class="modal-title">{{label.title}}</h5> 3083 <a href="javascript:;" @click="closeModal" class="btn btn-black btn-circle rounded-pill"><i class="zmdi zmdi-close font20"></i></a> 3084 </div> 3085 3086 <div class="modal-body" > 3087 3088 <template v-if="cmaps_config.provider=='mapbox'"> 3089 <div :class="{ 'map-large': cmaps_full, 'map-small': !cmaps_full }" > 3090 <div ref="cmaps" id="cmaps" style="height:100%; width:100%;"></div> 3091 </div> 3092 </template> 3093 <template v-else> 3094 <div ref="cmaps" id="cmaps" :class="{ 'map-large': cmaps_full, 'map-small': !cmaps_full }"></div> 3095 </template> 3096 3097 <template v-if="!cmaps_full"> 3098 3099 <div class="row mt-3" > 3100 <div class="col"> 3101 <h5 class="m-0"> 3102 {{formattedAddress}} 3103 </h5> 3104 </div> 3105 <div class="col text-right"> 3106 <button class="btn small btn-black" @click="adjustPin" :disabled="!DataValid" >{{label.adjust_pin}}</button> 3107 </div> 3108 </div> 3109 <!--row--> 3110 3111 <div class="forms mt-3 mb-2"> 3112 3113 3114 3115 <template v-if="cmaps_config.address_format_use==2"> 3116 3117 <div class="row"> 3118 <div class="col"> 3119 <div class="form-label-group"> 3120 <input v-model="formatted_address" class="form-control form-control-text" placeholder="" id="formatted_address" type="text"> 3121 <label for="formatted_address"> 3122 {{label.street_name}} ({{label.mandatory}}) 3123 </label> 3124 </div> 3125 </div> 3126 <div class="col"> 3127 <div class="form-label-group"> 3128 <input v-model="address1" class="form-control form-control-text" placeholder="" id="address1" type="text"> 3129 <label for="address1"> 3130 {{label.street_number}} ({{label.mandatory}}) 3131 </label> 3132 </div> 3133 </div> 3134 </div> 3135 3136 <div class="row"> 3137 <div class="col"> 3138 <div class="form-label-group"> 3139 <input v-model="location_name" class="form-control form-control-text" placeholder="" id="location_name" type="text"> 3140 <label for="location_name"> 3141 {{label.entrance}} 3142 </label> 3143 </div> 3144 </div> 3145 <div class="col"> 3146 <div class="form-label-group"> 3147 <input v-model="address2" class="form-control form-control-text" placeholder="" id="address2" type="text"> 3148 <label for="address2"> 3149 {{label.floor}} 3150 </label> 3151 </div> 3152 </div> 3153 </div> 3154 3155 3156 <div class="row"> 3157 <div class="col"> 3158 3159 <div class="form-label-group"> 3160 <input v-model="postal_code" class="form-control form-control-text" placeholder="" id="postal_code" type="text"> 3161 <label for="postal_code"> 3162 {{label.door}} ({{label.mandatory}}) 3163 </label> 3164 </div> 3165 3166 </div> 3167 <div class="col"> 3168 3169 <div class="form-label-group"> 3170 <input v-model="company" class="form-control form-control-text" placeholder="" id="company" type="text"> 3171 <label for="company"> 3172 {{label.company}} 3173 </label> 3174 </div> 3175 3176 </div> 3177 </div> 3178 3179 3180 </template> 3181 <template v-else> 3182 3183 <div class="form-label-group"> 3184 <input v-model="formatted_address" class="form-control form-control-text" placeholder="" id="formatted_address" type="text"> 3185 <label for="formatted_address"> 3186 {{label.street_name}} 3187 </label>
3188 </div> 3189 3190 <div class="form-label-group"> 3191 <input v-model="address1" class="form-control form-control-text" placeholder="" id="address1" type="text"> 3192 <label for="address1"> 3193 {{label.street_number}} 3194 </label> 3195 </div> 3196 3197 <div class="form-label-group"> 3198 <input class="form-control form-control-text" v-model="location_name" 3199 id="location_name" type="text" > 3200 <label for="location_name">{{label.location_name}}</label> 3201 </div> 3202 3203 </template> 3204 3205 <h5 class="m-0 mt-2 mb-2">{{label.delivery_options}}</h5> 3206 <select class="form-control custom-select" v-model="delivery_options"> 3207 <option v-for="(items, key) in delivery_options_data" :value="key" >{{items}}</option> 3208 </select> 3209 3210 3211 <h5 class="m-0 mt-2 mb-2">{{label.delivery_instructions}}</h5> 3212 <div class="form-label-group"> 3213 <textarea id="delivery_instructions" 3214 style="max-height:150px;" v-model="delivery_instructions" class="form-control form-control-text font13" 3215 :placeholder="label.notes"> 3216 </textarea> 3217 </div> 3218 3219 <template v-if="custom_field_enabled"> 3220 <div class="d-flex align-items-center"> 3221 <div class="mr-2"><h5 class="m-0 mt-2 mb-2">{{label.custom_field1}}</h5></div> 3222 <div> 3223 <el-tooltip placement="top" :content="label.custom_field1_info"> 3224 <el-button link type="plain"> 3225 <i class="zmdi zmdi-info font20"></i> 3226 </el-button> 3227 </el-tooltip> 3228 </div> 3229 </div> 3230 3231 <select class="form-control custom-select" v-model="custom_field1"> 3232 <option v-for="(items, key) in custom_field1_data" :value="key" >{{items}}</option> 3233 </select> 3234 3235 <div class="d-flex align-items-center"> 3236 <div class="m-0 mt-2 mb-2"><h5 class="m-0 mt-2 mb-2">{{label.custom_field2}}</h5></div> 3237 <div> 3238 <el-tooltip placement="top" :content="label.custom_field2_info"> 3239 <el-button link type="plain"> 3240 <i class="zmdi zmdi-info font20"></i> 3241 </el-button> 3242 </el-tooltip> 3243 </div> 3244 </div> 3245 3246 <div class="form-label-group"> 3247 <textarea id="delivery_instructions" 3248 style="max-height:150px;" v-model="custom_field2" class="form-control form-control-text font13" > 3249 </textarea> 3250 </div> 3251 </template> 3252 3253 <div class="mb-1 mt-1"></div> 3254 3255 <p>{{label.address_label}}</p> 3256 <div class="btn-group btn-group-toggle input-group-small mb-4" > 3257 <label class="btn" v-for="(items, key) in address_label_data" :class="{ active: address_label==key }" > 3258 <input v-model="address_label" type="radio" :value="key" > 3259 {{ items }} 3260 </label> 3261 </div> 3262 <!--btn-group--> 3263 3264 </div> <!--forms--> 3265 3266 </template> 3267 3268 <div id="error_message" v-cloak v-if="error.length>0" class="alert alert-warning mb-2" role="alert"> 3269 <p v-for="err in error" class="m-0">{{err}}</p> 3270 </div> 3271 3272 3273 </div> <!--modal-body--> 3274 3275 3276 <div class="modal-footer justify-content-start"> 3277 3278 <template v-if="!cmaps_full"> 3279 <div class="border flex-fill"> 3280 <button class="btn btn-black w-100" @click="closeModal" > 3281 {{label.cancel}} 3282 </button> 3283 </div> 3284 <div class="border flex-fill"> 3285 <button class="btn btn-green w-100" @click="save" :class="{ loading: is_loading }" :disabled="!DataValid" > 3286 <span class="label">{{label.save}}</span> 3287 <div class="m-auto circle-loader" data-loader="circle-side"></div> 3288 </button> 3289 </div> 3290 </template> 3291 3292 <template v-else-if="cmaps_full"> 3293 <div class="border flex-fill"> 3294 <button class="btn btn-black w-100" @click="cancelPin" > 3295 {{label.cancel}} 3296 </button> 3297 </div> 3298 <div class="border flex-fill"> 3299 <button class="btn btn-green w-100" @click="setNewCoordinates" 3300 :class="{ loading: is_loading }" :disabled="!DataValidNew" >
3301 <span class="label">{{label.save}}</span> 3302 <div class="m-auto circle-loader" data-loader="circle-side"></div> 3303 </button> 3304 </div> 3305 </template> 3306 3307 </div> <!--content--> 3308 </div> <!--dialog--> 3309 </div> <!--modal--> 3310 `, 3311}; 3312 3313 3314/* 3315DIRECTIVE CLICK OUTSIDE 3316*/ 3317const clickOutside = { 3318 beforeMount: (el, binding) => { 3319 el.clickOutsideEvent = event => { 3320 // here I check that click was outside the el and his children 3321 if (!(el == event.target || el.contains(event.target))) { 3322 // and if it did, call method provided in attribute value 3323 binding.value(); 3324 } 3325 }; 3326 document.addEventListener("click", el.clickOutsideEvent); 3327 }, 3328 unmounted: el => { 3329 document.removeEventListener("click", el.clickOutsideEvent); 3330 }, 3331}; 3332 3333 3334/* 3335 COMPONENTS MERCHANT SERVICES 3336*/ 3337const ComponentsMerchantServices = { 3338 props: ['title','label'], 3339 data(){ 3340 return { 3341 transaction_list :[], 3342 transaction : '', 3343 loading : false, 3344 charge_type : '', 3345 estimation : [] 3346 }; 3347 }, 3348 mounted () { 3349 this.getMerchantServices(); 3350 }, 3351 methods :{ 3352 getMerchantServices(){ 3353 3354 var $params; var timenow = getTimeNow(); 3355 $params="merchant_id=" + merchant_id; 3356 $params+="&cart_uuid=" + getCookie('cart_uuid'); 3357 $params+=addValidationRequest(); 3358 ajax_request[timenow] = $.ajax({ 3359 url: ajaxurl+"/servicesList", 3360 method: "POST", 3361 dataType: "json", 3362 data: $params, 3363 contentType : $content_type.form , 3364 timeout: $timeout, 3365 crossDomain: true, 3366 beforeSend: function( xhr ) { 3367 this.loading = false; 3368 if(ajax_request[timenow] != null) { 3369 ajax_request[timenow].abort(); 3370 } 3371 } 3372 }); 3373 3374 ajax_request[timenow].done( data => { 3375 if ( data.code==1){ 3376 this.transaction_list = data.details.data; 3377 this.transaction = data.details.transaction; 3378 this.charge_type = data.details.charge_type; 3379 this.estimation = data.details.estimation; 3380 } else { 3381 this.transaction_list = []; 3382 this.transaction = ''; 3383 this.charge_type = ''; 3384 this.estimation = []; 3385 } 3386 }); // ajax done 3387 3388 ajax_request[timenow].always( data => { 3389 this.loading = false; 3390 }); 3391 3392 }, 3393 doUpdateService(data){ 3394 this.transaction = data; 3395 this.updateService(); 3396 }, 3397 updateService(){ 3398 axios({ 3399 method: 'POST', 3400 url: ajaxurl+"/updateService" , 3401 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') +"&transaction_type="+this.transaction + "&cart_uuid=" + getCookie('cart_uuid'), 3402 timeout: $timeout, 3403 }).then( response => { 3404 if(response.data.code==1){ 3405 setCookie('cart_transaction_type', this.transaction ,30); 3406 setCookie('cart_uuid', response.data.details.cart_uuid ,30); 3407 } 3408 if ((typeof vm_addres_needed !== "undefined") && ( vm_addres_needed !== null)) { 3409 vm_addres_needed.addressNeeded(); 3410 } 3411 }).catch(error => { 3412 // 3413 }).then(data => { 3414 this.$emit('afterUpdate',this.transaction); 3415 }); 3416 }, 3417 }, 3418 template: ` 3419 <div class="btn-group-rounded btn-group btn-group-toggle" > 3420 <label class="btn d-flex" 3421 v-for="trans in transaction_list" :class="{ active: transaction==trans.service_code }" > 3422 <input type="radio" :value="trans.service_code" v-model="transaction" @click="doUpdateService(trans.service_code)" > 3423 <div class="align-self-center"> 3424 <div class="bold">{{ trans.service_name }}</div> 3425 3426 <template v-if="estimation[trans.service_code]"> 3427 <template v-for="(item,index) in estimation[trans.service_code] "> 3428 3429 <template v-if="trans.service_code=='delivery'"> 3430 <template v-if="item.charge_type==charge_type"> 3431 <p class="m-0">{{item.estimation}} {{label.min}}</p> 3432 </template> 3433 </template> 3434 <template v-else> 3435 <template v-if="item.charge_type=='fixed'"> 3436 <p class="m-0">{{item.estimation}} {{label.min}}</p> 3437 </template> 3438 </template> 3439 3440 </template> 3441 </template> 3442 3443 </div> 3444 </label> 3445 </div> 3446 `, 3447}; 3448 3449 3450/* 3451 COMPONENTS RECAPCHA 3452 https://github.com/bbonch/vue3-recaptcha2 3453*/ 3454 3455const componentsRecaptcha = { 3456 props: ['sitekey','size','theme','is_enabled','captcha_lang'], 3457 data() { 3458 return { 3459 recaptcha: null, 3460 } 3461 }, 3462 mounted() { 3463 if(this.is_enabled==1 || this.is_enabled=="true" || this.is_enabled==true){ 3464 this.initCapcha(); 3465 } 3466 }, 3467 methods: { 3468 initCapcha(){ 3469 if (window.grecaptcha == null) { 3470 new Promise((resolve) => { 3471 window.recaptchaReady = function () { 3472 resolve(); 3473 }; 3474 3475 const doc = window.document; 3476 const scriptId = "recaptcha-script"; 3477 const scriptTag = doc.createElement("script"); 3478 scriptTag.id = scriptId; 3479 scriptTag.setAttribute("src", "https://www.google.com/recaptcha/api.js?onload=recaptchaReady&render=explicit&hl="+ this.captcha_lang); 3480 doc.head.appendChild(scriptTag); 3481 }).then(() => { 3482 this.renderRecaptcha(); 3483 }); 3484 } else { 3485 this.renderRecaptcha(); 3486 } 3487 }, 3488 renderRecaptcha(){ 3489 this.recaptcha = grecaptcha.render( this.$refs.recaptcha_target , { 3490 'sitekey' : this.sitekey, 3491 'theme': this.theme, 3492 'size': this.size, 3493 'tabindex': this.tabindex, 3494 'callback': (response) => this.$emit("verify", response), 3495 'expired-callback': () => this.$emit("expire"), 3496 'error-callback': () => this.$emit("fail") 3497 }); 3498 }, 3499 reset() { 3500 grecaptcha.reset(this.recaptcha); 3501 } 3502 }, 3503 template: ` 3504 <div class="mb-2 mt-2" ref="recaptcha_target"></div> 3505 ` 3506}; 3507 3508 3509/* 3510 COMPONENTS PHONE NUMBER 3511*/ 3512const ComponentsPhoneNumber = { 3513 props: ['label','mobile_number','mobile_prefix','default_country','only_countries'], 3514 emits: ['update:mobile_number','update:mobile_prefix'], 3515 data(){ 3516 return { 3517 data : [], 3518 country_flag : '' 3519 }; 3520 }, 3521 updated () { 3522 3523 }, 3524 mounted () { 3525 this.getLocationCountries(); 3526 }, 3527 methods :{ 3528 getLocationCountries(){ 3529 3530 var $params = { 3531 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 3532 'default_country': this.default_country, 3533 'only_countries': this.only_countries 3534 }; 3535 var timenow = getTimeNow(); 3536 $params = JSON.stringify($params); 3537 3538 ajax_request[timenow] = $.ajax({ 3539 url: ajaxurl+"/getLocationCountries", 3540 method: "PUT", 3541 dataType: "json", 3542 data: $params , 3543 contentType : $content_type.json , 3544 timeout: $timeout, 3545 crossDomain: true, 3546 beforeSend: data => { 3547 this.is_loading = true; 3548 if(ajax_request[timenow] != null) { 3549 ajax_request[timenow].abort(); 3550 } 3551 } 3552 }); 3553 3554 ajax_request[timenow].done( data => { 3555 if ( data.code==1){ 3556 this.data = data.details.data; 3557 this.country_flag = data.details.default_data.flag; 3558 this.$emit('update:mobile_prefix', data.details.default_data.phonecode ); 3559 } else { 3560 this.data = []; 3561 this.country_flag=''; 3562 this.mobile_prefix=''; 3563 } 3564 }); 3565 3566 ajax_request[timenow].always( data => { 3567 3568 }); 3569 3570 }, 3571 setValue(data){ 3572 this.country_flag = data.flag; 3573 this.$emit('update:mobile_prefix', data.phonecode ); 3574 this.$refs.ref_mobile_number.focus(); 3575 }, 3576 }, 3577 template: `
3578 <div class="inputs-with-dropdown d-flex align-items-center mb-3" > 3579 <div class="dropdown"> 3580 <button class="dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> 3581 <img v-if="country_flag" :src="country_flag"> 3582 </button> 3583 <div class="dropdown-menu" > 3584 <a v-for="item in data" @click="setValue(item)" 3585 href="javascript:;" class="dropdown-item d-flex align-items-center"> 3586 <div class="mr-2"> 3587 <img :src="item.flag"> 3588 </div> 3589 <div>{{item.country_name}}</div> 3590 </a> 3591 </div> 3592 </div> <!--dropdown--> 3593 3594 <div class="mr-0 ml-1" v-if="mobile_prefix">+{{mobile_prefix}}</div> 3595 <input type="text" v-maska="'###################'" ref="ref_mobile_number" 3596 :value="mobile_number" @input="$emit('update:mobile_number', $event.target.value)" > 3597 3598 </div> <!--inputs--> 3599 ` 3600}; 3601 3602 3603 3604/*COMPONENTS CONFIRM AND ALERT*/ 3605const Componentsbootbox = { 3606 props: ['label','size'], 3607 methods :{ 3608 confirm(){ 3609 3610 bootbox.confirm({ 3611 size: this.size, 3612 title : this.label.confirm , 3613 message: this.label.are_you_sure, 3614 centerVertical: true, 3615 animate: false, 3616 buttons: { 3617 cancel: { 3618 label: this.label.cancel, 3619 className: 'btn btn-black small pl-4 pr-4' 3620 }, 3621 confirm: { 3622 label: this.label.yes, 3623 className: 'btn btn-green small pl-4 pr-4' 3624 }, 3625 }, 3626 callback: result => { 3627 this.$emit('callback',result); 3628 } 3629 }); 3630 3631 }, 3632 alert(message,options){ 3633 bootbox.alert({ 3634 size: !empty(options.size)?options.size:'' , 3635 closeButton: false, 3636 message: message , 3637 animate: false, 3638 centerVertical: true, 3639 buttons: { 3640 ok:{ 3641 label: this.label.ok, 3642 className: 'btn btn-green small pl-4 pr-4' 3643 } 3644 } 3645 }); 3646 }, 3647 }, 3648}; 3649 3650// const loadingBox = { 3651// props: ['message','donnot_close'], 3652// data(){ 3653// return { 3654// new_message : '' 3655// } 3656// }, 3657// methods :{ 3658// show(){ 3659// $('#loadingBox').modal('show'); 3660// }, 3661// close(){ 3662// $('#loadingBox').modal('hide'); 3663// }, 3664// setMessage(new_message){ 3665// this.new_message = new_message; 3666// }, 3667// }, 3668// template:` 3669// <div class="modal" id="loadingBox" tabindex="-1" role="dialog" aria-labelledby="loadingBox" aria-hidden="true" 3670// data-backdrop="static" data-keyboard="false" 3671// > 3672// <div class="modal-dialog modal-dialog-centered modal-loadingbox" role="document"> 3673// <div class="modal-content"> 3674// <div class="modal-body"> 3675// <div class="loading mt-2"> 3676// <div class="m-auto circle-loader medium" data-loader="circle-side"></div> 3677// </div> 3678// <p class="text-center mt-2"> 3679// <div v-if="!new_message">{{message}}</div> 3680// <div v-if="new_message">{{new_message}}</div> 3681// <div>{{donnot_close}}</div> 3682// </p> 3683// </div> 3684// </div> <!--content--> 3685// </div> <!--dialog--> 3686// </div> <!--modal--> 3687// ` 3688// }; 3689 3690 3691 3692/* 3693COMPONENTS REVIEW MODAL 3694*/ 3695var tagify,tagify2,$dropzone; 3696const ComponentsReview = { 3697 components: { 3698 'star-rating' : VueStarRating.default, 3699 }, 3700 props: ['label','accepted_files','max_file'], 3701 data(){ 3702 return { 3703 upload_images : [], 3704 required_message :[], 3705 rating_value : '', 3706 review_content : '', 3707 as_anonymous : false, 3708 order_uuid : '', 3709 is_loading : false, 3710 error : [] , 3711 is_reset : false, 3712 }; 3713 }, 3714 mounted () { 3715 tagify = new Tagify ( document.querySelector(".tags_like") ); 3716 tagify2 = new Tagify ( document.querySelector(".tags_not_like") ); 3717 autosize( document.getElementById("review_content") ); 3718 this.initDropZone(this.label , this); 3719 }, 3720 methods :{ 3721 show(){ 3722 $('#reviewModal').modal('show'); 3723 }, 3724 close(){ 3725 $( this.$refs.review_modal ).modal('hide'); 3726 Dropzone.forElement('#dropzone_multiple').removeAllFiles(true); 3727 }, 3728 reset(){ 3729 Dropzone.forElement('#dropzone_multiple').files = []; 3730 $('.dz-preview').remove(); 3731 $('.dropzone').removeClass('dz-started'); 3732 this.upload_images = []; 3733 this.rating_value = ''; 3734 this.review_content = ''; 3735 this.as_anonymous = false;
3736 this.order_uuid = ''; 3737 this.error = []; 3738 tagify.removeAllTags(); 3739 tagify2.removeAllTags(); 3740 3741 }, 3742 initDropZone(label, object){ 3743 var $upload_params = { 3744 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 3745 }; 3746 Dropzone.autoDiscover = false; 3747 $dropzone = $("#dropzone_multiple").dropzone({ 3748 dictDefaultMessage : label.dictDefaultMessage, 3749 dictFallbackMessage : label.dictFallbackMessage , 3750 dictFallbackText : label.dictFallbackText, 3751 dictFileTooBig : label.dictFileTooBig, 3752 dictInvalidFileType : label.dictInvalidFileType, 3753 dictResponseError : label.dictResponseError, 3754 dictCancelUpload : label.dictCancelUpload, 3755 dictCancelUploadConfirmation : label.dictCancelUploadConfirmation, 3756 dictRemoveFile : label.dictRemoveFile, 3757 dictMaxFilesExceeded : label.dictMaxFilesExceeded, 3758 paramName: "file", 3759 url: ajaxurl+"/uploadReview" , 3760 params: $upload_params, 3761 addRemoveLinks : true, 3762 maxFiles : parseInt(this.max_file), 3763 acceptedFiles: this.accepted_files , 3764 autoProcessQueue : true, 3765 init: function() { 3766 var instance = this; 3767 instance.on("maxfilesexceeded", function(file) { 3768 //component_alert.alert( [label.max_file_exceeded] ); 3769 notify(label.max_file_exceeded,'error'); 3770 instance.removeFile(file); 3771 }); 3772 instance.on("removedfile", function (file) { 3773 dump("removedfile"); 3774 object.removeUpload(file.upload_uuid); 3775 //file.previewElement.remove(); 3776 }); 3777 instance.on("success", (file,response) => { 3778 dump(response); 3779 var $resp = response; 3780 if($resp.code==1){ 3781 file.upload_uuid = $resp.details.id; 3782 object.upload_images.push( $resp.details ); 3783 } else { 3784 var $resp = JSON.parse(response); 3785 notify($resp.msg,'error'); 3786 instance.removeFile(file); 3787 } 3788 }); 3789 instance.on("addedfile", function() { 3790 dump("addedfile"); 3791 }); 3792 }, 3793 }); 3794 }, 3795 removeUpload(id){ 3796 3797 return new Promise((resolve, reject) => { 3798 3799 var $params = { 3800 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 3801 'id':id, 3802 }; 3803 var timenow = getTimeNow(); 3804 3805 ajax_request[timenow] = $.ajax({ 3806 url: ajaxurl+"/removeReviewImage", 3807 method: "PUT", 3808 dataType: "json", 3809 data: JSON.stringify($params) , 3810 contentType : $content_type.json , 3811 timeout: $timeout, 3812 crossDomain: true, 3813 beforeSend: data => { 3814 this.is_loading = true; 3815 if(ajax_request[timenow] != null) { 3816 ajax_request[timenow].abort(); 3817 this.is_loading = false; 3818 } 3819 } 3820 }); 3821 3822 ajax_request[timenow].done( data => { 3823 this.is_loading = false; 3824 resolve(true); 3825 if(data.code==1){ 3826 //this.remove(data.details); 3827 } 3828 }); // ajax done 3829 3830 ajax_request[timenow].always( data => { 3831 this.is_loading = false; 3832 }); 3833 3834 }); 3835 }, 3836 remove(uuid){ 3837 if(this.upload_images){ 3838 this.upload_images.forEach((item,index) => { 3839 if ( item.id==uuid){ 3840 dump("index remove=>" + index); 3841 this.upload_images.splice(index,1); 3842 } 3843 }); 3844 } 3845 }, 3846 getTag(data){ 3847 var $tag_data = []; 3848 if(data){ 3849 data.forEach((data,index) => { 3850 $tag_data.push( data.value ); 3851 }); 3852 } 3853 return $tag_data; 3854 }, 3855 addReview(){ 3856 3857 var $params = { 3858 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 3859 'order_uuid' : this.order_uuid, 3860 'review_content':this.review_content, 3861 'rating_value':this.rating_value, 3862 'as_anonymous':this.as_anonymous, 3863 'tags_like': this.getTag(tagify.value), 3864 'tags_not_like': this.getTag(tagify2.value), 3865 'upload_images':this.upload_images, 3866 }; 3867 var timenow = 1; 3868 3869 ajax_request[timenow] = $.ajax({ 3870 url: ajaxurl+"/addReview", 3871 method: "PUT", 3872 dataType: "json", 3873 data: JSON.stringify($params) , 3874 contentType : $content_type.json , 3875 timeout: $timeout, 3876 crossDomain: true, 3877 beforeSend: data => { 3878 this.is_loading = true; 3879 this.error = []; 3880 if(ajax_request[timenow] != null) { 3881 ajax_request[timenow].abort(); 3882 this.is_loading = false;
3883 } 3884 } 3885 }); 3886 3887 ajax_request[timenow].done( data => { 3888 dump(data); 3889 if(data.code==1){ 3890 notify(data.msg); 3891 this.reset(); 3892 $( this.$refs.review_modal ).modal('hide'); 3893 this.$emit('afterAddreview'); 3894 } else { 3895 this.error = data.msg; 3896 setTimeout(function() { 3897 location.href = "#error_message"; 3898 }, 1); 3899 } 3900 }); 3901 3902 ajax_request[timenow].always( data => { 3903 this.is_loading = false; 3904 }); 3905 }, 3906 deleteAllImages(){ 3907 3908 if(this.upload_images.length<=0){ 3909 return false; 3910 } 3911 3912 var $params = { 3913 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 3914 'upload_images':this.upload_images, 3915 }; 3916 3917 var timenow = getTimeNow(); 3918 ajax_request[timenow] = $.ajax({ 3919 url: ajaxurl+"/removeAllReviewImage", 3920 method: "PUT", 3921 dataType: "json", 3922 data: JSON.stringify($params) , 3923 contentType : $content_type.json , 3924 timeout: $timeout, 3925 crossDomain: true, 3926 beforeSend: data => { 3927 if(ajax_request[timenow] != null) { 3928 ajax_request[timenow].abort(); 3929 } 3930 } 3931 }); 3932 3933 ajax_request[timenow].done( data => { 3934 if(data.code==1){ 3935 this.upload_images = []; 3936 Dropzone.forElement('#dropzone_multiple').removeAllFiles(true); 3937 } 3938 }); // ajax done 3939 }, 3940 }, 3941 template: ` 3942 <div class="modal" ref="review_modal" id="reviewModal" tabindex="-1" role="dialog" aria-labelledby="reviewModal" aria-hidden="true" data-backdrop="static" data-keyboard="false" > 3943 <div class="modal-dialog modal-dialog-centered" role="document"> 3944 <div class="modal-content"> 3945 3946 3947 <div class="modal-body" > 3948 3949 <a href="javascript:;" @click="close" 3950 class="btn btn-black btn-circle rounded-pill"><i class="zmdi zmdi-close font20"></i></a> 3951 3952 <h4 class="bold m-0 mb-3 mt-3">{{label.write_review}}</h4> 3953 3954 <star-rating 3955 v-model:rating="rating_value" 3956 :star-size="30" 3957 :show-rating="false" 3958 @update:rating="rating_value = $event" 3959 > 3960 </star-rating> 3961 3962 <h5 class="m-0 mt-3 mb-2">{{label.what_did_you_like}}</h5> 3963 <input type="text" name="tags_like" class="tags_like" id="tags_like" :placeholder="label.search_tag"> 3964 3965 <h5 class="m-0 mt-2 mb-2">{{label.what_did_you_not_like}}</h5> 3966 <input type="text" name="tags_not_like" class="tags_not_like" id="tags_not_like" :placeholder="label.search_tag"> 3967 3968 <h5 class="m-0 mt-3 mb-2">{{label.add_photo}}</h5> 3969 <div class="mb-3"> 3970 <div class="dropzone dropzone_container" id="dropzone_multiple" data-action="gallery_create"> 3971 <div class="dz-default dz-message"> 3972 <i class="fas fa-cloud-upload-alt"></i> 3973 <p>{{label.drop_files_here}}</p> 3974 </div> 3975 </div> 3976 </div> 3977 3978 <!-- <div v-if="upload_images.length>0" class="row gallery m-0"> 3979 <div v-for="images in upload_images" class="col-lg-4 col-md-4 col-sm-12 mb-0 mb-lg-0 p-1"> 3980 <div class="position-relative"> 3981 <img :src="images.url_image"> 3982 <a href="javascript:;" 3983 @click="removeUpload(images.id)" data-dz-remove 3984 class="remove btn btn-black btn-circle rounded-pill"><i class="zmdi zmdi-plus"></i></a> 3985 </div> 3986 </div> 3987 </div>--> 3988 3989 <h5 class="m-0 mt-2 mb-2">{{label.write_your_review}}</h5> 3990 <div class="form-label-group"> 3991 <textarea id="review_content" class="form-control form-control-text font13" 3992 :placeholder="label.review_helps" 3993 v-model="review_content" 3994 style="max-height:150px;" 3995 > 3996 </textarea> 3997 </div> 3998 3999 <div class="custom-control custom-checkbox flex-grow-1"> 4000 <input type="checkbox" class="custom-control-input" 4001 name="as_anonymous" value="1" 4002 id="as_anonymous" 4003 v-model="as_anonymous" 4004 > 4005 <label class="custom-control-label font14 bold" for="as_anonymous" > 4006 {{label.post_review_anonymous}} 4007 </label> 4008 </div> 4009 4010 4011 <div id="error_message" v-cloak v-if="error.length>0" class="alert alert-warning mb-2 mt-2" role="alert"> 4012 <p v-cloak v-for="message in error" class="m-0">{{message}}</p> 4013 </div> 4014 4015 </div> <!--modal body--> 4016 4017 <div class="modal-footer justify-content-start"> 4018 <button class="btn btn-black w-100" @click="addReview" :class="{ loading: is_loading }" >
4019 <span class="label">{{label.add_review}}</span> 4020 <div class="m-auto circle-loader" data-loader="circle-side"></div> 4021 </button> 4022 </div> <!--footer--> 4023 4024 </div> <!--content--> 4025 </div> <!--dialog--> 4026 </div> <!--modal--> 4027 `, 4028}; 4029 4030 4031/* 4032 COMPONENTS MONEY 4033*/ 4034const ComponentsMoney = { 4035 props: ['ajax_url', 'amount','price_format'], 4036 data(){ 4037 return { 4038 data : 0, 4039 config : JSON.parse(money_config) 4040 /*config : { 4041 prefix : '$', 4042 suffix: '', 4043 thousands : ',', 4044 decimal : '.', 4045 precision : 2, 4046 }, */ 4047 }; 4048 }, 4049 mounted() { 4050 this.data = window["v-money3"].format(this.amount, this.config); 4051 }, 4052 watch: { 4053 price_format(newval,oldval){ 4054 this.config = newval; 4055 } 4056 }, 4057 updated(){ 4058 this.data = window["v-money3"].format(this.amount, this.config); 4059 }, 4060 methods :{ 4061 formatNumber(data){ 4062 return window["v-money3"].format(data, this.config); 4063 }, 4064 }, 4065 template:` 4066 {{data}} 4067 ` 4068}; 4069 4070var MoneyFormat = function(amount){ 4071 return window["v-money3"].format(amount, JSON.parse(money_config)); 4072}; 4073 4074 4075// START 1.0.8 COMPONENTS 4076//let bounds; 4077let yandex_map; 4078let yandex_zoom = 16.6; 4079const ComponentsMaps = { 4080 props: ["keys", "provider", "zoom", "center", "markers", "size"], 4081 template : ` 4082 <div ref="cmaps" class="map border" :class="size"></div> 4083 4084 <div class="position-absolute map-buttons-wrap" v-if="size=='map-lg-large'" > 4085 <div class="btn-group-vertical" v-loading="loading" v-if="provider!='yandex'" > 4086 <div class="mb-2"> 4087 <button @click="locateLocation" type="button" class="btn btn-white rounded-circle"> 4088 <i class="zmdi zmdi-gps-dot font25"></i> 4089 </button> 4090 </div> 4091 <button @click="setPlusZoom()" type="button" class="btn btn-white"> 4092 <i class="zmdi zmdi-plus font25"></i> 4093 </button> 4094 <div class="divider py-1 bg-dark"></div> 4095 <button @click="setLessZoom()" type="button" class="btn btn-white"> 4096 <i class="zmdi zmdi-minus font25"></i> 4097 </button> 4098 </div> 4099 </div> 4100 `, 4101 // setup(props) { 4102 // const enabled_controls = props.enabled_controls !== undefined ? props.enabled_controls : true; 4103 // return { 4104 // enabled_controls 4105 // }; 4106 // }, 4107 data() { 4108 return { 4109 cmapsMarker : [], 4110 latLng : [], 4111 cmaps: undefined, 4112 bounds : undefined, 4113 loading : false, 4114 } 4115 }, 4116 mounted() { 4117 this.renderMap(); 4118 }, 4119 watch: { 4120 markers(newval, oldval) { 4121 this.renderMap(); 4122 }, 4123 }, 4124 methods: { 4125 locateLocation(){ 4126 this.$emit("dragMarker", true); 4127 this.loading = true; 4128 if (navigator.geolocation) { 4129 navigator.geolocation.getCurrentPosition( 4130 (data) => { 4131 this.$emit("dragMarker", false); 4132 this.loading = false; 4133 this.$emit("afterSelectmap", data.coords.latitude,data.coords.longitude); 4134 dump(data); 4135 }, 4136 (error) => { 4137 this.$emit("dragMarker", false); 4138 this.loading = false; 4139 const $sw = JSON.parse(some_words); 4140 let msg; 4141 switch (error.code) { 4142 case error.PERMISSION_DENIED: 4143 msg = $sw.location_permission_denied; 4144 break; 4145 case error.POSITION_UNAVAILABLE: 4146 msg = $sw.location_position_unavailable; 4147 break; 4148 case error.TIMEOUT: 4149 msg = $sw.location_requesttimeout; 4150 break; 4151 default: 4152 msg = $sw.location_uknown; 4153 } 4154 ElementPlus.ElNotification({ 4155 title: "", 4156 message: msg, 4157 position: 'bottom-right', 4158 type: 'warning', 4159 }); 4160 } 4161 ); 4162 } else { 4163 this.$emit("dragMarker", false); 4164 this.loading = false; 4165 const $sw = JSON.parse(some_words); 4166 ElementPlus.ElNotification({ 4167 title: "", 4168 message: $sw.location_not_supported, 4169 position: 'bottom-right', 4170 type: 'warning', 4171 }); 4172 } 4173 }, 4174 renderMap(){ 4175 try { 4176 switch (this.provider) { 4177 case "google.maps": 4178 this.bounds = new window.google.maps.LatLngBounds(); 4179 if (typeof this.cmaps !== "undefined" && this.cmaps !== null && Object.keys(this.cmapsMarker).length>0 ) { 4180 this.moveAllMarker(); 4181 } else { 4182 this.cmaps = new window.google.maps.Map(this.$refs.cmaps, { 4183 center: { 4184 lat: parseFloat(this.center.lat), 4185 lng: parseFloat(this.center.lng), 4186 }, 4187 zoom: parseInt(this.zoom), 4188 disableDefaultUI: true , 4189 styles : map_style 4190 }); 4191
4192 Object.entries(this.markers).forEach(([key, items]) => { 4193 this.addMarker( 4194 { 4195 position: { 4196 lat: parseFloat(items.lat), 4197 lng: parseFloat(items.lng), 4198 }, 4199 map: this.cmaps, 4200 draggable: items.draggable==1?true:false, 4201 label: items.label, 4202 }, 4203 items.id, 4204 items.draggable 4205 ); 4206 }); 4207 4208 } 4209 break; 4210 4211 case "mapbox": 4212 if (typeof this.cmaps !== "undefined" && this.cmaps !== null && Object.keys(this.cmapsMarker).length>0 ) { 4213 this.moveAllMarker(); 4214 } else { 4215 mapboxgl.accessToken = this.keys; 4216 this.bounds = new mapboxgl.LngLatBounds(); 4217 this.cmaps = new mapboxgl.Map({ 4218 container: this.$refs.cmaps, 4219 style: 'mapbox://styles/mapbox/streets-v12', 4220 center: [ parseFloat(this.center.lng), parseFloat(this.center.lat)], 4221 zoom: 14 4222 }); 4223 4224 this.cmaps.on('error', (response) => { 4225 dump(response.error.message) 4226 }); 4227 4228 Object.entries(this.markers).forEach(([key, items]) => { 4229 this.addMarker( 4230 { 4231 position: { 4232 lat: parseFloat(items.lat), 4233 lng: parseFloat(items.lng), 4234 }, 4235 map: this.cmaps, 4236 draggable: items.draggable==1?true:false, 4237 }, 4238 items.id, 4239 items.draggable 4240 ); 4241 }); 4242 4243 if (Object.keys(this.markers).length > 1) { 4244 this.FitBounds(); 4245 } else { 4246 if(this.markers[0]){ 4247 this.setCenter(this.markers[0].lat, this.markers[0].lng); 4248 } 4249 } 4250 } 4251 break; 4252 4253 case "yandex": 4254 this.initYandex(); 4255 break; 4256 4257 } 4258 } catch (err) { 4259 console.error(err); 4260 } 4261 }, 4262 async initYandex(){ 4263 console.debug("initYandex"); 4264 await ymaps3.ready; 4265 const {YMap, YMapDefaultSchemeLayer,YMapMarker,YMapDefaultFeaturesLayer,YMapListener,YMapControls } = ymaps3; 4266 const {YMapDefaultMarker} = await ymaps3.import('@yandex/[email protected]'); 4267 const {YMapZoomControl,YMapGeolocationControl} = await ymaps3.import('@yandex/[email protected]'); 4268 4269 const LOCATION = { 4270 center: [ parseFloat(this.center.lng), parseFloat(this.center.lat) ], 4271 zoom: yandex_zoom 4272 }; 4273 4274 if ((typeof this.$refs.cmaps !== "undefined") && ( this.$refs.cmaps !== null)) { 4275 } else { 4276 return; 4277 } 4278 4279 console.debug("yandex_map",yandex_map); 4280 console.debug("this.markers",this.markers); 4281 4282 if (!yandex_map) { 4283 console.debug("ADD Yandex map"); 4284 yandex_map = new YMap( 4285 this.$refs.cmaps, 4286 { 4287 location: LOCATION, 4288 showScaleInCopyrights: false, 4289 behaviors: ['drag','scrollZoom'] 4290 }, 4291 [ 4292 new YMapDefaultSchemeLayer({}), 4293 new YMapDefaultFeaturesLayer({}) 4294 ] 4295 ); 4296 4297 let is_dragable = true; 4298 if (Object.keys(this.markers).length > 0) { 4299 is_dragable = this.markers[0].draggable; 4300 } 4301 console.debug("is_dragable",is_dragable); 4302 4303 if(is_dragable){ 4304 yandex_map.addChild( 4305 new YMapListener({ 4306 onUpdate : (data)=>{ 4307 if(data.mapInAction){ 4308 this.cmapsMarker[0].update({ 4309 coordinates : data.location.center 4310 }); 4311 this.$emit("dragMarker", true); 4312 } else { 4313 this.$emit("dragMarker", false); 4314 } 4315 }, 4316 onActionEnd : (data)=>{ 4317 console.log("onActionEnd",data.type); 4318 if(data.type=="drag"){ 4319 this.cmapsMarker[0].update({ 4320 coordinates : data.location.center 4321 }); 4322 this.$emit( 4323 "afterSelectmap", 4324 data.location.center[1], 4325 data.location.center[0] 4326 ); 4327 } else if ( data.type=="scrollZoom" ){ 4328 yandex_zoom = data.location.zoom; 4329 } 4330 }, 4331 }) 4332 ); 4333 } 4334 4335 if(this.size=='map-lg-large'){ 4336 yandex_map.addChild(
4337 new YMapControls({position: 'right'}) 4338 .addChild(new YMapZoomControl({})) 4339 ); 4340 4341 yandex_map.addChild( 4342 new YMapControls({position: 'top right'}) 4343 .addChild(new YMapGeolocationControl({ 4344 onGeolocatePosition:(results)=>{ 4345 console.log("onGeolocatePosition",results); 4346 this.$emit( 4347 "afterSelectmap", 4348 results[1], 4349 results[0] 4350 ); 4351 } 4352 })) 4353 ); 4354 } 4355 4356 Object.entries(this.markers).forEach(([key, items]) => { 4357 let index = items.id; 4358 this.cmapsMarker[index] = new YMapDefaultMarker({ 4359 coordinates: [ parseFloat(items.lng), parseFloat(items.lat) ] , 4360 draggable: items.draggable, 4361 onDragEnd: (coordinates)=>{ 4362 console.log("onDragEnd",coordinates); 4363 this.$emit( 4364 "afterSelectmap", 4365 coordinates[1], 4366 coordinates[0] 4367 ); 4368 } 4369 }); 4370 yandex_map.addChild(this.cmapsMarker[index]); 4371 }); 4372 4373 4374 if (Object.keys(this.markers).length > 1) { 4375 //this.FitBounds(); 4376 } else { 4377 if(this.markers[0]){ 4378 //console.log("set Center"); 4379 const NEWLOCATION = { 4380 center : [this.markers[0].lng,this.markers[0].lat], 4381 zoom :yandex_zoom 4382 }; 4383 yandex_map.update({ 4384 location : NEWLOCATION 4385 }); 4386 } 4387 } 4388 } else { 4389 console.debug("move all marker"); 4390 Object.entries(this.markers).forEach(([key, items]) => { 4391 let index = items.id; 4392 if(this.cmapsMarker[index]){ 4393 this.cmapsMarker[index].update({ 4394 coordinates: [ items.lng, items.lat ] , 4395 }); 4396 } 4397 }); 4398 4399 if (Object.keys(this.markers).length > 1) { 4400 //this.FitBounds(); 4401 } else { 4402 if(this.markers[0]){ 4403 const NEWLOCATION = { 4404 center : [this.markers[0].lng,this.markers[0].lat], 4405 zoom : yandex_zoom 4406 }; 4407 yandex_map.update({ 4408 location : NEWLOCATION 4409 }); 4410 } 4411 } 4412 } 4413 4414 4415 }, 4416 async addMarker(properties, index, draggable) { 4417 try { 4418 4419 switch (this.provider) { 4420 case "google.maps": 4421 this.cmapsMarker[index] = new window.google.maps.Marker(properties); 4422 4423 this.cmaps.panTo( 4424 new window.google.maps.LatLng( 4425 properties.position.lat, 4426 properties.position.lng 4427 ) 4428 ); 4429 this.bounds.extend(this.cmapsMarker[index].position); 4430 4431 if (draggable === true) { 4432 google.maps.event.addListener(this.cmaps, 'drag',(data)=>{ 4433 this.$emit("dragMarker", true); 4434 let new_position = new google.maps.LatLng(this.cmaps.getCenter().lat(),this.cmaps.getCenter().lng()); 4435 this.cmapsMarker[index].setPosition(new_position); 4436 }); 4437 4438 google.maps.event.addListener(this.cmaps, 'dragend',(data)=>{ 4439 let wrapped = new google.maps.LatLng(this.cmaps.getCenter().lat(), this.cmaps.getCenter().lng()); 4440 this.$emit("dragMarker", false); 4441 this.$emit("afterSelectmap",wrapped.lat() , wrapped.lng()); 4442 }); 4443 4444 window.google.maps.event.addListener( 4445 this.cmapsMarker[index], 4446 "drag", 4447 (marker) => { 4448 this.$emit("dragMarker", true); 4449 } 4450 ); 4451 4452 window.google.maps.event.addListener( 4453 this.cmapsMarker[index], 4454 "dragend", 4455 (marker) => { 4456 const latLng = marker.latLng; 4457 this.latLng = { 4458 lat :latLng.lat(), 4459 lng : latLng.lng() 4460 } 4461 this.$emit("dragMarker", false); 4462 this.$emit("afterSelectmap", latLng.lat(), latLng.lng()); 4463 } 4464 ); 4465 } 4466 4467 break; 4468 4469 case "mapbox": 4470 this.cmapsMarker[index] = new mapboxgl.Marker(properties) 4471 .setLngLat([properties.position.lng, properties.position.lat]) 4472 .addTo(this.cmaps); 4473 4474 this.bounds.extend(new mapboxgl.LngLat(properties.position.lng, properties.position.lat)); 4475 4476 if (draggable === true) { 4477 this.cmapsMarker[index].on("dragend", (event) => { 4478 const lngLat = this.cmapsMarker[index].getLngLat(); 4479 dump( lngLat.lat +"=>"+ lngLat.lng); 4480 this.$emit("afterSelectmap", lngLat.lat, lngLat.lng); 4481 }); 4482 4483 this.cmaps.on("drag", () => { 4484 this.cmapsMarker[index].setLngLat([ 4485 this.cmaps.getCenter().lng.toFixed(4), 4486 this.cmaps.getCenter().lat.toFixed(4), 4487 ]); 4488 }); 4489 4490 this.cmaps.on("dragend", () => { 4491 this.cmapsMarker[index].setLngLat([ 4492 this.cmaps.getCenter().lng.toFixed(4), 4493 this.cmaps.getCenter().lat.toFixed(4), 4494 ]); 4495 this.$emit( 4496 "afterSelectmap", 4497 this.cmaps.getCenter().lat.toFixed(4), 4498 this.cmaps.getCenter().lng.toFixed(4) 4499 ); 4500 }); 4501 4502 } 4503 4504 this.mapBoxResize(); 4505 break; 4506 4507 } 4508 4509 } catch (err) { 4510 console.error(err); 4511 } 4512 }, 4513 mapBoxResize() { 4514 if (this.provider == "mapbox") { 4515 setTimeout(() => { 4516 this.cmaps.resize(); 4517 }, 500); 4518 } 4519 }, 4520 moveAllMarker(){ 4521 console.log("moveAllMarker"); 4522 console.log(this.markers); 4523 4524 if(this.provider=='google.maps'){ 4525 if (Object.keys(this.markers).length > 0) {
4526 Object.entries(this.markers).forEach(([key, items]) => { 4527 let latlng = new google.maps.LatLng(parseFloat(items.lat), parseFloat(items.lng)); 4528 if(!empty(this.cmapsMarker[items.id])){ 4529 this.cmapsMarker[items.id].setPosition(latlng); 4530 } 4531 }); 4532 4533 if (Object.keys(this.markers).length > 1) { 4534 this.FitBounds(); 4535 } else { 4536 this.cmaps.panTo( 4537 new window.google.maps.LatLng( 4538 this.markers[0].lat, 4539 this.markers[0].lng 4540 ) 4541 ); 4542 } 4543 } 4544 } else { 4545 if (Object.keys(this.markers).length > 0) { 4546 Object.entries(this.markers).forEach(([key, items]) => { 4547 if(!empty(this.cmapsMarker[items.id])){ 4548 this.cmapsMarker[items.id].setLngLat([items.lng, items.lat]) 4549 .addTo(this.cmaps); 4550 } 4551 }); 4552 4553 if (Object.keys(this.markers).length > 1) { 4554 this.FitBounds(); 4555 } else { 4556 this.cmaps.flyTo({ 4557 center : [ this.markers[0].lng , this.markers[0].lat ], 4558 essential: true, 4559 zoom: 14, 4560 }); 4561 } 4562 } 4563 } 4564 }, 4565 centerMap() { 4566 this.FitBounds(); 4567 }, 4568 FitBounds() { 4569 try { 4570 switch (this.provider) { 4571 case "google.maps": 4572 if (!empty(this.bounds)) { 4573 this.cmaps.fitBounds(this.bounds); 4574 } 4575 break; 4576 case "mapbox": 4577 if (!empty(this.bounds)) { 4578 this.cmaps.fitBounds(this.bounds, { duration: 0, padding: 50 }); 4579 } 4580 break; 4581 } 4582 } catch (err) { 4583 //console.error(err); 4584 } 4585 }, 4586 setCenter(lat, lng) { 4587 try { 4588 switch (this.provider) { 4589 case "google.maps": 4590 this.cmaps.setCenter(new window.google.maps.LatLng(lat, lng)); 4591 break; 4592 case "mapbox": 4593 this.cmaps.flyTo({ 4594 center: [lng, lat], 4595 essential: true, 4596 }); 4597 break; 4598 } 4599 } catch (err) { 4600 console.error(err); 4601 } 4602 }, 4603 setPlusZoom(){ 4604 if(this.provider=="yandex"){ 4605 } else { 4606 this.cmaps.setZoom(this.cmaps.getZoom() + 2); 4607 } 4608 }, 4609 setLessZoom(){ 4610 if(this.provider=="yandex"){ 4611 } else { 4612 this.cmaps.setZoom(this.cmaps.getZoom() - 2); 4613 } 4614 }, 4615 //methods 4616 }, 4617}; 4618 4619/* 4620 COMPONENTS MAPS AUTO COMPLETE 4621*/ 4622const ComponentsAutoCompleteAdress = { 4623 props: ['label','modelValue','formatted_address','enabled_locate'], 4624 emits: ['update:modelValue'], 4625 data(){ 4626 return { 4627 q: '', 4628 awaitingSearch : false, 4629 show_list : false, 4630 data : [], 4631 error : [], 4632 hasSelected : false, 4633 loading : false, 4634 addressData : [], 4635 auto_locate : false, 4636 is_fullwidth : false, 4637 selectedData : [], 4638 // Flag to prevent watcher from overwriting user's selection with abbreviated form 4639 userSelectedFromDropdown : false 4640 }; 4641 }, 4642 created() { 4643 this.q = this.formatted_address; 4644 if ((typeof is_mobile !== "undefined") && ( is_mobile !== null)) { 4645 if(is_mobile){ 4646 this.is_fullwidth = true; 4647 } 4648 } 4649 }, 4650 watch: { 4651 formatted_address(newval,oldval){ 4652 // Don't overwrite if user just selected from dropdown (they have the long-form name) 4653 if(this.userSelectedFromDropdown){ 4654 // Reset the flag after skipping this update 4655 this.userSelectedFromDropdown = false; 4656 return; 4657 } 4658 this.q = newval; 4659 }, 4660 }, 4661 computed: { 4662 hasData(){ 4663 if(this.data.length>0){ 4664 return true; 4665 } 4666 return false; 4667 }, 4668 }, 4669 methods: { 4670 showList(){ 4671 this.show_list = true; 4672 }, 4673 clearData(){ 4674 this.data = []; 4675 this.q = ''; 4676 }, 4677 setData(data){ 4678 this.clearData(); 4679 this.q = data.description; 4680 this.$emit('update:modelValue', data.description); 4681 this.$emit('afterChoose',data); 4682 }, 4683 locateLocation(){ 4684 this.loading = true; 4685 if (navigator.geolocation) { 4686 navigator.geolocation.getCurrentPosition( 4687 (data) => { 4688 //this.loading = false; 4689 this.reverseGeocoding(data.coords.latitude,data.coords.longitude); 4690 }, 4691 (error) => { 4692 this.loading = false; 4693 ElementPlus.ElNotification({ 4694 title: "", 4695 message: error.message, 4696 position: 'bottom-right', 4697 type: 'warning', 4698 }); 4699 } 4700 ); 4701 } else { 4702 this.loading = false;
4703 ElementPlus.ElNotification({ 4704 title: "", 4705 message: "Your browser doesn't support geolocation.", 4706 position: 'bottom-right', 4707 type: 'warning', 4708 }); 4709 } 4710 }, 4711reverseGeocoding(lat,lng){ 4712 axios({ 4713 method: 'POST', 4714 url: ajaxurl+"/reverseGeocoding" , 4715 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&lat="+ lat+ "&lng="+lng, 4716 timeout: $timeout, 4717 }).then( response => { 4718 if(response.data.code==1){ 4719 // Use long-form address (formattedAddress has long street names like "Ravey Street") 4720 // Fall back to parsed_address.formatted_address_long, then formatted_address 4721 const longFormAddress = response.data.details.data.address?.formattedAddress 4722 || response.data.details.data.parsed_address?.formatted_address_long 4723 || response.data.details.data.address?.formatted_address 4724 || ''; 4725 const reversePostcode = response.data.details.data.address?.postal_code 4726 || response.data.details.data.parsed_address?.postal_code 4727 || ''; 4728 this.q = reorderAddressPostcode(longFormAddress, reversePostcode); 4729 this.addressData = response.data.details.data; 4730 // Also include the cleaned address as userSelectedDescription 4731 this.addressData.userSelectedDescription = this.q; 4732 //if(this.auto_locate){ 4733 this.$emit('afterGetcurrentlocation',this.addressData); 4734 //} 4735 } else { 4736 this.addressData = []; 4737 ElementPlus.ElNotification({ 4738 title: "", 4739 message: response.data.msg, 4740 position: 'bottom-right', 4741 type: 'warning', 4742 }); 4743 } 4744 }).catch(error => { 4745 // 4746 }).then(data => { 4747 this.loading = false; 4748 this.auto_locate = false; 4749 }); 4750 }, 4751 setAddressData(data){ 4752 this.addressData = data; 4753 // Don't overwrite this.q if user has already selected an address from dropdown 4754 // The dropdown already shows the long-form name (e.g., "Westdene Drive") 4755 // Place Details API returns abbreviated form (e.g., "Westdene Dr") which we don't want 4756 // Only update if this.q is empty (e.g., from auto-detect location) 4757 if(!this.q || this.q.trim() === ''){ 4758 if(data?.parsed_address?.formatted_address){ 4759 this.q = data.parsed_address.formatted_address; 4760 } else if(data?.address?.formattedAddress){ 4761 this.q = data.address.formattedAddress; 4762 } 4763 } 4764 }, 4765 setLoading(data){ 4766 this.loading = data; 4767 }, 4768onSubmit(){ 4769 if (Object.keys(this.addressData).length > 0) { 4770 console.log("selectedData",this.selectedData); 4771 if(this.selectedData.from_addressbook){ 4772 this.$emit('afterPointaddress',this.selectedData); 4773 } else { 4774 // Include the user's selected long-form description to preserve it 4775 // this.q contains the full street name (e.g., "Westdene Drive") 4776 // while addressData.address.formatted_address has abbreviated form 4777 let dataToEmit = {...this.addressData}; 4778 if(this.q && this.q.trim() !== ''){ 4779 // Get postcode from address data to append if missing from description 4780 const postcode = this.addressData?.address?.postal_code || this.addressData?.parsed_address?.postal_code || ''; 4781 // Reorder address to put postcode at end, append postcode if missing 4782 dataToEmit.userSelectedDescription = reorderAddressPostcode(this.q, postcode); 4783 } 4784 this.$emit('afterGetcurrentlocation',dataToEmit); 4785 } 4786 } else { 4787 this.auto_locate = true; 4788 this.locateLocation(); 4789 } 4790 }, 4791searchLocation(queryString,cb){ 4792 let data = []; 4793 let is_guest = 1; 4794 if ((typeof isGuest !== "undefined") && ( isGuest !== null)) { 4795 is_guest = isGuest; 4796 } 4797 let methods = empty(queryString)?'getRecentAddress':'getlocationAutocomplete'; 4798 methods = is_guest==1?'getlocationAutocomplete':methods; 4799 if(is_guest==1 && empty(queryString)){ 4800 cb(data); 4801 return; 4802 } 4803 axios({ 4804 method: 'POST', 4805 url: ajaxurl+"/"+methods , 4806 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content')+"&q="+queryString, 4807 timeout: $timeout, 4808 }).then( response => { 4809 if(response.data.code==1){ 4810 data = response.data.details.data; 4811 // Build display name from addressLine1 + addressLine2 (uses full names like "Westdene Drive") 4812 // instead of description (which has abbreviated forms like "Westdene Dr") 4813 data = data.map(item => { 4814 if(item.addressLine1 && item.addressLine2){ 4815 item.description = item.addressLine1 + ', ' + item.addressLine2; 4816 } 4817 return item; 4818 }); 4819 } else { 4820 data = [] 4821 } 4822 cb(data); 4823 }).catch(error => { 4824 // 4825 }).then(data => { 4826 }); 4827 }, 4828 handleSelect(item){ 4829 this.selectedData = item; 4830 // Set flag to prevent watcher from overwriting with abbreviated form 4831 this.userSelectedFromDropdown = true; 4832 // Directly set this.q to preserve the long-form description (e.g., "Westdene Drive") 4833 // This prevents it from being overwritten by abbreviated forms from Place Details API 4834 this.q = item.description; 4835 this.$emit('update:modelValue', item.description); 4836 this.$emit('afterChoose',item); 4837 }, 4838 // 4839 }, 4840 template: ` 4841 <div class="d-flex flex-sm-row flex-column align-items-center justify-content-between"> 4842 <div class="position-relative search-geocomplete" v-loading="loading" :class="{width_87 : enabled_locate , 'w-100' : !enabled_locate}" > 4843 <div class="p-0"> 4844 <el-autocomplete 4845 v-model="q" 4846 :placeholder="label.enter_address" 4847 size="large" 4848 class="w-100" 4849 :trigger-on-focus="true" 4850 value-key="description" 4851 :fit-input-width="is_fullwidth" 4852 clearable 4853 :fetch-suggestions="searchLocation" 4854 @select="handleSelect" 4855 > 4856 <template #suffix> 4857 <button v-if="enabled_locate" @click="locateLocation" type="button" class="btn btn-link"> 4858 <i class="zmdi zmdi-my-location font20" style="color:#000;"></i> 4859 </button> 4860 </template> 4861 </el-autocomplete> 4862 </div> 4863 </div> 4864 <div v-if="enabled_locate" class="flex-enabled-locate"> 4865 <button @click="onSubmit" type="button" class="btn btn-green pl-3 pr-3" :disabled="loading"> 4866 <i class="zmdi zmdi-arrow-right font25"></i> 4867 </button> 4868 </div> 4869 </div> 4870 ` 4871}; 4872/*END AUTO COMPLETE*/ 4873 4874const ComponentsSelectAddress = { 4875 props : ['data','keys','provider','zoom','center' ,'label'], 4876 components: { 4877 'components-maps' : ComponentsMaps, 4878 'component-auto-complete' : ComponentsAutoCompleteAdress, 4879 }, 4880 data() { 4881 return { 4882 markers :[], 4883 address_data :[], 4884 loading : false, 4885 drag : false, 4886 visible : false 4887 } 4888 }, 4889 computed: { 4890 hasFormatAddress(){ 4891 if (Object.keys(this.address_data).length > 0) { 4892 return true; 4893 } 4894 return false;
4895 }, 4896 getFormatAddress(){ 4897 return this.address_data; 4898 }, 4899 isMobileView(){ 4900 if ((typeof is_mobile !== "undefined") && ( is_mobile !== null)) { 4901 if(is_mobile==1){ 4902 return true; 4903 } 4904 } 4905 return false; 4906 }, 4907 }, 4908 watch: { 4909 data(newval,oldval){ 4910 console.debug("new data",newval); 4911 this.address_data = newval; 4912 }, 4913 address_data(newval,oldval){ 4914 dump("watch address_data"); 4915 dump(newval); 4916 this.dataMarkers(newval.latitude,newval.longitude); 4917 } 4918 }, 4919 methods: { 4920 getFormatAddress(){ 4921 return 'test'; 4922 }, 4923 setInitialMarker(){ 4924 console.debug("setInitialMarker",this.data); 4925 if(yandex_map){ 4926 yandex_map.destroy(); 4927 yandex_map = null; 4928 } 4929 this.dataMarkers(this.data.latitude,this.data.longitude); 4930 }, 4931 dataMarkers(lat,lng){ 4932 this.markers = [ 4933 { 4934 id: 0, 4935 lat: parseFloat(lat), 4936 lng: parseFloat(lng), 4937 draggable: true, 4938 } 4939 ]; 4940 }, 4941 setLoading(data){ 4942 this.loading = data; 4943 }, 4944 show(data){ 4945 if(data){ 4946 this.address_data = this.data; 4947 $(this.$refs.modal).modal('show'); 4948 } else { 4949 $(this.$refs.modal).modal('hide'); 4950 } 4951 }, 4952 afterChoose(data){ 4953 this.getLocationDetails(data); 4954 }, 4955 getLocationDetails(data){ 4956 console.log("provider",this.provider); 4957 console.debug("getLocationDetails",data); 4958 let placeID = data.id; 4959 if(this.provider=='mapbox'){ 4960 placeID = `${data?.longitude},${data?.latitude}`; 4961 } 4962 axios({ 4963 method: 'POST', 4964 url: ajaxurl+"/getLocationDetails" , 4965 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&id="+ placeID + "&saveplace=0" + "&description="+data.description, 4966 timeout: $timeout, 4967 }).then( response => { 4968 if(response.data.code==1){ 4969 this.dataMarkers( 4970 response.data.details.data.latitude, 4971 response.data.details.data.longitude 4972 ); 4973 this.address_data = response.data.details.data; 4974 // Update the autocomplete display to show long-form address 4975 if(this.$refs.auto_complete){ 4976 this.$refs.auto_complete.setAddressData(response.data.details.data); 4977 } 4978 } else { 4979 4980 } 4981 }).catch(error => { 4982 // 4983 }).then(data => { 4984 4985 }); 4986 }, 4987 afterSelectmap(lat,lng){ 4988 this.loading = true; 4989 axios({ 4990 method: 'POST', 4991 url: ajaxurl+"/reverseGeocoding" , 4992 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&lat="+ lat+ "&lng="+lng, 4993 timeout: $timeout, 4994 }).then( response => { 4995 if(response.data.code==1){ 4996 if (Object.keys(response.data.details.data).length > 0) { 4997 this.address_data = response.data.details.data; 4998 this.address_data.latitude = lat; 4999 this.address_data.longitude = lng; 5000 // Update autocomplete input with long-form address 5001 if(this.$refs.auto_complete){ 5002 const longFormAddr = response.data.details.data.address?.formattedAddress 5003 || response.data.details.data.parsed_address?.formatted_address_long 5004 || response.data.details.data.address?.formatted_address 5005 || ''; 5006 const mapPostcode = response.data.details.data.address?.postal_code 5007 || response.data.details.data.parsed_address?.postal_code 5008 || ''; 5009 this.$refs.auto_complete.q = reorderAddressPostcode(longFormAddr, mapPostcode); 5010 } 5011 } 5012 } else { 5013 5014 } 5015 }).catch(error => { 5016 // 5017 }).then(data => { 5018 this.loading = false; 5019 }); 5020 }, 5021 dragMarker(data){ 5022 this.drag = data; 5023 }, 5024 setNewAdress(){ 5025 // Include user's long-form description from the autocomplete component 5026 let dataToEmit = {...this.address_data}; 5027 if(this.$refs.auto_complete && this.$refs.auto_complete.q){ 5028 // Get postcode from address data to append if missing from description 5029 const postcode = this.address_data?.address?.postal_code || this.address_data?.parsed_address?.postal_code || ''; 5030 // Reorder address to put postcode at end, append postcode if missing 5031 dataToEmit.userSelectedDescription = reorderAddressPostcode(this.$refs.auto_complete.q, postcode); 5032 } 5033 setInLocalStorageStore(StoreMapName,"selectedAddress",dataToEmit); 5034 this.$emit("afterChangeaddress", dataToEmit); 5035 }, 5036 afterClosemodal(){ 5037 this.$emit("afterClosemodal",this.provider); 5038 } 5039 // 5040 }, 5041 template : ` 5042 <el-dialog v-model="visible" :close-on-click-modal="false" :show-close="true" :title="label.exact_location" width="55%" @closed="afterClosemodal" > 5043 5044 <div class="position-relative" > 5045 5046 <component-auto-complete 5047 ref="auto_complete" 5048 :label="{ 5049 enter_address : label.enter_address 5050 }" 5051 :formatted_address="hasFormatAddress?getFormatAddress.address.formatted_address:''" 5052 @after-choose="afterChoose" 5053 > 5054 </component-auto-complete> 5055 5056 <div class="pt-2"></div> 5057 5058 <components-maps 5059 ref="cmaps" 5060 :keys="keys" 5061 :provider="provider" 5062 :zoom="zoom" 5063 size="map-lg-large" 5064 :center="center" 5065 :markers="markers" 5066 @after-selectmap="afterSelectmap" 5067 @drag-marker="dragMarker" 5068 > 5069 </components-maps> 5070 5071 <div v-if="!drag" class="w-100 position-absolute" style="bottom:20px;"> 5072 <div class="w-50 m-auto"> 5073 <button type="button" @click="setNewAdress" class="btn btn-green w-100" :class="{ loading: loading }" > 5074 <span class="label"> 5075 {{label.submit}} 5076 </span> 5077 <div class="m-auto circle-loader" data-loader="circle-side"></div> 5078 </button> 5079 </div> 5080 </div> 5081 5082 </div> 5083 5084 </el-dialog> 5085 `, 5086}; 5087 5088const ComponentsSavedAddress = { 5089 props : ['label'], 5090 data() { 5091 return { 5092 loading : false, 5093 data : [], 5094 address_data : '' 5095 } 5096 }, 5097 created() {
5098 this.getSavedAddress(); 5099 }, 5100 computed: { 5101 getData(){ 5102 return this.data; 5103 }, 5104 totalCount(){ 5105 return Object.keys(this.data).length-1; 5106 }, 5107 hasSelectAddress(){ 5108 if (Object.keys(this.address_data).length > 0) { 5109 return false; 5110 } 5111 return true; 5112 } 5113 }, 5114 methods: { 5115 show(data){ 5116 if(data){ 5117 $(this.$refs.modal).modal('show'); 5118 } else { 5119 $(this.$refs.modal).modal('hide'); 5120 } 5121 }, 5122 getSavedAddress(){ 5123 this.loading = true; 5124 axios({ 5125 method: 'POST', 5126 url: ajaxurl+"/getAddresses" , 5127 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') , 5128 timeout: $timeout, 5129 }).then( response => { 5130 if(response.data.code==1){ 5131 this.data = response.data.details.data; 5132 } else { 5133 this.data = []; 5134 } 5135 }).catch(error => { 5136 // 5137 }).then(data => { 5138 this.loading = false; 5139 }); 5140 }, 5141 setAddress(data){ 5142 setInLocalStorageStore(StoreMapName,"selectedAddress",data); 5143 this.show(false); 5144 this.$emit("afterSelectaddress",data); 5145 } 5146 }, 5147 template : ` 5148 <div class="modal" ref="modal" id="modal" tabindex="-1" role="dialog" aria-labelledby="modal" aria-hidden="true" data-backdrop="static" data-keyboard="false" > 5149 <div class="modal-dialog modal-dialog-centered" role="document"> 5150 <div class="modal-content"> 5151 <div class="modal-header border-bottom-0" > 5152 <h5 class="modal-title" id="exampleModalLongTitle">{{label.save_address}}</h5> 5153 <button type="button" class="close" data-dismiss="modal" aria-label="Close"> 5154 <span aria-hidden="true">×</span> 5155 </button> 5156 </div> 5157 <div class="modal-body"> 5158 5159 <el-radio-group v-model="address_data" class="ml-4"> 5160 <template v-for="(items,index) in getData" :keys="items" > 5161 <el-radio :label="items" size="large"> 5162 <div class="text-dark font-weight-bold">{{items.attributes.address_label}}</div> 5163 <div class="text-truncatex max-width-addressx"> 5164 {{items.address.formattedAddress}} 5165 </div> 5166 </el-radio> 5167 </template> 5168 </el-radio-group> 5169 5170 </div> 5171 5172 <div class="modal-footer"> 5173 <button type="button" class="btn btn-light" data-dismiss="modal"> 5174 {{label.cancel}} 5175 </button> 5176 <button @click="setAddress(address_data)" type="button" class="btn btn-green pl-3 pr-3" 5177 :disabled="hasSelectAddress" 5178 > 5179 {{label.save}} 5180 </button> 5181 </div> 5182 5183 </div> 5184 </div> 5185 </div> 5186 `, 5187}; 5188 5189/* 5190 COMPONENTS ADDRESS FORM 5191*/ 5192let cmapsMarker = []; 5193const ComponentsAddressForm = { 5194 template: '#xtemplate_address_form', 5195 props : ['location_data'], 5196 data() { 5197 return { 5198 error : [], 5199 cmaps_config : [], 5200 address1 : '', 5201 formatted_address : '', 5202 location_name :'', 5203 delivery_options : '', 5204 delivery_options_data : [], 5205 delivery_instructions :'', 5206 address_label : '', 5207 address_label_data : [], 5208 cmaps_full : false, 5209 new_coordinates : [], 5210 is_loading : false, 5211 address2 : '', 5212 postal_code :'', 5213 company : '', 5214 custom_field1 : '', 5215 custom_field2 : '', 5216 custom_field1_data : [], 5217 custom_field_enabled : false 5218 } 5219 }, 5220 created() { 5221 this.getAddressAttributes(); 5222 }, 5223 watch: { 5224 location_data(newval,oldval){ 5225 if(empty(newval)){ 5226 return; 5227 } 5228 //console.log("location_data",newval); 5229 if ((typeof newval.parsed_address !== "undefined") && ( newval.parsed_address !== null)) { 5230 if(!empty(newval.parsed_address.street_name)){ 5231 this.formatted_address = newval.parsed_address.street_name; 5232 this.address1 = newval.parsed_address.street_number; 5233 } else { 5234 this.formatted_address = newval.address.formatted_address; 5235 this.address1 = newval.address.address1; 5236 } 5237 } else { 5238 this.formatted_address = newval.address.formatted_address; 5239 this.address1 = newval.address.address1; 5240 } 5241 5242 // this.formatted_address = newval.address.formatted_address; 5243 // this.address1 = newval.address.address1; 5244 5245 // this.address2 = newval.address.address2; 5246 // this.postal_code = newval.address.postal_code;
5247 // this.company = newval.address.company; 5248 5249 if(!empty(newval.attributes)){ 5250 this.location_name = newval.attributes.location_name; 5251 this.delivery_options = newval.attributes.delivery_options; 5252 this.delivery_instructions = newval.attributes.delivery_instructions; 5253 this.address_label = newval.attributes.address_label; 5254 } else { 5255 this.location_name = ''; 5256 this.delivery_instructions = ''; 5257 this.delivery_options = 'Hand it to me'; 5258 this.address_label = 'Home'; 5259 } 5260 this.show(); 5261 } 5262 }, 5263 computed: { 5264 hasLocationData(){ 5265 if ((typeof this.location_data !== "undefined") && ( this.location_data !== null)) { 5266 var count = Object.keys(this.location_data).length; 5267 if(count>0){ 5268 return true; 5269 } 5270 } 5271 return false; 5272 }, 5273 hasNewCoordinates(){ 5274 var count = Object.keys(this.new_coordinates).length; 5275 if(count>0){ 5276 return true; 5277 } 5278 return false; 5279 }, 5280 }, 5281 methods: { 5282 show(){ 5283 this.cmaps_full = false; 5284 $( this.$refs.address_modal ).modal('show'); 5285 setTimeout(() => { 5286 this.renderMap(); 5287 }, 100); 5288 }, 5289 hide(){ 5290 this.error=[]; 5291 $(this.$refs.address_modal).modal('hide'); 5292 }, 5293 close(){ 5294 this.hide(); 5295 }, 5296 setLoading(data){ 5297 this.is_loading = data; 5298 }, 5299 closeModal(){ 5300 dump('closeModal'); 5301 this.hide() 5302 this.$emit('afterClosemodal'); 5303 }, 5304 getAddressAttributes(){ 5305 axios({ 5306 method: 'POST', 5307 url: ajaxurl+"/getAddressAttributes" , 5308 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') , 5309 timeout: $timeout, 5310 }).then( response => { 5311 if(response.data.code==1){ 5312 this.cmaps_config = response.data.details.maps_config; 5313 this.delivery_options_data = response.data.details.delivery_option; 5314 this.address_label_data = response.data.details.address_label; 5315 this.delivery_options = response.data.details.default_atts.delivery_options; 5316 this.address_label = response.data.details.default_atts.address_label; 5317 this.custom_field_enabled = response.data.details.custom_field_enabled; 5318 this.custom_field1_data = response.data.details.custom_field1_data; 5319 this.custom_field1 = Object.keys(this.custom_field1_data)[0]; 5320 } else { 5321 this.cmaps_config = []; 5322 this.delivery_options_data = []; 5323 this.address_label_data = []; 5324 this.custom_field1_data = []; 5325 this.custom_field_enabled = false; 5326 } 5327 }).catch(error => { 5328 // 5329 }).then(data => { 5330 // 5331 }); 5332 }, 5333 renderMap(){ 5334 this.cmaps_provider = this.cmaps_config.provider; 5335 5336 switch(this.cmaps_provider){ 5337 case "google.maps": 5338 if ((typeof this.cmaps !== "undefined") && ( this.cmaps !== null)) { 5339 this.removeMarker(); 5340 } else { 5341 this.cmaps = new google.maps.Map( this.$refs.ref_map, { 5342 center: { lat: parseFloat(this.location_data.latitude), lng: parseFloat(this.location_data.longitude) }, 5343 zoom: parseInt(this.cmaps_config.zoom) , 5344 disableDefaultUI: true, 5345 }); 5346 } 5347 this.addMarker({ 5348 position: { lat: parseFloat(this.location_data.latitude) , lng: parseFloat(this.location_data.longitude) }, 5349 map: this.cmaps, 5350 animation: google.maps.Animation.DROP, 5351 }); 5352 break; 5353 case "mapbox": 5354 mapboxgl.accessToken = this.cmaps_config.key; 5355 this.cmaps = new mapboxgl.Map({ 5356 container: this.$refs.ref_map, 5357 style: 'mapbox://styles/mapbox/streets-v12', 5358 center: [ parseFloat(this.location_data.longitude) , parseFloat(this.location_data.latitude)], 5359 zoom: 14 5360 }); 5361 this.addMarker({ 5362 position: { lat: parseFloat(this.location_data.latitude) , lng: parseFloat(this.location_data.longitude) }, 5363 map: this.cmaps, 5364 icon : this.cmaps_config.icon, 5365 animation: null 5366 }); 5367 break; 5368 5369 case "yandex": 5370 this.initYandexDeliveryDetails(); 5371 break; 5372 5373 } 5374 }, 5375 async initYandexDeliveryDetails(){ 5376 await ymaps3.ready; 5377 const {YMap, YMapDefaultSchemeLayer,YMapMarker,YMapDefaultFeaturesLayer,YMapListener,YMapControl
5377s } = ymaps3; 5378 const {YMapDefaultMarker} = await ymaps3.import('@yandex/[email protected]'); 5379 const {YMapZoomControl,YMapGeolocationControl} = await ymaps3.import('@yandex/[email protected]'); 5380 5381 const LOCATION = { 5382 center: [ parseFloat(this.location_data.longitude), parseFloat(this.location_data.latitude) ], 5383 zoom: yandex_zoom 5384 }; 5385 5386 if (!yandex_map) { 5387 yandex_map = new YMap( 5388 this.$refs.ref_map, 5389 { 5390 location: LOCATION, 5391 showScaleInCopyrights: false, 5392 behaviors: ['drag','scrollZoom'] 5393 }, 5394 [ 5395 new YMapDefaultSchemeLayer({}), 5396 new YMapDefaultFeaturesLayer({}) 5397 ] 5398 ); 5399 5400 cmapsMarker = new YMapDefaultMarker({ 5401 coordinates: LOCATION.center, 5402 }); 5403 yandex_map.addChild(cmapsMarker); 5404 } else { 5405 console.debug('here here'); 5406 } 5407 }, 5408 addMarker(properties){ 5409 switch(this.cmaps_provider){ 5410 case "google.maps": 5411 cmapsMarker = new google.maps.Marker(properties); 5412 this.cmaps.panTo(new google.maps.LatLng(properties.position.lat,properties.position.lng)); 5413 break; 5414 case "mapbox": 5415 let markerProperties = {}; 5416 if(properties.draggable){ 5417 markerProperties = {draggable: true}; 5418 } 5419 cmapsMarker = new mapboxgl.Marker(markerProperties) 5420 .setLngLat([properties.position.lng, properties.position.lat]) 5421 .addTo(this.cmaps); 5422 break; 5423 } 5424 }, 5425 removeMarker(){ 5426 switch(this.cmaps_provider){ 5427 case "google.maps": 5428 cmapsMarker.setMap(null); 5429 break; 5430 case "mapbox": 5431 cmapsMarker.remove(); 5432 break; 5433 } 5434 }, 5435 adjustPin(){ 5436 this.new_coordinates = []; 5437 this.cmaps_full = true; 5438 try { 5439 this.removeMarker(); 5440 } catch(err) { 5441 dump(err); 5442 } 5443 5444 console.log("adjustPin" , this.cmaps_provider); 5445 5446 this.addMarker({ 5447 position: { lat: parseFloat(this.location_data.latitude) , lng: parseFloat(this.location_data.longitude) }, 5448 map: this.cmaps, 5449 animation: this.cmaps_provider=="google.maps" ? google.maps.Animation.DROP : null, 5450 draggable:true, 5451 }); 5452 5453 if(this.cmaps_provider=="google.maps"){ 5454 cmapsMarker.addListener('dragend', event => { 5455 this.new_coordinates = { 5456 'lat': event.latLng.lat(), 5457 'lng': event.latLng.lng(), 5458 }; 5459 }); 5460 } else if ( this.cmaps_provider=="mapbox" ) { 5461 cmapsMarker.on('dragend', (event)=>{ 5462 const lngLat = cmapsMarker.getLngLat(); 5463 this.new_coordinates = { 5464 'lat': lngLat.lat, 5465 'lng': lngLat.lng, 5466 }; 5467 }); 5468 this.mapBoxResize(); 5469 } else if ( this.cmaps_provider=="yandex" ) { 5470 const LOCATION = { 5471 center: [ parseFloat(this.location_data.longitude), parseFloat(this.location_data.latitude) ], 5472 zoom: yandex_zoom 5473 }; 5474 cmapsMarker.update({ 5475 coordinates : LOCATION.center, 5476 draggable: true, 5477 onDragEnd: (coordinates)=>{ 5478 console.log("onDragEnd",coordinates); 5479 this.new_coordinates = { 5480 'lat': coordinates[1], 5481 'lng': coordinates[0], 5482 }; 5483 } 5484 }); 5485 } 5486 // end if 5487 }, 5488 cancelPin(){ 5489 this.error = []; 5490 this.cmaps_full=false; 5491 5492 if(this.cmaps_provider=="yandex"){ 5493 const LOCATION = { 5494 center: [ parseFloat(this.location_data.longitude), parseFloat(this.location_data.latitude) ], 5495 zoom: yandex_zoom 5496 }; 5497 cmapsMarker.update({ 5498 coordinates : LOCATION.center, 5499 draggable: false 5500 }); 5501 } else { 5502 this.removeMarker(); 5503 this.addMarker({ 5504 position: { lat: parseFloat(this.location_data.latitude) , lng: parseFloat(this.location_data.longitude) }, 5505 map: this.cmaps, 5506 animation: this.cmaps_provider=="google.maps" ? google.maps.Animation.DROP : null, 5507 }); 5508 this.mapBoxResize(); 5509 } 5510 }, 5511 mapBoxResize(){ 5512 if(this.cmaps_provider=="mapbox"){ 5513 setTimeout(()=>{ 5514 this.cmaps.resize(); 5515 }, 500); 5516 } 5517 }, 5518 setNewCoordinates(){ 5519 let params = "YII_CSRF_TOKEN="+$('meta[name=YII_CSRF_TOKEN]').attr('content'); 5520 params+="&cart_uuid="+getCookie('cart_uuid'); 5521 params+="&lat="+this.location_data.latitude; 5522 params+="&lng="+this.location_data.longitude;
5523 params+="&new_lat="+this.new_coordinates.lat; 5524 params+="&new_lng="+this.new_coordinates.lng; 5525 axios({ 5526 method: 'POST', 5527 url: ajaxurl + "/checkoutValidateCoordinates" , 5528 data : params, 5529 timeout: $timeout, 5530 }).then( response => { 5531 if(response.data.code==1){ 5532 this.location_data.latitude = this.new_coordinates.lat; 5533 this.location_data.longitude = this.new_coordinates.lng; 5534 this.cmaps_full=false; 5535 this.removeMarker(); 5536 this.addMarker({ 5537 position: { lat: parseFloat(this.location_data.latitude) , lng: parseFloat(this.location_data.longitude) }, 5538 map: this.cmaps, 5539 animation: this.cmaps_provider=="google.maps" ? google.maps.Animation.DROP : null, 5540 }); 5541 this.mapBoxResize(); 5542 } else { 5543 ElementPlus.ElNotification({ 5544 title: "", 5545 message: response.data.msg[0], 5546 position: 'bottom-right', 5547 type: 'warning', 5548 }); 5549 } 5550 }).catch(error => { 5551 // 5552 }).then(data => { 5553 5554 }); 5555 }, 5556 save(){ 5557 confirmIncompleteAddressSave({ 5558 formattedAddress: this.formattedAddress, 5559 formatted_address: this.formatted_address, 5560 address1: this.address1, 5561 address2: this.address2, 5562 location_name: this.location_name, 5563 postal_code: this.postal_code 5564 }, () => { 5565 this.$emit('onSavelocation',this.location_data,{ 5566 address1 : this.address1, 5567 formatted_address : this.formatted_address, 5568 location_name : this.location_name, 5569 delivery_options : this.delivery_options, 5570 address_label : this.address_label, 5571 delivery_instructions : this.delivery_instructions, 5572 address2 : this.address2, 5573 postal_code : this.postal_code, 5574 company : this.company, 5575 address_format_use : this.cmaps_config.address_format_use, 5576 custom_field1 : this.custom_field1, 5577 custom_field2 : this.custom_field2, 5578 }); 5579 }); 5580 }, 5581 // 5582 }, 5583}; 5584 5585// END 1.0.8 COMPONENTS 5586 5587/* 5588=============================================================================== 5589 END OF ALL COMPONENTS 5590=============================================================================== 5591*/ 5592 5593 5594/* 5595 LOADING BOX 5596*/ 5597const vm_loading = Vue.createApp({ 5598 components: { 5599 'components-loading-box': loadingBox, 5600 }, 5601}).mount('#vue-loading-box'); 5602 5603 5604/* 5605 HOME SEARCH 5606*/ 5607const vm_search = Vue.createApp({ 5608 components: { 5609 'component-home-search' : ComponentsSearch, 5610 }, 5611}).mount('#vue-home-search'); 5612 5613const vm_search_mobile = Vue.createApp({ 5614 components: { 5615 'component-home-search' : ComponentsSearch, 5616 }, 5617 }).mount('#vue-home-search-mobile'); 5618 5619 5620/* 5621COMPONENTS CAROUSEL 5622*/ 5623//let owl; 5624const ComponentsCarousel = { 5625 props: ['title','featured_name','settings','responsive'], 5626 data(){ 5627 return { 5628 is_loading : false, 5629 owl : undefined, 5630 data : [], 5631 services : [], 5632 estimation : [], 5633 location_details : [] 5634 }; 5635 }, 5636 mounted () { 5637 this.GetFeaturedLocation(); 5638 }, 5639 computed: { 5640 hasData(){ 5641 if(this.data.length>0){ 5642 return true; 5643 } 5644 return false; 5645 }, 5646 classObject() { 5647 return { 5648 'w-100' : this.settings.theme==='rounded', 5649 'w-75' : this.settings.theme==='rounded-circle' 5650 } 5651 } 5652 }, 5653 methods: { 5654 GetFeaturedLocation(){ 5655 5656 var $params = { 5657 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 5658 'featured_name': this.featured_name 5659 }; 5660 var timenow = getTimeNow(); 5661 $params = JSON.stringify($params); 5662 5663 ajax_request[timenow] = $.ajax({ 5664 url: ajaxurl+"/GetFeaturedLocation", 5665 method: "PUT", 5666 dataType: "json", 5667 data: $params , 5668 contentType : $content_type.json , 5669 timeout: $timeout, 5670 crossDomain: true, 5671 beforeSend: data => { 5672 this.is_loading = true; 5673 if(ajax_request[timenow] != null) { 5674 ajax_request[timenow].abort(); 5675 } 5676 } 5677 }); 5678 5679 ajax_request[timenow].done( data => { 5680 if ( data.code==1){ 5681 this.location_details = data.details.location_details; 5682 this.data = data.details.data; 5683 this.services = data.details.services; 5684 this.estimation = data.details.estimation; 5685 setTimeout(() => { 5686 this.RenderCarousel(); 5687 }, 1); 5688 } else { 5689 this.location_details = ''; 5690 this.data = ''; 5691 this.services = ''; 5692 this.estimation = ''; 5693 } 5694 }); 5695 5696 ajax_request[timenow].always( data => { 5697 this.is_loading = false;
5698 }); 5699 5700 }, 5701 RenderCarousel(){ 5702 let $is_rtl = false; 5703 if ((typeof is_rtl !== "undefined") && ( is_rtl !== null)) { 5704 $is_rtl = is_rtl=='1'?true:false; 5705 } 5706 this.owl = $(this.$refs.owl_carousel).owlCarousel({ 5707 items: parseInt(this.settings.items), 5708 lazyLoad: this.settings.lazyLoad=="1"?true:false , 5709 loop: this.settings.loop=="1"?true:false , 5710 margin: parseInt(this.settings.margin) , 5711 nav: this.settings.nav=="1"?true:false , 5712 dots: this.settings.dots=="1"?true:false , 5713 stagePadding: parseInt(this.settings.stagePadding), 5714 responsive : this.responsive, 5715 rtl : $is_rtl 5716 }); 5717 }, 5718 SlideNext(){ 5719 this.owl.trigger('next.owl.carousel'); 5720 }, 5721 SlidePrev(){ 5722 this.owl.trigger('prev.owl.carousel', [300]); 5723 }, 5724 }, 5725 template: ` 5726 5727 <DIV class="mt-5 mb-5"> 5728 5729 <div class="row no-gutters mb-4 " v-if="hasData" > 5730 <div class="col d-flex justify-content-start align-items-center "> 5731 <h5 class="m-0 section-title"> 5732 {{title}} <span>{{location_details.location_name}}</span> 5733 </h5> 5734 </div> 5735 <div class="col d-flex justify-content-end align-items-center "> 5736 <a @click="SlidePrev" href="javascript:;" class="owl-carousel-nav prev mr-4"> </a> 5737 <a @click="SlideNext" href="javascript:;" class="owl-carousel-nav next"> </a> 5738 </div> <!--col--> 5739 </div> <!--row--> 5740 5741 <div ref="owl_carousel" class="owl-carousel restaurant-carousel" :class="settings.theme" v-if="hasData" > 5742 5743 <div v-for="item in data" class="row equal align-items-center position-relative" 5744 :class="classObject" 5745 > 5746 5747 <template v-for="(cuisine,index) in item.cuisine_name" > 5748 <template v-if="index <= 0"> 5749 5750 <span class="badge mr-1 top-left" v-if="settings.theme==='rounded'" 5751 :style="'background:'+cuisine.bgcolor+';font-color:'+cuisine.fncolor" 5752 >{{cuisine.cuisine_name}}</span> 5753 5754 <div class="rounded-pill badge top-right" v-if="item.ratings.rating>0" 5755 :style="'background:'+cuisine.bgcolor+';font-color:'+cuisine.fncolor" 5756 > 5757 {{item.ratings.rating}} 5758 </div> 5759 5760 </template> 5761 </template> 5762 5763 5764 <div class="w-100 list-items p-0 " > 5765 <a :href="item.merchant_url" ><img :class="settings.theme" :src="item.url_logo" /></a> 5766 </div> 5767 5768 <!--ROUNDED TEMPLATE--> 5769 <template v-if="settings.theme==='rounded'"> 5770 <div class="d-flex justify-content-between mt-2 w-100 pl-1 pr-1 "> 5771 <div class="flex-col "> 5772 <a :href="item.merchant_url" ><h6>{{item.restaurant_name}}</h6></a> 5773 </div> 5774 </div> <!--flex--> 5775 5776 <div class="d-flex justify-content-between w-100 pl-1 pr-1"> 5777 <div class="flex-col"> 5778 <p class="m-0"> 5779 <i class="zmdi zmdi-time mr-1"></i> 5780 5781 <template v-if="estimation[item.merchant_id]"> 5782 <template v-if="services[item.merchant_id]"> 5783 <template v-for="(service_name,index_service) in services[item.merchant_id]" > 5784 <template v-if="index_service<=0"> 5785 5786 <template v-if="estimation[item.merchant_id][service_name]"> 5787 <template v-if="estimation[item.merchant_id][service_name][item.charge_type] "> 5788 {{ estimation[item.merchant_id][service_name][item.charge_type].estimation }} <?php echo t("min")?> 5789 </template> 5790 </template> 5791 5792 </template> 5793 </template> 5794 </template> 5795 </template> 5796 5797 </p> 5798 </div> 5799 <div class="flex-col"><p class="m-0" v-if="item.free_delivery==='1'" >{{ settings.free_delivery}}</p></div>
5800 </div> <!--flex--> 5801 </template> 5802 <!--END ROUNDED TEMPLATE--> 5803 5804 <!-- ROUNDED CIRCLE TEMPLATE--> 5805 <template v-else > 5806 <div class="mt-3 text-center w-100"> 5807 <a :href="item.merchant_url" ><h6 class="mb-1">{{item.restaurant_name}}</h6></a> 5808 5809 <template v-for="(cuisine,index) in item.cuisine_name" > 5810 <template v-if="index <= 0"> 5811 5812 <span class="badge" 5813 :style="'background:'+cuisine.bgcolor+';font-color:'+cuisine.fncolor" 5814 >{{cuisine.cuisine_name}}</span> 5815 5816 5817 </template> 5818 </template> 5819 5820 </div> 5821 </template> 5822 <!-- END ROUNDED CIRCLE TEMPLATE--> 5823 5824 </div> <!-- row--> 5825 5826 </div><!-- owl-carousel--> 5827 5828 </DIV> 5829 ` 5830}; 5831 5832 5833const componentCuisine = { 5834 props: ['data'], 5835 data(){ 5836 return { 5837 owl : undefined, 5838 }; 5839 }, 5840 mounted(){ 5841 5842 }, 5843 watch: { 5844 data(new_data,old_data){ 5845 setTimeout(() => { 5846 this.renderCarousel(); 5847 }, 1); 5848 } 5849 }, 5850 methods: { 5851 renderCarousel(){ 5852 let $is_rtl = false; 5853 if ((typeof is_rtl !== "undefined") && ( is_rtl !== null)) { 5854 $is_rtl = is_rtl=='1'?true:false; 5855 } 5856 this.owl = $(this.$refs.cuisine_carousel).owlCarousel({ 5857 loop:true, 5858 dots:false, 5859 nav:false, 5860 autoWidth:true, 5861 rtl : $is_rtl 5862 }); 5863 }, 5864 }, 5865 template: ` 5866 <div ref="cuisine_carousel" class="owl-carousel owl-theme cuisine_carousel"> 5867 <div v-for="(item, index) in data" class="mr-2"> 5868 <a :href="item.url" class="d-block bg-light rounded-pill" 5869 :class="{active : index==0 }" 5870 > 5871 {{item.cuisine_name}} 5872 </a> 5873 </div> 5874 </div> 5875 ` 5876}; 5877 5878const componentThreeSteps = { 5879 props: ['responsive','label'], 5880 data(){ 5881 return { 5882 owl : undefined, 5883 }; 5884 }, 5885 mounted(){ 5886 this.renderCarousel(); 5887 }, 5888 methods : { 5889 renderCarousel(){ 5890 let $is_rtl = false; 5891 if ((typeof is_rtl !== "undefined") && ( is_rtl !== null)) { 5892 $is_rtl = is_rtl=='1'?true:false; 5893 } 5894 this.owl = $(this.$refs.carousel_three_steps).owlCarousel({ 5895 rtl : $is_rtl, 5896 loop:true, 5897 dots:true, 5898 nav:false, 5899 responsive:{ 5900 0:{ 5901 items:1, 5902 loop : false, 5903 }, 5904 320:{ 5905 items:1, 5906 loop : false, 5907 }, 5908 480:{ 5909 items:1, 5910 loop : false, 5911 }, 5912 600:{ 5913 items:1, 5914 loop : false, 5915 }, 5916 700:{ 5917 items:2, 5918 loop : false, 5919 }, 5920 1000:{ 5921 items:2, 5922 loop : false, 5923 } 5924 } 5925 }); 5926 }, 5927 }, 5928 template: '#three-steps-ordering', 5929}; 5930 5931 5932const componentsCuisineList = { 5933 template: '#xtemplate_cuisine_list', 5934 props : ['title'], 5935 data() { 5936 return { 5937 swiperCuisine : null, 5938 data : [], 5939 loading : false 5940 } 5941 }, 5942 mounted() { 5943 this.getCuisine(); 5944 }, 5945 computed: { 5946 hasData(){ 5947 if (!this.loading && Object.keys(this.data).length > 0) { 5948 return true; 5949 } 5950 return false; 5951 }, 5952 }, 5953 methods: { 5954 getCuisine(){ 5955 this.loading = true; 5956 let params = "language="+language; 5957 axios.get(ajaxurl+"/CuisineList2?" + params ).then(response => { 5958 if(response.data.code==1){ 5959 this.data = response.data.details; 5960 setTimeout(() => { 5961 this.initSwiper(); 5962 }, 1); 5963 this.$emit("afterGetcuisine",true); 5964 } else { 5965 this.data = []; 5966 this.$emit("afterGetcuisine",false); 5967 } 5968 }) 5969 .catch(error => { 5970 console.error('Error:', error); 5971 }).then(data => { 5972 this.loading = false; 5973 }); 5974 }, 5975 initSwiper(){ 5976 this.swiperCuisine = new Swiper(this.$refs.swiperCuisineList, { 5977 lazy: true, 5978 slidesPerView: 7.5, 5979 spaceBetween: 15, 5980 autoHeight: true, 5981 navigation: { 5982 nextEl: ".swiper-button-next", 5983 prevEl: ".swiper-button-prev", 5984 }, 5985 breakpoints: { 5986 310: { 5987 slidesPerView: 3, 5988 spaceBetween: 0 5989 }, 5990 320: { 5991 slidesPerView: 3, 5992 spaceBetween: 0 5993 }, 5994 480: { 5995 slidesPerView: 3.5, 5996 spaceBetween: 0 5997 }, 5998 640: { 5999 slidesPerView: 4.5, 6000 spaceBetween: 5, 6001 }, 6002 768: { 6003 slidesPerView: 7, 6004 spaceBetween: 10, 6005 }, 6006 1024: { 6007 slidesPerView: 7.5, 6008 spaceBetween: 15, 6009 }, 6010 }, 6011 }); 6012 }, 6013 setUrl(value){ 6014 window.location.href = value; 6015 }, 6016 // 6017 }, 6018}; 6019 6020const componentSwiperList = { 6021 template: '#xtemplate_swiper_list',
6022 props : ['title','query','filters_transactions','city_id','area_id','state_id','postal_id'], 6023 data() { 6024 return { 6025 swiperList : null, 6026 loading : true, 6027 data : [], 6028 available_vouchers : null, 6029 available_promos : null 6030 } 6031 }, 6032 mounted() { 6033 this.getData(); 6034 }, 6035 computed: { 6036 hasData(){ 6037 if (!this.loading && Object.keys(this.data).length > 0) { 6038 return true; 6039 } 6040 return false; 6041 }, 6042 }, 6043 methods: { 6044 getData(){ 6045 this.loading = true; 6046 const params = "query="+this.query; 6047 axios.get(ajaxurl+"/GetFeaturedLocation?" + params ).then(response => { 6048 if(response.data.code==1){ 6049 this.data = response.data.details.data; 6050 this.available_vouchers = response.data.details.available_vouchers; 6051 this.available_promos = response.data.details.available_promos; 6052 setTimeout(() => { 6053 this.initSwiper(); 6054 }, 1); 6055 this.$emit("afterGetfeatured",true); 6056 } else { 6057 this.data = []; 6058 this.$emit("afterGetfeatured",false); 6059 } 6060 }) 6061 .catch(error => { 6062 console.error('Error:', error); 6063 }).then(data => { 6064 this.loading = false; 6065 }); 6066 }, 6067 initSwiper(){ 6068 this.swiperList = new Swiper( this.$refs.refSwiperList, { 6069 lazy: true, 6070 slidesPerView: 3.5, 6071 spaceBetween: 15, 6072 autoHeight: true, 6073 navigation: { 6074 nextEl: ".swiper-button-next", 6075 prevEl: ".swiper-button-prev", 6076 }, 6077 breakpoints: { 6078 310: { 6079 slidesPerView: 1, 6080 spaceBetween: 0 6081 }, 6082 320: { 6083 slidesPerView: 1, 6084 spaceBetween: 0 6085 }, 6086 480: { 6087 slidesPerView: 1, 6088 spaceBetween: 0 6089 }, 6090 640: { 6091 slidesPerView: 2, 6092 spaceBetween: 10, 6093 }, 6094 768: { 6095 slidesPerView: 3, 6096 spaceBetween: 10, 6097 }, 6098 1024: { 6099 slidesPerView: 3.5, 6100 spaceBetween: 15, 6101 }, 6102 }, 6103 }); 6104 }, 6105 setUrl(value){ 6106 window.location.href = value; 6107 }, 6108 // 6109 }, 6110}; 6111 6112 6113const componentJoin = { 6114 template: '#xtemplate_join', 6115 props : ['title'], 6116 data() { 6117 return { 6118 swiperList : null, 6119 loading : true, 6120 data : [], 6121 } 6122 }, 6123 mounted() { 6124 this.getData(); 6125 }, 6126 computed: { 6127 hasData(){ 6128 if (!this.loading && Object.keys(this.data).length > 0) { 6129 return true; 6130 } 6131 return false; 6132 }, 6133 }, 6134 methods: { 6135 getData(){ 6136 this.loading = true; 6137 let params = "language="+language; 6138 axios.get(ajaxurl+"/getJoin?" + params ).then(response => { 6139 if(response.data.code==1){ 6140 this.data = response.data.details.data; 6141 setTimeout(() => { 6142 this.initSwiper(); 6143 }, 1); 6144 } else { 6145 this.data = []; 6146 } 6147 }) 6148 .catch(error => { 6149 console.error('Error:', error); 6150 }).then(data => { 6151 this.loading = false;
6152 }); 6153 }, 6154 initSwiper(){ 6155 this.swiperList = new Swiper( this.$refs.refSwiperList, { 6156 lazy: true, 6157 slidesPerView: 3, 6158 spaceBetween: 15, 6159 autoHeight: true, 6160 navigation: { 6161 nextEl: ".swiper-button-next", 6162 prevEl: ".swiper-button-prev", 6163 }, 6164 breakpoints: { 6165 310: { 6166 slidesPerView: 1, 6167 spaceBetween: 0 6168 }, 6169 320: { 6170 slidesPerView: 1, 6171 spaceBetween: 0 6172 }, 6173 480: { 6174 slidesPerView: 1, 6175 spaceBetween: 0 6176 }, 6177 640: { 6178 slidesPerView: 2, 6179 spaceBetween: 10, 6180 }, 6181 768: { 6182 slidesPerView: 3, 6183 spaceBetween: 10, 6184 }, 6185 1024: { 6186 slidesPerView: 3, 6187 spaceBetween: 15, 6188 }, 6189 }, 6190 }); 6191 }, 6192 // 6193 }, 6194}; 6195 6196/* 6197 HOME WIDGET 6198*/ 6199 6200let components_FeaturedItemList=null; 6201let components_ItemDialog=null; 6202if ((typeof componentsFeaturedItemList !== "undefined") && ( componentsFeaturedItemList !== null)) { 6203 components_FeaturedItemList = componentsFeaturedItemList; 6204} 6205if ((typeof componentsItemDialog !== "undefined") && ( componentsItemDialog !== null)) { 6206 components_ItemDialog = componentsItemDialog; 6207} 6208let components_FeaturedList = null; 6209if ((typeof componentsFeaturedList !== "undefined") && ( componentsFeaturedList !== null)) { 6210 components_FeaturedList = componentsFeaturedList; 6211} 6212 6213const vm_home_widget = Vue.createApp({ 6214 components: { 6215 'components-swiper-list' :componentSwiperList, 6216 'component-three-steps' : componentThreeSteps, 6217 'components-cuisine-list' : componentsCuisineList, 6218 'components-join' :componentJoin, 6219 'components-featured-list' : components_FeaturedItemList, 6220 'components-item-dialog' : components_ItemDialog, 6221 'components-featured-merchant' : components_FeaturedList, 6222 }, 6223 data(){ 6224 return { 6225 data_cuisine : [], 6226 cuisine_url : '' 6227 }; 6228 }, 6229 methods: { 6230 viewItem(value){ 6231 const is_eligible = value?.is_eligible; 6232 if(!is_eligible){ 6233 return; 6234 } 6235 this.$refs.ref_item_dialog.viewItem({ 6236 cat_id: value.cat_id, 6237 item_uuid: value.item_uuid, 6238 merchant_id: value.merchant_id, 6239 }); 6240 }, 6241 afterAddtocart(){ 6242 if ((typeof vm_cart_preview !== "undefined") && ( vm_cart_preview !== null)) { 6243 vm_cart_preview.getCartPreview(); 6244 } 6245 if ((typeof homeWidgets !== "undefined") && ( homeWidgets !== null)) { 6246 homeWidgets.$refs.ref_featured_list.getFeaturedItems(); 6247 } 6248 }, 6249 // 6250 }, 6251}); 6252vm_home_widget.use(ElementPlus); 6253vm_home_widget.component("infinite-loading", V3InfiniteLoading.default); 6254const homeWidgets = vm_home_widget.mount('#vue-home-widgets'); 6255 6256 6257 6258/* 6259COMPONENTS SAVE STORE HEARTH BUTTON 6260*/ 6261const ComponentsSaveStore = { 6262 props: ['active','merchant_id','is_guest','please_login'], 6263 data() { 6264 return { 6265 data : [], 6266 loading : false, 6267 } 6268 }, 6269 methods :{ 6270 SaveStore(){ 6271 if(this.is_guest){ 6272 ElementPlus.ElNotification({ 6273 title: "", 6274 message: this.please_login, 6275 position: 'bottom-right', 6276 type: 'warning', 6277 }); 6278 return ; 6279 } 6280 var $params = { 6281 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 6282 'merchant_id': this.merchant_id, 6283 }; 6284 var timenow = 500; 6285 $params = JSON.stringify($params); 6286 this.loading = true; 6287 ajax_request[timenow] = $.ajax({ 6288 url: ajaxurl+"/SaveStore", 6289 method: "PUT", 6290 dataType: "json", 6291 data: $params , 6292 contentType : $content_type.json , 6293 timeout: $timeout, 6294 crossDomain: true, 6295 beforeSend: data => { 6296 if(ajax_request[timenow] != null) { 6297 ajax_request[timenow].abort(); 6298 } 6299 } 6300 }); 6301 6302 ajax_request[timenow].done( data => { 6303 if ( data.code==1){ 6304 this.$emit('afterSave',true); 6305 } else { 6306 vm_bootbox.alert( data.msg , {} ); 6307 } 6308 }); 6309 6310 ajax_request[timenow].always( data => { 6311 this.loading = false;
6312 }); 6313 6314 }, 6315 }, 6316 template:` 6317 <div class="d-none d-lg-block" > 6318 <a @click="SaveStore()" href="javascript:;" class="btn bg-light btn-circle rounded-pill"> 6319 <i class="zmdi" :class="{'zmdi-favorite text-green': active, 'zmdi-favorite-outline': !active }"></i> 6320 </a> 6321 </div> 6322 <div class="d-block d-lg-none"> 6323 <a @click="SaveStore()" href="javascript:;" class="btn bg-light btn-circle rounded-pill"> 6324 <i class="zmdi" :class="{'zmdi-favorite text-green': active, 'zmdi-favorite-outline': !active }"></i> 6325 </a> 6326 </div> 6327 `, 6328}; 6329 6330/* 6331 GET THE SELECTED DELIVERY TIME 6332*/ 6333var getChoosenDeliveryTime = function(){ 6334 var $response = []; 6335 var $choosen_delivery = !empty(getCookie('choosen_delivery'))? JSON.parse(getCookie('choosen_delivery')) : [] ; 6336 var $count = Object.keys($choosen_delivery).length; 6337 if($count>0){ 6338 $response = { 6339 'whento_deliver' : $choosen_delivery.whento_deliver 6340 }; 6341 if($choosen_delivery.whento_deliver=="schedule"){ 6342 $response = { 6343 'whento_deliver' : $choosen_delivery.whento_deliver, 6344 'delivery_date' : $choosen_delivery.delivery_date, 6345 'delivery_time' : $choosen_delivery.delivery_time.start_time, 6346 'delivery_time_raw' : $choosen_delivery.delivery_time, 6347 }; 6348 } 6349 return $response; 6350 } 6351 return false; 6352}; 6353 6354 6355/* 6356 MOBILE FILTER FOR FEED 6357*/ 6358const ComponentsFilterFeed = { 6359 components: { 6360 'star-rating' : VueStarRating.default, 6361 }, 6362 props : ['data_attributes', 'data_cuisine' ,'label'], 6363 data(){ 6364 return { 6365 sortby : '', 6366 cuisine : [], 6367 price_range : 0, 6368 max_delivery_fee : 0, 6369 rating : 0, 6370 }; 6371 }, 6372 computed: { 6373 hasFilter(){ 6374 if(!empty(this.sortby)){ 6375 return true; 6376 } 6377 if(this.price_range>0){ 6378 return true; 6379 } 6380 if(this.max_delivery_fee>0){ 6381 return true; 6382 } 6383 if(this.cuisine.length>0){ 6384 return true; 6385 } 6386 if(this.rating>0){ 6387 return true; 6388 } 6389 return false; 6390 }, 6391 }, 6392 methods: { 6393 show(data){ 6394 $(this.$refs.filterFeed).modal('show'); 6395 }, 6396 close(){ 6397 $(this.$refs.filterFeed).modal('hide'); 6398 }, 6399 clearFilter(){ 6400 this.sortby = ''; 6401 this.price_range = 0; 6402 this.max_delivery_fee = 0; 6403 this.cuisine = []; 6404 this.rating = 0; 6405 }, 6406 applyFilter(){ 6407 this.close(); 6408 this.$emit('afterFilter',{ 6409 sortby : this.sortby, 6410 cuisine : this.cuisine, 6411 price_range : this.price_range, 6412 max_delivery_fee : this.max_delivery_fee, 6413 rating : this.rating 6414 }); 6415 }, 6416 }, 6417 template: ` 6418 <div class="modal" ref="filterFeed" tabindex="-1" role="dialog" 6419 aria-labelledby="filterFeed" aria-hidden="true" > 6420 <div class="modal-dialog modal-full modal-dialog-scrollable" role="document"> 6421 <div class="modal-content"> 6422 <div class="modal-body" > 6423 6424 <a href="javascript:;" @click="close" 6425 class="btn btn-black btn-circle rounded-pill"><i class="zmdi zmdi-close font20"></i></a> 6426 6427 <h5 class="mt-3">{{label.filters}}</h5> 6428 6429 <div v-for="(sort_by, key) in data_attributes.sort_by" class="row m-0 ml-2 mb-2"> 6430 <div class="custom-control custom-radio"> 6431 <input v-model="sortby" :value="key" type="radio" :id="key+1" class="custom-control-input"> 6432 <label class="custom-control-label" :for="key+1">{{sort_by}}</label> 6433 </div> 6434 </div><!--row--> 6435 6436 <h5 class="mt-3">{{label.price_range}}</h5> 6437 6438 <div class="btn-group btn-group-toggle input-group-small mt-2 mb-2 w-100" > 6439 <label v-for="(price, key) in data_attributes.price_range" class="btn" :class="{ active: price_range==key }" > 6440 <input type="radio" :value="key" v-model="price_range"> 6441 <!-- {{price}} --> 6442 <span v-html="price"></span> 6443 </label> 6444 </div> 6445 6446 <h5 class="mt-3">{{label.cuisine}}</h5> 6447 6448 <div class="row m-0"> 6449 <template v-for="(item_cuisine, index) in data_cuisine" > 6450 <div class="col-6 mb-1" > 6451 <div class="custom-control custom-checkbox"> 6452 <input type="checkbox" class="custom-control-input cuisine" :id="'cuisine'+item_cuisine.cuisine_id+1" 6453 :value="item_cuisine.cuisine_id" 6454 v-model="cuisine" 6455 > 6456 <label class="custom-control-label" :for="'cuisine'+item_cuisine.cuisine_id+1"> 6457 {{item_cuisine.cuisine_name}} 6458 </label> 6459 </div> 6460 </div> <!--col--> 6461 </template> 6462 </div><!-- row--> 6463 6464 <h5 class="mt-3">{{label.max_delivery_fee}}</h5> 6465 6466 <div class="form-group"> 6467 <label for="formControlRange">{{label.delivery_fee}} <b><span class="min-selected-range"></span></b></label> 6468 <input v-model="max_delivery_fee" 6469 id="min_range_slider" value="10" type="range" class="custom-range" id="formControlRange" min="1" max="20" >
6470 </div> 6471 6472 <h5 class="mt-3">{{label.ratings}}</h5> 6473 <p class="bold">{{label.over}} {{rating}}</p> 6474 <star-rating 6475 v-model:rating="rating" 6476 :star-size="30" 6477 :show-rating="false" 6478 @update:rating="rating = $event" 6479 > 6480 </star-rating> 6481 6482 </div> <!--content--> 6483 6484 <div class="modal-footer border-top-0"> 6485 <template v-if="hasFilter"> 6486 <button @click="clearFilter" class="btn btn-light rounded-0 w-50" > 6487 {{label.clear_all}} 6488 </button> 6489 <button @click="applyFilter" class="btn btn-black rounded-0 w-50" > 6490 {{label.done}} 6491 </button> 6492 </template> 6493 <template v-else> 6494 <button @click="applyFilter" class="btn btn-black rounded-0 w-100" > 6495 {{label.done}} 6496 </button> 6497 </template> 6498 </div> 6499 <!--- modal footer --> 6500 6501 </div> <!--dialog--> 6502 </div> <!--modal--> 6503 ` 6504}; 6505 6506 6507/* 6508 MOBILE SEARCH SUGGESTION 6509*/ 6510const ComponentsMobileSearchSuggestion = { 6511 props : ['ajax_url','tabs_suggestion' , 'label'], 6512 data() { 6513 return { 6514 active_tab : 'restaurant', 6515 data : [], 6516 q: '', 6517 awaitingSearch : false, 6518 is_loading : false 6519 }; 6520 }, 6521 watch: { 6522 q(newsearch,oldsearch){ 6523 if (!this.awaitingSearch) { 6524 6525 if(empty(newsearch)){ 6526 this.clearData(); 6527 return false; 6528 } 6529 6530 this.show_list = true; 6531 this.is_loading = true; 6532 6533 setTimeout(() => { 6534 axios({ 6535 method: 'POST', 6536 url: ajaxurl+"/getSearchSuggestionV1" , 6537 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&q=" + this.q + "&category=" + this.active_tab, 6538 timeout: $timeout, 6539 }).then( response => { 6540 if(response.data.code==1){ 6541 this.data = response.data.details.data; 6542 } else { 6543 this.data = []; 6544 } 6545 }).catch(error => { 6546 // 6547 }).then(data => { 6548 this.awaitingSearch = false; 6549 this.is_loading = false; 6550 }); 6551 6552 }, 1000); // 1 sec delay 6553 } 6554 6555 this.data = []; 6556 this.awaitingSearch = true; 6557 } 6558 }, 6559 methods: { 6560 show(data){ 6561 this.clearData(); 6562 $(this.$refs.suggestion).modal('show'); 6563 setTimeout(() => { 6564 this.$refs.q.focus(); 6565 }, 500); 6566 }, 6567 close(){ 6568 $(this.$refs.suggestion).modal('hide'); 6569 }, 6570 showList(){ 6571 this.show_list = true; 6572 }, 6573 clearData(){ 6574 this.data = []; 6575 this.q = ''; 6576 this.show_list = false; 6577 }, 6578 setTab(index){ 6579 this.clearData(); 6580 this.show_list = false; 6581 this.active_tab = index; 6582 }, 6583 }, 6584 computed : { 6585 hasData(){ 6586 if(this.data.length>0){ 6587 return true; 6588 } 6589 return false; 6590 }, 6591 }, 6592 template: ` 6593 <div class="modal" ref="suggestion" tabindex="-1" role="dialog" 6594 aria-labelledby="suggestion" aria-hidden="true" > 6595 <div class="modal-dialog modal-full modal-dialog-scrollable" role="document"> 6596 <div class="modal-content"> 6597 <div class="modal-body p-0" > 6598 6599 <div class="container-fluid mt-3 mb-2"> 6600 <a href="javascript:;" @click="close" 6601 class="btn btn-black btn-circle rounded-pill"><i class="zmdi zmdi-close font20"></i></a> 6602 6603 <div class="position-relative inputs-box-wrap mt-3 "> 6604 <input @click="showList" ref="q" v-model="q" class="inputs-box-grey rounded w-100" :placeholder="label.search"> 6605 <div class="search_placeholder pos-right img-15"></div> 6606 <button @click="clearData" v-if="show_list" class="btn btn-sm icon-remove">{{label.clear}}</button> 6607 </div> 6608 6609 </div> 6610 <!-- container --> 6611 6612 <ul class="suggestion-tab row no-gutters list-unstyled list-inline"> 6613 <li v-for="(item, index) in tabs_suggestion" 6614 class="col list-inline-item mr-0" 6615 :class="{active : active_tab==index }" 6616 @click="setTab(index)" 6617 > 6618 {{item}} 6619 </li> 6620 </ul> 6621 6622 <div class="container-fluid "> 6623 6624 <el-skeleton :count="9" animated :loading="is_loading" > 6625 <template #template> 6626 <div class="row mb-2"> 6627 <div class="col-2"> 6628 <el-skeleton style="--el-skeleton-circle-size: 40px"> 6629 <template #template> 6630 <el-skeleton-item variant="circle" /> 6631 </template> 6632 </el-skeleton> 6633 </div> <!-- col --> 6634 6635 <div class="col"> 6636 <el-skeleton animated> 6637 <template #template> 6638 <div style="padding: 0px"> 6639 <el-skeleton-item variant="p" style="width: 50%" /> 6640 <div 6641 style=" 6642 display: flex; 6643 align-items: center; 6644 justify-items: space-between; 6645 " 6646 > 6647 <el-skeleton-item variant="text" style="margin-right: 16px" /> 6648 <el-skeleton-item variant="text" style="width: 30%" /> 6649 </div> 6650 </div> 6651 </template> 6652 </el-skeleton> 6653 </div> <!-- col --> 6654 </div> 6655 <!-- row --> 6656 </template> 6657 6658 <template #default> 6659 <template v-if="hasData"> 6660 <ul class="list-unstyled m-0"> 6661 <li v-for="items in data"> 6662 <a :href="items.url"> 6663 <div class="row align-items-center no-gutters"> 6664 <div class="col-1 mr-3"> 6665 <img class="img-40 rounded-pill" :src="items.url_logo"> 6666 </div> 6667 <div class="col text-truncate border-bottom p-2"> 6668 <h6 class="m-0 text-truncate">{{items.title}}</h6> 6669 <p class="m-0 text-truncate text-grey "> 6670 <span class="mr-1" v-for="cuisine in items.cuisine_name" >{{cuisine.cuisine_name}},</span> 6671 </p> 6672 </div> 6673 </div> 6674 </a> 6675 </li> 6676 </ul> 6677 </template> 6678 <template v-else> 6679 <template v-if="q"> 6680 <el-empty :description="label.no_results"></el-empty> 6681 </template> 6682 </template> 6683 6684 </template> 6685 6686 </el-skeleton> 6687 6688 6689 </div> 6690 <!-- container --> 6691 6692 6693 6694
6695 </div> <!--content--> 6696 </div> <!--dialog--> 6697 </div> <!--modal--> 6698 ` 6699}; 6700 6701 6702const componentsBanner = { 6703 template: '#xtemplate_banner', 6704 data() { 6705 return { 6706 loading : false, 6707 swiperBanner : null, 6708 data : null 6709 } 6710 }, 6711 mounted() { 6712 this.getBanner(); 6713 }, 6714 computed: { 6715 hasBanner(){ 6716 if (!this.loading && Object.keys(this.data).length > 0) { 6717 return true; 6718 } 6719 return false; 6720 }, 6721 }, 6722 methods: { 6723 getBanner(){ 6724 const selectedAddress = getFromLocalStorageStore(StoreMapName,"selectedAddress"); 6725 if (typeof selectedAddress === "undefined" || selectedAddress === null || selectedAddress === "") { 6726 return; 6727 } 6728 let params = "latitude="+selectedAddress.latitude + "&longitude="+ selectedAddress.longitude; 6729 this.loading = true; 6730 axios.get(ajaxurl+"/getBanner?"+params ).then(response => { 6731 if(response.data.code==1){ 6732 this.data = response.data.details.data; 6733 setTimeout(() => { 6734 this.initSwiper(); 6735 }, 1); 6736 this.$emit("afterGetbanner",true); 6737 } else { 6738 this.data = null; 6739 this.$emit("afterGetbanner",false); 6740 } 6741 }) 6742 .catch(error => { 6743 console.error('Error:', error); 6744 }).then(data => { 6745 this.loading = false; 6746 }); 6747 }, 6748 initSwiper(){ 6749 this.swiperBanner = new Swiper(this.$refs.refSwiper, { 6750 lazy: true, 6751 slidesPerView: 3, 6752 spaceBetween: 15, 6753 autoHeight: true, 6754 autoplay: { 6755 delay: 2500, 6756 disableOnInteraction: false, 6757 }, 6758 pagination: { 6759 el: ".swiper-pagination", 6760 clickable : true, 6761 dynamicBullets: true, 6762 }, 6763 breakpoints: { 6764 310: { 6765 slidesPerView: 1, 6766 spaceBetween: 0 6767 }, 6768 320: { 6769 slidesPerView: 1, 6770 spaceBetween: 0 6771 }, 6772 480: { 6773 slidesPerView: 1, 6774 spaceBetween: 0 6775 }, 6776 640: { 6777 slidesPerView: 2, 6778 spaceBetween: 10, 6779 }, 6780 768: { 6781 slidesPerView: 2, 6782 spaceBetween: 10, 6783 }, 6784 1024: { 6785 slidesPerView: 3, 6786 spaceBetween: 15, 6787 }, 6788 }, 6789 }); 6790 }, 6791 onBannerClick(value){ 6792 window.location.href = value.url; 6793 }, 6794 // 6795 }, 6796}; 6797 6798/* 6799 FEED / SEARCH RESULTS 6800 @target = vue-feed 6801*/ 6802const app_feed = Vue.createApp({ 6803 components: { 6804 'component-save-store' : ComponentsSaveStore, 6805 'star-rating' : VueStarRating.default, 6806 'component-filter-feed' : ComponentsFilterFeed, 6807 'component-mobile-search-suggestion' : ComponentsMobileSearchSuggestion, 6808 'components-banner' : componentsBanner, 6809 }, 6810 data(){ 6811 return { 6812 is_loading : false, 6813 reload_loading : false, 6814 collapse : true, 6815 data_attributes : [], 6816 data_cuisine : [], 6817 cuisine : [], 6818 sortby : '', 6819 price_range : 0, 6820 max_delivery_fee : 0, 6821 page : 0, 6822 show_next_page : false, 6823 datas : [], 6824 services : [], 6825 estimation : [], 6826 total_message : '', 6827 rating: 0, 6828 transaction_type : '', 6829 whento_deliver : '', 6830 delivery_date : '', 6831 delivery_time : '', 6832 response_code : 1, 6833 pause_reason_data : [], 6834 data_attributes_loading : false, 6835 enabled_review : true, 6836 has_banner : false, 6837 is_guest : true 6838 }; 6839 }, 6840 mounted () { 6841 this.getCuisineList(); 6842 this.searchAttributes(); 6843 this.pauseReasonList(); 6844 6845 if ((typeof cuisine_filter !== "undefined") && ( cuisine_filter !== null)) { 6846 let $cuisine_filter = JSON.parse(cuisine_filter); 6847 this.cuisine = $cuisine_filter; 6848 } 6849 6850 this.Search(false); 6851 if ((typeof isGuest !== "undefined") && ( isGuest !== null)) { 6852 this.is_guest = isGuest; 6853 } 6854 }, 6855 computed: { 6856 hasFilter(){ 6857 if(!empty(this.sortby)){ 6858 return true; 6859 } 6860 if(this.price_range>0){ 6861 return true; 6862 } 6863 if(this.max_delivery_fee>0){ 6864 this.AutoFeed(); 6865 return true; 6866 } 6867 if(this.cuisine.length>0){ 6868 return true; 6869 } 6870 if(this.rating>0){ 6871 this.AutoFeed(); 6872 return true; 6873 } 6874 return false;
6875 }, 6876 hasMore(){ 6877 if(this.show_next_page){ 6878 return true; 6879 } 6880 return false; 6881 }, 6882 hasData(){ 6883 if(this.datas.length>0){ 6884 return true; 6885 } 6886 return false; 6887 }, 6888 hasFilter() { 6889 if (Object.keys(this.cuisine).length > 0) { 6890 return true; 6891 } 6892 if(!empty(this.sortby)){ 6893 return true; 6894 } 6895 if(!empty(this.price_range)){ 6896 return true; 6897 } 6898 if(!empty(this.max_delivery_fee)){ 6899 return true; 6900 } 6901 if(!empty(this.rating)){ 6902 return true; 6903 } 6904 return false; 6905 } 6906 }, 6907 methods: { 6908 afterGetbanner(value){ 6909 this.has_banner = value; 6910 }, 6911 clearFilter(){ 6912 this.sortby = ''; 6913 this.price_range = 0; 6914 this.max_delivery_fee = 0; 6915 this.cuisine = []; 6916 this.rating = 0; 6917 this.Search(false); 6918 }, 6919 getCuisineList(){ 6920 6921 var $params = { 6922 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 6923 }; 6924 var timenow = getTimeNow(); 6925 $params = JSON.stringify($params); 6926 6927 ajax_request[timenow] = $.ajax({ 6928 url: ajaxurl+"/CuisineList", 6929 method: "PUT", 6930 dataType: "json", 6931 data: $params , 6932 contentType : $content_type.json , 6933 timeout: $timeout, 6934 crossDomain: true, 6935 beforeSend: data => { 6936 if(ajax_request[timenow] != null) { 6937 ajax_request[timenow].abort(); 6938 } 6939 } 6940 }); 6941 6942 ajax_request[timenow].done( data => { 6943 if ( data.code==1){ 6944 this.data_cuisine = data.details.data_cuisine; 6945 } else { 6946 this.data_cuisine = []; 6947 } 6948 }); 6949 6950 ajax_request[timenow].always( data => { 6951 6952 }); 6953 }, 6954 6955 searchAttributes(){ 6956 6957 let currency_code = getCookie('currency_code'); 6958 currency_code = !empty(currency_code)?currency_code:''; 6959 var $params = { 6960 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 6961 'currency_code' : currency_code 6962 }; 6963 var timenow = getTimeNow(); 6964 $params = JSON.stringify($params); 6965 6966 this.data_attributes_loading = true; 6967 ajax_request[timenow] = $.ajax({ 6968 url: ajaxurl+"/searchAttributes", 6969 method: "PUT", 6970 dataType: "json", 6971 data: $params , 6972 contentType : $content_type.json , 6973 timeout: $timeout, 6974 crossDomain: true, 6975 beforeSend: data => { 6976 if(ajax_request[timenow] != null) { 6977 ajax_request[timenow].abort(); 6978 } 6979 } 6980 }); 6981 6982 ajax_request[timenow].done( data => { 6983 if ( data.code==1){ 6984 this.data_attributes = data.details; 6985 } else { 6986 this.data_attributes = []; 6987 } 6988 }); 6989 6990 ajax_request[timenow].always( data => { 6991 this.data_attributes_loading = false; 6992 }); 6993 6994 }, 6995 ShowMore(){ 6996 this.Search( this.show_next_page ); 6997 }, 6998 AutoFeed(){ 6999 setTimeout(() => { 7000 this.Search(false); 7001 }, 100); 7002 }, 7003 Search($reload){ 7004 7005 if($reload){ 7006 var timenow = 11; 7007 } else { 7008 var timenow = getTimeNow(); 7009 this.page=0; 7010 } 7011 7012 var $data_delivery; 7013 if($data_delivery = getChoosenDeliveryTime()){ 7014 if(empty(this.whento_deliver)){ 7015 this.whento_deliver = $data_delivery.whento_deliver; 7016 this.delivery_date = $data_delivery.delivery_date; 7017 this.delivery_time = $data_delivery.delivery_time; 7018 } 7019 } 7020 7021 let currency_code = getCookie('currency_code'); 7022 7023 var $params = { 7024 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 7025 'local_id': getCookie('kmrs_local_id'), 7026 'cart_uuid':getCookie('cart_uuid'), 7027 'page' : this.page, 7028 'currency_code' : currency_code, 7029 'filters':{ 7030 'cuisine': this.cuisine, 7031 'sortby' : this.sortby, 7032 'price_range': this.price_range, 7033 'max_delivery_fee': this.max_delivery_fee, 7034 'rating': this.rating, 7035 'transaction_type':this.transaction_type, 7036 'whento_deliver': this.whento_deliver, 7037 'delivery_date': this.delivery_date, 7038 'delivery_time': this.delivery_time, 7039 }, 7040 }; 7041 7042 $params = JSON.stringify($params); 7043 ajax_request[timenow] = $.ajax({ 7044 url: ajaxurl+"/getFeedV1", 7045 method: "PUT", 7046 dataType: "json", 7047 data: $params , 7048 contentType : $content_type.json , 7049 timeout: $timeout, 7050 crossDomain: true, 7051 beforeSend: data => { 7052 //if(!$reload) { this.is_loading = true; } else { this.reload_loading = true; } 7053 this.is_loading = true; 7054 if(ajax_request[timenow] != null) { 7055 ajax_request[timenow].abort(); 7056 } 7057 } 7058 }); 7059 7060 ajax_request[timenow].done( data => { 7061 this.response_code = data.code; 7062 if ( data.code==1){ 7063 if(!$reload){ 7064 this.datas = []; 7065 this.services = []; 7066 this.estimation = []; 7067 } 7068 7069 //this.datas.push(data.details.data); 7070 this.datas = [...this.datas, ...data.details.data]; 7071 this.services = data.details.services; 7072 this.estimation = data.details.estimation; 7073 this.total_message = data.details.total_message; 7074 this.show_next_page = data.details.show_next_page; 7075 this.page = data.details.page; 7076 this.transaction_type = data.details.transaction_type; 7077 this.enabled_review = data.details.enabled_review; 7078 this.updateImage(); 7079 } else { 7080 this.datas = []; 7081 this.services = []; 7082 this.estimation = []; 7083 this.total_message=''; 7084 this.show_next_page = false;
7085 this.page = 0; 7086 this.transaction_type = ''; 7087 } 7088 }); 7089 7090 ajax_request[timenow].always( data => { 7091 this.is_loading = false; 7092 this.reload_loading = false; 7093 }); 7094 }, 7095 pauseReasonList(){ 7096 7097 axios({ 7098 method: 'POST', 7099 url: ajaxurl+"/pauseReasonList" , 7100 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content'), 7101 timeout: $timeout, 7102 }).then( response => { 7103 if(response.data.code==1){ 7104 this.pause_reason_data = response.data.details; 7105 } else { 7106 this.pause_reason_data = []; 7107 } 7108 }).catch(error => { 7109 // 7110 }).then(data => { 7111 7112 }); 7113 7114 }, 7115 updateImage(){ 7116 updateLazyImage(); 7117 }, 7118 afterSaveStore(item){ 7119 item.saved_store = item.saved_store==1?false:true; 7120 }, 7121 showFilter(){ 7122 this.$refs.filter_feed.show(); 7123 }, 7124 afterApplyFilter(data){ 7125 this.sortby = data.sortby; 7126 this.cuisine = data.cuisine; 7127 this.price_range = data.price_range; 7128 this.max_delivery_fee = data.max_delivery_fee; 7129 this.rating = data.rating; 7130 this.AutoFeed(); 7131 }, 7132 showSearchSuggestion(){ 7133 this.$refs.search_suggestion.show(); 7134 }, 7135 }, 7136}); 7137app_feed.use(ElementPlus); 7138const vm_feed = app_feed.mount('#vue-feed'); 7139 7140 7141/* 7142 COMPONENTS SERVICES BUTTON 7143*/ 7144 7145const ComponentsServices = { 7146 data() { 7147 return { 7148 data : [], 7149 transaction_type : '', 7150 is_loading : false, 7151 } 7152 }, 7153 mounted () { 7154 this.getServices(); 7155 }, 7156 methods: { 7157 getServices(){ 7158 7159 var timenow = getTimeNow(); 7160 var $params = { 7161 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 7162 'cart_uuid':getCookie('cart_uuid'), 7163 }; 7164 7165 ajax_request[timenow] = $.ajax({ 7166 url: ajaxurl+"/getServices", 7167 method: "PUT", 7168 dataType: "json", 7169 data: JSON.stringify($params), 7170 contentType : $content_type.json , 7171 timeout: $timeout, 7172 crossDomain: true, 7173 beforeSend: data => { 7174 this.is_loading = true; 7175 if(ajax_request[timenow] != null) { 7176 ajax_request[timenow].abort(); 7177 } 7178 } 7179 }); 7180 7181 ajax_request[timenow].done( data => { 7182 if ( data.code==1){ 7183 this.data = data.details.data; 7184 this.transaction_type = data.details.transaction_type; 7185 this.$emit('setTransaction',this.transaction_type,data.details.data); 7186 } else { 7187 this.data = []; 7188 this.transaction_type = ''; 7189 } 7190 }); 7191 7192 ajax_request[timenow].always( data => { 7193 this.is_loading = false; 7194 }); 7195 7196 }, 7197 setTransactionType(transaction_type){ 7198 7199 var timenow = getTimeNow(); 7200 var $params = { 7201 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 7202 'transaction_type':transaction_type, 7203 'cart_uuid':getCookie('cart_uuid'), 7204 }; 7205 7206 ajax_request[timenow] = $.ajax({ 7207 url: ajaxurl+"/setTransactionType", 7208 method: "PUT", 7209 dataType: "json", 7210 data: JSON.stringify($params), 7211 contentType : $content_type.json , 7212 timeout: $timeout, 7213 crossDomain: true, 7214 beforeSend: data => { 7215 if(ajax_request[timenow] != null) { 7216 ajax_request[timenow].abort(); 7217 } 7218 } 7219 }); 7220 7221 ajax_request[timenow].done( data => { 7222 if ( data.code==1){ 7223 setCookie('cart_uuid',data.details.cart_uuid,30); 7224 this.transaction_type = data.details.transaction_type; 7225 this.$emit('afterSettransaction',this.transaction_type); 7226 } else { 7227 this.this.transaction_type = ''; 7228 } 7229 }); 7230 7231 ajax_request[timenow].always( data => { 7232 // 7233 }); 7234 7235 }, 7236 }, 7237 template: ` 7238 7239 <template v-if="is_loading" > 7240 <el-skeleton animated style="width:auto;" class="mr-2"> 7241 <template #template> 7242 <el-skeleton-item variant="button"></el-skeleton-item> 7243 </template> 7244 </el-skeleton> 7245 </template> 7246 7247 <div v-else class="dropdown widget-dropdown mr-2" >
7248 <button class="" type="button" id="dropdownMenuButton" 7249 data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> 7250 <template v-if="data[transaction_type]"> 7251 {{data[transaction_type].service_name}} 7252 </template> 7253 </button> 7254 7255 <div class="dropdown-menu" aria-labelledby="services"> 7256 <a v-for="item in data" href="javascript:;" @click="setTransactionType(item.service_code)" > 7257 {{item.service_name}} 7258 </a> 7259 </div> 7260 7261 </div> <!--dropdown--> 7262 `, 7263}; 7264 7265/* 7266 COMPONENTS TRANSACTION INFORMATION 7267*/ 7268 7269const ComponentsTransactionInfo = { 7270 props: ['layout' , 'transaction_type', 'label','transaction_list'], 7271 data() { 7272 return { 7273 address1 : '', 7274 whento_deliver : '', 7275 formatted_address : '', 7276 loading : false, 7277 delivery_option : [], 7278 delivery_datetime : '', 7279 visible : false, 7280 } 7281 }, 7282 mounted () { 7283 this.TransactionInfo(); 7284 }, 7285 methods: { 7286 TransactionInfo(){ 7287 7288 var $merchant_id = 0; 7289 if ((typeof merchant_id !== "undefined") && ( merchant_id !== null)) { 7290 $merchant_id = merchant_id; 7291 } 7292 7293 var $choosen_delivery = !empty(getCookie('choosen_delivery'))? JSON.parse(getCookie('choosen_delivery')) : [] ; 7294 var timenow = getTimeNow(); 7295 var $params = { 7296 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 7297 'cart_uuid':getCookie('cart_uuid'), 7298 'choosen_delivery' : $choosen_delivery, 7299 'merchant_id': $merchant_id 7300 }; 7301 7302 ajax_request[timenow] = $.ajax({ 7303 url: ajaxurl+"/TransactionInfo", 7304 method: "PUT", 7305 dataType: "json", 7306 data: JSON.stringify($params), 7307 contentType : $content_type.json , 7308 timeout: $timeout, 7309 crossDomain: true, 7310 beforeSend: data => { 7311 this.loading = true; 7312 if(ajax_request[timenow] != null) { 7313 ajax_request[timenow].abort(); 7314 } 7315 } 7316 }); 7317 7318 ajax_request[timenow].done( data => { 7319 if(data.code==1){ 7320 this.address1 = data.details.address1; 7321 this.whento_deliver = data.details.whento_deliver; 7322 this.formatted_address = data.details.formatted_address; 7323 this.delivery_option = data.details.delivery_option; 7324 this.delivery_datetime = data.details.delivery_datetime; 7325 this.visible = true; 7326 7327 if(data.details.time_already_passed){ 7328 setCookie('choosen_delivery', [] ,30); 7329 } 7330 } else { 7331 this.address1 = ''; 7332 this.whento_deliver = ''; 7333 this.formatted_address = ''; 7334 this.delivery_option = []; 7335 this.delivery_datetime = ''; 7336 this.visible = false; 7337 } 7338 }); // ajax done 7339 7340 ajax_request[timenow].always( data => { 7341 this.loading = false; 7342 }); 7343 7344 }, 7345 setTransactionInfo(){ 7346 this.$emit('afterClick',{ 7347 address1 : this.address1, 7348 delivery_option : this.delivery_option, 7349 whento_deliver : this.whento_deliver, 7350 formatted_address : this.formatted_address, 7351 delivery_datetime : this.delivery_datetime 7352 }); 7353 7354 }, 7355 }, 7356 template: ` 7357 <template v-if="loading" > 7358 <el-skeleton animated style="width:auto;"> 7359 <template #template> 7360 <el-skeleton-item variant="button"></el-skeleton-item> 7361 </template> 7362 </el-skeleton> 7363 </template> 7364 <div v-else class="position-relative"> 7365 <template v-if="layout=='widget-dropdown-address'"> 7366 <p class="m-0"> 7367 7368 <template v-if="whento_deliver=='schedule'"> 7369 {{delivery_datetime}} 7370 </template> 7371 <template v-else> 7372 <span class="text-capitalize"> 7373 <template v-if="transaction_list[transaction_type]"> 7374 {{transaction_list[transaction_type].service_name}} 7375 </template> 7376 <template v-else> 7377 {{transaction_type}} 7378 </template> 7379 </span> {{label.now}} 7380 </template> 7381 7382 </p> 7383 <div class="dropdown"> 7384 <button @click="setTransactionInfo()" class="btn-text dropdown-toggle" type="button" >
7385 <span class="text-truncate">{{address1}}</span> 7386 </button> 7387 </template> 7388 7389 <template v-else> 7390 7391 <div class="widget-dropdown" v-if="visible" > 7392 <button class="no-icons d-flex align-items-center" @click="setTransactionInfo()" > 7393 <span class="d-inline text-truncate"> 7394 <template v-if="address1"> 7395 {{address1}} {{formatted_address}} 7396 </template> 7397 <template v-else> 7398 {{label.select_address}} 7399 </template> 7400 </span> 7401 <span class="d-inline"> • 7402 7403 <template v-if="whento_deliver=='schedule'"> 7404 {{delivery_datetime}} 7405 </template> 7406 <template v-else> 7407 <template v-if="delivery_option[whento_deliver]"> 7408 {{ delivery_option[whento_deliver].short_name }} 7409 </template> 7410 </template> 7411 7412 </span> 7413 </button> 7414 </div> 7415 </template> 7416 </div> 7417 `, 7418}; 7419 7420 7421/* 7422 COMPONENTS DELIVERY DETAILS 7423*/ 7424const ComponentsDeliveryDetails = { 7425 props: ['label'], 7426 data() { 7427 return { 7428 data : [], 7429 screen_size: { 7430 width: 0, 7431 height: 0 7432 }, 7433 } 7434 }, 7435 mounted () { 7436 this.handleResize(); 7437 window.addEventListener('resize', this.handleResize); 7438 }, 7439 computed : { 7440 isMobileView(){ 7441 if(this.screen_size.width<=991){ 7442 return true; 7443 } 7444 return false; 7445 }, 7446 }, 7447 methods: { 7448 show(data){ 7449 this.data = data; 7450 $(this.$refs.ModalDeliveryDetails).modal('show'); 7451 }, 7452 close(){ 7453 $(this.$refs.ModalDeliveryDetails).modal('hide'); 7454 }, 7455 handleResize() { 7456 this.screen_size.width = window.innerWidth; 7457 this.screen_size.height = window.innerHeight; 7458 }, 7459 }, 7460 template: ` 7461 <div class="modal" ref="ModalDeliveryDetails" tabindex="-1" role="dialog" 7462 aria-labelledby="ModalDeliveryDetails" aria-hidden="true" data-backdrop="static" data-keyboard="false" > 7463 <div class="modal-dialog modal-dialog-centered modal-lg" role="document"> 7464 <div class="modal-content" :class="{ 'modal-mobile': isMobileView }" > 7465 7466 <div class="modal-header border-bottom-0" style="padding-bottom:0px !important;"> 7467 <h5 class="modal-title">{{label.title}}</h5> 7468 <a href="javascript:;" @click="close" class="btn btn-black btn-circle rounded-pill"><i class="zmdi zmdi-close font20"></i></a> 7469 </div> 7470 7471 <div class="modal-body" > 7472 7473 <a href="javascript:;" @click="$emit('showAddress')" 7474 class="d-block chevron-section promo-section d-flex align-items-center rounded mb-2"> 7475 <div class="flexcol mr-2"><i class="zmdi zmdi-pin"></i></div> 7476 <div class="flexcol" > 7477 <template v-if="data.address1"> 7478 <span class="bold mr-1">{{data.address1}}</span> 7479 <p class="m-0 text-muted">{{data.formatted_address}}</p> 7480 </template> 7481 <template v-else> 7482 <span class="bold mr-1">{{label.select_address}}</span> 7483 </template> 7484 </div> 7485 </a> 7486 7487 <a v-if="data" href="javascript:;" @click="$emit('showTransOptions')" 7488 class="d-block chevron-section promo-section d-flex align-items-center rounded mb-2"> 7489 <div class="flexcol mr-2"><i class="zmdi zmdi-time"></i></div> 7490 <div class="flexcol" > 7491 <template v-if="data.whento_deliver=='schedule'"> 7492 {{data.delivery_datetime}} 7493 </template> 7494 <template v-else> 7495 <template v-if="data.delivery_option"> 7496 {{ data.delivery_option[data.whento_deliver].short_name }} 7497 </template> 7498 </template> 7499 </div> 7500 </a> 7501 7502 </div> <!--modal-body--> 7503 7504 <div class="modal-footer justify-content-start"> 7505 7506 <button class="btn btn-black w-100" @click="close();" > 7507 {{label.done}} 7508 </button> 7509 7510 </div> <!--modal-footer--> 7511 7512 </div> <!--content--> 7513 </div> <!--dialog--> 7514 </div> <!--modal--> 7515 `, 7516}; 7517 7518/* 7519 COMPONENTS DELIVERY OPTIONS 7520*/ 7521const ComponenstTransactionOptions = { 7522 props: ['label'], 7523 data() { 7524 return { 7525 data : [], 7526 loading : false, 7527 delivery_option : [], 7528 whento_deliver : '', 7529 opening_hours_date : [], 7530 opening_hours_time : [], 7531 delivery_date : '', 7532 delivery_time : '', 7533 error : [] 7534 } 7535 }, 7536 mounted () { 7537 7538 }, 7539 computed: { 7540 hasError(){ 7541 if(this.error.length>0){ 7542 return true; 7543 } 7544 return false;
7545 }, 7546 }, 7547 methods: { 7548 show(data){ 7549 $(this.$refs.modalselecttime).modal('show'); 7550 this.getDeliveryTimes(); 7551 }, 7552 close(){ 7553 $(this.$refs.modalselecttime).modal('hide'); 7554 this.$emit('afterClose'); 7555 }, 7556 getDeliveryTimes(){ 7557 7558 var timenow = getTimeNow(); 7559 var $merchant_id = 0; 7560 if ((typeof merchant_id !== "undefined") && ( merchant_id !== null)) { 7561 $merchant_id = merchant_id; 7562 } 7563 var $params = { 7564 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 7565 'cart_uuid':getCookie('cart_uuid'), 7566 'merchant_id': $merchant_id 7567 }; 7568 7569 ajax_request[timenow] = $.ajax({ 7570 url: ajaxurl+"/getDeliveryTimes", 7571 method: "PUT", 7572 dataType: "json", 7573 data: JSON.stringify($params), 7574 contentType : $content_type.json , 7575 timeout: $timeout, 7576 crossDomain: true, 7577 beforeSend: data => { 7578 this.loading = true; 7579 if(ajax_request[timenow] != null) { 7580 ajax_request[timenow].abort(); 7581 } 7582 } 7583 }); 7584 7585 ajax_request[timenow].done( data => { 7586 if(data.code==1){ 7587 this.delivery_option = data.details.delivery_option; 7588 this.whento_deliver = data.details.whento_deliver; 7589 this.opening_hours_date = data.details.opening_hours.dates; 7590 this.opening_hours_time = data.details.opening_hours.time_ranges; 7591 7592 var keys = Object.keys(data.details.opening_hours.dates); 7593 this.delivery_date = keys[0]; 7594 7595 var keys = data.details.opening_hours.time_ranges[this.delivery_date][0]; 7596 this.delivery_time = JSON.stringify(keys); 7597 7598 if(!empty(data.details.delivery_date)){ 7599 this.delivery_date = data.details.delivery_date; 7600 } 7601 if(!empty(data.details.delivery_time)){ 7602 this.delivery_time = data.details.delivery_time; 7603 } 7604 7605 dump("SELECTED=>"); 7606 dump(this.delivery_date); 7607 dump(this.delivery_time); 7608 dump(this.delivery_option); 7609 7610 7611 } else { 7612 this.delivery_option = []; 7613 this.whento_deliver = ''; 7614 this.error = data.msg; 7615 } 7616 }); // ajax done 7617 7618 ajax_request[timenow].always( data => { 7619 this.loading = false; 7620 }); 7621 7622 }, 7623 save(){ 7624 var timenow = 1; 7625 var $params = { 7626 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 7627 'cart_uuid':getCookie('cart_uuid'), 7628 'delivery_date': this.delivery_date, 7629 'whento_deliver': this.whento_deliver, 7630 'delivery_time': !empty(this.delivery_time)?JSON.parse(this.delivery_time):'' 7631 //'delivery_time': this.delivery_time, 7632 }; 7633 7634 ajax_request[timenow] = $.ajax({ 7635 url: ajaxurl+"/saveTransactionInfo", 7636 method: "PUT", 7637 dataType: "json", 7638 data: JSON.stringify($params), 7639 contentType : $content_type.json , 7640 timeout: $timeout, 7641 crossDomain: true, 7642 beforeSend: data => { 7643 this.loading = true; 7644 if(ajax_request[timenow] != null) { 7645 ajax_request[timenow].abort(); 7646 } 7647 } 7648 }); 7649 7650 ajax_request[timenow].done( data => { 7651 this.$emit('afterSave',data.details); 7652 if(data.code==1){ 7653 var $json = { 7654 'whento_deliver' : data.details.whento_deliver, 7655 'delivery_date' : data.details.delivery_date, 7656 'delivery_time' : data.details.delivery_time 7657 /*'delivery_time' : { 7658 'start_time' : data.details.delivery_time_raw.start_time, 7659 'end_time' : data.details.delivery_time_raw.end_time, 7660 'pretty_time' : data.details.delivery_time_raw.pretty_time, 7661 }*/ 7662 }; 7663 setCookie('choosen_delivery', JSON.stringify($json) ,30); 7664 } 7665 }); 7666 7667 ajax_request[timenow].always( data => { 7668 this.loading = false;
7669 }); 7670 }, 7671 JsonValue(item){ 7672 return JSON.stringify({ 7673 start_time : item.start_time, 7674 end_time : item.end_time, 7675 pretty_time : item.pretty_time 7676 }); 7677 } 7678 }, 7679 template: ` 7680 <div class="modal" ref="modalselecttime" id="ModalTRNOptions" tabindex="-1" role="dialog" 7681 aria-labelledby="ModalTRNOptions" aria-hidden="true" > 7682 <div class="modal-dialog" role="document"> 7683 <div class="modal-content"> 7684 <div class="modal-body" > 7685 7686 <a href="javascript:;" @click="close" 7687 class="btn btn-black btn-circle rounded-pill"><i class="zmdi zmdi-close font20"></i></a> 7688 7689 <h4 class="m-0 mb-3 mt-3">{{label.title}}</h4> 7690 7691 <div v-cloak v-if="error.length>0" class="alert alert-warning mb-2" role="alert"> 7692 <p v-cloak v-for="err in error" class="m-0">{{err}}</p> 7693 </div> 7694 7695 <div class="btn-group btn-group-toggle input-group-small mt-2 mb-3" > 7696 <label v-for="(item, index) in delivery_option" class="btn" :class="{ active: whento_deliver==item.value }" > 7697 <input type="radio" :value="item.value" name="whento_deliver" v-model="whento_deliver"> 7698 {{item.name}} 7699 </label> 7700 </div> 7701 7702 <template v-if="whento_deliver=='schedule'"> 7703 7704 <select class="form-control custom-select mb-3" v-model="delivery_date"> 7705 <option v-for="(item, index) in opening_hours_date" :value="item.value" > 7706 {{ item.name}} 7707 </option> 7708 </select> 7709 7710 <select id="delivery_time" class="form-control custom-select" 7711 v-model="delivery_time" v-if="opening_hours_date[delivery_date]" > 7712 <option v-for="(item, index) in opening_hours_time[delivery_date]" 7713 :value="JsonValue(item)" > 7714 {{item.pretty_time}} 7715 </option> 7716 </select> 7717 7718 </template> 7719 7720 </div> <!--modal-body--> 7721 7722 7723 <div class="modal-footer justify-content-start"> 7724 7725 <button @click="save" 7726 class="btn btn-green w-100" :class="{ loading: loading }" 7727 :disabled="hasError" 7728 > 7729 <span class="label">{{label.save}}</span> 7730 <div class="m-auto circle-loader" data-loader="circle-side"></div> 7731 </button> 7732 7733 </div> <!--modal-footer--> 7734 7735 </div> <!--content--> 7736 </div> <!--dialog--> 7737 </div> <!--modal--> 7738 `, 7739}; 7740 7741/* 7742 COMPONENTS searchSuggestion 7743*/ 7744const ComponentSearchSuggestion = { 7745 props: ['label'], 7746 data(){ 7747 return { 7748 q: '', 7749 awaitingSearch : false, 7750 show_list : false, 7751 data : [], 7752 }; 7753 }, 7754 watch: { 7755 q(newsearch,oldsearch){ 7756 if (!this.awaitingSearch) { 7757 7758 if(empty(newsearch)){ 7759 this.clearData(); 7760 return false; 7761 } 7762 7763 this.show_list = true; 7764 7765 setTimeout(() => { 7766 7767 var $params; var timenow = 2; 7768 $params="q=" + this.q; 7769 $params+=addValidationRequest(); 7770 ajax_request[timenow] = $.ajax({ 7771 url: ajaxurl+"/getSearchSuggestion", 7772 method: "POST", 7773 dataType: "json", 7774 data: $params, 7775 contentType : $content_type.form , 7776 timeout: $timeout, 7777 crossDomain: true, 7778 beforeSend: data => { 7779 if(ajax_request[timenow] != null) { 7780 ajax_request[timenow].abort(); 7781 } 7782 } 7783 }); 7784 7785 ajax_request[timenow].done( data => { 7786 if ( data.code==1){ 7787 this.data = data.details.data; 7788 } else { 7789 this.data = []; 7790 } 7791 }); // ajax done 7792 7793 ajax_request[timenow].always( data => { 7794 this.awaitingSearch = false; 7795 }); 7796 7797 }, 1000); // 1 sec delay 7798 } 7799 7800 this.data = []; 7801 this.awaitingSearch = true; 7802 } 7803 }, 7804 computed: { 7805 hasData(){ 7806 if(this.data.length>0){ 7807 return true; 7808 } 7809 return false;
7810 }, 7811 }, 7812 methods: { 7813 showList(){ 7814 this.show_list = true; 7815 }, 7816 clearData(){ 7817 this.data = []; 7818 this.q = ''; 7819 }, 7820 }, 7821 template: ` 7822 7823 <div class="mr-2 position-relative inputs-box-wrap d-none d-md-block"> 7824 <input @click="showList" v-model="q" class="inputs-box-grey " :placeholder="label.placeholder" /> 7825 <div v-if="!awaitingSearch" class="search_placeholder pos-right img-15"></div> 7826 <div v-if="awaitingSearch" class="icon img-15" data-loader="circle"></div> 7827 7828 <div v-if="hasData" @click="clearData" class="icon-remove"><i class="zmdi zmdi-close"></i></div> 7829 7830 <div class="results with-border" v-if="show_list" > 7831 <ul class="list-unstyled m-0"> 7832 <li v-for="items in data" > 7833 <a :href="items.url" > 7834 <div class="row align-items-center no-gutters"> 7835 <div class="col col-md-auto mr-2"> 7836 <img class="img-30 rounded-pill" :src="items.url_logo" > 7837 </div> 7838 <div class="col text-truncate"> 7839 <h6 class="m-0 text-truncate">{{items.title}}</h6> 7840 <p class="m-0 text-truncate text-grey "> 7841 <span class="mr-1" v-for="cuisine in items.cuisine_name" >{{cuisine.cuisine_name}},</span> 7842 </p> 7843 </div> 7844 </div> 7845 </a> 7846 </li> 7847 </ul> 7848 </div> 7849 </div> 7850 7851 <!--- 7852 <div class="d-block d-md-none mr-3 mr-md-2"> 7853 <button class="btn btn-search rounded-circle bg-light"><i class="zmdi zmdi-search"></i></button> 7854 </div> 7855 ---> 7856 ` 7857}; 7858 7859 7860/* 7861 WIDGET SEARCH NAV 7862*/ 7863const app_search_widget = Vue.createApp({ 7864 components: { 7865 'component-search-suggestion' : ComponentSearchSuggestion, 7866 }, 7867 methods: { 7868 closeSuggestion(){ 7869 this.$refs.suggestion.show_list = false; 7870 } 7871 }, 7872}); 7873app_search_widget.directive("click-outside",clickOutside); 7874const vm_search_nav = app_search_widget.mount('#vue-search-nav'); 7875 7876 7877const ComponentsLocationCurrentAddress = { 7878 template : "#xtemplate_location_current_address", 7879 data() { 7880 return { 7881 data :[], 7882 city_id : null, 7883 area_id : null, 7884 state_id : null, 7885 postal_id : null, 7886 loading : false, 7887 search_type : null 7888 } 7889 }, 7890 created() { 7891 const urlParams = new URLSearchParams(window.location.search); 7892 this.city_id = urlParams.get('city_id'); 7893 this.area_id = urlParams.get('area_id'); 7894 this.state_id = urlParams.get('state_id'); 7895 this.postal_id = urlParams.get('postal_id'); 7896 7897 if ((typeof location_searchtype !== "undefined") && ( location_searchtype !== null)) { 7898 this.search_type = location_searchtype; 7899 } 7900 7901 if(!this.city_id && this.search_type==1){ 7902 const location = getLocation(); 7903 if (location.city_id && location.area_id) { 7904 this.city_id = location.city_id; 7905 this.area_id = location.area_id; 7906 } 7907 } else if ( !this.state_id && this.search_type==2 ) { 7908 const location = getLocation(); 7909 if (location.state_id && location.city_id) { 7910 this.city_id = location.city_id; 7911 this.state_id = location.state_id; 7912 } 7913 } 7914 }, 7915 mounted() { 7916 this.getLocationCurrentAddress(); 7917 }, 7918 computed: { 7919 hasLocation(){ 7920 if (Object.keys(this.data).length > 0) { 7921 return true; 7922 } 7923 return false; 7924 }, 7925 }, 7926 methods: { 7927 getLocationCurrentAddress(){ 7928 this.loading = true; 7929 7930 if(!this.city_id && this.search_type==1 ){ 7931 const location = getLocation(); 7932 if (location.city_id && location.area_id) { 7933 this.city_id = location.city_id; 7934 this.area_id = location.area_id; 7935 } 7936 } else if ( !this.state_id && this.search_type==2 ) { 7937 const location = getLocation(); 7938 if (location.state_id && location.city_id) { 7939 this.city_id = location.city_id; 7940 this.state_id = location.state_id; 7941 } 7942 } else if ( !this.state_id && this.search_type==3 ) { 7943 const location = getLocation(); 7944 if (location.postal_id) { 7945 this.postal_id = location.postal_id; 7946 } 7947 } else {
7948 const urlParams = new URLSearchParams(window.location.search); 7949 if(urlParams.size>0){ 7950 if(this.search_type==1){ 7951 this.city_id = urlParams.get('city_id'); 7952 this.area_id = urlParams.get('area_id'); 7953 } else if ( this.search_type==2 ){ 7954 this.city_id = urlParams.get('city_id'); 7955 this.state_id = urlParams.get('state_id'); 7956 } else if ( this.search_type==3 ){ 7957 this.postal_id = urlParams.get('postal_id'); 7958 } 7959 } 7960 } 7961 7962 let params='city_id='+this.city_id; 7963 params+="&area_id="+ this.area_id; 7964 params+="&state_id="+ this.state_id; 7965 params+="&postal_id="+ this.postal_id; 7966 7967 let transactionType = getFromLocalStorageStore(StoreName,'SelectedtransactionType'); 7968 if(transactionType){ 7969 params+="&transaction_type="+ transactionType; 7970 } 7971 if ((typeof merchant_id !== "undefined") && ( merchant_id !== null)) { 7972 params+="&merchant_id="+merchant_id; 7973 } 7974 axios.get(api_location+"/getLocationCurrentAddress?"+params).then(response => { 7975 if(response.data.code==1){ 7976 this.data = response.data.details.data; 7977 } else { 7978 this.data = []; 7979 } 7980 7981 if(!response.data.details.transaction_type_valid){ 7982 let transaction_type = response.data.details.transaction_type; 7983 setCookie('cart_transaction_type', transaction_type ,30); 7984 //setStorage("SelectedtransactionType",transaction_type); 7985 setInLocalStorageStore(StoreName,'SelectedtransactionType',transaction_type); 7986 } 7987 7988 setTimeout(() => { 7989 if(window.vm_location_feed){ 7990 window.vm_location_feed.location_required = response.data.details.address_needed; 7991 } 7992 }, 500); 7993 }) 7994 .catch(error => { 7995 console.error('Error:', error); 7996 }).then(data => { 7997 this.loading = false; 7998 }); 7999 }, 8000 showSelectLocation(){ 8001 window.vm_location_feed.showCurrentaddress(); 8002 }, 8003 // 8004 }, 8005}; 8006 8007/* 8008 WIDGET TOP NAV 8009*/ 8010const app_widget_nav = Vue.createApp({ 8011 data() { 8012 return { 8013 data : [], 8014 addresses : [], 8015 deliveryAddress : [], 8016 location_data : [] 8017 } 8018 }, 8019 components: { 8020 'component-services' : ComponentsServices, 8021 'component-transaction-info' : ComponentsTransactionInfo, 8022 'component-delivery-details' : ComponentsDeliveryDetails, 8023 'component-change-address': changeAddressComponent, 8024 'component-trans-options' : ComponenstTransactionOptions, 8025 //'component-address': ComponentsAddress, 8026 'components-select-address': ComponentsSelectAddress, 8027 'components-address-form' : ComponentsAddressForm, 8028 'components-location-current-address' : ComponentsLocationCurrentAddress, 8029 }, 8030 mounted () { 8031 8032 }, 8033 methods: { 8034 setTransaction(transaction_type){ 8035 this.transaction_type = transaction_type; 8036 }, 8037 reloadFeed(transaction_type){ 8038 vm_feed.transaction_type = transaction_type; 8039 vm_feed.Search(false); 8040 }, 8041 setTransactionInfo(data){ 8042 this.data = data; 8043 this.$refs.transaction.show(this.data); 8044 }, 8045 showAddress(){ 8046 this.$refs.transaction.close(); 8047 this.$refs.address.showModal(); 8048 this.getClientAddresses(); 8049 }, 8050 afterChangeAddress(data){ 8051 if(isGuest==='1'){ 8052 this.deliveryAddress = data; 8053 this.$refs.transaction.close(); 8054 //this.$refs.address_modal.show(true); 8055 this.$refs.address_modal.visible = true; 8056 } else { 8057 this.$refs.transaction.close(); 8058 this.location_data = data; 8059 } 8060 }, 8061 onSavelocation(data,addressData){ 8062 dump('onSavelocation 1',data); 8063 setInLocalStorageStore(StoreMapName,"selectedAddress",data); 8064 this.$refs.address_form.setLoading(true); 8065 let params = { 8066 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 8067 'cart_uuid':getCookie('cart_uuid'), 8068 'data': data, 8069 'location_name' : addressData.location_name, 8070 'delivery_instructions' : addressData.delivery_instructions, 8071 'delivery_options' : addressData.delivery_options, 8072 'address_label' : addressData.address_label, 8073 'formatted_address' : addressData.formatted_address, 8074 'address1' : addressData.address1, 8075 'address2' : addressData.address2, 8076 'postal_code' : addressData.postal_code, 8077 'company' : addressData.company, 8078 }; 8079 axios({ 8080 method: 'PUT', 8081 url: ajaxurl+"/checkoutSaveAddress" , 8082 data : params, 8083 timeout: $timeout, 8084 }).then( response => { 8085 if(response.data.code==1){ 8086 this.refreshWidget(); 8087 this.$refs.address_form.close(); 8088 } else { 8089 ElementPlus.ElNotification({ 8090 title: "", 8091 message: response.data.msg, 8092 position: 'bottom-right', 8093 type: 'warning', 8094 }); 8095 } 8096 }).catch(error => { 8097 ElementPlus.ElNotification({ 8098 title: "", 8099 message: error, 8100 position: 'bottom-right', 8101 type: 'warning', 8102 }); 8103 }).then(data => { 8104 this.$refs.address_form.setLoading(false); 8105 }); 8106 }, 8107afterPointaddress(data){ 8108 this.$refs.address_modal.setLoading(true); 8109 // Include user's long-form description for storage 8110 if(data.userSelectedDescription){ 8111 setInLocalStorageStore(StoreMapName,"userSelectedDescription", data.userSelectedDescription); 8112 } 8113 setInLocalStorageStore(StoreMapName,"selectedAddress",data); 8114 8115 // Build request params including the user's selected description 8116 let requestData = 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&place_id="+ data.place_id; 8117 if(data.userSelectedDescription){ 8118 requestData += "&user_description=" + encodeURIComponent(data.userSelectedDescription); 8119 } 8120 8121 axios({ 8122 method: 'POST', 8123 url: ajaxurl+"/setPlaceID" , 8124 data : requestData, 8125 timeout: $timeout, 8126 }).then( response => { 8127 this.refreshWidget(); 8128 //this.$refs.address_modal.show(false); 8129 this.$refs.address_modal.visible = false;
8130 }).catch(error => { 8131 ElementPlus.ElNotification({ 8132 title: "", 8133 message: error, 8134 position: 'bottom-right', 8135 type: 'warning', 8136 }); 8137 }).then(data => { 8138 this.$refs.address_modal.setLoading(false); 8139 }); 8140 }, 8141 refreshWidget(data){ 8142 if ((typeof vm_feed !== "undefined") && ( vm_feed !== null)) { 8143 vm_feed.Search(false); 8144 vm_feed.$refs.ref_banner.getBanner(); 8145 } 8146 if ((typeof vue_cart !== "undefined") && ( vue_cart !== null)) { 8147 vue_cart.loadcart(); 8148 } 8149 this.$refs.transaction_info.TransactionInfo(); 8150 this.$refs.transaction.close(); 8151 8152 if ((typeof vm_merchant_details !== "undefined") && ( vm_merchant_details !== null)) { 8153 vm_merchant_details.$refs.ref_services.getMerchantServices(); 8154 } 8155 }, 8156 afterSetAddress(){ 8157 dump('afterSetAddress'); 8158 this.$refs.address.close(); 8159 this.refreshWidget(); 8160 }, 8161 afterCloseAddress(){ 8162 this.$refs.transaction.show(this.data); 8163 }, 8164 ShowTransOptions(){ 8165 this.$refs.transaction.close(); 8166 this.$refs.transaction_options.show(); 8167 }, 8168 afterSaveTransOptions(data){ 8169 this.$refs.transaction_options.close(); 8170 8171 if ((typeof vm_feed !== "undefined") && ( vm_feed !== null)) { 8172 dump("afterSaveTransOptions"); 8173 dump(data.delivery_time); 8174 vm_feed.whento_deliver = data.whento_deliver; 8175 vm_feed.delivery_date = data.delivery_date; 8176 vm_feed.delivery_time = data.delivery_time.start_time; 8177 vm_feed.Search(false); 8178 } 8179 8180 if ((typeof vue_cart !== "undefined") && ( vue_cart !== null)) { 8181 vue_cart.loadcart(); 8182 } 8183 8184 this.$refs.transaction_info.whento_deliver = data.whento_deliver; 8185 this.$refs.transaction_info.delivery_datetime = data.delivery_datetime; 8186 8187 this.$refs.transaction.close(); 8188 }, 8189 editAddress(data){ 8190 dump("editAddress=>"); 8191 dump(data); 8192 this.$refs.address.close(); 8193 this.location_data = data; 8194 }, 8195 afterCloseAddForm(){ 8196 this.$refs.address.showModal(); 8197 }, 8198 afterSaveAddForm(){ 8199 if ((typeof vm_feed !== "undefined") && ( vm_feed !== null)) { 8200 vm_feed.Search(false); 8201 } 8202 if ((typeof vue_cart !== "undefined") && ( vue_cart !== null)) { 8203 vue_cart.loadcart(); 8204 } 8205 this.$refs.transaction_info.TransactionInfo(); 8206 }, 8207 afterDeleteAddress(){ 8208 this.getClientAddresses(); 8209 }, 8210 afterDeleteAddForm(){ 8211 8212 }, 8213 getClientAddresses(){ 8214 axios({ 8215 method: 'POST', 8216 url: ajaxurl +"/getAddresses" , 8217 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content'), 8218 timeout: $timeout, 8219 }).then( response => { 8220 if(response.data.code==1){ 8221 this.addresses = response.data.details.data; 8222 } else { 8223 this.addresses = []; 8224 } 8225 }).catch(error => { 8226 // 8227 }).then(data => { 8228 8229 }); 8230 }, 8231 }, 8232}); 8233app_widget_nav.use(ElementPlus); 8234//const vm_widget_nav = app_widget_nav.mount('#vue-widget-nav'); 8235window.vm_widget_nav = app_widget_nav.mount('#vue-widget-nav'); 8236 8237 8238const appWidgetNavMobile = Vue.createApp({ 8239 components : { 8240 'components-location-current-address' : ComponentsLocationCurrentAddress, 8241 }, 8242}); 8243appWidgetNavMobile.use(ElementPlus); 8244window.VmWidgetNavMobile = appWidgetNavMobile.mount('#location-widget-subnav-mobile'); 8245 8246const app_widget_nav_mobile = Vue.createApp({ 8247 data() { 8248 return { 8249 data : [], 8250 addresses : [], 8251 transaction_type : '', 8252 transaction_list : [], 8253 deliveryAddress : [], 8254 location_data : [] 8255 } 8256 }, 8257 components: { 8258 'component-services' : ComponentsServices, 8259 'component-transaction-info' : ComponentsTransactionInfo, 8260 'component-delivery-details' : ComponentsDeliveryDetails, 8261 'component-change-address': changeAddressComponent, 8262 'component-trans-options' : ComponenstTransactionOptions, 8263 'component-address': ComponentsAddress, 8264 'component-mobile-search-suggestion' : ComponentsMobileSearchSuggestion , 8265 'components-select-address': ComponentsSelectAddress, 8266 'components-address-form' : ComponentsAddressForm, 8267 }, 8268 mounted () { 8269 8270 }, 8271 methods: { 8272 setTransaction(transaction_type,transaction_list){ 8273 this.transaction_type = transaction_type; 8274 this.transaction_list = transaction_list; 8275 }, 8276 reloadFeed(transaction_type){ s 8277 this.transaction_type = transaction_type; 8278 vm_feed.transaction_type = transaction_type; 8279 vm_feed.Search(false); 8280 }, 8281 setTransactionInfo(data){ 8282 this.data = data; 8283 this.$refs.transaction.show(this.data); 8284 }, 8285 showAddress(){ 8286 this.$refs.transaction.close(); 8287 this.$refs.address.showModal(); 8288 this.getClientAddresses(); 8289 }, 8290 afterChangeAddress(data){ 8291 if(isGuest==='1'){ 8292 this.deliveryAddress = data; 8293 //this.$refs.address_modal.show(true); 8294 this.$refs.address_modal.visible = true; 8295 } else { 8296 this.$refs.transaction.close(); 8297 this.location_data = data; 8298 } 8299 }, 8300afterPointaddress(data){ 8301 this.$refs.address_modal.setLoading(true); 8302 // Include user's long-form description for storage 8303 if(data.userSelectedDescription){ 8304 setInLocalStorageStore(StoreMapName,"userSelectedDescription", data.userSelectedDescription); 8305 } 8306 setInLocalStorageStore(StoreMapName,"selectedAddress",data); 8307 8308 // Build request params including the user's selected description 8309 let requestData = 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&place_id="+ data.place_id; 8310 if(data.userSelectedDescription){ 8311 requestData += "&user_description=" + encodeURIComponent(data.userSelectedDescription); 8312 } 8313 8314 axios({ 8315 method: 'POST', 8316 url: ajaxurl+"/setPlaceID" , 8317 data : requestData, 8318 timeout: $timeout, 8319 }).then( response => { 8320 this.afterSetAddress(); 8321 //this.$refs.address_modal.show(false); 8322 this.$refs.address_modal.visible = false;
8323 }).catch(error => { 8324 ElementPlus.ElNotification({ 8325 title: "", 8326 message: error, 8327 position: 'bottom-right', 8328 type: 'warning', 8329 }); 8330 }).then(data => { 8331 this.$refs.address_modal.setLoading(false); 8332 }); 8333 }, 8334 afterSetAddress(){ 8335 if ((typeof vm_feed !== "undefined") && ( vm_feed !== null)) { 8336 vm_feed.Search(false); 8337 } 8338 if ((typeof vue_cart !== "undefined") && ( vue_cart !== null)) { 8339 vue_cart.loadcart(); 8340 } 8341 this.$refs.transaction_info.TransactionInfo(); 8342 this.$refs.address.close(); 8343 this.$refs.transaction.close(); 8344 8345 if ((typeof vm_merchant_details !== "undefined") && ( vm_merchant_details !== null)) { 8346 vm_merchant_details.$refs.ref_services.getMerchantServices(); 8347 } 8348 }, 8349 afterCloseAddress(){ 8350 this.$refs.transaction.show(this.data); 8351 }, 8352 ShowTransOptions(){ 8353 this.$refs.transaction.close(); 8354 this.$refs.transaction_options.show(); 8355 }, 8356 afterSaveTransOptions(data){ 8357 this.$refs.transaction_options.close(); 8358 8359 if ((typeof vm_feed !== "undefined") && ( vm_feed !== null)) { 8360 dump("afterSaveTransOptions"); 8361 dump(data.delivery_time); 8362 vm_feed.whento_deliver = data.whento_deliver; 8363 vm_feed.delivery_date = data.delivery_date; 8364 vm_feed.delivery_time = data.delivery_time.start_time; 8365 vm_feed.Search(false); 8366 } 8367 8368 if ((typeof vue_cart !== "undefined") && ( vue_cart !== null)) { 8369 vue_cart.loadcart(); 8370 } 8371 8372 this.$refs.transaction_info.whento_deliver = data.whento_deliver; 8373 this.$refs.transaction_info.delivery_datetime = data.delivery_datetime; 8374 8375 this.$refs.transaction.close(); 8376 }, 8377 editAddress(data){ 8378 this.$refs.address.close(); 8379 this.$refs.addressform.show( data.address_uuid ); 8380 }, 8381 afterCloseAddForm(){ 8382 this.$refs.address.showModal(); 8383 }, 8384 afterSaveAddForm(){ 8385 if ((typeof vm_feed !== "undefined") && ( vm_feed !== null)) { 8386 vm_feed.Search(false); 8387 } 8388 if ((typeof vue_cart !== "undefined") && ( vue_cart !== null)) { 8389 vue_cart.loadcart(); 8390 } 8391 this.$refs.transaction_info.TransactionInfo(); 8392 }, 8393 afterDeleteAddress(){ 8394 this.getClientAddresses(); 8395 }, 8396 afterDeleteAddForm(){ 8397 8398 }, 8399 getClientAddresses(){ 8400 8401 var timenow = getTimeNow(); 8402 var $params = { 8403 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 8404 }; 8405 8406 $params = JSON.stringify($params); 8407 8408 ajax_request[timenow] = $.ajax({ 8409 url: ajaxurl+"/getAddresses", 8410 method: "PUT", 8411 dataType: "json", 8412 data: $params , 8413 contentType : $content_type.json , 8414 timeout: $timeout, 8415 crossDomain: true, 8416 beforeSend: function( xhr ) { 8417 if(ajax_request[timenow] != null) { 8418 ajax_request[timenow].abort(); 8419 } 8420 } 8421 }); 8422 8423 ajax_request[timenow].done( data => { 8424 if ( data.code==1){ 8425 this.addresses = data.details.data; 8426 } else { 8427 this.addresses = []; 8428 } 8429 }); 8430 8431 }, 8432 showSearchSuggestion(){ 8433 this.$refs.search_suggestion.show(); 8434 }, 8435 onSavelocation(data,addressData){ 8436 dump('onSavelocation here'); 8437 this.$refs.address_form.setLoading(true); 8438 let params = { 8439 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 8440 'cart_uuid':getCookie('cart_uuid'), 8441 'data': data, 8442 'location_name' : addressData.location_name, 8443 'delivery_instructions' : addressData.delivery_instructions, 8444 'delivery_options' : addressData.delivery_options, 8445 'address_label' : addressData.address_label, 8446 'formatted_address' : addressData.formatted_address, 8447 'address1' : addressData.address1, 8448 }; 8449 axios({ 8450 method: 'PUT', 8451 url: ajaxurl+"/checkoutSaveAddress" , 8452 data : params, 8453 timeout: $timeout, 8454 }).then( response => { 8455 if(response.data.code==1){ 8456 this.afterSetAddress(); 8457 this.$refs.address_form.close(); 8458 } else { 8459 ElementPlus.ElNotification({ 8460 title: "", 8461 message: response.data.msg, 8462 position: 'bottom-right', 8463 type: 'warning', 8464 }); 8465 } 8466 }).catch(error => { 8467 ElementPlus.ElNotification({ 8468 title: "", 8469 message: error, 8470 position: 'bottom-right', 8471 type: 'warning', 8472 }); 8473 }).then(data => { 8474 this.$refs.address_form.setLoading(false); 8475 }); 8476 }, 8477 editAddress(data){ 8478 this.$refs.address.close(); 8479 this.location_data = data; 8480 }, 8481 }, 8482}); 8483app_widget_nav_mobile.use(ElementPlus); 8484const vm_widget_nav_mobile = app_widget_nav_mobile.mount('#vue-widget-nav-mobile'); 8485 8486 8487const ComponentsPromoDetails = { 8488 props: ['merchant_id','label'], 8489 data() { 8490 return { 8491 loading : false, 8492 data :[], 8493 modal : false, 8494 } 8495 }, 8496 mounted() { 8497 this.getPromoDetails(); 8498 }, 8499 computed: { 8500 getData(){ 8501 return this.data; 8502 }, 8503 hasData(){ 8504 if (Object.keys(this.data).length > 0) { 8505 return true; 8506 } 8507 return false;
8508 }, 8509 }, 8510 methods: { 8511 getPromoDetails(){ 8512 this.loading = true; 8513 8514 let $params; 8515 let currency_code = getCookie('currency_code'); 8516 currency_code = !empty(currency_code)?currency_code:''; 8517 8518 $params="merchant_id=" + this.merchant_id; 8519 $params+="¤cy_code=" + currency_code; 8520 $params+=addValidationRequest(); 8521 8522 axios({ 8523 method: 'POST', 8524 url: ajaxurl+"/getPromoDetails" , 8525 data : $params, 8526 timeout: $timeout, 8527 }).then( response => { 8528 if(response.data.code==1){ 8529 this.data = response.data.details; 8530 } 8531 }).catch(error => { 8532 // 8533 }).then(data => { 8534 this.loading = false; 8535 }); 8536 }, 8537 }, 8538 template :` 8539 <el-skeleton :rows="1" animated :loading="loading" ></el-skeleton> 8540 <div v-if="hasData" class="d-flex align-self-center"> 8541 <div class="mr-1"><i style="transform: rotate(90deg);" class="fas fa-tag"></i></div> 8542 <p class="mr-1">{{label.enjoy}}</p> 8543 <p class="mr-1"> 8544 <a href="javascript:;" class="text-green" @click="modal=true"> 8545 {{label.see_details}} 8546 </a> 8547 </p> 8548 </div> 8549 8550 <el-dialog 8551 v-model="modal" 8552 :title="label.title" 8553 width="40%" 8554 > 8555 <template v-for="items in getData" :key="items" > 8556 <div class="d-flex align-items-center mb-2"> 8557 <div class="with-promo-icon"></div> 8558 <div class="text-truncatex">{{ items.discount_name }}</div> 8559 </div> 8560 </template> 8561 8562 </el-dialog> 8563 ` 8564}; 8565 8566 8567 8568const ComponentsLocationEstimation = { 8569 template: '#xtemplate_location_estimation', 8570 data() { 8571 return { 8572 data : [], 8573 loading : false, 8574 merchant_id : null, 8575 search_type : null, 8576 transaction_type : null 8577 } 8578 }, 8579 created() { 8580 if ((typeof merchant_id !== "undefined") && ( merchant_id !== null)) { 8581 this.merchant_id = merchant_id; 8582 } 8583 if ((typeof location_searchtype !== "undefined") && ( location_searchtype !== null)) { 8584 this.search_type = location_searchtype; 8585 } 8586 }, 8587 mounted() { 8588 this.getLocationEstimation(); 8589 }, 8590 methods: { 8591 getLocationEstimation(){ 8592 this.loading = true; 8593 let params = "search_type="+this.search_type; 8594 const location = getLocation(); 8595 params+="&cart_uuid=" + getCookie('cart_uuid'); 8596 params+= "&city_id="+location.city_id; 8597 params+= "&area_id="+location.area_id; 8598 params+= "&state_id="+location.state_id; 8599 params+= "&postal_id="+location.postal_id; 8600 8601 params+= "&merchant_id="+this.merchant_id; 8602 axios.get(api_location+"/getLocationEstimation?" + params ).then(response => { 8603 if(response.data.code==1){ 8604 this.data = response.data.details.data; 8605 this.transaction_type = response.data.details.transaction_type; 8606 } else { 8607 this.data = []; 8608 this.transaction_type = null; 8609 } 8610 }) 8611 .catch(error => { 8612 console.error('Error:', error); 8613 }).then(data => { 8614 this.loading = false; 8615 }); 8616 }, 8617 setTransactionType(value){ 8618 if(value!=this.transaction_type){ 8619 axios({ 8620 method: 'POST', 8621 url: ajaxurl+"/updateService" , 8622 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') +"&transaction_type="+ value + "&cart_uuid=" + getCookie('cart_uuid'), 8623 timeout: $timeout, 8624 }).then( response => { 8625 if(response.data.code==1){ 8626 this.transaction_type = value; 8627 setCookie('cart_transaction_type', this.transaction_type ,30); 8628 setCookie('cart_uuid', response.data.details.cart_uuid ,30); 8629 8630 setInLocalStorageStore(StoreName,"SelectedtransactionType",this.transaction_type); 8631 8632 if ((typeof vue_cart !== "undefined") && ( vue_cart !== null)) { 8633 vue_cart.loadcart(); 8634 } 8635 if ((typeof vm_widget_nav !== "undefined") && ( vm_widget_nav !== null)) { 8636 vm_widget_nav.$refs.ref_location_current_address.getLocationCurrentAddress(); 8637 } 8638 8639 if ((typeof window.vm_location_feed !== "undefined") && ( window.vm_location_feed !== null)) { 8640 window.vm_location_feed.$refs.ref_check_location.checkLocations(); 8641 } 8642 8643 } 8644 }).catch(error => { 8645 // 8646 }).then(data => { 8647 8648 }); 8649 8650 } 8651 }, 8652 }, 8653}; 8654 8655/* 8656MENU MERCHANT DETAILS 8657*/ 8658const app_merchant_details = Vue.createApp({ 8659 components: { 8660 'component-save-store' : ComponentsSaveStore, 8661 'component-merchant-services' : ComponentsMerchantServices,
8662 'component-promo-details' : ComponentsPromoDetails, 8663 'components-location-estimation': ComponentsLocationEstimation 8664 }, 8665 data(){ 8666 return { 8667 found : false, 8668 is_loading : false, 8669 image_background : '' 8670 }; 8671 }, 8672 mounted () { 8673 this.getSaveStore(); 8674 }, 8675 methods :{ 8676 afterUpdateServices(data){ 8677 if ((typeof vue_cart !== "undefined") && ( vue_cart !== null)) { 8678 vue_cart.loadcart(); 8679 } 8680 }, 8681 getSaveStore(){ 8682 8683 var $params = { 8684 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 8685 'merchant_id': merchant_id, 8686 }; 8687 var timenow = getTimeNow(); 8688 $params = JSON.stringify($params); 8689 8690 ajax_request[timenow] = $.ajax({ 8691 url: ajaxurl+"/getSaveStore", 8692 method: "PUT", 8693 dataType: "json", 8694 data: $params , 8695 contentType : $content_type.json , 8696 timeout: $timeout, 8697 crossDomain: true, 8698 beforeSend: data => { 8699 this.is_loading = true; 8700 if(ajax_request[timenow] != null) { 8701 ajax_request[timenow].abort(); 8702 } 8703 } 8704 }); 8705 8706 ajax_request[timenow].done( data => { 8707 if ( data.code==1){ 8708 this.found = true; 8709 } else { 8710 this.found = false; 8711 } 8712 }); 8713 8714 ajax_request[timenow].always( data => { 8715 this.is_loading = false; 8716 }); 8717 8718 }, 8719 }, 8720}); 8721app_merchant_details.use(ElementPlus); 8722//const vm_merchant_details = app_merchant_details.mount('#vue-merchant-details'); 8723window.vm_merchant_details = app_merchant_details.mount('#vue-merchant-details'); 8724 8725 8726/* 8727 CATEGORY CAROUSEL 8728*/ 8729const componentsCategoryCarousel = { 8730 props : ['data','restaurant_name'], 8731 data(){ 8732 return { 8733 owl : undefined, 8734 drawer : false 8735 }; 8736 }, 8737 watch: { 8738 data(new_data,old_data){ 8739 setTimeout(() => { 8740 this.renderCarousel(); 8741 }, 1); 8742 } 8743 }, 8744 mounted () { 8745 setTimeout(() => { 8746 $(window).on('activate.bs.scrollspy', (e,obj)=>{ 8747 var myElement = $("a[href='"+ obj.relatedTarget +"']"); 8748 var index = parseInt(myElement[1].dataset.id); 8749 this.SlideTo( index ); 8750 }) 8751 }, 500); 8752 }, 8753 methods: { 8754 renderCarousel(){ 8755 let $is_rtl = false; 8756 if ((typeof is_rtl !== "undefined") && ( is_rtl !== null)) { 8757 $is_rtl = is_rtl=='1'?true:false; 8758 } 8759 this.owl = $(this.$refs.category_carousel).owlCarousel({ 8760 loop:false, 8761 dots:false, 8762 nav:false, 8763 autoWidth:true, 8764 rtl : $is_rtl 8765 }); 8766 }, 8767 nextSlide(){ 8768 this.owl.trigger('next.owl.carousel'); 8769 }, 8770 prevSlide(){ 8771 this.owl.trigger('prev.owl.carousel'); 8772 }, 8773 SlideTo(index){ 8774 this.owl.trigger('to.owl.carousel', [index, 500, true]); 8775 }, 8776 }, 8777 template : ` 8778 <el-affix target=".section-menu" :offset="0" z-index="9" > 8779 <div class="row no-gutters align-items-center category-carousel border-bottom"> 8780 <div class="col-1 text-left"> 8781 <a @click="drawer=true" class="btn font-weight-bold"><i class="zmdi zmdi-menu"></i></a> 8782 </div> 8783 <div class="col-1 text-left"> 8784 <a @click="prevSlide" class="btn font-weight-bold"><i class="zmdi zmdi-chevron-left"></i></a> 8785 </div> 8786 <div class="col-9"> 8787 <div ref="category_carousel" id="menu-category" class="owl-carousel owl-theme"> 8788 <template v-for="(item, index) in data" > 8789 <a :href="'#'+item.category_uiid" :data-id="index" :class="{active : index==0}" class="nav-link d-flex align-items-center font-weight-bolder mr-3"> 8790 <p class="m-0">{{item.category_name}}</p> 8791 </a> 8792 </template> 8793 </div> 8794 </div> 8795 <div class="col-1 text-right"> 8796 <a @click="nextSlide" class="btn font-weight-bold"><i class="zmdi zmdi-chevron-right"></i></a> 8797 </div> 8798 </div> 8799 </el-affix> 8800 8801 <el-drawer 8802 v-model="drawer" 8803 direction="btt" 8804 size="65%" 8805 append-to-body="true" 8806 :title="restaurant_name" 8807 :with-header="true" 8808 custom-class="drawer-category" 8809 > 8810 <div class="list-group list-group-modified"> 8811 <a @click="drawer=false" v-for="(item, index) in data" :href="'#'+item.category_uiid" class="list-group-item d-flex justify-content-between"> 8812 <div class="">{{item.category_name}}</div> 8813 <div class=""> 8814 <div class="bg-light btn-circle rounded-pill">{{item.items.length}}</div> 8815 </div> 8816 </a> 8817 </div> 8818 </el-drawer> 8819 ` 8820}; 8821 8822const componentsSearchMenu = { 8823 data() { 8824 return { 8825 awaitingSearch : false, 8826 q :'', 8827 some_words : [], 8828 } 8829 }, 8830 created() { 8831 this.some_words = JSON.parse(some_words); 8832 }, 8833 computed: { 8834 hasSearch(){ 8835 if(this.q){ 8836 return true; 8837 } 8838 return false;
8839 } 8840 }, 8841 watch: { 8842 q(newsearch,oldsearch){ 8843 if (!this.awaitingSearch) { 8844 if(empty(newsearch)){ 8845 return false; 8846 } 8847 8848 let currency_code = getCookie('currency_code'); 8849 currency_code = !empty(currency_code)?currency_code:''; 8850 8851 setTimeout(() => { 8852 axios({ 8853 method: 'POST', 8854 url: ajaxurl+"/searchmenu" , 8855 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&q=" + this.q + "&merchant_id="+ merchant_id + "¤cy_code="+currency_code, 8856 timeout: $timeout, 8857 }).then( response => { 8858 if(response.data.code==1){ 8859 this.$emit("afterSearch",this.q,response.data.details.data); 8860 } else { 8861 this.$emit("afterSearch",this.q,[]); 8862 } 8863 }).catch(error => { 8864 // 8865 }).then(data => { 8866 this.awaitingSearch = false; 8867 }); 8868 }, 1000); // 1 sec delay 8869 8870 this.awaitingSearch = true; 8871 } 8872 }, 8873 }, 8874 methods: { 8875 clearSearch(){ 8876 this.q = ''; 8877 this.$emit("clearSearch"); 8878 }, 8879 }, 8880 template : ` 8881 <el-input 8882 v-model="q" 8883 class="w-100" 8884 size="large" 8885 :placeholder="some_words.search_in_menu" 8886 > 8887 <template #prefix> 8888 <i class="zmdi zmdi-search" class="font20"></i> 8889 </template> 8890 <template #suffix> 8891 <div v-if="awaitingSearch" class="loading"> 8892 <div class="circle-loader" data-loader="circle-side"></div> 8893 </div> 8894 <template v-else> 8895 <template v-if="hasSearch"> 8896 <el-link type="primary" @click="clearSearch" > 8897 {{some_words.clear}} 8898 </el-link> 8899 </template> 8900 </template> 8901 </template> 8902 </el-input> 8903 ` 8904}; 8905 8906const componentsTopCategory = { 8907 props : ['data'], 8908 components : { 8909 'component-search-menu' : componentsSearchMenu, 8910 }, 8911 data() { 8912 return { 8913 mySwiper : undefined, 8914 some_words : [] 8915 } 8916 }, 8917 mounted () { 8918 setTimeout(() => { 8919 $(window).on('activate.bs.scrollspy', (e,obj)=>{ 8920 let myElement = $("a[href='"+ obj.relatedTarget +"']"); 8921 let index = parseInt(myElement[1].dataset.id); 8922 this.SlideTo( index ); 8923 }) 8924 }, 500); 8925 this.some_words = JSON.parse(some_words); 8926 }, 8927 watch: { 8928 data(newval,oldval){ 8929 setTimeout(() => { 8930 this.renderCarousel(); 8931 }, 1); 8932 }, 8933 }, 8934 methods: { 8935 renderCarousel(){ 8936 let $is_rtl = false; 8937 if ((typeof is_rtl !== "undefined") && ( is_rtl !== null)) { 8938 $is_rtl = is_rtl=='1'?true:false; 8939 } 8940 this.owl = $(this.$refs.category_carousel).owlCarousel({ 8941 loop:false, 8942 dots:false, 8943 nav:false, 8944 autoWidth:true, 8945 rtl : $is_rtl 8946 }); 8947 }, 8948 SlideTo(index){ 8949 this.owl.trigger('to.owl.carousel', [index, 500, true]); 8950 }, 8951 afterSearch(q,data){ 8952 this.$emit('afterSearch',q,data); 8953 }, 8954 clearSearch(){ 8955 this.$emit('clearSearch'); 8956 }, 8957 }, 8958 template : ` 8959 <el-affix target=".section-menu" :offset="0" z-index="9" > 8960 <div class="bg-white p-1 mb-4 d-none d-lg-block category-owlcarousel"> 8961 <div class="row no-gutters"> 8962 <div class="col-3"> 8963 8964 <component-search-menu 8965 @after-search="afterSearch" 8966 @clear-search="clearSearch" 8967 > 8968 </component-search-menu> 8969 8970 </div> 8971 <div class="col-9"> 8972 <div ref="category_carousel" id="menu-category" class="owl-carousel owl-theme"> 8973 <template v-for="(item, index) in data" > 8974 <a :href="'#'+item.category_uiid" :data-id="index" :class="{active : index==0}" class="nav-link d-flex align-items-center mr-3"> 8975 <div class="m-0">{{item.category_name}}</div> 8976 </a> 8977 </template> 8978 </div> 8979 8980 </div> 8981 </div> 8982 </div> 8983 </el-affix> 8984 ` 8985}; 8986 8987const componentsMenuSearchResult = { 8988 template: '#xtemplate_menusearch', 8989 props: ['q','data' , 'promo'], 8990 computed: { 8991 hasSearch(){ 8992 if(!empty(this.q)){ 8993 return true; 8994 } 8995 return false; 8996 }, 8997 getData(){ 8998 if (Object.keys(this.data).length > 0) { 8999 return this.data; 9000 } 9001 return false; 9002 }, 9003 hasResults(){ 9004 if (Object.keys(this.data).length > 0) { 9005 return true; 9006 } 9007 return false; 9008 }, 9009 }, 9010 methods: { 9011 viewItem(data){ 9012 if ((typeof vm !== "undefined") && ( vm !== null)) { 9013 vm.viewItemBefore(data); 9014 } 9015 }, 9016 getPromoMessage(item) { 9017 return this.promo[item.item_id]?.message || item?.promo_data?.message; 9018 }, 9019 isEligible(item) { 9020 return this.promo[item.item_id]?.is_eligible; 9021 }, 9022 isEligibleItem(item) { 9023 if(!item.is_promo_free_item){ 9024 return true; 9025 } 9026 return this.promo[item.item_id]?.is_eligible || false; 9027 }, 9028 }, 9029}; 9030 9031const componentsSearchMenuMobile = { 9032 components : { 9033 'component-search-menu' : componentsSearchMenu, 9034 }, 9035 methods: { 9036 afterSearch(q,data){ 9037 this.$emit('afterSearch',q,data); 9038 }, 9039 clearSearch(){ 9040 this.$emit('clearSearch'); 9041 }, 9042 }, 9043 template : ` 9044 <div class="pt-2"> 9045 <component-search-menu 9046 @after-search="afterSearch" 9047 @clear-search="clearSearch" 9048 > 9049 </component-search-menu> 9050 </div> 9051 ` 9052}; 9053 9054const ComponentsAgeVerifications = { 9055 props : ['label','enabled','merchant_id'], 9056 data() { 9057 return { 9058 modal : false 9059 } 9060 }, 9061 mounted() { 9062 const ageVerifications = getFromLocalStorageStore(StoreMapName,"ageVerifications"+this.merchant_id); 9063 if(this.enabled && !ageVerifications){ 9064 this.modal = true; 9065 } 9066 }, 9067 methods: { 9068 ConfirmAge(){ 9069 setInLocalStorageStore(StoreMapName,"ageVerifications"+this.merchant_id,this.merchant_id); 9070 this.modal = false;
9071 }, 9072 Cancel(){ 9073 window.location.href = this.label.home_url; 9074 } 9075 }, 9076 template: '#xtemplate_age_verifications', 9077}; 9078 9079/** 9080 CATEGORY VUE RENDER 9081 this is function for displaying category 9082 target = vue-merchant-category 9083*/ 9084const app_merchant_category = Vue.createApp({ 9085 components : { 9086 'components-category-carousel' : componentsCategoryCarousel, 9087 'component-topcategory' : componentsTopCategory, 9088 'component-menu-search-result' : componentsMenuSearchResult, 9089 'components-search-menu-mobile' : componentsSearchMenuMobile, 9090 'components-age-verification' : ComponentsAgeVerifications 9091 }, 9092 data(){ 9093 return { 9094 category_loading : true, 9095 category_data : [], 9096 q : '', 9097 search_menu_data : [] 9098 }; 9099 }, 9100 mounted () { 9101 this.getCategory(); 9102 }, 9103 methods: { 9104 getCategory(){ 9105 this.category_loading = true; 9106 let params = "merchant_id=" + merchant_id; 9107 params+=addValidationRequest(); 9108 axios({ 9109 method: 'POST', 9110 url: ajaxurl+"/getCategory" , 9111 data : params, 9112 }).then( response => { 9113 if(response.data.code==1){ 9114 this.category_data = response.data.details.data.category; 9115 } else { 9116 this.category_data = []; 9117 } 9118 }).catch(error => { 9119 // 9120 }).then(data => { 9121 this.category_loading = false; 9122 }); 9123 }, 9124 afterSearch(q,data){ 9125 this.q = q; 9126 this.search_menu_data = data; 9127 this.scrollToResults(); 9128 }, 9129 clearSearch(){ 9130 this.q = ''; 9131 this.search_menu_data = []; 9132 }, 9133 scrollToResults() { 9134 this.$refs["search_result"].scrollIntoView({ behavior: "smooth" }) 9135 }, 9136 }, 9137}); 9138app_merchant_category.use(ElementPlus); 9139const vm_merchant_category = app_merchant_category.mount('#vue-merchant-category'); 9140 9141 9142/** 9143 TRANSACTION VUE RENDER 9144 this is function for displaying merchant transaction list 9145 target = vue-transaction-list 9146*/ 9147const vm_services = Vue.createApp({ 9148 9149 data(){ 9150 return { 9151 transaction_list :[], 9152 transaction : '' 9153 }; 9154 }, 9155 mounted () { 9156 this.getTransactionList() 9157 }, 9158 updated () { 9159 dump( "=>"+this.transaction ); 9160 this.updateService(); 9161 }, 9162 methods: { 9163 getTransactionList(){ 9164 9165 var $params; var timenow = getTimeNow(); 9166 $params="merchant_id=" + merchant_id; 9167 $params+="&cart_uuid=" + getCookie('cart_uuid'); 9168 $params+=addValidationRequest(); 9169 ajax_request[timenow] = $.ajax({ 9170 url: ajaxurl+"/servicesList", 9171 method: "POST", 9172 dataType: "json", 9173 data: $params, 9174 contentType : $content_type.form , 9175 timeout: $timeout, 9176 crossDomain: true, 9177 beforeSend: function( xhr ) { 9178 if(ajax_request[timenow] != null) { 9179 ajax_request[timenow].abort(); 9180 } 9181 } 9182 }); 9183 9184 ajax_request[timenow].done( data => { 9185 if ( data.code==1){ 9186 this.transaction_list = data.details.data; 9187 this.transaction = data.details.transaction; 9188 } else { 9189 this.transaction_list = []; 9190 this.transaction = ''; 9191 } 9192 }); // ajax done 9193 }, 9194 updateService(){ 9195 9196 if(!empty(vue_cart.cart_uuid)){ 9197 9198 var $params; var timenow = getTimeNow(); 9199 $params="cart_uuid=" + vue_cart.cart_uuid; 9200 $params+="&transaction_type=" + this.transaction; 9201 9202 $params+=addValidationRequest(); 9203 ajax_request[timenow] = $.ajax({ 9204 url: ajaxurl+"/updateService", 9205 method: "POST", 9206 dataType: "json", 9207 data: $params, 9208 contentType : $content_type.form , 9209 timeout: $timeout, 9210 crossDomain: true, 9211 beforeSend: function( xhr ) { 9212 if(ajax_request[timenow] != null) { 9213 ajax_request[timenow].abort(); 9214 } 9215 } 9216 }); 9217 9218 ajax_request[timenow].done( data => { 9219 vue_cart.loadcart(); 9220 }); // ajax done 9221 9222 } 9223 }, 9224 }, 9225}).mount('#vue-services-list'); 9226 9227 9228const componentsAllergens = { 9229 props : ['label','merchant_id'], 9230 data() { 9231 return { 9232 modal : false, 9233 loading : false, 9234 item_id : '', 9235 mode : 'list', 9236 notice_title : '', 9237 notice_message : '', 9238 notice_phone : '', 9239 notice_tel : '', 9240 allergen : [], 9241 allergen_data : [] 9242 } 9243 }, 9244 computed: { 9245 dialogTitle(){ 9246 if(this.mode=='notice' && !empty(this.notice_title)){ 9247 return this.notice_title; 9248 } 9249 return this.label.title; 9250 }, 9251 noticeMessageParts(){ 9252 let message = this.notice_message || ''; 9253 let phone = this.notice_phone || ''; 9254 if(!phone || message.indexOf(phone) === -1){ 9255 return [{ type:'text', text: message }]; 9256 } 9257 let parts = message.split(phone); 9258 let result = [];
9259 parts.forEach((part, index) => { 9260 if(part){ 9261 result.push({ type:'text', text: part }); 9262 } 9263 if(index < parts.length - 1){ 9264 result.push({ 9265 type:'phone', 9266 text: phone, 9267 href: this.notice_tel || phone 9268 }); 9269 } 9270 }); 9271 return result; 9272 } 9273 }, 9274 methods: { 9275 show(data){ 9276 this.modal = true; 9277 this.item_id = data; 9278 this.getAllergenInfo(); 9279 }, 9280 closeNotice(){ 9281 this.modal = false; 9282 }, 9283 getAllergenInfo(){ 9284 this.loading = true; 9285 axios({ 9286 method: 'POST', 9287 url: ajaxurl+"/getAllergenInfo" , 9288 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&item_id=" + this.item_id + "&merchant_id=" + this.merchant_id , 9289 timeout: $timeout, 9290 }).then( response => { 9291 if(response.data.code==1){ 9292 this.mode = response.data.details.mode || 'list'; 9293 this.allergen = response.data.details.allergen || []; 9294 this.allergen_data = response.data.details.allergen_data || []; 9295 let notice = response.data.details.allergen_notice || {}; 9296 this.notice_title = notice.title || ''; 9297 this.notice_message = notice.message || ''; 9298 this.notice_phone = notice.contact_phone || ''; 9299 this.notice_tel = notice.tel_href || notice.contact_phone || ''; 9300 } else { 9301 this.mode = 'list'; 9302 this.allergen = []; 9303 this.allergen_data = []; 9304 this.notice_title = ''; 9305 this.notice_message = ''; 9306 this.notice_phone = ''; 9307 this.notice_tel = ''; 9308 } 9309 }).catch(error => { 9310 // 9311 }).then(data => { 9312 this.loading = false; 9313 }); 9314 }, 9315 }, 9316 template : ` 9317 <el-dialog 9318 v-model="modal" 9319 :title="dialogTitle" 9320 width="40%" 9321 class="modal-allergens" 9322 > 9323 9324 <template v-if="loading" > 9325 <div style="min-height:100px;" v-loading="loading"> 9326 </div> 9327 </template> 9328 <template v-else-if="mode=='notice'" > 9329 <p class="mb-0 allergen-notice-message"> 9330 <template v-for="(part, index) in noticeMessageParts"> 9331 <a v-if="part.type==='phone'" :key="'p'+index" :href="'tel:'+part.href">{{ part.text }}</a> 9332 <span v-else :key="'t'+index">{{ part.text }}</span> 9333 </template> 9334 </p> 9335 <button type="button" class="btn btn-green w-100 allergen-notice-close" @click="closeNotice"> 9336 {{label.close}} 9337 </button> 9338 </template> 9339 <template v-else > 9340 <h5>{{label.sub_title}}</h5> 9341 <ul class="pl-3"> 9342 <template v-for="item in allergen"> 9343 <li v-if="allergen_data[item]"> 9344 {{ allergen_data[item] }} 9345 </li> 9346 </template> 9347 </ul> 9348 </template> 9349 9350 </el-dialog> 9351 ` 9352}; 9353 9354const ComponentsTextdescription = { 9355 props :['description','max_lenght','label'], 9356 data() { 9357 return { 9358 isExpanded: false, 9359 } 9360 }, 9361 computed: { 9362 truncatedDescription() { 9363 return this.description.length > this.max_lenght 9364 ? this.description.slice(0, this.max_lenght) + "..." 9365 : this.description; 9366 }, 9367 showReadMore() { 9368 return this.description.length > this.max_lenght; 9369 }, 9370 }, 9371 methods: { 9372 toggleReadMore() { 9373 this.isExpanded = !this.isExpanded; 9374 }, 9375 }, 9376 template:` 9377 <p class="text-descriptions"> 9378 <span v-html="isExpanded ? description : truncatedDescription" ></span> 9379 <span v-if="showReadMore" @click="toggleReadMore" class="read-more"> 9380 {{ isExpanded ? label.read_less : label.read_more }} 9381 </span> 9382 </p> 9383 ` 9384}; 9385 9386/** 9387 MENU VUE RENDER 9388 this is function for displaying menu and item details 9389 target = vue-merchant-menu 9390*/ 9391var $global_items = []; 9392var $global_addons = []; 9393var $global_addon_items = []; 9394var $global_item_addons = []; 9395var $new_item_addons 9396 9397const app_vm = Vue.createApp({ 9398 components: { 9399 'component-change-address': changeAddressComponent, 9400 'money-format': ComponentsMoney, 9401 'components-search-menu' : componentsSearchMenuMobile, 9402 'component-menu-search-result' : componentsMenuSearchResult, 9403 'component-allergens' : componentsAllergens, 9404 'text-description' : ComponentsTextdescription 9405 }, 9406 data(){ 9407 return { 9408 merchant_id : 0, 9409 menu_loading : true, 9410 menu_data: [], 9411 items : [], 9412 item_addons : [], 9413 item_addons_load : false, 9414 size_id : 0, 9415 disabled_cart : true, 9416 item_qty : 1, 9417 item_total : 0, 9418 add_to_cart : false, 9419 meta : [], 9420 special_instructions : '', 9421 sold_out_options : [], 9422 if_sold_out : 'substitute', 9423 view_data : [] , 9424 item_loading : false, 9425 item_in_cart : 0, 9426 checkout_blocked : false, 9427 merchant_data : [], 9428 items_not_available : [], 9429 category_not_available : [], 9430 menu_layout :'list', 9431 q: '', 9432 search_menu_data : [], 9433 allergen : [], 9434 allergen_data : [], 9435 allergen_notice : { enabled : true, title : '', message : '' }, 9436 item_gallery : [], 9437 image_featured : '', 9438 money_config : '', 9439 dish : [], 9440 show_points : null, 9441 promoEligibility : {}, 9442 } 9443 }, 9444 created() { 9445 this.geStoreMenu(); 9446 }, 9447 mounted () { 9448 let menu_layout = getCookie('menu_layout'); 9449 if(!empty(menu_layout)){ 9450 this.menu_layout = menu_layout; 9451 } 9452 }, 9453 updated () { 9454 if(this.item_addons_load==true){ 9455 this.ItemSummary(); 9456 } 9457 updateStickySibader(); 9458 }, // 9459 computed: { 9460 getAllergen(){ 9461 return this.allergen; 9462 }, 9463 hasAllergen(){ 9464 if (Object.keys(this.allergen).length > 0) { 9465 return true; 9466 } 9467 return false;
9468 }, 9469 getItemGallery(){ 9470 return this.item_gallery; 9471 }, 9472 }, 9473 methods: { 9474 getPromoMessage(item) { 9475 return this.promoEligibility[item.item_id]?.message || item?.promo_data?.message; 9476 }, 9477 isEligible(item) { 9478 return this.promoEligibility[item.item_id]?.is_eligible; 9479 }, 9480 isEligibleItem(item) { 9481 if(!item.is_promo_free_item){ 9482 return true; 9483 } 9484 return this.promoEligibility[item.item_id]?.is_eligible || false; 9485 }, 9486 geStoreMenu(){ 9487 var $params; 9488 let currency_code = getCookie('currency_code'); 9489 currency_code = !empty(currency_code)?currency_code:''; 9490 9491 $params="merchant_id=" + merchant_id; 9492 $params+="¤cy_code=" + currency_code; 9493 $params+=addValidationRequest(); 9494 var timenow = getTimeNow(); 9495 ajax_request[timenow] = $.ajax({ 9496 url: ajaxurl+"/geStoreMenu", 9497 method: "POST", 9498 dataType: "json", 9499 data: $params , 9500 contentType : $content_type.form , 9501 timeout: $timeout, 9502 crossDomain: true, 9503 beforeSend: function( xhr ) { 9504 if(ajax_request[timenow] != null) { 9505 ajax_request[timenow].abort(); 9506 } 9507 } 9508 }).done( data => { 9509 9510 this.menu_loading = false; 9511 if(data.code==1) { 9512 this.merchant_id = data.details.merchant_id; 9513 var $category = data.details.data.category; 9514 var $items = data.details.data.items; 9515 var $new_category = []; var $new_items = []; 9516 9517 this.items_not_available = data.details.data.items_not_available; 9518 this.category_not_available = data.details.data.category_not_available; 9519 this.dish = data.details.data.dish; 9520 if(data.details.allergen_notice){ 9521 this.allergen_notice = data.details.allergen_notice; 9522 } else if(data.details.data.allergen_notice){ 9523 this.allergen_notice = data.details.data.allergen_notice; 9524 } 9525 9526 if($category.length>0){ 9527 $.each($category, function(key, val){ 9528 $.each(val.items, function(items_key, $item_id){ 9529 if(!empty($items[$item_id])){ 9530 $new_items.push( $items[$item_id] ); 9531 } 9532 }); // loop 9533 $new_category.push({ 9534 'cat_id': val.cat_id, 9535 'category_name': val.category_name, 9536 'category_description': val.category_description, 9537 'category_uiid': val.category_uiid, 9538 'items':$new_items 9539 }); 9540 $new_items = []; 9541 }); // loop 9542 } 9543 9544 this.menu_data = $new_category; 9545 this.updateImage(); 9546 } 9547 9548 }); 9549 // 9550 }, 9551 itemAvailable(item_id,cat_id){ 9552 if(this.items_not_available.includes(parseInt(item_id))===false){ 9553 if(this.category_not_available.includes(parseInt(cat_id))===false){ 9554 return true; 9555 } 9556 } 9557 return false; 9558 }, 9559 updateImage(){ 9560 updateLazyImage(); 9561 }, 9562 viewItemBefore(data){ 9563 this.viewItem(data); 9564 }, 9565 afterChangeAddress(){ 9566 9567 if ((typeof vm_addres_needed !== "undefined") && ( vm_addres_needed !== null)) { 9568 vm_addres_needed.visible = false; 9569 } 9570 9571 if ((typeof vm_widget_nav !== "undefined") && ( vm_widget_nav !== null)) { 9572 vm_widget_nav.afterChangeAddress(); 9573 } 9574 9575 if ((typeof vm_merchant_details !== "undefined") && ( vm_merchant_details !== null)) { 9576 vm_merchant_details.$refs.ref_services.getMerchantServices(); 9577 } 9578 9579 var count = Object.keys(this.view_data).length; 9580 dump("count=>"+ count); 9581 dump(this.view_data); 9582 if(count>0){ 9583 this.viewItem( this.view_data ); 9584 this.view_data = []; 9585 } 9586 }, 9587 viewItem(data) { 9588 9589 this.special_instructions = ''; 9590 9591 $(this.$refs.modal_item_details).modal('show'); 9592 9593 var $item_uuid = data.item_uuid; 9594 var $cat_id = data.cat_id; 9595 9596 var $params; 9597 let currency_code = getCookie('currency_code'); 9598 currency_code = !empty(currency_code)?currency_code:''; 9599 9600 $params="merchant_id=" + merchant_id; 9601 $params+="&item_uuid="+ $item_uuid; 9602 $params+="&cat_id="+ $cat_id; 9603 $params+="¤cy_code="+ currency_code; 9604 9605 $params+=addValidationRequest(); 9606 var timenow = 1; 9607 this.item_loading = true; 9608 NProgress.start(); 9609 9610 ajax_request[timenow] = $.ajax({ 9611 url: ajaxurl+"/getMenuItem", 9612 method: "POST", 9613 dataType: "json", 9614 data: $params , 9615 contentType : $content_type.form, 9616 timeout: $timeout, 9617 crossDomain: true, 9618 beforeSend: function( xhr ) { 9619 if(ajax_request[timenow] != null) { 9620 ajax_request[timenow].abort(); 9621 } 9622 } 9623 }); 9624 9625 ajax_request[timenow].done( data => { 9626 9627 if(data.code==2){ 9628 $('#itemModal').modal('hide'); 9629 return; 9630 } 9631 9632 this.show_points = data.details.show_points; 9633 9634 $global_items = data.details.data.items; 9635 $global_addons = data.details.data.addons; 9636 $global_addon_items = data.details.data.addon_items; 9637 $global_item_addons = data.details.data.items.item_addons; 9638 9639 var $meta = data.details.data.meta; 9640 this.money_config = data.details.money_config; 9641 this.item_gallery = data.details.data.meta.item_gallery; 9642 this.image_featured = ''; 9643 this.renderGallery(); 9644 9645 var $meta_details = data.details.data.meta_details; 9646 var $new_meta = { 9647 'cooking_ref' : [], 9648 'ingredients' : [], 9649 'dish' : [], 9650 }; 9651 9652 let $ingredients_preselected = data.details.data.items.ingredients_preselected; 9653 9654 if( !empty($meta)){ 9655 $.each($meta,function(key, item) { 9656 $.each(item,function(key2, item2) { 9657 if(!empty($meta_details[key])){ 9658 if(!empty($meta_details[key][item2])){ 9659 let $defaul_check = false;
9660 if(key=="ingredients" && $ingredients_preselected){ 9661 $defaul_check = true; 9662 } 9663 $new_meta[key].push({ 9664 'meta_id': $meta_details[key][item2].meta_id, 9665 'meta_name': $meta_details[key][item2].meta_name, 9666 'checked': $defaul_check 9667 }); 9668 } 9669 } 9670 }); 9671 }); 9672 } 9673 9674 var $price = $global_items.price; 9675 var $size_id = Object.keys($price)[0]; 9676 9677 //$('#itemModal').modal('show'); 9678 9679 this.item_qty = 1; 9680 this.items = $global_items; 9681 this.size_id = $size_id; 9682 this.meta = $new_meta; 9683 this.getSizeData($size_id); 9684 this.sold_out_options = data.details.sold_out_options; 9685 this.updateImage(); 9686 9687 }); 9688 9689 ajax_request[timenow].always( data => { 9690 this.item_loading = false; 9691 NProgress.done(); 9692 }); 9693 9694 }, // end viewitem 9695 renderGallery(){ 9696 setTimeout(() => { 9697 let $is_rtl = false; 9698 if ((typeof is_rtl !== "undefined") && ( is_rtl !== null)) { 9699 $is_rtl = is_rtl=='1'?true:false; 9700 } 9701 $(this.$refs.owl_item_gallery).owlCarousel({ 9702 rtl : $is_rtl, 9703 loop:false, 9704 margin:10, 9705 nav:false, 9706 dots:false, 9707 responsive:{ 9708 0:{ 9709 items:3 9710 }, 9711 600:{ 9712 items:3 9713 }, 9714 1000:{ 9715 items:5 9716 } 9717 } 9718 }); 9719 }, 10); 9720 }, 9721 setImage(data){ 9722 this.image_featured = data; 9723 }, 9724 updateImage(){ 9725 updateLazyImage(); 9726 }, 9727 setItemSize(event){ 9728 var $size_id = event.currentTarget.firstElementChild.value; 9729 this.size_id = $size_id; 9730 this.getSizeData($size_id); 9731 9732 }, // end setItemSize 9733 getSizeData($size_id){ 9734 9735 $new_item_addons = []; var $sub_items=[]; 9736 9737 if( !empty($global_item_addons[$size_id]) ){ 9738 $.each($global_item_addons[$size_id],function(key, item) { 9739 if(!empty($global_addons[$size_id])){ 9740 if(!empty($global_addons[$size_id][item])){ 9741 9742 $global_addons[$size_id][item].subcat_id 9743 $.each($global_addons[$size_id][item].sub_items,function(key2, item2) { 9744 if ((typeof $global_addon_items[item2] !== "undefined") && ( $global_addon_items[item2] !== null)) { 9745 $sub_items.push({ 9746 'sub_item_id':$global_addon_items[item2].sub_item_id, 9747 'sub_item_name':$global_addon_items[item2].sub_item_name, 9748 'item_description':$global_addon_items[item2].item_description, 9749 'price':$global_addon_items[item2].price, 9750 'pretty_price':$global_addon_items[item2].pretty_price, 9751 'checked':false, 9752 'disabled':false, 9753 'qty':1 9754 }); 9755 } 9756 }); 9757 9758 $new_item_addons.push({ 9759 'subcat_id' : $global_addons[$size_id][item].subcat_id, 9760 'subcategory_name' : $global_addons[$size_id][item].subcategory_name, 9761 'subcategory_description' : $global_addons[$size_id][item].subcategory_description, 9762 'multi_option' : $global_addons[$size_id][item].multi_option, 9763 'multi_option_min' : $global_addons[$size_id][item].multi_option_min, 9764 'multi_option_value' : $global_addons[$size_id][item].multi_option_value, 9765 'require_addon' : $global_addons[$size_id][item].require_addon, 9766 'pre_selected' : $global_addons[$size_id][item].pre_selected, 9767 'sub_items_checked':'', 9768 'sub_items':$sub_items 9769 }); 9770 $sub_items = [] ; 9771 } 9772 } 9773 }); 9774 } 9775 9776 9777 this.item_addons = $new_item_addons; 9778 this.item_addons_load = true; 9779 }, // end getSizeData 9780 9781 ItemSummary(data){ 9782 9783 $item_total = 0; 9784 var $required_addon = []; 9785 var $required_addon_added = []; 9786 let $min_addon = []; 9787 let $min_addon_added = []; 9788 9789 if(!empty(this.items.price)){ 9790 if(!empty(this.items.price[this.size_id])){ 9791 var item = this.items.price[this.size_id]; 9792 if( item.discount>0){ 9793 $item_total+=( this.item_qty * parseFloat(item.price_after_discount) ); 9794 } else $item_total+=( this.item_qty * parseFloat(item.price) ); 9795 } 9796 } 9797 9798 this.item_addons.forEach((item,index) => { 9799 9800 //dump("=>" + item.multi_option); 9801 if ( item.require_addon==1){ 9802 $required_addon.push(item.subcat_id); 9803 } 9804 9805 if(item.multi_option=="custom"){ 9806 var total_check = 0; 9807 let multi_option_min = item.multi_option_min; 9808 var multi_option_value = item.multi_option_value; 9809 9810 if(multi_option_value>0){ 9811 $min_addon.push({ 9812 'subcat_id': item.subcat_id, 9813 'min':multi_option_min, 9814 'max':multi_option_value 9815 }); 9816 } 9817 9818 var item_index=[]; var item_index2=[];
9819 item.sub_items.forEach((item2,index2) => { 9820 if(item2.checked==true){ 9821 total_check++; 9822 $item_total+=( this.item_qty * parseFloat(item2.price) ); 9823 $required_addon_added.push( item.subcat_id ); 9824 } else item_index.push(index2); 9825 9826 if(item2.disabled==true){ 9827 item_index2.push(index2); 9828 } 9829 9830 }); 9831 9832 9833 $min_addon_added[item.subcat_id] = { 9834 'total' : total_check 9835 }; 9836 9837 if(total_check>=multi_option_value){ 9838 item_index.forEach((item3,index3) => { 9839 this.item_addons[index].sub_items[item3].disabled = true; 9840 }); 9841 } else { 9842 item_index2.forEach((item3,index3) => { 9843 this.item_addons[index].sub_items[item3].disabled = false; 9844 }); 9845 } 9846 9847 } else if ( item.multi_option=="one" ){ 9848 item.sub_items.forEach((item2,index2) => { 9849 if( item2.sub_item_id == item.sub_items_checked ) { 9850 $item_total+=( this.item_qty * parseFloat(item2.price) ); 9851 $required_addon_added.push( item.subcat_id ); 9852 } 9853 }); 9854 } else if ( item.multi_option=="multiple" ){ 9855 var item_index=[]; 9856 let multi_option_min = item.multi_option_min; 9857 var multi_option_value = item.multi_option_value; 9858 var limit = 0; 9859 9860 if(multi_option_value>0){ 9861 $min_addon.push({ 9862 'subcat_id': item.subcat_id, 9863 'min':multi_option_min, 9864 'max':multi_option_value 9865 }); 9866 } 9867 9868 item.sub_items.forEach((item2,index2) => { 9869 if(item2.checked==true){ 9870 $item_total+=( item2.qty * parseFloat(item2.price) ); 9871 $required_addon_added.push( item.subcat_id ); 9872 limit += item2.qty; 9873 } 9874 item_index.push(index2); 9875 }); 9876 9877 $min_addon_added[item.subcat_id] = { 9878 'total' : limit 9879 }; 9880 9881 this.item_addons[index].qty_selected =limit; 9882 if ( this.item_addons[index].qty_selected>= multi_option_value){ 9883 item_index.forEach((item3,index2) => { 9884 this.item_addons[index].sub_items[item3].disabled = true; 9885 }); 9886 } else { 9887 item_index.forEach((item3,index2) => { 9888 this.item_addons[index].sub_items[item3].disabled = false; 9889 }); 9890 } 9891 9892 } /*endif custom*/ 9893 9894 });/* end loop*/ 9895 9896 9897 this.item_total = $item_total; 9898 9899 var $required_meet=true; 9900 if($required_addon.length>0){ 9901 $.each($required_addon, function(i, val){ 9902 if($required_addon_added.includes(val)===false){ 9903 $required_meet = false; 9904 return false; 9905 } 9906 }); 9907 } 9908 9909 // CHECK COOKING REF 9910 if(this.items.cooking_ref_required){ 9911 let $cooking_ref_check = false; 9912 if (Object.keys(this.meta.cooking_ref).length > 0) { 9913 Object.entries(this.meta.cooking_ref).forEach(([cooking_key, cooking_items]) => { 9914 if(cooking_items.checked){ 9915 $cooking_ref_check = true; 9916 } 9917 }); 9918 } 9919 if(!$cooking_ref_check){ 9920 $required_meet = false; 9921 } 9922 } 9923 9924 if (Object.keys($min_addon).length > 0) { 9925 let min_value,min_selected; 9926 Object.entries($min_addon).forEach(([key_min_addon, items_min_addon]) => { 9927 min_value = parseInt(items_min_addon.min); 9928 if($min_addon_added[items_min_addon.subcat_id]){ 9929 min_selected = parseInt($min_addon_added[items_min_addon.subcat_id].total); 9930 } 9931 if(min_selected>0){ 9932 if(min_value>min_selected){ 9933 $required_meet = false; 9934 } 9935 } 9936 }); 9937 } 9938 9939 //dump("required_meet=>"+$required_meet); 9940 if($required_meet){ 9941 this.disabled_cart = false; 9942 } else this.disabled_cart = true; 9943 9944 }, // end ItemSummary 9945 updateInlineQtyBefore(dos,data,cat_id){ 9946 // this.view_data = []; 9947 // var $local_id = getCookie('kmrs_local_id'); 9948 // if(empty($local_id)){ 9949 // this.$refs.address.showModal(); 9950 // } else this.updateInlineQty(dos,data,cat_id); 9951 9952 this.updateInlineQty(dos,data,cat_id); 9953 }, 9954 updateInlineQty(dos,data,cat_id){ 9955 if(!empty(vue_cart.cart_merchant.merchant_id)){ 9956 if ( this.merchant_id != vue_cart.cart_merchant.merchant_id ){
9957 //var message = t("Your order contains items from") + " " + vue_cart.cart_merchant.restaurant_name + t(". Create a new order to add items."); 9958 var message = vue_cart.cart_merchant.confirm_add_item; 9959 vue_confirm_neworder.show({ content:message }).then((result) => { 9960 if(result){ 9961 vue_confirm_neworder.clearCart(vue_cart.cart_uuid).then((result) => { 9962 this.inlineQty( dos,data,cat_id ); 9963 }); 9964 } 9965 }); 9966 } else this.inlineQty( dos,data,cat_id ); 9967 } else this.inlineQty( dos,data,cat_id ); 9968 }, 9969 inlineQty(dos,data,cat_id) { 9970 if(dos=="add"){ 9971 data.qty+= 1; 9972 } else data.qty-= 1; 9973 9974 var item_size_id = $(".active .item_size_id_"+ data.item_uuid ).val(); 9975 if(empty(item_size_id)){ 9976 item_size_id = data.price[0]? data.price[0].item_size_id : ''; 9977 } 9978 9979 let transactionType = getCookie('cart_transaction_type'); 9980 try { 9981 if(empty(transactionType)){ 9982 if ((typeof vm_merchant_details.$refs.ref_services !== "undefined") && ( vm_merchant_details.$refs.ref_services !== null)) { 9983 transactionType = vm_merchant_details.$refs.ref_services.transaction; 9984 } else if ( (typeof vm_merchant_details.$refs.ref_location_services !== "undefined") && ( vm_merchant_details.$refs.ref_location_services !== null) ){ 9985 transactionType = vm_merchant_details.$refs.ref_location_services.transaction_type; 9986 } 9987 } 9988 } catch(err){} 9989 9990 var $params = { 9991 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 9992 'merchant_id' : this.merchant_id, 9993 'cat_id' : cat_id, 9994 'item_token': data.item_uuid, 9995 'item_size_id': item_size_id, 9996 'item_qty': data.qty, 9997 'item_addons': [], 9998 'special_instructions': '', 9999 'meta' : [], 10000 'cart_uuid':getCookie('cart_uuid'), 10001 'inline_qty':1, 10002 'transaction_type': transactionType, 10003 'if_sold_out' : this.if_sold_out, 10004 }; 10005 10006 var $data_delivery; 10007 if($data_delivery = getChoosenDeliveryTime()){ 10008 $params.whento_deliver = $data_delivery.whento_deliver; 10009 $params.delivery_date = $data_delivery.delivery_date; 10010 $params.delivery_time = $data_delivery.delivery_time; 10011 $params.delivery_time_raw = $data_delivery.delivery_time_raw; 10012 } 10013 10014 var timenow = 1; 10015 $params = JSON.stringify($params); 10016 10017 ajax_request[timenow] = $.ajax({ 10018 url: ajaxurl+"/addCartItems", 10019 method: "PUT", 10020 dataType: "json", 10021 data: $params , 10022 contentType : $content_type.json , 10023 timeout: $timeout, 10024 crossDomain: true, 10025 beforeSend: function( xhr ) { 10026 if(ajax_request[timenow] != null) { 10027 ajax_request[timenow].abort(); 10028 } 10029 } 10030 }); 10031 10032 ajax_request[timenow].done( data => { 10033 if ( data.code==1){ 10034 setCookie('cart_uuid',data.details.cart_uuid,30); 10035 10036 if ((typeof vue_cart !== "undefined") && ( vue_cart !== null)) { 10037 vue_cart.loadcart(); 10038 } 10039 10040 if ((typeof vm_cart_preview !== "undefined") && ( vm_cart_preview !== null)) { 10041 vm_cart_preview.getCartPreview(); 10042 } 10043 10044 } 10045 }); 10046 10047 },// 10048 CheckaddCartItems(){ 10049 10050 if(!empty(vue_cart.cart_merchant.merchant_id)){ 10051 if ( this.items.merchant_id != vue_cart.cart_merchant.merchant_id ){ 10052 $('#itemModal').modal('hide'); 10053 //var message = t("Your order contains items from") + " " + vue_cart.cart_merchant.restaurant_name + t(". Create a new order to add items."); 10054 var message = vue_cart.cart_merchant.confirm_add_item; 10055 vue_confirm_neworder.show({ content:message } ).then((result) => { 10056 if(result){ 10057 vue_confirm_neworder.clearCart(vue_cart.cart_uuid).then((result) => { 10058 dump("resp:"+ result); 10059 this.addCartItems(); 10060 }); 10061 } 10062 }); 10063 } else this.addCartItems(); 10064 } else this.addCartItems(); 10065 10066 }, 10067 addCartItems(event){ 10068 if (event) { 10069 event.preventDefault() 10070 } 10071 10072 this.add_to_cart = true; 10073 let transactionType = getCookie('cart_transaction_type'); 10074 10075 try { 10076 if(empty(transactionType)){ 10077 if ((typeof vm_merchant_details.$refs.ref_services !== "undefined") && ( vm_merchant_details.$refs.ref_services !== null)) { 10078 transactionType = vm_merchant_details.$refs.ref_services.transaction; 10079 } else if ( (typeof vm_merchant_details.$refs.ref_location_services !== "undefined") && ( vm_merchant_details.$refs.ref_location_services !== null) ){ 10080 transactionType = vm_merchant_details.$refs.ref_location_services.transaction_type; 10081 } 10082 } 10083 } catch(err){} 10084 10085 var $params = { 10086 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 10087 'merchant_id' : this.items.merchant_id, 10088 'cat_id' : this.items.cat_id, 10089 'item_token': this.items.item_token, 10090 'item_size_id': this.size_id,
10091 'item_qty': this.item_qty, 10092 'item_addons': this.item_addons, 10093 'special_instructions': this.special_instructions, 10094 'meta' : this.meta, 10095 'cart_uuid':getCookie('cart_uuid'), 10096 'transaction_type': transactionType, 10097 'if_sold_out' : this.if_sold_out, 10098 }; 10099 10100 var timenow = 1; 10101 $params = JSON.stringify($params); 10102 10103 ajax_request[timenow] = $.ajax({ 10104 url: ajaxurl+"/addCartItems", 10105 method: "PUT", 10106 dataType: "json", 10107 data: $params , 10108 contentType : $content_type.json , 10109 timeout: $timeout, 10110 crossDomain: true, 10111 beforeSend: function( xhr ) { 10112 if(ajax_request[timenow] != null) { 10113 ajax_request[timenow].abort(); 10114 } 10115 } 10116 }); 10117 10118 ajax_request[timenow].done( data => { 10119 if ( data.code==1){ 10120 setCookie('cart_uuid',data.details.cart_uuid,30); 10121 $('#itemModal').modal('hide'); 10122 if ((typeof vue_cart !== "undefined") && ( vue_cart !== null)) { 10123 vue_cart.loadcart(); 10124 } 10125 if ((typeof vm_cart_preview !== "undefined") && ( vm_cart_preview !== null)) { 10126 vm_cart_preview.getCartPreview(); 10127 } 10128 } 10129 }); 10130 10131 ajax_request[timenow].always( data => { 10132 dump('always'); 10133 this.add_to_cart = false; 10134 }); 10135 10136 } , 10137 // end addCartItems 10138 // 10139 hasItemInCart(data, merchant_data){ 10140 this.item_in_cart = data; 10141 this.merchant_data = merchant_data; 10142 }, 10143 showDrawerCart(){ 10144 if (typeof window.vue_cart !== "undefined" && window.vue_cart !== null 10145 && Array.isArray(window.vue_cart.error) && window.vue_cart.error.length > 0) { 10146 return; 10147 } 10148 if ((typeof vm_cart_preview !== "undefined") && ( vm_cart_preview !== null)) { 10149 vm_cart_preview.showCartPreview(); 10150 } 10151 }, 10152 changeMenuLayout(data){ 10153 this.menu_layout = data; 10154 setCookie('menu_layout', data ,30); 10155 }, 10156 afterSearch(q,data){ 10157 this.q = q; 10158 this.search_menu_data = data; 10159 this.scrollToResults(); 10160 }, 10161 clearSearch(){ 10162 this.q = ''; 10163 this.search_menu_data = []; 10164 }, 10165 scrollToResults() { 10166 this.$refs["search_result"].scrollIntoView({ behavior: "smooth" }) 10167 }, 10168 showAllergens(item_id){ 10169 this.$refs.ref_allergens.show(item_id); 10170 }, 10171 showAllergenIcon(items){ 10172 if(this.allergen_notice && this.allergen_notice.enabled){ 10173 return true; 10174 } 10175 return items && items.total_allergens>0; 10176 }, 10177 async promoCheck(subtotal){ 10178 try { 10179 let currency_code = getCookie('currency_code'); 10180 currency_code = !empty(currency_code)?currency_code:''; 10181 const params = new URLSearchParams({ 10182 cart_uuid:getCookie('cart_uuid'), 10183 merchant_id : merchant_id ?? 0, 10184 currency_code : currency_code ?? '' 10185 }).toString(); 10186 const response = await axios.get(ajaxurl+"/PromoCheck?"+params); 10187 if(response.data.code==1){ 10188 this.promoEligibility = response.data.details.data; 10189 } else { 10190 this.promoEligibility = []; 10191 } 10192 } catch (error) { 10193 //console.error('Error fetching data:', error); 10194 } 10195 } 10196 } 10197 // 10198}); 10199app_vm.use(ElementPlus); 10200const vm = app_vm.mount('#vue-merchant-menu'); 10201 10202 10203 10204/* 10205 CHECKOUT BACK URL 10206*/ 10207const vm_checkout_back = Vue.createApp({ 10208 data() { 10209 return { 10210 back_url: '' 10211 } 10212 }, 10213}).mount('#vue-checkout-back'); 10214 10215 10216/** 10217 CART VUE RENDER 10218 this is function for displaying cart 10219 target = vue-cart 10220*/ 10221const app_cart = Vue.createApp({ 10222 data(){ 10223 return { 10224 cart_loading : true, 10225 cart_uuid : '', 10226 cart_items : [], 10227 cart_summary : [], 10228 cart_merchant : [], 10229 cart_total : [], 10230 cart_subtotal : [], 10231 error : [], 10232 selected_payment_uuid : 'default', 10233 error_payment : '', 10234 error_placeorder : [], 10235 is_submit : false, 10236 distance_pretty : '', 10237 points_data : [], 10238 some_words :[], 10239 use_digital_wallet : false, 10240 use_partial_payment : false, 10241 checkout_transaction_type : '', 10242 min_order_free_delivery : [], 10243 delivery_details: null 10244 }; 10245 }, 10246 mounted () { 10247 this.loadcart(); 10248 this.hasSelectedPayment( this.selected_payment_uuid ); 10249 if ((typeof some_words !== "undefined") && ( some_words !== null)) { 10250 this.some_words = JSON.parse(some_words); 10251 } 10252 }, 10253 updated () { 10254 $('.section-cart .lazy').each(function(index, $obj){ 10255 if ( !empty($(this).attr("src")) && !empty($(this).attr("data-src")) ){ 10256 $(this).attr("src", $(this).attr("data-src") ); 10257 } 10258 }); 10259 }, 10260 computed: { 10261 hasError(){ 10262 if(this.error.length>0){ 10263 return true; 10264 } 10265 return false;
10266 }, 10267 hasPayment(){ 10268 if(!empty(this.error_payment)){ 10269 updateStickyCart(); 10270 return true; 10271 } 10272 return false; 10273 }, 10274 showFreeDelivery(){ 10275 if(this.min_order_free_delivery){ 10276 if(this.min_order_free_delivery.amount_needed>0){ 10277 return true; 10278 } 10279 } 10280 return false; 10281 }, 10282 freeDeliveryPercentage(){ 10283 if(this.min_order_free_delivery){ 10284 return this.min_order_free_delivery.percentage; 10285 } 10286 return 0; 10287 }, 10288 }, 10289 watch: { 10290 selected_payment_uuid(newdata,olddata){ 10291 this.hasSelectedPayment(newdata); 10292 }, 10293 use_digital_wallet(newdata,oldata){ 10294 if(newdata){ 10295 this.error_payment = ''; 10296 } else { 10297 if(empty(this.selected_payment_uuid)){ 10298 this.error_payment = this.some_words.please_select_valid_payment; 10299 } 10300 } 10301 }, 10302 }, 10303 methods: { 10304 inArray: function(needle, haystack) { 10305 var length = haystack.length; 10306 for(var i = 0; i < length; i++) { 10307 if(haystack[i] == needle) return true; 10308 } 10309 return false; 10310 }, 10311 hasSelectedPayment(payment_uuid){ 10312 if(empty(payment_uuid)){ 10313 //let $some_words = JSON.parse(some_words); 10314 //this.error_payment = $some_words.please_select_valid_payment; 10315 this.error_payment = this.some_words.please_select_valid_payment; 10316 } else this.error_payment=''; 10317 }, 10318 loadcart(){ 10319 var $cart_uuid = getCookie('cart_uuid'); 10320 if(!empty($cart_uuid)){ 10321 10322 var $payload=''; 10323 if ((typeof payload !== "undefined") && ( payload !== null)) { 10324 $payload = JSON.parse(payload); 10325 } 10326 10327 var timenow = getTimeNow(); 10328 let currency_code = getCookie('currency_code'); 10329 currency_code = !empty(currency_code)?currency_code:''; 10330 10331 const location = getLocation(); 10332 const selectedAddress = getFromLocalStorageStore(StoreMapName,"selectedAddress"); 10333 10334 var $params = { 10335 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 10336 'cart_uuid':$cart_uuid, 10337 'currency_code':currency_code, 10338 'payload':$payload, 10339 'location':location, 10340 'latitude': selectedAddress?selectedAddress.latitude :'', 10341 'longitude': selectedAddress?selectedAddress.longitude :'', 10342 }; 10343 10344 NProgress.start(); 10345 10346 ajax_request[timenow] = $.ajax({ 10347 url: ajaxurl+"/getCart", 10348 method: "PUT", 10349 dataType: "json", 10350 data: JSON.stringify($params), 10351 contentType : $content_type.json , 10352 timeout: $timeout, 10353 crossDomain: true, 10354 beforeSend: data => { 10355 if(ajax_request[timenow] != null) { 10356 ajax_request[timenow].abort(); 10357 } 10358 } 10359 }); 10360 10361 ajax_request[timenow].done( data => { 10362 if (data.code==1){ 10363 this.cart_merchant = data.details.data.merchant; 10364 this.cart_uuid = data.details.cart_uuid; 10365 this.cart_items = data.details.data.items; 10366 this.cart_summary = data.details.data.summary; 10367 this.cart_total = data.details.data.total; 10368 this.error = data.details.error; 10369 this.cart_subtotal = data.details.data.subtotal; 10370 this.distance_pretty = data.details.distance_pretty; 10371 this.points_data = data.details.points_data; 10372 this.min_order_free_delivery = data.details.data.min_order_free_delivery; 10373 this.delivery_details = data.details.delivery_details; 10374 if ((typeof vm !== "undefined") && ( vm !== null)) { 10375 vm.checkout_blocked = Array.isArray(this.error) && this.error.length > 0; 10376 } 10377 10378 var $is_checkout = false; 10379 if ( this.inArray('checkout',data.details.payload) ){ 10380 $is_checkout = true; 10381 if ((typeof vm_checkout_transaction !== "undefined") && ( vm_checkout_transaction !== null)) { 10382 vm_checkout_transaction.setData( data.details.checkout_data ); 10383 } 10384 } 10385 10386 this.checkout_transaction_type = data.details.checkout_data.transaction_type; 10387 var $transaction_type = data.details.checkout_data.transaction_type; 10388 10389 if ((typeof vm_tips !== "undefined") && ( vm_tips !== null) && $is_checkout==true ) { 10390 vm_tips.transaction_type = $transaction_type; 10391 } 10392 10393 if ((typeof vm_manage_address !== "undefined") && ( vm_manage_address !== null) && $is_checkout==true ) { 10394 vm_manage_address.transaction_type = $transaction_type; 10395 } 10396 10397 if ((typeof vm_payment_lists !== "undefined") && ( vm_payment_lists !== null) && $is_checkout==true ) { 10398 vm_payment_lists.transaction_type = $transaction_type; 10399 vm_payment_lists.amount_to_pay = this.cart_total.raw; 10400 } 10401 10402 if ((typeof data.details.out_of_range !== "undefined") && ( data.details.out_of_range !== null)) { 10403 if ((typeof vm_change_address !== "undefined") && ( vm_change_address !== null)) { 10404 vm_change_address.out_of_range = data.details.out_of_range; 10405 vm_change_address.address_component = data.details.address_component; 10406 } 10407 if ((typeof vm_addres_needed !== "undefined") && ( vm_addres_needed !== null)) { 10408 vm_addres_needed.out_of_range = data.details.out_of_range; 10409 vm_addres_needed.address_component = data.details.address_component; 10410 } 10411 } 10412 10413 if ((typeof vm_cart_preview !== "undefined") && ( vm_cart_preview !== null) ) { 10414 vm_cart_preview.cartCount(data.details.items_count); 10415 } 10416 10417 if ((typeof vm_checkout_back !== "undefined") && ( vm_checkout_back !== null) ) { 10418 vm_checkout_back.back_url = data.details.data.merchant.restaurant_slug;
10419 } 10420 10421 if ((typeof vm_utensils !== "undefined") && ( vm_utensils !== null) ) { 10422 vm_utensils.setTransaction($transaction_type); 10423 } 10424 10425 if ((typeof vm_checkout_booking !== "undefined") && ( vm_checkout_booking !== null) ) { 10426 vm_checkout_booking.transaction_type = $transaction_type; 10427 } 10428 10429 if ((typeof vm_payment_lists !== "undefined") && ( vm_payment_lists !== null) ) { 10430 vm_payment_lists.refreshWallet({ 10431 cart_total : this.cart_total.raw, 10432 use_digital_wallet : this.use_digital_wallet, 10433 }); 10434 } 10435 10436 // if ((typeof vm_checkout_address !== "undefined") && ( vm_checkout_address !== null) ) { 10437 // vm_checkout_address.handleAddressRequirement(); 10438 // } 10439 10440 10441 } else { 10442 this.cart_items = []; 10443 this.cart_summary = []; 10444 this.cart_total = []; 10445 this.error = []; 10446 this.cart_subtotal = []; 10447 this.min_order_free_delivery = []; 10448 if ((typeof vm !== "undefined") && ( vm !== null)) { 10449 vm.checkout_blocked = false; 10450 } 10451 10452 if ((typeof vm_cart_preview !== "undefined") && ( vm_cart_preview !== null) ) { 10453 vm_cart_preview.cartCount(0); 10454 } 10455 } 10456 10457 if ((typeof vm_schedule_order !== "undefined") && ( vm_schedule_order !== null) ) { 10458 vm_schedule_order.checkStoreOpen(); 10459 setTimeout(() => { 10460 vm_schedule_order.storeAvailable(); 10461 }, 1); 10462 } 10463 10464 updateStickyCart(); 10465 this.updateImage(); 10466 10467 setTimeout(() => { 10468 this.updateMenuQty(); 10469 }, 1); 10470 10471 if ((typeof vm !== "undefined") && ( vm !== null) ) { 10472 vm.promoCheck(this.cart_subtotal?.raw || 0); 10473 } 10474 10475 if ((typeof vmWalletPayment !== "undefined") && ( vmWalletPayment !== null) ) { 10476 vmWalletPayment.fetchWallet(this.cart_total.raw); 10477 } 10478 10479 }); // ajax done 10480 10481 ajax_request[timenow].always( data => { 10482 NProgress.done(); 10483 this.cart_loading = false; 10484 this.hasSelectedPayment( this.selected_payment_uuid ); 10485 }); 10486 10487 } else this.cart_loading = false; // end if 10488 10489 }, // 10490 updateImage(){ 10491 updateLazyImage(); 10492 }, 10493 remove(cart_row,cart_uuid){ 10494 var $params; var timenow = 1; 10495 $params="row=" + cart_row +"&cart_uuid="+cart_uuid; 10496 $params+=addValidationRequest(); 10497 ajax_request[timenow] = $.ajax({ 10498 url: ajaxurl+"/removeCartItem", 10499 method: "POST", 10500 dataType: "json", 10501 data: $params, 10502 contentType : 'application/x-www-form-urlencoded; charset=UTF-8' , 10503 timeout: $timeout, 10504 crossDomain: true, 10505 beforeSend: function( xhr ) { 10506 if(ajax_request[timenow] != null) { 10507 ajax_request[timenow].abort(); 10508 } 10509 } 10510 }); 10511 10512 ajax_request[timenow].done( data => { 10513 if (data.code==1){ 10514 this.loadcart(); 10515 if ((typeof vm_checkout_points !== "undefined") && ( vm_checkout_points !== null) ) { 10516 vm_checkout_points.getAvailablePoints(0); 10517 } 10518 } 10519 }); // ajax done 10520 10521 },// 10522 updateCartQty(addOrSubract,item_qty,cart_row,cart_uuid){ 10523 if(addOrSubract==1){ 10524 item_qty++; 10525 } else item_qty--; 10526 10527 if(item_qty<=0){ 10528 this.remove(cart_row,cart_uuid); 10529 } else { 10530 this.updateCartItems( item_qty,cart_row,cart_uuid ); 10531 } 10532 },// 10533 updateCartItems(item_qty,cart_row,cart_uuid){ 10534 10535 10536 var $params; var timenow = 1; 10537 $params="cart_uuid=" + cart_uuid; 10538 $params+="&cart_row=" + cart_row; 10539 $params+="&item_qty=" + item_qty; 10540 10541 $params+=addValidationRequest(); 10542 ajax_request[timenow] = $.ajax({ 10543 url: ajaxurl+"/updateCartItems", 10544 method: "POST", 10545 dataType: "json", 10546 data: $params, 10547 contentType : $content_type.form , 10548 timeout: $timeout, 10549 crossDomain: true, 10550 beforeSend: function( xhr ) { 10551 if(ajax_request[timenow] != null) { 10552 ajax_request[timenow].abort(); 10553 } 10554 } 10555 }); 10556 10557 ajax_request[timenow].done( data => { 10558 dump("done"); 10559 if (data.code==1){ 10560 this.loadcart(); 10561 } 10562 }); // ajax done 10563 10564 }, // 10565 clear(cart_uuid){ 10566 10567 var $params; var timenow = 1; 10568 $params="cart_uuid=" + cart_uuid; 10569 $params+=addValidationRequest(); 10570 ajax_request[timenow] = $.ajax({ 10571 url: ajaxurl+"/clearCart", 10572 method: "POST", 10573 dataType: "json", 10574 data: $params, 10575 contentType : $content_type.form , 10576 timeout: $timeout, 10577 crossDomain: true, 10578 beforeSend: function( xhr ) { 10579 if(ajax_request[timenow] != null) { 10580 ajax_request[timenow].abort(); 10581 } 10582 } 10583 }); 10584 10585 ajax_request[timenow].done( data => { 10586 if (data.code==1){ 10587 this.loadcart(); 10588 } 10589 }); // ajax done 10590 10591 }, // 10592 updateMenuQty(){ 10593 var $single_items = []; 10594 if(this.cart_items.length>0){ 10595 $.each( this.cart_items ,function(key, data) { 10596 if( data.attributes.length<=0 && data.addons.length<=0 ){ 10597 $single_items.push({ 10598 'item_token':data.item_token, 10599 'qty':data.qty, 10600 'cat_id':data.cat_id, 10601 }); 10602 } 10603 }); 10604 } 10605 10606 10607 if ((typeof vm !== "undefined") && ( vm !== null)) { 10608 if(vm.menu_data.length>0){ 10609 vm.menu_data.forEach((item,index) => {
10610 item.items.forEach((item2,index2) => { 10611 if($single_items.length>0){ 10612 var found_item_qty = this.findItems($single_items , item.cat_id , item2.item_uuid); 10613 if(found_item_qty>0){ 10614 item2.qty = found_item_qty; 10615 } else item2.qty=0; 10616 } else item2.qty=0; 10617 }); 10618 }); 10619 } 10620 } 10621 10622 }, // 10623 findItems(items,cat_id,item_token){ 10624 var $found = 0; 10625 items.forEach((item,index) => { 10626 if( item.cat_id==cat_id && item.item_token==item_token ){ 10627 $found = item.qty; 10628 } 10629 }); 10630 return $found; 10631 },// 10632 placeOrder(){ 10633 // Validate delivery address client-side so the user gets a friendly 10634 // message in the yellow warning box instead of a raw backend error. 10635 if (this.checkout_transaction_type === 'delivery') { 10636 var addressFound = window.vm_delivery_details 10637 ? !!window.vm_delivery_details.address_found 10638 : false; 10639 if (!addressFound) { 10640 var deliveryMsg = (this.some_words && this.some_words.please_complete_delivery_address) 10641 ? this.some_words.please_complete_delivery_address 10642 : 'Please complete your delivery address to continue.'; 10643 this.error_placeorder = [deliveryMsg]; 10644 return; 10645 } 10646 } 10647 10648 if(this.checkout_transaction_type=="pickup"){ 10649 let $some_words = JSON.parse(some_words); 10650 ElementPlus.ElMessageBox.confirm( 10651 $some_words.pickup_collection_confirm, 10652 $some_words.confirm, 10653 { 10654 confirmButtonText: $some_words.ok, 10655 cancelButtonText: $some_words.cancel, 10656 type: 'info', 10657 } 10658 ) 10659 .then(() => { 10660 this.submitOrder(); 10661 }) 10662 .catch(() => { 10663 // 10664 }); 10665 } else { 10666 this.submitOrder(); 10667 } 10668 }, 10669 submitOrder(){ 10670 var timenow = 100; 10671 var $choosen_delivery = !empty(getCookie('choosen_delivery'))? JSON.parse(getCookie('choosen_delivery')) : [] ; 10672 let currency_code = getCookie('currency_code'); 10673 currency_code = !empty(currency_code)?currency_code:''; 10674 10675 let address_uuid = ''; 10676 if ((typeof vm_checkout_address !== "undefined") && ( vm_checkout_address !== null)) { 10677 address_uuid = vm_checkout_address.address_uuid; 10678 } 10679 if ((typeof vm_delivery_details !== "undefined") && ( vm_delivery_details !== null)) { 10680 address_uuid = vm_delivery_details.address_uuid; 10681 } 10682 10683 var $params = { 10684 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 10685 'cart_uuid':getCookie('cart_uuid'), 10686 'payment_uuid' : this.selected_payment_uuid, 10687 'choosen_delivery' : $choosen_delivery, 10688 'include_utensils' : getStorage("include_utensils"), 10689 'payment_change' : vm_payment_lists ? vm_payment_lists.payment_change : 0, 10690 'currency_code' : currency_code, 10691 'room_uuid': vm_checkout_booking.room_uuid, 10692 'table_uuid': vm_checkout_booking.table_uuid, 10693 'guest_number': vm_checkout_booking.guest_number, 10694 'use_digital_wallet': this.use_digital_wallet==true?1:0, 10695 'address_uuid': address_uuid 10696 }; 10697 10698 ajax_request[timenow] = $.ajax({ 10699 url: ajaxurl+"/placeOrder", 10700 method: "PUT", 10701 dataType: "json", 10702 data: JSON.stringify($params), 10703 contentType : $content_type.json , 10704 timeout: $timeout, 10705 crossDomain: true, 10706 beforeSend: data => { 10707 this.is_submit = true; 10708 if(ajax_request[timenow] != null) { 10709 ajax_request[timenow].abort(); 10710 } 10711 } 10712 }); 10713 10714 ajax_request[timenow].done( data => { 10715 if (data.code==1){ 10716 this.error_placeorder = []; 10717 var $payment_instructions = data.details.payment_instructions; 10718 var $order_bw = parseInt(data.details.order_bw); 10719 if ((typeof data.details.order_bw !== "undefined") && ( data.details.order_bw !== null)) { 10720 // 10721 } else { 10722 $order_bw = 3; 10723 } 10724 10725 if($order_bw>2) { 10726 return false; 10727 } 10728 10729 var $redirect = data.details.redirect; 10730 10731 if($payment_instructions.method=="offline"){ 10732 window.location.href = $redirect; 10733 } else { 10734 vm_payment_lists.PaymentRender({ 10735 'order_uuid': data.details.order_uuid, 10736 'payment_code' : data.details.payment_code, 10737 'payment_uuid' : data.details.payment_uuid, 10738 'force_payment_data': data.details.force_payment_data 10739 }); 10740 } 10741 } else { 10742 this.is_submit = false;
10743 this.error_placeorder = data.msg; 10744 } 10745 }); // ajax done 10746 10747 ajax_request[timenow].always( data => { 10748 updateStickyCart(); 10749 }); 10750 10751 } 10752 }, 10753}); 10754app_cart.use(ElementPlus); 10755//const vue_cart = app_cart.mount('#vue-cart'); 10756window.vue_cart = app_cart.mount('#vue-cart'); 10757 10758 10759 10760/* 10761COMPONENTS NEW ORDER MODAL 10762*/ 10763const app_neworder = Vue.createApp({ 10764 data() { 10765 return { 10766 resolvePromise: undefined, 10767 rejectPromise: undefined, 10768 title : t('Create new order?'), 10769 new_order_label : "New order", 10770 content : '', 10771 is_loading : false, 10772 } 10773 }, 10774 mounted() { 10775 let $some_words = JSON.parse(some_words); 10776 if (Object.keys($some_words).length > 0) { 10777 this.title = $some_words.created_new_order + "?"; 10778 this.new_order_label = $some_words.new_order_label; 10779 } 10780 }, 10781 methods: { 10782 show(opts = {}){ 10783 this.content = opts.content; 10784 $('#confirmModalOrder').modal('show'); 10785 return new Promise((resolve, reject) => { 10786 this.resolvePromise = resolve 10787 this.rejectPromise = reject 10788 }); 10789 }, 10790 onConfirm() { 10791 this.resolvePromise(true); 10792 }, 10793 onClose(){ 10794 this.resolvePromise(false); 10795 $('#confirmModalOrder').modal('hide'); 10796 }, 10797 clearCart(cart_uuid){ 10798 10799 this.is_loading = true; 10800 10801 return new Promise((resolve, reject) => { 10802 10803 var $params; var timenow = 1; 10804 $params="cart_uuid=" + cart_uuid; 10805 $params+=addValidationRequest(); 10806 ajax_request[timenow] = $.ajax({ 10807 url: ajaxurl+"/clearCart", 10808 method: "POST", 10809 dataType: "json", 10810 data: $params, 10811 contentType : $content_type.form , 10812 timeout: $timeout, 10813 crossDomain: true, 10814 beforeSend: function( xhr ) { 10815 if(ajax_request[timenow] != null) { 10816 ajax_request[timenow].abort(); 10817 } 10818 } 10819 }); 10820 10821 ajax_request[timenow].done( data => { 10822 this.is_loading = false; 10823 $('#confirmModalOrder').modal('hide'); 10824 resolve(true); 10825 }); // ajax done 10826 10827 }); 10828 } 10829 }// 10830}); 10831 10832app_neworder.component("components-neworder", { 10833 props: ['title','content','is_loading','new_order_label'], 10834 template: ` 10835 <div class="modal" id="confirmModalOrder" tabindex="-1" role="dialog" aria-labelledby="confirmModalOrder" aria-hidden="true"> 10836 <div class="modal-dialog modal-dialog-centered" role="document"> 10837 <div class="modal-content"> 10838 10839 <div class="modal-header"> 10840 <button type="button" class="close" aria-label="Close" @click="$emit('closeOrder')" > 10841 <span aria-hidden="true">×</span> 10842 </button> 10843 </div> 10844 10845 <div class="modal-body" > 10846 <h4 class="bold">{{ title }}</h4> 10847 <div>{{ content }}</div> 10848 </div> 10849 10850 <div class="modal-footer justify-content-start"> 10851 <button class="btn btn-black w-100" @click="$emit('newOrder')" :class="{ loading: is_loading }" > 10852 <span class="label">{{ new_order_label }}</span> 10853 <div class="m-auto circle-loader" data-loader="circle-side"></div> 10854 </button> 10855 </div> <!--footer--> 10856 10857 </div> <!--content--> 10858 </div> <!--dialog--> 10859 </div> <!--modal--> 10860 `, 10861})
10862const vue_confirm_neworder = app_neworder.mount('#components-modal-neworder') 10863 10864 10865 10866/** 10867 REVIEWS 10868 this is function for displaying reviews 10869 target = section-review 10870*/ 10871const app_review = Vue.createApp({ 10872 data(){ 10873 return { 10874 review_loading : true, 10875 review_loadmore : false, 10876 review_page : 0, 10877 review_data : [] 10878 }; 10879 }, 10880 mounted () { 10881 this.loadReview(); 10882 }, 10883 updated () { 10884 setTimeout(function() { 10885 initStarRating(); 10886 }, 1); 10887 }, 10888 methods: { 10889 loadReview(page){ 10890 10891 var $params; var timenow = getTimeNow(); 10892 $params="merchant_id=" + merchant_id; 10893 if(!empty(page)){ 10894 $params+="&page=" + page; 10895 } 10896 $params+=addValidationRequest(); 10897 10898 ajax_request[timenow] = $.ajax({ 10899 url: ajaxurl+"/getReview", 10900 method: "POST", 10901 dataType: "json", 10902 data: $params, 10903 contentType : $content_type.form , 10904 timeout: $timeout, 10905 crossDomain: true, 10906 beforeSend: data => { 10907 if(ajax_request[timenow] != null) { 10908 ajax_request[timenow].abort(); 10909 } 10910 } 10911 }); 10912 10913 ajax_request[timenow].done( data => { 10914 if(data.code==1){ 10915 this.review_data.push(data.details.data); 10916 this.review_loadmore = data.details.show_next_page; 10917 this.review_page = data.details.page; 10918 this.magnific(); 10919 } 10920 }); // ajax done 10921 10922 ajax_request[timenow].always( data => { 10923 this.review_loading = false; 10924 }); 10925 10926 }, 10927 loadMore(event){ 10928 if (event) { 10929 event.preventDefault() 10930 } 10931 this.loadReview(this.review_page); 10932 }, 10933 openFormReview(event){ 10934 if (event) { 10935 event.preventDefault() 10936 } 10937 dump("openFormReview"); 10938 /*$('#reviewModal').modal('hide'); 10939 vue_app_review.show({}); 10940 */ 10941 }, 10942 magnific(){ 10943 10944 setTimeout(function() { 10945 $('.review_magnific').magnificPopup({ 10946 delegate: 'a', 10947 type: 'image', 10948 gallery: { 10949 enabled: true 10950 }, 10951 removalDelay: 300, 10952 mainClass: 'mfp-fade' 10953 }); 10954 }, 1); 10955 10956 }, 10957 }, 10958}); 10959app_review.use(ElementPlus); 10960const vue_review = app_review.mount('#section-review'); 10961 10962 10963/* 10964 FACEBOOK LOGIN 10965*/ 10966const componentsFacebook = { 10967 props: ['app_id','version','errors','verification','redirect_to','label','show_button','button_width'], 10968 data() { 10969 return { 10970 social_strategy :'facebook', 10971 access_token : '' 10972 } 10973 }, 10974 mounted() { 10975 if(this.show_button){ 10976 this.includeFacebook(); 10977 window.checkLoginState = this.checkLoginState; 10978 } 10979 }, 10980 methods: { 10981 includeFacebook(){ 10982 if (window.fbAsyncInit == null) { 10983 new Promise((resolve) => { 10984 window.fbAsyncInit = function () { 10985 resolve(); 10986 }; 10987 const doc = window.document; 10988 const scriptId = "facebook-script"; 10989 const scriptTag = doc.createElement("script"); 10990 scriptTag.id = scriptId; 10991 scriptTag.setAttribute("src", "https://connect.facebook.net/en_US/sdk.js"); 10992 doc.head.appendChild(scriptTag); 10993 }).then(() => { 10994 this.initFacebook(); 10995 }); 10996 } else { 10997 this.initFacebook(); 10998 } 10999 }, 11000 initFacebook(){ 11001 FB.init({ 11002 appId : this.app_id, 11003 cookie : true, 11004 xfbml : true, 11005 version: this.version 11006 }); 11007 }, 11008 checkLoginState(){ 11009 FB.getLoginStatus(response => { 11010 dump(response); 11011 if (response.status === 'connected') { 11012 this.access_token = response.authResponse.accessToken; 11013 this.fetchInformation(); 11014 } else { 11015 this.attempLogin(); 11016 } 11017 }); 11018 }, 11019 attempLogin(){ 11020 FB.login(response => { 11021 dump(response); 11022 if (response.authResponse) { 11023 this.access_token = response.authResponse.accessToken; 11024 this.fetchInformation(); 11025 } else { 11026 vm_bootbox.alert(this.errors.user_cancelled, {}); 11027 } 11028 }, { scope: 'public_profile,email' }); 11029 }, 11030 fetchInformation(){ 11031 FB.api('/me?fields=id,email,first_name,last_name', data => { 11032 dump(data); 11033 if (!data.email) { 11034 data.email = 'fb_noemail_' + data.id + '@placeholder.invalid'; 11035 } 11036 var social_params = { 11037 'YII_CSRF_TOKEN': $('meta[name=YII_CSRF_TOKEN]').attr('content'), 11038 id: data.id, 11039 email_address: data.email, 11040 first_name: data.first_name, 11041 last_name: data.last_name, 11042 social_strategy: this.social_strategy, 11043 verification: this.verification, 11044 redirect_to: this.redirect_to, 11045 social_token: this.access_token 11046 }; 11047 this.$emit('socialRegistration', social_params); 11048 }); 11049 }, 11050 }, 11051 template: ` 11052 <div v-if="show_button" class="social-login"> 11053 <div class="fb-login-button fullwidth-child" 11054 :data-width="button_width" 11055 data-size="large" 11056 data-button-type="login_with" 11057 data-layout="rounded" 11058 data-scope="public_profile,email" 11059 data-auto-logout-link="false" 11060 data-use-continue-as="true" 11061 data-onlogin="checkLoginState" 11062 ></div> 11063 </div> 11064 ` 11065}; 11066 11067 11068/* 11069 APPLE LOGIN (WEB) 11070 Uses Apple's JS SDK with usePopup:true. 11071 The id_token JWT returned by Apple is decoded client-side to extract the 11072 Apple user ID (sub) and email, then passed to the shared SocialRegister flow. 11073*/ 11074const componentsAppleLogin = { 11075 props: ['label', 'client_id', 'redirect_uri', 'show_button', 'verification', 'redirect_to'], 11076 data() { 11077 return { social_strategy: 'apple' }; 11078 }, 11079 mounted() { 11080 if (this.show_button) { 11081 this.includeLibrary(); 11082 } 11083 }, 11084 methods: { 11085 includeLibrary() { 11086 $.getScript( 11087 'https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js', 11088 () => { this.init(); } 11089 ); 11090 }, 11091 init() { 11092 try { 11093 AppleID.auth.init({ 11094 clientId: this.client_id, 11095 scope: 'name email', 11096 redirectURI: this.redirect_uri, 11097 usePopup: true, 11098 }); 11099 } catch (e) { 11100 console.log('Apple Sign In init error:', e); 11101 } 11102 }, 11103 async handleAppleLogin() { 11104 try { 11105 const response = await AppleID.auth.signIn(); 11106 const idToken = response.authorization.id_token; 11107 11108 // Decode the JWT payload â Apple signs it, no client-side verification needed. 11109 const b64 = idToken.split('.')[1].replace(/-/g, '+').replace(/_/g, '/'); 11110 const payload = JSON.parse(atob(b64)); 11111 11112 const firstName = (response.user && response.user.name) 11113 ? (response.user.name.firstName || '') : ''; 11114 const lastName = (response.user && response.user.name) 11115 ? (response.user.name.lastName || '') : ''; 11116 11117 const social_params = { 11118 YII_CSRF_TOKEN: $('meta[name=YII_CSRF_TOKEN]').attr('content'), 11119 id: payload.sub, 11120 email_address: payload.email || '', 11121 first_name: firstName, 11122 last_name: lastName, 11123 social_strategy: this.social_strategy, 11124 verification: this.verification, 11125 redirect_to: this.redirect_to, 11126 social_token: idToken, 11127 }; 11128 this.$emit('socialRegistration', social_params); 11129 } catch (e) { 11130 // Ignore deliberate popup close 11131 if (e && e.error === 'popup_closed_by_user') return; 11132 console.log('Apple Sign In error:', e); 11133 } 11134 }, 11135 }, 11136 template: ` 11137 <div v-if="show_button" class="apple-web-wrap"> 11138 <a href="javascript:;" @click="handleAppleLogin" class="apple-web-btn">
11139 <svg class="apple-web-icon" viewBox="0 0 814 1000" xmlns="http://www.w3.org/2000/svg"> 11140 <path d="M788.1 340.9c-5.8 4.5-108.2 62.2-108.2 190.5 0 148.4 130.3 200.9 134.2 202.2-.6 3.2-20.7 71.9-68.7 141.9-42.8 61.6-87.5 123.1-155.5 123.1s-85.5-39.5-164-39.5c-76.5 0-103.7 40.8-165.9 40.8s-105.6-57.8-155.5-127.4C46 790.7 0 663 0 541.8c0-207.5 135.4-317.5 268.5-317.5 86.5 0 148.9 56.8 199.8 56.8 49.4 0 126.4-60.3 225.9-60.3 36.3 0 130.6 3.2 198.7 99.2zm-234-181.5c43.1-50.8 74.3-121.3 74.3-191.8 0-9.7-.6-19.4-2.6-27.4-70.7 2.6-154.7 47.6-205.6 103.3-39.5 44.5-72.5 114.9-72.5 186.6 0 10.4 1.9 20.7 2.6 23.9 4.5.6 11.7 1.3 18.2 1.3 63.6 0 144.7-43.8 185.6-95.9z"/> 11141 </svg> 11142 {{label.title}} 11143 </a> 11144 </div> 11145 `, 11146}; 11147 11148 11149/* 11150 GOOGLE LOGIN 11151*/ 11152const componentsGoogleLogin = { 11153 props: ['label','client_id','cookiepolicy','scope','redirect_to','verification','show_button','button_width'], 11154 data() { 11155 return { 11156 social_strategy :'google', 11157 auth2 : undefined 11158 } 11159 }, 11160 mounted() { 11161 if(this.show_button){ 11162 this.includeLibrary(); 11163 } 11164 }, 11165 methods: { 11166 includeLibrary(){ 11167 $.getScript("https://accounts.google.com/gsi/client", ()=> { 11168 this.init(); 11169 }); 11170 }, 11171 init(){ 11172 try { 11173 // iOS Safari cannot auto-close the OAuth popup, leaving a blank 11174 // accounts.google.com tab. Redirect mode fixes this on iOS. 11175 // On Android/desktop, redirect mode sends the auth request from 11176 // inside Google's iframe and causes a 401, so keep popup mode there. 11177 const isIOS = /iPhone|iPad|iPod/i.test(navigator.userAgent); 11178 const googleConfig = { client_id: this.client_id }; 11179 if (isIOS) { 11180 googleConfig.ux_mode = 'redirect'; 11181 googleConfig.login_uri = window.location.origin + '/account/google_callback'; 11182 } else { 11183 googleConfig.callback = this.handleResponse; 11184 } 11185 google.accounts.id.initialize(googleConfig); 11186 11187 google.accounts.id.renderButton( 11188 this.$refs.google_target, 11189 { theme: 'outline', shape: 'pill', size: 'large', width: parseFloat(this.button_width) } 11190 ); 11191 } catch (error) { 11192 console.log(error); 11193 } 11194 }, 11195 handleResponse(data){ 11196 const payload = jwt_decode(data.credential) 11197 dump(payload); 11198 var social_params = { 11199 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 11200 id : payload.sub, 11201 email_address : payload.email, 11202 first_name : payload.given_name , 11203 last_name : payload.family_name , 11204 social_strategy : this.social_strategy, 11205 verification : this.verification, 11206 redirect_to : this.redirect_to, 11207 social_token : data.credential 11208 }; 11209 this.$emit('socialRegistration',social_params); 11210 11211 }, 11212 }, 11213 template: ` 11214 <div v-if="show_button" class="fullwidth-child" > 11215 <a href="javascript:;" ref="google_target" class="s-google"> 11216 {{label.title}} 11217 </a> 11218 </div> 11219 ` 11220}; 11221 11222 11223/** 11224 LOGIN VIEW RENDER 11225 target = vue-login 11226*/ 11227const app_login = Vue.createApp({ 11228 components: { 11229 'component-facebook' : componentsFacebook, 11230 'component-google' : componentsGoogleLogin, 11231 'component-apple' : componentsAppleLogin, 11232 'component-bootbox': Componentsbootbox, 11233 'components-recapcha' : componentsRecaptcha, 11234 'component-phone' : ComponentsPhoneNumber, 11235 }, 11236 data(){ 11237 return { 11238 username : '', 11239 password : '', 11240 loading : false, 11241 ready : false, 11242 show_password : false, 11243 password_type: 'password', 11244 rememberme : false, 11245 redirect : '', 11246 error : [], 11247 success : '', 11248 recaptcha_response : '', 11249 11250 email_address : '', 11251 mobile_number : '', 11252 mobile_prefix :'', 11253 otp :'', 11254 validation_type : 1, 11255 is_verify : false, 11256 origCounter : 20, 11257 counter : 5, 11258 timer : undefined, 11259 }; 11260 }, 11261 mounted () { 11262 if ((typeof _resend_counter !== "undefined") && ( _resend_counter !== null)) { 11263 this.origCounter = parseInt(_resend_counter); 11264 } 11265 this.redirect = redirect_to; 11266 // this.validateIdentity(); // LICENSE CHECK REMOVED 11267 }, 11268 computed: { 11269 formValid(){ 11270 if( !empty(this.username) && !empty(this.password) ){ 11271 if( this.$refs.vueRecaptcha.is_enabled ){ 11272 if(!empty(this.recaptcha_response)){ 11273 return true; 11274 } else return false;
11275 } else return true; 11276 } else return false; 11277 }, 11278 checkForm(){ 11279 if(this.validation_type==2){ 11280 if(empty(this.mobile_number)){ 11281 return true; 11282 } 11283 } else { 11284 if(!this.validEmail(this.email_address)){ 11285 return true; 11286 } 11287 } 11288 return false; 11289 }, 11290 }, 11291 methods: { 11292 startTimer(){ 11293 this.counter = this.origCounter; 11294 this.timer = setInterval(() => { 11295 this.counter--; 11296 if(this.counter<=0){ 11297 this.stopTimer(); 11298 } 11299 }, 1000) 11300 }, 11301 stopTimer(){ 11302 clearInterval(this.timer); 11303 }, 11304 createMerchantUser(redirectUrl){ 11305 try{ 11306 const url = new URL(redirectUrl, window.location.origin); 11307 const merchant_uuid = url.searchParams.get('uuid'); 11308 if(!merchant_uuid){ 11309 window.location.href = redirectUrl; 11310 return; 11311 } 11312 axios({ 11313 method: 'PUT', 11314 url: ajaxurl+"/createMerchantUser" , 11315 data : { 11316 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 11317 'username' : this.username, 11318 'password' : this.password, 11319 'cpassword' : this.cpassword, 11320 'first_name' : this.restaurant_name, 11321 'last_name' : '', 11322 'contact_email' : this.contact_email, 11323 'mobile_number' : this.mobile_number, 11324 'mobile_prefix' : this.mobile_prefix, 11325 'merchant_uuid' : merchant_uuid, 11326 }, 11327 timeout: $timeout, 11328 }).then( response => { 11329 if(response.data.code==1){ 11330 const _base = (typeof site_url !== 'undefined' && site_url) ? site_url : ''; 11331 window.location.href = _base+"/merchant/stripeconnect?uuid="+merchant_uuid; 11332 } else { 11333 this.response = response.data; 11334 } 11335 }).catch(error => {}).then(() => {}); 11336 }catch(e){ 11337 window.location.href = redirectUrl; 11338 } 11339 }, 11340 validEmail: function (email) { 11341 var re = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; 11342 return re.test(email); 11343 }, 11344 showPassword() 11345 { 11346 this.show_password = this.show_password==true?false:true; 11347 if(this.show_password){ 11348 this.password_type = 'text'; 11349 } else this.password_type = 'password'; 11350 }, 11351 login(){ 11352 11353 var timenow = getTimeNow(); 11354 var $params = { 11355 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 11356 'username' : this.username, 11357 'password' : this.password, 11358 'rememberme' : this.rememberme, 11359 'redirect': this.redirect, 11360 'recaptcha_response' : this.recaptcha_response, 11361 }; 11362 11363 ajax_request[timenow] = $.ajax({ 11364 url: ajaxurl+"/userLogin", 11365 method: "PUT", 11366 dataType: "json", 11367 data: JSON.stringify($params) , 11368 contentType : $content_type.json , 11369 timeout: $timeout, 11370 crossDomain: true, 11371 beforeSend: data => { 11372 this.loading = true; 11373 this.error = []; 11374 this.success = ''; 11375 if(ajax_request[timenow] != null) { 11376 ajax_request[timenow].abort(); 11377 } 11378 } 11379 }); 11380 11381 ajax_request[timenow].done( data => { 11382 if ( data.code==1){ 11383 this.success = data.msg; 11384 window.location.href = data.details.redirect; 11385 } else { 11386 this.error = data.msg; 11387 this.recaptchaExpired(); 11388 } 11389 }); // ajax done 11390 11391 ajax_request[timenow].always( data => { 11392 this.loading = false; 11393 }); 11394 11395 }, 11396 SocialRegister(data){ 11397 11398 var $params = data; 11399 var timenow = 1; 11400 $params = JSON.stringify($params); 11401 11402 ajax_request[timenow] = $.ajax({ 11403 url: ajaxurl+"/SocialRegister", 11404 method: "PUT", 11405 dataType: "json", 11406 data: $params , 11407 contentType : $content_type.json , 11408 timeout: $timeout, 11409 crossDomain: true, 11410 beforeSend: data => { 11411 this.loading = true; 11412 this.error = []; 11413 if(ajax_request[timenow] != null) { 11414 ajax_request[timenow].abort(); 11415 } 11416 } 11417 }); 11418 11419 ajax_request[timenow].done( data => { 11420 if(data.code==1){ 11421 if(!empty(data.details.redirect)){ 11422 this.success = data.msg; 11423 window.location.href = data.details.redirect; 11424 } else if (data.details && data.details.is_login === false && data.details.uuid) { 11425 // New social user â send to complete_registration to collect phone number. 11426 window.location.href = site_url + 'account/complete_registration?uuid=' + encodeURIComponent(data.details.uuid); 11427 } else this.success = data.msg; 11428 } else this.error = data.msg; 11429 }); // ajax done 11430 11431 ajax_request[timenow].always( data => { 11432 this.loading = false;
11433 }); 11434 11435 }, 11436 recaptchaVerified(response) { 11437 this.recaptcha_response = response; 11438 }, 11439 recaptchaExpired() { 11440 if( this.$refs.vueRecaptcha.is_enabled ){ 11441 this.$refs.vueRecaptcha.reset(); 11442 } 11443 }, 11444 recaptchaFailed() { 11445 11446 }, 11447 validateIdentity(){ 11448 var domain = window.location.hostname; 11449 axios.get('https://bastisapp.com/activation/index/check', { 11450 params: { 11451 id: "UYIiWfAfWx414it65oUbeXf4I1yjDNSZi2UxnBBLQa8hpHAcVlyP+Sx0OL8vmfcwnzSYkw==", 11452 domain: domain 11453 } 11454 }) 11455 .then( response => { 11456 if(response.data.code==1){ 11457 // 11458 } else { 11459 window.location.href = "https://bastisapp.com/activation/"; 11460 } 11461 }).catch(error => { 11462 11463 }).then(data => { 11464 11465 }); 11466 }, 11467 getOTPLogin(){ 11468 this.loading = true; 11469 this.success = ''; 11470 this.stopTimer(); 11471 let actionPassword = this.validation_type==2 ? ajaxurl+"/requestResetpasswordsms" : ajaxurl+"/requestEmailOTP"; 11472 let params = "&email_address="+this.email_address; 11473 params += "&mobile_number="+this.mobile_number; 11474 params += "&mobile_prefix="+this.mobile_prefix; 11475 axios({ 11476 method: 'POST', 11477 url: actionPassword , 11478 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + params, 11479 timeout: $timeout, 11480 }).then( response => { 11481 if(response.data.code==1){ 11482 this.startTimer(); 11483 this.is_verify = true; 11484 this.success = response.data.msg; 11485 this.otp = ''; 11486 } else { 11487 ElementPlus.ElNotification({ 11488 title: "", 11489 message: response.data.msg, 11490 position: 'bottom-right', 11491 type: 'warning', 11492 }); 11493 } 11494 }).catch(error => { 11495 // 11496 }).then(data => { 11497 this.loading = false; 11498 }); 11499 }, 11500 userLoginByOTP(){ 11501 this.loading = true; 11502 let params = "&email_address="+this.email_address; 11503 params += "&mobile_number="+this.mobile_number; 11504 params += "&mobile_prefix="+this.mobile_prefix; 11505 params += "&validation_type="+this.validation_type; 11506 params += "&otp="+this.otp; 11507 params += "&redirect="+this.redirect; 11508 axios({ 11509 method: 'POST', 11510 url: ajaxurl+"/userLoginByOTP" , 11511 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + params, 11512 timeout: $timeout, 11513 }).then( response => { 11514 if(response.data.code==1){ 11515 this.success = response.data.msg; 11516 window.location.href = response.data.details.redirect; 11517 } else { 11518 ElementPlus.ElNotification({ 11519 title: "", 11520 message: response.data.msg, 11521 position: 'bottom-right', 11522 type: 'warning', 11523 }); 11524 } 11525 }).catch(error => { 11526 // 11527 }).then(data => { 11528 this.loading = false; 11529 }); 11530 }, 11531 startOver(){ 11532 this.is_verify = false; 11533 this.success = ''; 11534 }, 11535 // 11536 }, 11537}); 11538app_login.use(Maska); 11539app_login.use(ElementPlus); 11540const vm_login = app_login.mount('#vue-login'); 11541 11542 11543 11544/** 11545 CUSTOMER REGISTRATION 11546 target = vue-register 11547*/ 11548const app_client_register = Vue.createApp({ 11549 components: { 11550 'component-phone' : ComponentsPhoneNumber, 11551 'vue-recaptcha' : componentsRecaptcha, 11552 }, 11553 data(){ 11554 return { 11555 loading : false, 11556 ready : false, 11557 show_password : false, 11558 agree_terms : false, 11559 password_type: 'password', 11560 firstname : '', 11561 lastname : '', 11562 email_address : '', 11563 mobile_number : '', 11564 mobile_prefix :'', 11565 password : '', 11566 cpassword :'', 11567 mobile_prefixes : [], 11568 error : [], 11569 success : '', 11570 redirect : '', 11571 next_url : '', 11572 recaptcha_response : '', 11573 show_recaptcha : false, 11574 custom_fields :{} 11575 }; 11576 }, 11577 mounted () { 11578 dump("mounted"); 11579 this.redirect = redirect_to; 11580 this.next_url = next_url; 11581 if ((typeof _capcha !== "undefined") && ( _capcha !== null)) { 11582 this.show_recaptcha = _capcha==1?true:false; 11583 } 11584 }, 11585 updated () { 11586 //dump('updated') ; 11587 this.validate(); 11588 }, 11589 methods: { 11590 validate(){ 11591 if( !empty(this.firstname) && !empty(this.lastname) 11592 && !empty(this.email_address) && !empty(this.mobile_number) && !empty(this.password) && !empty(this.cpassword) ){ 11593 this.ready = true; 11594 } else this.ready = false;
11595 }, 11596 showPassword() 11597 { 11598 this.show_password = this.show_password==true?false:true; 11599 if(this.show_password){ 11600 this.password_type = 'text'; 11601 } else this.password_type = 'password'; 11602 }, 11603 onRegister(){ 11604 11605 var timenow = getTimeNow(); 11606 var $params = { 11607 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 11608 'firstname' : this.firstname, 11609 'lastname' : this.lastname, 11610 'email_address' : this.email_address, 11611 'mobile_number' : this.mobile_number, 11612 'mobile_prefix': this.mobile_prefix, 11613 'password': this.password, 11614 'cpassword': this.cpassword, 11615 'redirect': this.redirect, 11616 //'next_url': this.next_url, 11617 'recaptcha_response': this.recaptcha_response, 11618 'custom_fields':this.custom_fields 11619 }; 11620 11621 ajax_request[timenow] = $.ajax({ 11622 url: ajaxurl+"/registerUser", 11623 method: "PUT", 11624 dataType: "json", 11625 data: JSON.stringify($params) , 11626 contentType : $content_type.json , 11627 timeout: $timeout, 11628 crossDomain: true, 11629 beforeSend: data => { 11630 this.loading = true; 11631 this.error = []; 11632 this.success = ''; 11633 if(ajax_request[timenow] != null) { 11634 ajax_request[timenow].abort(); 11635 } 11636 } 11637 }); 11638 11639 ajax_request[timenow].done( data => { 11640 if ( data.code==1){ 11641 this.success = data.msg; 11642 window.location.href = data.details.redirect; 11643 } else if ( data.code==3){ 11644 this.success = data.msg; 11645 } else { 11646 this.error = data.msg; 11647 this.recaptchaExpired(); 11648 } 11649 }); // ajax done 11650 11651 ajax_request[timenow].always( data => { 11652 this.loading = false; 11653 }); 11654 11655 }, 11656 recaptchaVerified(response) { 11657 this.recaptcha_response = response; 11658 }, 11659 recaptchaExpired() { 11660 if ( this.show_recaptcha){ 11661 this.$refs.vueRecaptcha.reset(); 11662 } 11663 }, 11664 recaptchaFailed() { 11665 11666 }, 11667 11668 }, 11669}); 11670 11671app_client_register.use(Maska); 11672app_client_register.use(ElementPlus); 11673const vm_client_register = app_client_register.mount('#vue-register'); 11674 11675 11676/* 11677 ACCOUNT VERIFICATION FOR NORMAL SIGNUP 11678*/ 11679 11680const app_account_verification = Vue.createApp({ 11681 data(){ 11682 return { 11683 is_loading : false, 11684 error : [], 11685 success : '', 11686 steps : 1, 11687 verification_code : '', 11688 client_uuid : '', 11689 next_url : '', 11690 counter : 20, 11691 timer : undefined 11692 }; 11693 }, 11694 mounted () { 11695 if ((typeof _uuid !== "undefined") && ( _uuid !== null)) { 11696 this.client_uuid = _uuid; 11697 } 11698 if ((typeof _redirect_to !== "undefined") && ( _redirect_to !== null)) { 11699 this.next_url = _redirect_to; 11700 } 11701 if ((typeof _resend_counter !== "undefined") && ( _resend_counter !== null)) { 11702 this.counter = parseInt(_resend_counter); 11703 } 11704 this.startTimer(); 11705 }, 11706 computed: { 11707 CodeValid(){ 11708 if(!empty(this.verification_code) ){ 11709 return true; 11710 } 11711 return false; 11712 }, 11713 }, 11714 watch: { 11715 counter(newdata,olddata){ 11716 if(newdata<=0){ 11717 this.stopTimer(); 11718 } 11719 } 11720 }, 11721 methods: { 11722 startTimer(){ 11723 this.timer = setInterval(() => { 11724 this.counter--; 11725 }, 1000) 11726 }, 11727 stopTimer(){ 11728 clearInterval(this.timer); 11729 this.success=''; 11730 }, 11731 11732 resendCode(){ 11733 11734 var $params; var timenow = 1; 11735 var $params = { 11736 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 11737 'client_uuid': this.client_uuid, 11738 }; 11739 $params = JSON.stringify($params); 11740 ajax_request[timenow] = $.ajax({ 11741 url: ajaxurl+"/requestCode", 11742 method: "PUT", 11743 dataType: "json", 11744 data: $params , 11745 contentType : $content_type.json , 11746 timeout: $timeout, 11747 crossDomain: true, 11748 beforeSend: data => { 11749 this.is_loading = true; 11750 this.error = []; this.success =''; 11751 if(ajax_request[timenow] != null) { 11752 ajax_request[timenow].abort(); 11753 } 11754 } 11755 }); 11756 11757 ajax_request[timenow].done( data => { 11758 if(data.code==1){ 11759 if ((typeof _resend_counter !== "undefined") && ( _resend_counter !== null)) { 11760 this.counter = parseInt(_resend_counter); 11761 } else this.counter = 20; 11762 11763 this.startTimer(); 11764 this.success = data.msg; 11765 11766 if(!empty(data.details)){ 11767 if(!empty(data.details.verification_code)){ 11768 helpNotify(data.details.verification_code); 11769 } 11770 } 11771 } else { 11772 this.error = data.msg; 11773 } 11774 }); 11775 11776 ajax_request[timenow].always( data => { 11777 this.is_loading = false;
11778 }); 11779 11780 }, 11781 11782 verifyCode(){ 11783 11784 var $params = { 11785 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 11786 'client_uuid': this.client_uuid, 11787 'verification_code' : this.verification_code, 11788 'auto_login' : true 11789 }; 11790 var timenow = 1; 11791 $params = JSON.stringify($params); 11792 11793 ajax_request[timenow] = $.ajax({ 11794 url: ajaxurl+"/verifyCode", 11795 method: "PUT", 11796 dataType: "json", 11797 data: $params , 11798 contentType : $content_type.json , 11799 timeout: $timeout, 11800 crossDomain: true, 11801 beforeSend: data => { 11802 this.error = []; 11803 this.is_loading = true; 11804 if(ajax_request[timenow] != null) { 11805 ajax_request[timenow].abort(); 11806 } 11807 } 11808 }); 11809 11810 ajax_request[timenow].done( data => { 11811 if ( data.code==1){ 11812 window.location.href = data.details.redirect; 11813 } else { 11814 this.error = data.msg; 11815 } 11816 }); // ajax done 11817 11818 ajax_request[timenow].always( data => { 11819 this.is_loading = false; 11820 }); 11821 }, 11822 11823 }, 11824}); 11825app_account_verification.use(Maska); 11826const vm_account_verification = app_account_verification.mount('#vue-account-verification'); 11827 11828 11829 11830/* 11831 SIGNUP LESS 11832*/ 11833const app_client_register_less = Vue.createApp({ 11834 components: { 11835 'component-phone' : ComponentsPhoneNumber, 11836 'vue-recaptcha' : componentsRecaptcha, 11837 }, 11838 data(){ 11839 return { 11840 is_loading : false, 11841 mobile_number : '', 11842 mobile_prefix :'', 11843 error : [], 11844 steps : 1, 11845 verification_code : '', 11846 client_uuid : '', 11847 firstname : '', 11848 lastname : '', 11849 email_address : '', 11850 password : '', 11851 cpassword : '', 11852 show_password : false, 11853 password_type: 'password', 11854 next_url : '', 11855 show_recaptcha : false, 11856 recaptcha_response : '', 11857 counter : 40, 11858 timer : undefined, 11859 success : '', 11860 custom_fields : {} 11861 } 11862 }, 11863 mounted () { 11864 this.next_url = this.$refs.redirect.value; 11865 if ((typeof _capcha !== "undefined") && ( _capcha !== null)) { 11866 this.show_recaptcha = _capcha==1?true:false; 11867 } 11868 11869 if ((typeof _resend_counter !== "undefined") && ( _resend_counter !== null)) { 11870 this.counter = parseInt(_resend_counter); 11871 } 11872 11873 }, 11874 watch: { 11875 counter(newdata,olddata){ 11876 if(newdata<=0){ 11877 this.stopTimer(); 11878 } 11879 } 11880 }, 11881 computed: { 11882 DataValid(){ 11883 if(!empty(this.mobile_number) && empty(!this.mobile_prefix) ){ 11884 if ( this.show_recaptcha){ 11885 if (!empty(this.recaptcha_response)){ 11886 return true; 11887 } 11888 } else return true; 11889 } 11890 return false; 11891 }, 11892 CodeValid(){ 11893 if(!empty(this.verification_code) ){ 11894 return true; 11895 } 11896 return false; 11897 }, 11898 CompleteFormValid(){ 11899 if(!empty(this.firstname) && empty(!this.lastname) && !empty(this.email_address) ){ 11900 return true; 11901 } 11902 return false; 11903 }, 11904 }, 11905 methods: { 11906 startTimer(){ 11907 this.timer = setInterval(() => { 11908 this.counter--; 11909 }, 1000) 11910 }, 11911 stopTimer(){ 11912 clearInterval(this.timer); 11913 this.success = ''; 11914 }, 11915 showPassword() 11916 { 11917 this.show_password = this.show_password==true?false:true; 11918 if(this.show_password){ 11919 this.password_type = 'text'; 11920 } else this.password_type = 'password'; 11921 }, 11922 recaptchaVerified(response) { 11923 this.recaptcha_response = response; 11924 }, 11925 recaptchaExpired() { 11926 if ( this.show_recaptcha){ 11927 this.$refs.vueRecaptcha.reset(); 11928 } 11929 }, 11930 recaptchaFailed() { 11931 11932 }, 11933 registerPhone(){ 11934 11935 var $params = { 11936 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 11937 'mobile_prefix': this.mobile_prefix, 11938 'mobile_number': this.mobile_number, 11939 'recaptcha_response' : this.recaptcha_response 11940 }; 11941 11942 var timenow = 1; 11943 $params = JSON.stringify($params); 11944 11945 ajax_request[timenow] = $.ajax({ 11946 url: ajaxurl+"/RegistrationPhone", 11947 method: "PUT", 11948 dataType: "json", 11949 data: $params , 11950 contentType : $content_type.json , 11951 timeout: $timeout, 11952 crossDomain: true, 11953 beforeSend: data => { 11954 this.is_loading = true; 11955 this.error = []; 11956 if(ajax_request[timenow] != null) { 11957 ajax_request[timenow].abort(); 11958 } 11959 } 11960 }); 11961 11962 ajax_request[timenow].done( data => { 11963 if ( data.code==1){ 11964 this.steps = 2; 11965 this.client_uuid = data.details.client_uuid; 11966 setTimeout(() => { 11967 this.$refs.code.focus(); 11968 }, 500); 11969 11970 if(!empty(data.details.verification_code)){ 11971 helpNotify(data.details.verification_code); 11972 } 11973 11974 this.startTimer(); 11975 } else { 11976 this.recaptchaExpired(); 11977 this.error = data.msg; 11978 this.client_uuid = ''; 11979 } 11980 }); 11981 11982 ajax_request[timenow].always( data => { 11983 this.is_loading = false;
11984 }); 11985 11986 }, 11987 verifyPhoneCode(){ 11988 11989 var $params = { 11990 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 11991 'client_uuid': this.client_uuid, 11992 'verification_code': this.verification_code, 11993 }; 11994 11995 var timenow = 1; 11996 $params = JSON.stringify($params); 11997 11998 ajax_request[timenow] = $.ajax({ 11999 url: ajaxurl+"/verifyCode", 12000 method: "PUT", 12001 dataType: "json", 12002 data: $params , 12003 contentType : $content_type.json , 12004 timeout: $timeout, 12005 crossDomain: true, 12006 beforeSend: data => { 12007 this.is_loading = true; 12008 this.error = []; 12009 if(ajax_request[timenow] != null) { 12010 ajax_request[timenow].abort(); 12011 } 12012 } 12013 }); 12014 12015 ajax_request[timenow].done( data => { 12016 if ( data.code==1){ 12017 this.steps = 3; 12018 } else { 12019 this.error = data.msg; 12020 } 12021 }); 12022 12023 ajax_request[timenow].always( data => { 12024 this.is_loading = false; 12025 }); 12026 12027 }, 12028 resendCode(){ 12029 12030 var $params; var timenow = 1; 12031 var $params = { 12032 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 12033 'client_uuid': this.client_uuid, 12034 }; 12035 $params = JSON.stringify($params); 12036 ajax_request[timenow] = $.ajax({ 12037 url: ajaxurl+"/requestCodePhone", 12038 method: "PUT", 12039 dataType: "json", 12040 data: $params , 12041 contentType : $content_type.json , 12042 timeout: $timeout, 12043 crossDomain: true, 12044 beforeSend: data => { 12045 this.is_loading = true; 12046 this.error = []; this.success = ''; 12047 if(ajax_request[timenow] != null) { 12048 ajax_request[timenow].abort(); 12049 } 12050 } 12051 }); 12052 12053 ajax_request[timenow].done( data => { 12054 if(data.code==1){ 12055 if ((typeof _resend_counter !== "undefined") && ( _resend_counter !== null)) { 12056 this.counter = parseInt(_resend_counter) ; 12057 } else this.counter = 40; 12058 12059 this.startTimer(); 12060 this.success = data.msg; 12061 } else { 12062 this.error = data.msg; 12063 } 12064 }); 12065 12066 ajax_request[timenow].always( data => { 12067 this.is_loading = false; 12068 }); 12069 12070 }, 12071 completeSignup(){ 12072 12073 var $params = { 12074 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 12075 'client_uuid': this.client_uuid, 12076 'firstname': this.firstname, 12077 'lastname': this.lastname, 12078 'email_address': this.email_address, 12079 'password': this.password, 12080 'cpassword': this.cpassword, 12081 'next_url': this.next_url, 12082 'custom_fields': this.custom_fields 12083 }; 12084 12085 var timenow = 1; 12086 $params = JSON.stringify($params); 12087 12088 ajax_request[timenow] = $.ajax({ 12089 url: ajaxurl+"/completeSignup", 12090 method: "PUT", 12091 dataType: "json", 12092 data: $params , 12093 contentType : $content_type.json , 12094 timeout: $timeout, 12095 crossDomain: true, 12096 beforeSend: data => { 12097 this.is_loading = true; 12098 this.error = []; 12099 if(ajax_request[timenow] != null) { 12100 ajax_request[timenow].abort(); 12101 } 12102 } 12103 }); 12104 12105 ajax_request[timenow].done( data => { 12106 if ( data.code==1){ 12107 window.location.href = data.details.redirect_url; 12108 } else { 12109 this.error = data.msg; 12110 } 12111 }); 12112 12113 ajax_request[timenow].always( data => { 12114 this.is_loading = false; 12115 }); 12116 12117 }, 12118 }, 12119}); 12120app_client_register_less.use(Maska); 12121app_client_register_less.use(ElementPlus); 12122const vm_client_register_less = app_client_register_less.mount('#vue-register-less'); 12123 12124 12125/** 12126 COMPLETE ACCOUNT SIGNUP 12127*/ 12128 12129const app_account_information = Vue.createApp({ 12130 components: { 12131 'component-phone' : ComponentsPhoneNumber, 12132 }, 12133 data(){ 12134 return { 12135 is_loading : false, 12136 error : [], 12137 success : '', 12138 steps : 1, 12139 verification_code : '', 12140 client_uuid : '', 12141 next_url : '', 12142 firstname : '', 12143 lastname : '', 12144 email_address : '', 12145 email_editable : false, 12146 mobile_number : '', 12147 mobile_prefix : '', 12148 counter : 20, 12149 timer : undefined 12150 }; 12151}, 12152 mounted () { 12153 12154 if ((typeof _uuid !== "undefined") && ( _uuid !== null)) { 12155 this.client_uuid = _uuid; 12156 } 12157 if ((typeof _redirect_to !== "undefined") && ( _redirect_to !== null)) { 12158 this.next_url = _redirect_to; 12159 } 12160 12161 if ((typeof _steps !== "undefined") && ( _steps !== null)) { 12162 this.steps = _steps; 12163 } 12164 12165 if( this.steps==2){ 12166 this.getCustomerInfo(); 12167 } 12168 12169 if ((typeof _resend_counter !== "undefined") && ( _resend_counter !== null)) { 12170 this.counter = parseInt(_resend_counter); 12171 } 12172 12173 this.startTimer(); 12174 12175 }, 12176 computed: { 12177 CodeValid(){ 12178 if(!empty(this.verification_code) ){ 12179 return true; 12180 } 12181 return false;
12182 }, 12183 CompleteFormValid(){ 12184 if(!empty(this.firstname) && empty(!this.lastname) && !empty(this.mobile_number) && !empty(this.email_address) ){ 12185 return true; 12186 } 12187 return false; 12188 }, 12189 }, 12190 watch: { 12191 counter(newdata,olddata){ 12192 if(newdata<=0){ 12193 this.stopTimer(); 12194 } 12195 } 12196 }, 12197 methods: { 12198 startTimer(){ 12199 this.timer = setInterval(() => { 12200 this.counter--; 12201 }, 1000) 12202 }, 12203 stopTimer(){ 12204 clearInterval(this.timer); 12205 this.success=''; 12206 }, 12207 verifyCode(){ 12208 12209 var $params = { 12210 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 12211 'client_uuid': this.client_uuid, 12212 'verification_code' : this.verification_code 12213 }; 12214 var timenow = 1; 12215 $params = JSON.stringify($params); 12216 12217 ajax_request[timenow] = $.ajax({ 12218 url: ajaxurl+"/verifyCode", 12219 method: "PUT", 12220 dataType: "json", 12221 data: $params , 12222 contentType : $content_type.json , 12223 timeout: $timeout, 12224 crossDomain: true, 12225 beforeSend: data => { 12226 this.error = []; 12227 this.is_loading = true; 12228 if(ajax_request[timenow] != null) { 12229 ajax_request[timenow].abort(); 12230 } 12231 } 12232 }); 12233 12234 ajax_request[timenow].done( data => { 12235 if ( data.code==1){ 12236 this.steps = 2; 12237 this.getCustomerInfo(); 12238 } else { 12239 this.error = data.msg; 12240 } 12241 }); // ajax done 12242 12243 ajax_request[timenow].always( data => { 12244 this.is_loading = false; 12245 }); 12246 }, 12247 resendCode(){ 12248 12249 var $params; var timenow = 1; 12250 var $params = { 12251 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 12252 'client_uuid': this.client_uuid, 12253 }; 12254 $params = JSON.stringify($params); 12255 ajax_request[timenow] = $.ajax({ 12256 url: ajaxurl+"/requestCode", 12257 method: "PUT", 12258 dataType: "json", 12259 data: $params , 12260 contentType : $content_type.json , 12261 timeout: $timeout, 12262 crossDomain: true, 12263 beforeSend: data => { 12264 this.is_loading = true; 12265 this.error = []; this.success =''; 12266 if(ajax_request[timenow] != null) { 12267 ajax_request[timenow].abort(); 12268 } 12269 } 12270 }); 12271 12272 ajax_request[timenow].done( data => { 12273 if(data.code==1){ 12274 if ((typeof _resend_counter !== "undefined") && ( _resend_counter !== null)) { 12275 this.counter = parseInt(_resend_counter); 12276 } else this.counter = 20; 12277 12278 this.startTimer(); 12279 this.success = data.msg; 12280 } else { 12281 this.error = data.msg; 12282 } 12283 }); 12284 12285 ajax_request[timenow].always( data => { 12286 this.is_loading = false; 12287 }); 12288 12289 }, 12290 getCustomerInfo(){ 12291 12292 var $params = { 12293 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 12294 'client_uuid': this.client_uuid, 12295 }; 12296 var timenow = getTimeNow(); 12297 $params = JSON.stringify($params); 12298 12299 ajax_request[timenow] = $.ajax({ 12300 url: ajaxurl+"/getCustomerInfo", 12301 method: "PUT", 12302 dataType: "json", 12303 data: $params , 12304 contentType : $content_type.json , 12305 timeout: $timeout, 12306 crossDomain: true, 12307 beforeSend: data => { 12308 this.error = []; 12309 this.is_loading = true; 12310 if(ajax_request[timenow] != null) { 12311 ajax_request[timenow].abort(); 12312 } 12313 } 12314 }); 12315 12316 ajax_request[timenow].done( data => { 12317 if(data.code==1){ 12318 this.firstname = data.details.firstname; 12319 this.lastname = data.details.lastname; 12320 // Clear the placeholder email set for Facebook accounts with no email, 12321 // so the user sees an empty field and must enter their real address. 12322 var rawEmail = data.details.email_address; 12323 var isPlaceholder = rawEmail && rawEmail.indexOf('fb_noemail_') === 0 && rawEmail.indexOf('@placeholder.invalid') !== -1; 12324 this.email_address = isPlaceholder ? '' : rawEmail; 12325 this.email_editable = isPlaceholder; 12326 } else { 12327 this.error = data.msg; 12328 } 12329 }); 12330 12331 ajax_request[timenow].always( data => { 12332 this.is_loading = false;
12333 }); 12334 12335 }, 12336 completeSignup(){ 12337 12338 var $params = { 12339 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 12340 'client_uuid': this.client_uuid, 12341 'firstname': this.firstname, 12342 'lastname': this.lastname, 12343 'mobile_prefix': this.mobile_prefix, 12344 'mobile_number': this.mobile_number, 12345 'email_address': this.email_address, 12346 'next_url': this.next_url 12347 }; 12348 12349 var timenow = 1; 12350 $params = JSON.stringify($params); 12351 12352 ajax_request[timenow] = $.ajax({ 12353 url: ajaxurl+"/completeSocialSignup", 12354 method: "PUT", 12355 dataType: "json", 12356 data: $params , 12357 contentType : $content_type.json , 12358 timeout: $timeout, 12359 crossDomain: true, 12360 beforeSend: data => { 12361 this.is_loading = true; 12362 this.error = []; 12363 if(ajax_request[timenow] != null) { 12364 ajax_request[timenow].abort(); 12365 } 12366 } 12367 }); 12368 12369 ajax_request[timenow].done( data => { 12370 if ( data.code==1){ 12371 window.location.href = data.details.redirect_url; 12372 } else { 12373 this.error = data.msg; 12374 } 12375 }); 12376 12377 ajax_request[timenow].always( data => { 12378 this.is_loading = false; 12379 }); 12380 12381 }, 12382 }, 12383}); 12384app_account_information.use(Maska); 12385const vm_account_information = app_account_information.mount('#vue-account-information'); 12386 12387 12388/* 12389 FORGOT PASSWORD 12390*/ 12391const fpCounter = 5; 12392const app_forgot_password = Vue.createApp({ 12393 components: { 12394 'component-phone' : ComponentsPhoneNumber, 12395 }, 12396 data (){ 12397 return { 12398 loading : false, 12399 error : [], 12400 email_address : '', 12401 steps :1, 12402 uuid : '', 12403 success : '', 12404 counter : fpCounter, 12405 timer : undefined, 12406 mobile_number : '', 12407 mobile_prefix :'', 12408 password_reset_options :'', 12409 otp :'', 12410 validation_type : 1 12411 } 12412 }, 12413 watch: { 12414 counter(newdata,olddata){ 12415 if(newdata<=0){ 12416 this.stopTimer(); 12417 } 12418 } 12419 }, 12420 mounted() { 12421 if ((typeof password_reset_options !== "undefined") && ( password_reset_options !== null)) { 12422 this.password_reset_options = password_reset_options 12423 } 12424 if(this.password_reset_options=='sms'){ 12425 this.validation_type = 2; 12426 } 12427 }, 12428 computed: { 12429 checkForm(){ 12430 if(this.validation_type==2){ 12431 if(empty(this.mobile_number)){ 12432 return true; 12433 } 12434 } else { 12435 if(!this.validEmail(this.email_address)){ 12436 return true; 12437 } 12438 } 12439 return false; 12440 }, 12441 }, 12442 methods: { 12443 validEmail: function (email) { 12444 var re = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; 12445 return re.test(email); 12446 }, 12447 startTimer(){ 12448 this.counter = fpCounter; 12449 this.timer = setInterval(() => { 12450 this.counter--; 12451 }, 1000) 12452 }, 12453 stopTimer(){ 12454 clearInterval(this.timer); 12455 }, 12456 startOver(){ 12457 this.steps = 1; 12458 this.stopTimer(); 12459 }, 12460 requestResetPassword(){ 12461 12462 var $params = { 12463 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 12464 'email_address': this.email_address, 12465 'password_reset_options' : this.password_reset_options, 12466 'mobile_number': this.mobile_number, 12467 'mobile_prefix': this.mobile_prefix, 12468 }; 12469 12470 var timenow = 1; 12471 $params = JSON.stringify($params); 12472 12473 let actionPassword = this.validation_type==2 ? ajaxurl+"/requestResetpasswordsms" : ajaxurl+"/requestResetPassword"; 12474 12475 ajax_request[timenow] = $.ajax({ 12476 url: actionPassword, 12477 method: "PUT", 12478 dataType: "json", 12479 data: $params , 12480 contentType : $content_type.json , 12481 timeout: $timeout, 12482 crossDomain: true, 12483 beforeSend: data => { 12484 this.loading = true; this.error = []; this.success=''; 12485 if(ajax_request[timenow] != null) { 12486 ajax_request[timenow].abort(); 12487 } 12488 } 12489 }); 12490 12491 ajax_request[timenow].done( data => { 12492 if ( data.code==1){ 12493 this.steps = !empty(data.details.steps)? data.details.steps: 2; 12494 this.uuid = data.details.uuid; 12495 this.success = data.msg; 12496 this.startTimer(); 12497 } else { 12498 this.error = data.msg; 12499 this.success = ''; 12500 } 12501 }); 12502 12503 ajax_request[timenow].always( data => { 12504 this.loading = false;
12505 }); 12506 12507 }, 12508 resendResetEmail(){ 12509 12510 var $params = { 12511 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 12512 'client_uuid': this.uuid, 12513 'password_reset_options' : this.password_reset_options, 12514 'mobile_number': this.mobile_number, 12515 'mobile_prefix': this.mobile_prefix, 12516 }; 12517 12518 var timenow = 1; 12519 $params = JSON.stringify($params); 12520 12521 ajax_request[timenow] = $.ajax({ 12522 url: this.validation_type==2? ajaxurl+"/resendResetpasswordsms" : ajaxurl+"/resendResetEmail", 12523 method: "PUT", 12524 dataType: "json", 12525 data: $params , 12526 contentType : $content_type.json , 12527 timeout: $timeout, 12528 crossDomain: true, 12529 beforeSend: data => { 12530 this.loading = true; this.error = []; this.success=''; 12531 if(ajax_request[timenow] != null) { 12532 ajax_request[timenow].abort(); 12533 } 12534 } 12535 }); 12536 12537 ajax_request[timenow].done( data => { 12538 if ( data.code==1){ 12539 this.success = data.msg; 12540 this.counter = fpCounter; 12541 this.startTimer(); 12542 } else { 12543 this.error = data.msg; 12544 } 12545 }); 12546 12547 ajax_request[timenow].always( data => { 12548 this.loading = false; 12549 }); 12550 12551 }, 12552 verifyOTP(){ 12553 this.loading = true; 12554 axios({ 12555 method: 'POST', 12556 url: ajaxurl+"/verifyOTP" , 12557 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&client_uuid="+ this.uuid + "&otp=" + this.otp, 12558 timeout: $timeout, 12559 }).then( response => { 12560 if(response.data.code==1){ 12561 window.location.href = response.data.details.redirect; 12562 } else { 12563 ElementPlus.ElNotification({ 12564 title: "", 12565 message: response.data.msg, 12566 position: 'bottom-right', 12567 type: 'warning', 12568 }); 12569 } 12570 }).catch(error => { 12571 // 12572 }).then(data => { 12573 this.loading = false; 12574 }); 12575 } 12576 }, 12577}); 12578app_forgot_password.use(Maska); 12579app_forgot_password.use(ElementPlus); 12580const vm_forgot_password = app_forgot_password.mount('#vue-forgot-password'); 12581 12582 12583/* 12584 RESET PASSWORD 12585*/ 12586const vm_reset_password = Vue.createApp({ 12587 data (){ 12588 return { 12589 loading : false, 12590 success :'', 12591 error : [], 12592 uuid : '', 12593 password : '', 12594 cpassword : '', 12595 steps : 1, 12596 } 12597 }, 12598 mounted () { 12599 if ((typeof _client_id !== "undefined") && ( _client_id !== null)) { 12600 this.uuid = _client_id; 12601 } 12602 }, 12603 computed: { 12604 checkForm(){ 12605 if(!empty(this.password) && !empty(this.cpassword) ){ 12606 return true; 12607 } 12608 return false; 12609 } 12610 }, 12611 methods: { 12612 resetPassword(){ 12613 12614 var $params = { 12615 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 12616 'client_uuid': this.uuid, 12617 'password': this.password, 12618 'cpassword': this.cpassword, 12619 }; 12620 12621 var timenow = 1; 12622 $params = JSON.stringify($params); 12623 12624 ajax_request[timenow] = $.ajax({ 12625 url: ajaxurl+"/resetPassword", 12626 method: "PUT", 12627 dataType: "json", 12628 data: $params , 12629 contentType : $content_type.json , 12630 timeout: $timeout, 12631 crossDomain: true, 12632 beforeSend: data => { 12633 this.loading = true; this.error = []; this.success=''; 12634 if(ajax_request[timenow] != null) { 12635 ajax_request[timenow].abort(); 12636 } 12637 } 12638 }); 12639 12640 ajax_request[timenow].done( data => { 12641 if ( data.code==1){ 12642 this.success = data.msg; 12643 this.steps = 2; 12644 } else { 12645 this.error = data.msg; 12646 } 12647 }); 12648 12649 ajax_request[timenow].always( data => { 12650 this.loading = false; 12651 }); 12652 12653 }, 12654 }, 12655}).mount('#vue-reset-password'); 12656 12657/** 12658 VUE TRANSACTION 12659 this is function for displaying transaction during checkout 12660 target = vue-transaction 12661*/ 12662const app_checkout_transaction = Vue.createApp({ 12663 data(){ 12664 return { 12665 is_loading : false, 12666 error : [], 12667 transactions :[], 12668 transaction_type : '', 12669 delivery_option : [], 12670 whento_deliver : 'now', 12671 opening_hours : [], 12672 delivery_date : '', 12673 delivery_time : '', 12674 opt_contact_delivery : false, 12675 display_transaction_type:'', 12676 display_data : [], 12677 checkout_error : [], 12678 opening_hours_date : [], 12679 opening_hours_time : [] 12680 }; 12681 }, 12682 mounted () { 12683 this.getTransaction() 12684 }, 12685 updated () { 12686 //dump("display_transaction_type=>"+this.display_transaction_type); 12687 }, 12688 methods: { 12689 show(){ 12690 this.error = []; 12691 $('#orderTypeTime').modal('show'); 12692 }, 12693 close(){ 12694 $('#orderTypeTime').modal('hide'); 12695 }, 12696 JsonValue(item){ 12697 return JSON.stringify({ 12698 start_time : item.start_time, 12699 end_time : item.end_time, 12700 pretty_time : item.pretty_time 12701 }); 12702 }, 12703 getTransaction(){ 12704 var $params=''; var timenow = getTimeNow(); 12705 var $cart_uuid = getCookie('cart_uuid'); 12706 $params="cart_uuid=" + $cart_uuid; 12707 $params+=addValidationRequest(); 12708 12709 this.is_loading = true; 12710 12711 ajax_request[timenow] = $.ajax({ 12712 url: ajaxurl+"/checkoutTransaction", 12713 method: "POST", 12714 dataType: "json", 12715 data: $params, 12716 contentType : $content_type.form , 12717 timeout: $timeout, 12718 crossDomain: true, 12719 beforeSend: function( xhr ) { 12720 if(ajax_request[timenow] != null) { 12721 ajax_request[timenow].abort(); 12722 } 12723 } 12724 }); 12725 12726 ajax_request[timenow].done( data => { 12727 if ( data.code==1){ 12728 this.transactions = data.details.transactions; 12729 this.delivery_option = data.details.delivery_option; 12730 this.opening_hours_date = data.details.opening_hours.dates; 12731 this.opening_hours_time = data.details.opening_hours.time_ranges; 12732 12733 /* 12734 this.opening_hours = data.details.opening_hours; 12735 var keys = Object.keys(data.details.opening_hours); 12736 keys = keys[0]; 12737 this.delivery_date = data.details.opening_hours[keys].value; 12738 */ 12739 12740 } else { 12741 this.transactions = []; 12742 this.delivery_option = []; 12743 this.opening_hours = []; 12744 this.display_data = []; 12745 this.checkout_error = []; 12746 this.opening_hours_date = []; 12747 } 12748 }); // ajax done 12749 12750 ajax_request[timenow].always( data => { 12751 this.is_loading = false;
12752 }); 12753 }, 12754 setData(item){ 12755 12756 this.transaction_type = item.transaction_type; 12757 this.display_transaction_type = item.transaction_type; 12758 this.display_data = item.data; 12759 12760 if ((typeof item.data.whento_deliver !== "undefined") && ( item.data.whento_deliver !== null)) { 12761 this.whento_deliver = item.data.whento_deliver; 12762 } 12763 12764 if ((typeof item.data.delivery_date !== "undefined") && ( item.data.delivery_date !== null)) { 12765 this.delivery_date = item.data.delivery_date; 12766 } 12767 12768 if ((typeof item.data.delivery_time !== "undefined") && ( item.data.delivery_time !== null)) { 12769 this.delivery_time = item.data.delivery_time; 12770 } 12771 12772 if ((typeof item.data.error !== "undefined") && ( item.data.error !== null)) { 12773 this.checkout_error = item.data.error; 12774 } else this.checkout_error = []; 12775 12776 }, 12777 validate(){ 12778 this.error = []; 12779 if(this.whento_deliver=="now"){ 12780 this.save(); 12781 } else { 12782 if(empty(this.delivery_date)){ 12783 this.error.push( t("Delivery Date is required") ); 12784 } else if( empty(this.delivery_time) ){ 12785 this.error.push( t("Time is required") ); 12786 } else { 12787 this.save(); 12788 } 12789 } 12790 }, 12791 save(){ 12792 12793 var $params = { 12794 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 12795 'cart_uuid':getCookie('cart_uuid'), 12796 'transaction_type': this.transaction_type, 12797 'whento_deliver' : this.whento_deliver, 12798 'delivery_date': this.delivery_date, 12799 'delivery_time': !empty(this.delivery_time)?JSON.parse(this.delivery_time):'' 12800 }; 12801 12802 var timenow = 1; 12803 $params = JSON.stringify($params); 12804 12805 ajax_request[timenow] = $.ajax({ 12806 url: ajaxurl+"/checkoutSave", 12807 method: "PUT", 12808 dataType: "json", 12809 data: $params , 12810 contentType : $content_type.json , 12811 timeout: $timeout, 12812 crossDomain: true, 12813 beforeSend: data => { 12814 this.is_loading = true; 12815 if(ajax_request[timenow] != null) { 12816 ajax_request[timenow].abort(); 12817 } 12818 } 12819 }); 12820 12821 ajax_request[timenow].done( data => { 12822 if ( data.code==1){ 12823 12824 var $json = { 12825 'whento_deliver' : data.details.whento_deliver, 12826 'delivery_date' : data.details.delivery_date, 12827 'delivery_time' : data.details.delivery_time 12828 }; 12829 setCookie('choosen_delivery', JSON.stringify($json) ,30); 12830 setCookie('cart_transaction_type', this.transaction_type ,30); 12831 12832 $('#orderTypeTime').modal('hide'); 12833 vue_cart.loadcart(); 12834 vm_tips.loadTips(); 12835 if (typeof vm_promo !== 'undefined' && vm_promo !== null) { vm_promo.loadPromo(); } 12836 if ((typeof vm_delivery_details !== "undefined") && ( vm_delivery_details !== null)) { 12837 vm_delivery_details.addressNeeded(); 12838 } 12839 if ((typeof vm_checkout_booking !== "undefined") && ( vm_checkout_booking !== null)) { 12840 vm_checkout_booking.getTableAttributes(); 12841 } 12842 if ((typeof vm_checkout_address !== "undefined") && ( vm_checkout_address !== null)) { 12843 vm_checkout_address.handleAddressRequirement(); 12844 } 12845 } 12846 }); 12847 12848 ajax_request[timenow].always( data => { 12849 this.is_loading = false; 12850 }); 12851 }, 12852 }, 12853}); 12854app_checkout_transaction.use(ElementPlus); 12855const vm_checkout_transaction = app_checkout_transaction.mount('#vue-transaction'); 12856 12857 12858/*COMPONENTS CHANGE PHONE*/ 12859const ComponentsChangePhone = { 12860 components: { 12861 'component-phone' : ComponentsPhoneNumber, 12862 }, 12863 props: ['label','is_mobile','default_country','only_countries'], 12864 data() { 12865 return { 12866 error: [], 12867 is_loading : false, 12868 mobile_prefix : '', 12869 mobile_prefixes : [], 12870 mobile_number : '', 12871 mobile_number_old : '' 12872 } 12873 }, 12874 computed: { 12875 PhoneValid(){ 12876 if(!empty(this.mobile_number) && this.mobile_number!=this.mobile_number_old ){ 12877 return true; 12878 } 12879 return false;
12880 }, 12881 }, 12882 methods: { 12883 show(){ 12884 $('#changephoneModal').modal('show'); 12885 this.error = []; 12886 }, 12887 close(){ 12888 $('#changephoneModal').modal('hide'); 12889 }, 12890 SendCode(){ 12891 12892 var $params; var timenow = 1; 12893 var $params = { 12894 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 12895 }; 12896 $params = JSON.stringify($params); 12897 ajax_request[timenow] = $.ajax({ 12898 url: ajaxurl+"/RequestEmailCode", 12899 method: "PUT", 12900 dataType: "json", 12901 data: $params , 12902 contentType : $content_type.json , 12903 timeout: $timeout, 12904 crossDomain: true, 12905 beforeSend: data => { 12906 this.is_loading = true; 12907 this.error = []; 12908 if(ajax_request[timenow] != null) { 12909 ajax_request[timenow].abort(); 12910 } 12911 } 12912 }); 12913 12914 ajax_request[timenow].done( data => { 12915 if(data.code==1){ 12916 this.close(); 12917 this.$emit('setPhone',{ 12918 mobile_prefix:this.mobile_prefix, 12919 mobile_number: this.mobile_number, 12920 message : data.msg 12921 }); 12922 } else { 12923 this.error = data.msg; 12924 } 12925 }); 12926 12927 ajax_request[timenow].always( data => { 12928 this.is_loading = false; 12929 }); 12930 12931 }, 12932 }, 12933 template: ` 12934 <div class="modal" id="changephoneModal" tabindex="-1" role="dialog" 12935 aria-labelledby="changephoneModal" aria-hidden="true" > 12936 <div class="modal-dialog" role="document"> 12937 <div class="modal-content" :class="{ 'modal-mobile' : is_mobile==1 }"> 12938 12939 <div class="modal-header border-bottom-0" style="padding-bottom:0px !important;"> 12940 <h5 class="modal-title" id="exampleModalLongTitle"> 12941 {{label.edit_phone}} 12942 </h5> 12943 <div class="close"> 12944 <a href="javascript:;" @click="close" class="btn btn-black btn-circle rounded-pill"><i class="zmdi zmdi-close font20"></i></a> 12945 </div> 12946 </div> 12947 12948 <div class="modal-body" style="overflow-y:inherit !important;"> 12949 12950 <form class="forms mt-2 mb-2" @submit.prevent="SendCode" > 12951 12952 <!--COMPONENTS--> 12953 <component-phone 12954 :default_country="default_country" 12955 :only_countries="only_countries" 12956 v-model:mobile_number="mobile_number" 12957 v-model:mobile_prefix="mobile_prefix" 12958 > 12959 </component-phone> 12960 <!--END COMPONENTS--> 12961 12962 12963 </form> 12964 12965 <div v-cloak v-if="error.length>0" class="alert alert-warning mb-2" role="alert"> 12966 <p v-cloak v-for="err in error" class="m-0">{{err}}</p> 12967 </div> 12968 12969 </div> <!--modal body--> 12970 12971 <div class="modal-footer justify-content-start"> 12972 12973 <div class="border flex-fill"> 12974 <button class="btn btn-black w-100" @click="close" > 12975 {{label.cancel}} 12976 </button> 12977 </div> 12978 <div class="border flex-fill"> 12979 <button @click="SendCode" 12980 class="btn btn-green w-100" :class="{ loading: is_loading }" :disabled="!PhoneValid" > 12981 <span class="label">{{label.continue}}</span> 12982 <div class="m-auto circle-loader" data-loader="circle-side"></div> 12983 </button> 12984 </div> 12985 12986 </div> <!--footer--> 12987 12988 </div> <!--content--> 12989 </div> <!--dialog--> 12990 </div> <!--modal--> 12991 ` 12992}; 12993/*END COMPONENTS CHANGE PHONE*/ 12994 12995/* 12996ComponentsChangePhoneVerification 12997*/ 12998const ComponentsChangePhoneVerification = { 12999 props: ['label'], 13000 data() { 13001 return { 13002 error: [], 13003 is_loading : false, 13004 code : '', 13005 data : [], 13006 counter : 20, 13007 timer : undefined 13008 } 13009 }, 13010 computed: { 13011 CodeisValid(){ 13012 if(!empty(this.code)){ 13013 return true; 13014 } 13015 return false; 13016 }, 13017 }, 13018 watch: { 13019 counter(newdata,olddata){ 13020 if(newdata<=0){ 13021 this.stopTimer(); 13022 } 13023 } 13024 }, 13025 methods: { 13026 show(data){ 13027 this.data = data; 13028 this.code = ''; 13029 this.error = []; 13030 this.startTimer(); 13031 $('#verifyCodeModal').modal('show'); 13032 13033 setInterval(() => { 13034 this.$refs.refcode.focus(); 13035 }, 500) 13036 13037 }, 13038 startTimer(){ 13039 this.stopTimer(); 13040 this.counter = 20; 13041 this.timer = setInterval(() => { 13042 this.counter--; 13043 }, 1000) 13044 }, 13045 stopTimer(){ 13046 clearInterval(this.timer); 13047 }, 13048 close(){ 13049 $('#verifyCodeModal').modal('hide'); 13050 }, 13051 submit(){
13052 this.$emit('afterSubmit',this.code); 13053 }, 13054 resendCode(){ 13055 13056 var $params; var timenow = 1; 13057 var $params = { 13058 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 13059 }; 13060 dump("resendCode"); 13061 $params = JSON.stringify($params); 13062 ajax_request[timenow] = $.ajax({ 13063 url: ajaxurl+"/RequestEmailCode", 13064 method: "PUT", 13065 dataType: "json", 13066 data: $params , 13067 contentType : $content_type.json , 13068 timeout: $timeout, 13069 crossDomain: true, 13070 beforeSend: data => { 13071 this.is_loading = true; 13072 this.error = []; 13073 if(ajax_request[timenow] != null) { 13074 ajax_request[timenow].abort(); 13075 } 13076 } 13077 }); 13078 13079 ajax_request[timenow].done( data => { 13080 if(data.code==1){ 13081 this.counter = 20; 13082 this.startTimer(); 13083 if(!empty(data.details)){ 13084 if(!empty(data.details.verification_code)){ 13085 helpNotify(data.details.verification_code); 13086 } 13087 } 13088 } else { 13089 this.error = data.msg; 13090 } 13091 }); 13092 13093 ajax_request[timenow].always( data => { 13094 this.is_loading = false; 13095 }); 13096 13097 }, 13098 }, 13099 template: ` 13100 <div class="modal" id="verifyCodeModal" tabindex="-1" role="dialog" 13101 aria-labelledby="verifyCodeModal" aria-hidden="true" data-backdrop="static" data-keyboard="false" > 13102 <div class="modal-dialog" role="document"> 13103 <div class="modal-content"> 13104 13105 <form class="forms" @submit.prevent="submit" > 13106 13107 <div class="modal-body"> 13108 13109 13110 <a href="javascript:;" @click="close" 13111 class="btn btn-black btn-circle rounded-pill"><i class="zmdi zmdi-close font20"></i></a> 13112 13113 <div class="text-center"> 13114 <h4 class="m-0 mb-3 mt-3">{{label.steps}}</h4> 13115 <h6>{{label.for_security}}</h6> 13116 </div> 13117 13118 13119 13120 <p class="bold">{{label.enter_digit}}</p> 13121 <div class="form-label-group"> 13122 <input v-model="code" ref="refcode" v-maska="'######'" 13123 class="form-control form-control-text" 13124 placeholder="" type="text" maxlength="6" id="code" > 13125 <label for="code" class="required">{{label.code}}</label> 13126 </div> 13127 13128 13129 13130 <p class="bold">{{data.message}}</p> 13131 13132 <template v-if="counter===0"> 13133 <div class="mt-1 mb-3"> 13134 <a href="javascript:;" @click="resendCode" :disabled="is_loading" > 13135 <p class="m-0"><u>{{label.resend_code}}</u></p> 13136 </a> 13137 </div> 13138 </template> 13139 <template v-else> 13140 <p><u>{{label.resend_code_in}} {{counter}}</u></p> 13141 </template> 13142 13143 13144 <div v-cloak v-if="error.length>0" class="alert alert-warning mb-2" role="alert"> 13145 <p v-cloak v-for="err in error" class="m-0">{{err}}</p> 13146 </div> 13147 13148 </div> <!--modal body--> 13149 13150 <div class="modal-footer justify-content-start"> 13151 <button class="btn btn-green w-100" 13152 :class="{ loading: is_loading }" :disabled="!CodeisValid" > 13153 <span class="label">{{label.submit}}</span> 13154 <div class="m-auto circle-loader" data-loader="circle-side"></div> 13155 </button> 13156 </div> <!--footer--> 13157 13158 </form> 13159 </div> <!--content--> 13160 </div> <!--dialog--> 13161 </div> <!--modal--> 13162 ` 13163}; 13164 13165 13166/** 13167 CHECKOUT CONTACT PHONE 13168 target = vue-contactphone 13169*/ 13170const vm_contactphone = Vue.createApp({ 13171 components: { 13172 'component-change-phone' : ComponentsChangePhone, 13173 'component-change-phoneverify' : ComponentsChangePhoneVerification, 13174 }, 13175 mounted () { 13176 this.getCheckoutPhone(); 13177 }, 13178 data() { 13179 return { 13180 contact_number: '', 13181 data :[], 13182 is_loading : false, 13183 } 13184 }, 13185 methods: { 13186 showChangePhone(){ 13187 this.$refs.cphone.show(); 13188 }, 13189 loadVerification(data){ 13190 this.data = data; 13191 this.$refs.cphoneverify.show( data ); 13192 }, 13193 getCheckoutPhone(){ 13194 var $params; var timenow = getTimeNow(); 13195 var $params = { 13196 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 13197 'cart_uuid':getCookie('cart_uuid'), 13198 }; 13199 $params = JSON.stringify($params); 13200 this.is_loading = true; 13201 ajax_request[timenow] = $.ajax({ 13202 url: ajaxurl+"/getCheckoutPhone", 13203 method: "PUT", 13204 dataType: "json", 13205 data: $params , 13206 contentType : $content_type.json , 13207 timeout: $timeout, 13208 crossDomain: true, 13209 beforeSend: data => { 13210 if(ajax_request[timenow] != null) { 13211 ajax_request[timenow].abort(); 13212 } 13213 } 13214 }); 13215 13216 ajax_request[timenow].done( data => { 13217 if(data.code==1){ 13218 this.contact_number = data.details.contact_number_w_prefix; 13219 13220 this.$refs.cphone.mobile_prefixes = data.details.prefixes; 13221 this.$refs.cphone.mobile_prefix = data.details.default_prefix; 13222 this.$refs.cphone.mobile_number = data.details.contact_number; 13223 this.$refs.cphone.mobile_number_old = data.details.contact_number; 13224 } else { 13225 this.contact_number = ''; 13226 this.$refs.cphone.mobile_prefixes = []; 13227 } 13228 }); 13229 13230 ajax_request[timenow].always( data => { 13231 this.is_loading = false;
13232 }); 13233 13234 }, 13235 ChangePhone(code){ 13236 dump("change phone"); 13237 13238 var $params; var timenow = 1; 13239 var $params = { 13240 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 13241 'cart_uuid':getCookie('cart_uuid'), 13242 'data': this.data, 13243 'code': code 13244 }; 13245 $params = JSON.stringify($params); 13246 ajax_request[timenow] = $.ajax({ 13247 url: ajaxurl+"/ChangePhone", 13248 method: "PUT", 13249 dataType: "json", 13250 data: $params , 13251 contentType : $content_type.json , 13252 timeout: $timeout, 13253 crossDomain: true, 13254 beforeSend: data => { 13255 this.$refs.cphoneverify.is_loading = true; 13256 this.$refs.cphoneverify.error = []; 13257 if(ajax_request[timenow] != null) { 13258 ajax_request[timenow].abort(); 13259 } 13260 } 13261 }); 13262 13263 ajax_request[timenow].done( data => { 13264 if(data.code==1){ 13265 this.$refs.cphoneverify.close(); 13266 vm_contactphones.getCheckoutPhone(); 13267 } else { 13268 this.$refs.cphoneverify.error = data.msg; 13269 } 13270 }); 13271 13272 ajax_request[timenow].always( data => { 13273 this.$refs.cphoneverify.is_loading = false; 13274 }); 13275 13276 } 13277 }, 13278}); 13279 13280vm_contactphone.use(Maska); 13281vm_contactphone.use(ElementPlus); 13282const vm_contactphones = vm_contactphone.mount('#vue-contactphone'); 13283 13284 13285 13286 13287/* 13288COMPONENTS PROMO CODE 13289*/ 13290const componentPromocode = { 13291 props: ['title','add_promo_code','apply_text' ,'is_mobile'], 13292 data() { 13293 return { 13294 is_loading: false, 13295 promo_code : '', 13296 error : [] 13297 } 13298 }, 13299 methods: { 13300 showModal(){ 13301 $('#promocodeModal').modal('show'); 13302 }, 13303 closeModal(){ 13304 $('#promocodeModal').modal('hide'); 13305 this.error = []; 13306 this.promo_code = ''; 13307 }, 13308 applyCode(){ 13309 this.error = []; 13310 var $params; var timenow = 1; 13311 $params="promo_code="+ this.promo_code; 13312 $params+="&cart_uuid=" + getCookie('cart_uuid'); 13313 $params+=addValidationRequest(); 13314 ajax_request[timenow] = $.ajax({ 13315 url: ajaxurl+"/applyPromoCode", 13316 method: "POST", 13317 dataType: "json", 13318 data: $params, 13319 contentType : $content_type.form , 13320 timeout: $timeout, 13321 crossDomain: true, 13322 beforeSend: data => { 13323 this.is_loading = true; 13324 if(ajax_request[timenow] != null) { 13325 ajax_request[timenow].abort(); 13326 } 13327 } 13328 }); 13329 13330 ajax_request[timenow].done( data => { 13331 if ( data.code==1){ 13332 this.closeModal(); 13333 13334 if(vm_apply_promocode.enabled){ 13335 vm_apply_promocode.getAppliedPromo(); 13336 } else { 13337 this.$emit('setLoadpromo'); 13338 } 13339 vue_cart.loadcart(); 13340 } else { 13341 this.error[0] = data.msg; 13342 } 13343 }); // ajax done 13344 13345 ajax_request[timenow].always( data => { 13346 this.is_loading = false; 13347 }); 13348 13349 }, 13350 back(){ 13351 this.closeModal(); 13352 this.$emit('back'); 13353 } 13354 }, 13355 computed: { 13356 hasData(){ 13357 if(this.promo_code==""){ 13358 this.error = []; 13359 return true; 13360 } 13361 return false; 13362 }, 13363 }, 13364 template: ` 13365 <div class="modal" id="promocodeModal" tabindex="-1" role="dialog" 13366 aria-labelledby="promocodeModal" aria-hidden="true" data-backdrop="static" > 13367 <div class="modal-dialog" role="document"> 13368 <div class="modal-content" :class="{ 'modal-mobile' : is_mobile==1 }" > 13369 13370 <div class="modal-header border-bottom-0" style="padding-bottom:0px !important;"> 13371 <h5 class="modal-title" id="exampleModalLongTitle"> 13372 {{title}} 13373 </h5> 13374 <div class="close"> 13375 <a href="javascript:;" data-dismiss="modal" class="btn btn-black btn-circle rounded-pill"><i class="zmdi zmdi-close font20"></i></a> 13376 </div> 13377 </div> 13378 13379 <div class="modal-body"> 13380 13381 <form class="forms mt-2 mb-2" @submit.prevent="applyCode" > 13382 13383 <div class="form-label-group"> 13384 <input v-model="promo_code" class="form-control form-control-text" placeholder="" 13385 id="promo_code" type="text" maxlength="20" > 13386 <label for="promo_code" class="required">{{add_promo_code}}</label> 13387 </div> 13388 13389 </form> <!--forms--> 13390 13391 <div v-cloak v-if="error.length>0" class="alert alert-warning mb-2" role="alert"> 13392 <p v-cloak v-for="err in error" class="m-0">{{err}}</p> 13393 </div> 13394 13395 </div> <!--modal body--> 13396 13397 <div class="modal-footer"> 13398 <button type="button" class="btn btn-black pl-4 pr-4" @click="back" >Cancel</button> 13399 <button type="button" class="btn btn btn-green pl-4 pr-4" 13400 @click="applyCode" :class="{ loading: is_loading }" :disabled="hasData" 13401 >
13402 <span class="label">{{apply_text}}</span><div class="m-auto circle-loader" data-loader="circle-side"></div> 13403 </button> 13404 </div> 13405 13406 </div> <!--content--> 13407 </div> <!--dialog--> 13408 </div> <!--modal--> 13409 ` 13410}; 13411/* 13412END COMPONENTS PROMO CODE 13413*/ 13414 13415/** 13416 PROMO 13417 this is function for displaying promo in checkout 13418 target = vue-promo 13419*/ 13420const app_promo = Vue.createApp({ 13421 components: { 13422 'component-promocode': componentPromocode, 13423 }, 13424 data(){ 13425 return { 13426 is_loading : false, 13427 loading : false, 13428 remove_loading : false, 13429 saved_disabled : true, 13430 promo_id : [], 13431 data : [], 13432 error : '', 13433 promo_selected :[] 13434 }; 13435 }, 13436 created () { 13437 this.loadPromo(); 13438 }, 13439 updated () { 13440 if(this.promo_id.length>0){ 13441 this.saved_disabled = true; 13442 } else { 13443 this.saved_disabled = false; 13444 } 13445 }, 13446 computed: { 13447 hasSelectedPromo(){ 13448 if (Object.keys(this.promo_id).length > 0) { 13449 return true; 13450 } 13451 return false; 13452 } 13453 }, 13454 methods: { 13455 loadPromo(){ 13456 13457 this.is_loading = true; 13458 var $params; var timenow = getTimeNow(); 13459 let currency_code = getCookie('currency_code'); 13460 currency_code = !empty(currency_code)?currency_code:''; 13461 13462 $params="cart_uuid=" + getCookie('cart_uuid'); 13463 $params+="¤cy_code=" + currency_code; 13464 $params+=addValidationRequest(); 13465 ajax_request[timenow] = $.ajax({ 13466 url: ajaxurl+"/loadPromo", 13467 method: "POST", 13468 dataType: "json", 13469 data: $params, 13470 contentType : $content_type.form , 13471 timeout: $timeout, 13472 crossDomain: true, 13473 beforeSend: data => { 13474 if(ajax_request[timenow] != null) { 13475 ajax_request[timenow].abort(); 13476 } 13477 } 13478 }); 13479 13480 ajax_request[timenow].done( data => { 13481 if ( data.code===1){ 13482 const _was_empty = !this.promo_selected || this.promo_selected.length === 0; 13483 this.data = data.details.data; 13484 this.promo_selected = data.details.promo_selected; 13485 vm_apply_promocode.enabled = false; 13486 // Reload cart if promo state changed (appliedânone or noneâapplied) 13487 const _now_has_promo = this.promo_selected && this.promo_selected.length > 0; 13488 if (_was_empty === _now_has_promo) { vue_cart.loadcart(); } 13489 } else { 13490 this.data = []; 13491 this.promo_selected = []; 13492 vm_apply_promocode.enabled = true; 13493 } 13494 }); // ajax done 13495 13496 ajax_request[timenow].always( data => { 13497 this.is_loading = false; 13498 }); 13499 13500 }, 13501 show(){ 13502 this.error = ''; 13503 $( this.$refs.promo_modal ).modal('show'); 13504 }, 13505 hide(){ 13506 $(this.$refs.promo_modal).modal('hide'); 13507 }, 13508 close(){ 13509 $(this.$refs.promo_modal).modal('hide'); 13510 }, 13511 save(){ 13512 this.loading = true; 13513 axios({ 13514 method: 'PUT', 13515 url: ajaxurl+"/applyPromo" , 13516 data : { 13517 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 13518 'cart_uuid':getCookie('cart_uuid'), 13519 'promo_type': this.promo_id[0], 13520 'promo_id': this.promo_id[1], 13521 'currency_code': getCookie('currency_code') 13522 }, 13523 timeout: $timeout, 13524 }).then( response => { 13525 console.debug(response.data.code); 13526 if(response.data.code==1){ 13527 this.error = ''; 13528 this.close(); 13529 this.loadPromo(); 13530 vue_cart.loadcart(); 13531 } else { 13532 this.error = response.data.msg; 13533 } 13534 }).catch(error => { 13535 // 13536 }).then(data => { 13537 this.loading = false; 13538 }); 13539 }, 13540 removePromo(promo_type,promo_id){ 13541 13542 var $params = { 13543 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 13544 'cart_uuid':getCookie('cart_uuid'), 13545 'promo_id': promo_id, 13546 'promo_type':promo_type 13547 }; 13548 13549 var timenow = 1; 13550 $params = JSON.stringify($params); 13551 13552 ajax_request[timenow] = $.ajax({ 13553 url: ajaxurl+"/removePromo", 13554 method: "PUT", 13555 dataType: "json", 13556 data: $params , 13557 contentType : $content_type.json , 13558 timeout: $timeout, 13559 crossDomain: true, 13560 beforeSend: data => { 13561 this.remove_loading = true; 13562 if(ajax_request[timenow] != null) { 13563 ajax_request[timenow].abort(); 13564 } 13565 } 13566 }); 13567 13568 ajax_request[timenow].done( data => { 13569 if ( data.code==1){ 13570 this.close(); 13571 this.loadPromo(); 13572 this.promo_id = []; 13573 vue_cart.loadcart(); 13574 } else this.error = data.msg; 13575 }); 13576 13577 ajax_request[timenow].always( data => { 13578 this.remove_loading = false;
13579 }); 13580 13581 }, 13582 showPromoCode(){ 13583 this.$refs.childref.showModal(); 13584 this.hide(); 13585 }, 13586 }, 13587}); 13588app_promo.use(ElementPlus); 13589const vm_promo = app_promo.mount('#vue-promo'); 13590 13591 13592/** 13593 APPLY PROMO CODE MANUALLY 13594 target = vue-add-promocode 13595*/ 13596const vm_apply_promocode = Vue.createApp({ 13597 components: { 13598 'component-apply-promocode': componentPromocode, 13599 }, 13600 data(){ 13601 return { 13602 enabled : false, 13603 has_promocode : false, 13604 saving : '', 13605 data : [] 13606 }; 13607 }, 13608 mounted () { 13609 13610 }, 13611 watch: { 13612 enabled(newdata,olddata){ 13613 if(newdata){ 13614 this.getAppliedPromo(); 13615 } 13616 } 13617 }, 13618 methods :{ 13619 show(){ 13620 if(this.has_promocode){ 13621 this.removePromoCode(); 13622 } else { 13623 this.$refs.childref.showModal(); 13624 } 13625 }, 13626 getAppliedPromo(){ 13627 13628 var $params; var timenow = 1; 13629 $params="cart_uuid=" + getCookie('cart_uuid'); 13630 $params+=addValidationRequest(); 13631 ajax_request[timenow] = $.ajax({ 13632 url: ajaxurl+"/getAppliedPromo", 13633 method: "POST", 13634 dataType: "json", 13635 data: $params, 13636 contentType : $content_type.form , 13637 timeout: $timeout, 13638 crossDomain: true, 13639 beforeSend: data => { 13640 if(ajax_request[timenow] != null) { 13641 ajax_request[timenow].abort(); 13642 } 13643 } 13644 }); 13645 13646 ajax_request[timenow].done( data => { 13647 if ( data.code==1){ 13648 this.data = data.details.data; 13649 this.has_promocode = true; 13650 this.saving = data.details.saving; 13651 } else { 13652 this.has_promocode = false; 13653 this.saving = ''; 13654 this.data = []; 13655 } 13656 }); // ajax done 13657 13658 ajax_request[timenow].always( data => { 13659 13660 }); 13661 13662 }, 13663 removePromoCode(){ 13664 13665 var $params = { 13666 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 13667 'cart_uuid':getCookie('cart_uuid'), 13668 'promo_id': this.data.id, 13669 'promo_type': this.data.type 13670 }; 13671 13672 var timenow = 1; 13673 $params = JSON.stringify($params); 13674 13675 ajax_request[timenow] = $.ajax({ 13676 url: ajaxurl+"/removePromo", 13677 method: "PUT", 13678 dataType: "json", 13679 data: $params , 13680 contentType : $content_type.json , 13681 timeout: $timeout, 13682 crossDomain: true, 13683 beforeSend: data => { 13684 if(ajax_request[timenow] != null) { 13685 ajax_request[timenow].abort(); 13686 } 13687 } 13688 }); 13689 13690 ajax_request[timenow].done( data => { 13691 if ( data.code==1){ 13692 this.has_promocode = false; 13693 this.data = []; 13694 this.getAppliedPromo(); 13695 vue_cart.loadcart(); 13696 } 13697 }); 13698 13699 ajax_request[timenow].always( data => { 13700 13701 }); 13702 13703 }, 13704 }, 13705}).mount('#vue-add-promocode'); 13706 13707/** 13708 TIPS VUE RENDER 13709 this is function for displaying tips 13710 target = vue-tips 13711*/ 13712const app_tips = Vue.createApp({ 13713 data(){ 13714 return { 13715 data : [], 13716 tips : '', 13717 manual_tip : 0, 13718 transaction_type : '', 13719 is_loading : false, 13720 enabled_tips : false, 13721 in_transaction : false 13722 }; 13723 }, 13724 mounted () { 13725 this.loadTips() 13726 }, 13727 computed: { 13728 ifOthers(){ 13729 if(this.tips=="fixed"){ 13730 return true; 13731 } 13732 return false; 13733 }, 13734 ifDelivery(){ 13735 return this.in_transaction; 13736 }, 13737 }, 13738 updated () { 13739 //dump("tips:" + this.tips); 13740 }, 13741 methods: { 13742 loadTips(){ 13743 13744 this.is_loading = true; 13745 var $params; var timenow = getTimeNow(); 13746 let currency_code = getCookie('currency_code'); 13747 currency_code = !empty(currency_code)?currency_code:''; 13748 13749 $params="cart_uuid=" + getCookie('cart_uuid'); 13750 $params+="¤cy_code=" + currency_code; 13751 $params+=addValidationRequest(); 13752 ajax_request[timenow] = $.ajax({ 13753 url: ajaxurl+"/loadTips", 13754 method: "POST", 13755 dataType: "json", 13756 data: $params, 13757 contentType : $content_type.form , 13758 timeout: $timeout, 13759 crossDomain: true, 13760 beforeSend: data => { 13761 if(ajax_request[timenow] != null) { 13762 ajax_request[timenow].abort(); 13763 } 13764 } 13765 }); 13766 13767 ajax_request[timenow].done( data => { 13768 if ( data.code==1){ 13769 this.data=data.details.data; 13770 this.tips = data.details.tips; 13771 this.transaction_type = data.details.transaction_type; 13772 this.enabled_tips = data.details.enabled_tips; 13773 this.in_transaction = data.details.in_transaction; 13774 this.setOther(); 13775 } else { 13776 this.data=[]; 13777 } 13778 }); // ajax done 13779 13780 ajax_request[timenow].always( data => { 13781 this.is_loading= false;
13782 }); 13783 13784 }, 13785 checkoutAddTips(value,is_manual){ 13786 13787 if(value=="fixed"){ 13788 return; 13789 } 13790 13791 this.tips = value; 13792 13793 var $params = { 13794 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 13795 'cart_uuid':getCookie('cart_uuid'), 13796 'value': value, 13797 'is_manual' : is_manual 13798 }; 13799 13800 var timenow = 1; 13801 $params = JSON.stringify($params); 13802 13803 this.is_loading= true; 13804 13805 ajax_request[timenow] = $.ajax({ 13806 url: ajaxurl+"/checkoutAddTips", 13807 method: "PUT", 13808 dataType: "json", 13809 data: $params , 13810 contentType : $content_type.json , 13811 timeout: $timeout, 13812 crossDomain: true, 13813 beforeSend: data => { 13814 if(ajax_request[timenow] != null) { 13815 ajax_request[timenow].abort(); 13816 } 13817 } 13818 }); 13819 13820 ajax_request[timenow].done( data => { 13821 if ( data.code==1){ 13822 vue_cart.loadcart(); 13823 } else { 13824 /// 13825 } 13826 }); 13827 13828 ajax_request[timenow].always( data => { 13829 this.is_loading= false; 13830 }); 13831 13832 }, 13833 setOther(){ 13834 if(this.tips>0){ 13835 var $found = false; 13836 this.data.forEach((item,index) => { 13837 if (this.tips==item.value){ 13838 $found=true; 13839 } 13840 }); 13841 if(!$found){ 13842 this.manual_tip = this.tips; 13843 this.tips="fixed"; 13844 } 13845 } 13846 } 13847 }, 13848}); 13849app_tips.use(ElementPlus); 13850const vm_tips = app_tips.mount('#vue-tips'); 13851 13852 13853 13854/** 13855 CHECKOUT ADDRESS 13856 this is function for selecting checkout address 13857 target = vue-manage-address 13858*/ 13859let cmaps_marker; 13860let currentMarkers = []; 13861const vm_manage_address = Vue.createApp({ 13862 components: { 13863 'component-address': changeAddressComponent, 13864 }, 13865 data(){ 13866 return { 13867 q: '', 13868 awaitingSearch : false, 13869 is_loading : false, 13870 transaction_type : '', 13871 data : [], 13872 error : [], 13873 show_list : true, 13874 location_data : [], 13875 new_coordinates : [], 13876 location_name : '', 13877 delivery_instructions : '', 13878 delivery_options : '', 13879 address_label : '', 13880 delivery_options_data : [], 13881 address_label_data : [], 13882 auto_load_data : false, 13883 cmaps : null, 13884 cmaps_config : [], 13885 cmaps_provider : '', 13886 cmaps_marker: undefined, 13887 cmaps_full : false, 13888 current_page : 'checkout', 13889 out_of_range: false, 13890 address_component : [], 13891 addresses : [], 13892 inline_edit : false, 13893 formatted_address : '', 13894 address1 : '' 13895 }; 13896 }, 13897 beforeMount() { 13898 13899 }, 13900 mounted () { 13901 const el = document.getElementById("autoload"); 13902 if ((typeof el !== "undefined") && ( el !== null)) { 13903 this.auto_load_data = el.value; 13904 } 13905 13906 if(this.auto_load_data==1){ 13907 autosize( document.getElementById("delivery_instructions") ); 13908 this.loadData(); 13909 } 13910 }, 13911 updated () { 13912 13913 }, 13914 computed: { 13915 ifDelivery(){ 13916 if ( this.transaction_type=="delivery"){ 13917 return true; 13918 } 13919 return false; 13920 }, 13921 hasData(){ 13922 if(this.data.length>0){ 13923 return true; 13924 } 13925 return false; 13926 }, 13927 hasLocationData(){ 13928 if ((typeof this.location_data !== "undefined") && ( this.location_data !== null)) { 13929 var count = Object.keys(this.location_data).length; 13930 if(count>0){ 13931 return true; 13932 } 13933 } 13934 return false; 13935 }, 13936 hasNewCoordinates(){ 13937 var count = Object.keys(this.new_coordinates).length; 13938 if(count>0){ 13939 return true; 13940 } 13941 return false; 13942 }, 13943 }, 13944 methods: { 13945 show(){ 13946 this.cmaps_full = false; 13947 $('#addressModal').modal('show'); 13948 this.loadMap(); 13949 }, 13950 hide(){ 13951 this.error=[]; 13952 $('#addressModal').modal('hide'); 13953 }, 13954 close(){ 13955 this.error=[]; 13956 $('#addressModal').modal('hide'); 13957 }, 13958 showNewAddress(){ 13959 this.$refs.childref.showModal(); 13960 }, 13961 hideChange(){ 13962 $('#changeAddressModal').modal('hide'); 13963 }, 13964 save(){ 13965 confirmIncompleteAddressSave({ 13966 formattedAddress: this.formattedAddress, 13967 formatted_address: this.formatted_address, 13968 address1: this.address1, 13969 location_name: this.location_name, 13970 postal_code: this.postal_code 13971 }, () => { 13972 var $params = { 13973 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 13974 'cart_uuid':getCookie('cart_uuid'), 13975 'data': this.location_data, 13976 'location_name' : this.location_name, 13977 'delivery_instructions' : this.delivery_instructions, 13978 'delivery_options' : this.delivery_options, 13979 'address_label' : this.address_label, 13980 'formatted_address' : this.formatted_address, 13981 'address1': this.address1 13982 }; 13983 13984 var timenow = 1; 13985 $params = JSON.stringify($params); 13986 13987 ajax_request[timenow] = $.ajax({ 13988 url: ajaxurl+"/checkoutSaveAddress", 13989 method: "PUT", 13990 dataType: "json", 13991 data: $params , 13992 contentType : $content_type.json , 13993 timeout: $timeout, 13994 crossDomain: true, 13995 beforeSend: data => { 13996 this.is_loading = true; 13997 if(ajax_request[timenow] != null) { 13998 ajax_request[timenow].abort(); 13999 } 14000 } 14001 }); 14002 14003 ajax_request[timenow].done( data => { 14004 if ( data.code==1){ 14005 this.hide(); 14006 this.loadData(); 14007 vue_cart.loadcart(); 14008 } else { 14009 this.error[0] = data.msg; 14010 } 14011 }); 14012 14013 ajax_request[timenow].always( data => { 14014 this.is_loading = false;
14015 }); 14016 }); 14017 }, 14018 clearData(){ 14019 this.data = []; 14020 this.q = ''; 14021 }, 14022 showList(){ 14023 this.show_list = true; 14024 }, 14025 setLocationDetails(data){ 14026 this.location_data = data; 14027 this.formatted_address = data.address.formatted_address; 14028 this.address1 = data.address.address1; 14029 14030 if(!empty(data.attributes)){ 14031 this.location_name = data.attributes.location_name; 14032 this.delivery_instructions = data.attributes.delivery_instructions; 14033 this.delivery_options = data.attributes.delivery_options; 14034 this.address_label = data.attributes.address_label; 14035 } else { 14036 this.location_name = ''; 14037 this.delivery_instructions = ''; 14038 this.delivery_options = 'Hand it to me'; 14039 this.address_label = 'Home'; 14040 } 14041 this.hideChange(); 14042 this.show(); 14043 }, 14044 setPlaceData(){ 14045 this.hideChange(); 14046 this.loadData(); 14047 vue_cart.loadcart(); 14048 }, 14049 loadData(){ 14050 14051 var $params=''; var timenow = getTimeNow(); 14052 $params="cart_uuid=" + getCookie('cart_uuid'); 14053 $params+=addValidationRequest(); 14054 ajax_request[timenow] = $.ajax({ 14055 url: ajaxurl+"/checkoutAddress", 14056 method: "POST", 14057 dataType: "json", 14058 data: $params, 14059 contentType : $content_type.form , 14060 timeout: $timeout, 14061 crossDomain: true, 14062 beforeSend: data => { 14063 if(ajax_request[timenow] != null) { 14064 ajax_request[timenow].abort(); 14065 } 14066 } 14067 }); 14068 14069 ajax_request[timenow].done( data => { 14070 if ( data.code==1){ 14071 this.transaction_type = data.details.transaction_type; 14072 this.location_data = data.details.data; 14073 14074 if ((typeof data.details.data.address !== "undefined") && ( data.details.data.address !== null)) { 14075 this.formatted_address = data.details.data.address.formatted_address; 14076 this.address1 = data.details.data.address.address1; 14077 } 14078 14079 this.cmaps_config = data.details.maps_config; 14080 this.delivery_options_data = data.details.delivery_option; 14081 this.address_label_data = data.details.address_label; 14082 this.addresses = data.details.addresses; 14083 14084 var keys = Object.keys(data.details.delivery_option); 14085 keys = keys[0]; 14086 this.delivery_options = keys; 14087 14088 var keys = Object.keys(data.details.address_label); 14089 keys = keys[0]; 14090 this.address_label = keys; 14091 14092 if(!empty(data.details.data.attributes)){ 14093 this.location_name = data.details.data.attributes.location_name; 14094 this.delivery_instructions = data.details.data.attributes.delivery_instructions; 14095 this.delivery_options = data.details.data.attributes.delivery_options; 14096 this.address_label = data.details.data.attributes.address_label; 14097 } 14098 14099 } else { 14100 this.transaction_type = ''; 14101 this.error[0] = data.msg; 14102 this.location_data = []; 14103 this.cmaps_config = []; 14104 this.delivery_options_data = []; 14105 this.address_label_data = []; 14106 this.addresses = []; 14107 this.formatted_address = ''; 14108 this.address1 = ''; 14109 } 14110 }); // ajax done 14111 14112 ajax_request[timenow].always( data => { 14113 14114 }); 14115 14116 }, 14117 loadMap(){ 14118 14119 this.cmaps_provider = this.cmaps_config.provider; 14120 14121 switch(this.cmaps_provider){ 14122 case "google.maps": 14123 if ((typeof this.cmaps !== "undefined") && ( this.cmaps !== null)) { 14124 this.removeMarker(); 14125 } else { 14126 this.cmaps = new google.maps.Map(document.getElementById("cmaps"), { 14127 center: { lat: parseFloat(this.location_data.latitude), lng: parseFloat(this.location_data.longitude) }, 14128 zoom: parseInt(this.cmaps_config.zoom) , 14129 disableDefaultUI: true, 14130 }); 14131 } 14132 14133 this.addMarker({ 14134 position: { lat: parseFloat(this.location_data.latitude) , lng: parseFloat(this.location_data.longitude) }, 14135 map: this.cmaps, 14136 icon : this.cmaps_config.icon, 14137 animation: google.maps.Animation.DROP, 14138 }); 14139 break; 14140 case "mapbox": 14141 mapboxgl.accessToken = this.cmaps_config.key; 14142 this.cmaps = new mapboxgl.Map({ 14143 container: document.getElementById("cmaps"), 14144 style: 'mapbox://styles/mapbox/streets-v12', 14145 center: [ parseFloat(this.location_data.longitude) , parseFloat(this.location_data.latitude)], 14146 zoom: 14 14147 }); 14148 this.addMarker({ 14149 position: { lat: parseFloat(this.location_data.latitude) , lng: parseFloat(this.location_data.longitude) }, 14150 map: this.cmaps, 14151 icon : this.cmaps_config.icon, 14152 animation: null 14153 }); 14154 break; 14155 14156 } 14157 }, 14158 addMarker(properties){ 14159 dump("add markerx"); 14160 dump(this.cmaps_provider); 14161 dump(properties); 14162 switch(this.cmaps_provider){ 14163 case "google.maps": 14164 cmaps_marker = new google.maps.Marker(properties); 14165 this.cmaps.panTo(new google.maps.LatLng(properties.position.lat,properties.position.lng)); 14166 break; 14167 case "mapbox": 14168 let markerProperties = {}; 14169 if(properties.draggable){ 14170 markerProperties = {draggable: true}; 14171 } 14172 cmaps_marker = new mapboxgl.Marker(markerProperties) 14173 .setLngLat([properties.position.lng, properties.position.lat]) 14174 .addTo(this.cmaps); 14175 break; 14176 } 14177 }, 14178 removeMarker(){ 14179 dump("remove marker"); 14180 switch(this.cmaps_provider){ 14181 case "google.maps": 14182 cmaps_marker.setMap(null); 14183 break; 14184 case "mapbox": 14185 cmaps_marker.remove(); 14186 //this.cmaps.clearMarkers(); 14187 break; 14188 } 14189 }, 14190 cancelPin(){ 14191 this.error = []; 14192 this.cmaps_full=false; 14193 this.removeMarker(); 14194 this.addMarker({ 14195 position: { lat: parseFloat(this.location_data.latitude) , lng: parseFloat(this.location_data.longitude) }, 14196 map: this.cmaps, 14197 icon : this.cmaps_config.icon, 14198 animation: this.cmaps_provider=="google.maps" ? google.maps.Animation.DROP : null, 14199 }); 14200 this.mapBoxResize(); 14201 }, 14202 adjustPin(){ 14203 14204 dump("adjustPin");
14205 this.new_coordinates = []; 14206 this.cmaps_full = true; 14207 try { 14208 this.removeMarker(); 14209 } catch(err) { 14210 dump(err); 14211 } 14212 14213 this.addMarker({ 14214 position: { lat: parseFloat(this.location_data.latitude) , lng: parseFloat(this.location_data.longitude) }, 14215 map: this.cmaps, 14216 icon : this.cmaps_config.icon, 14217 animation: this.cmaps_provider=="google.maps" ? google.maps.Animation.DROP : null, 14218 draggable:true, 14219 }); 14220 14221 if(this.cmaps_provider=="google.maps"){ 14222 cmaps_marker.addListener('dragend', event => { 14223 this.new_coordinates = { 14224 'lat': event.latLng.lat(), 14225 'lng': event.latLng.lng(), 14226 }; 14227 }); 14228 } else if ( this.cmaps_provider=="mapbox" ) { 14229 cmaps_marker.on('dragend', (event)=>{ 14230 const lngLat = cmaps_marker.getLngLat(); 14231 this.new_coordinates = { 14232 'lat': lngLat.lat, 14233 'lng': lngLat.lng, 14234 }; 14235 }); 14236 this.mapBoxResize(); 14237 } 14238 }, 14239 mapBoxResize(){ 14240 if(this.cmaps_provider=="mapbox"){ 14241 setTimeout(()=>{ 14242 this.cmaps.resize(); 14243 }, 500); 14244 } 14245 }, 14246 setNewCoordinates(){ 14247 var $params = { 14248 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 14249 'cart_uuid':getCookie('cart_uuid'), 14250 'lat' : this.location_data.latitude, 14251 'lng' : this.location_data.longitude, 14252 'new_lat' : this.new_coordinates.lat, 14253 'new_lng' : this.new_coordinates.lng, 14254 }; 14255 14256 var timenow = 1; 14257 $params = JSON.stringify($params); 14258 14259 ajax_request[timenow] = $.ajax({ 14260 url: ajaxurl+"/checkoutValidateCoordinates", 14261 method: "PUT", 14262 dataType: "json", 14263 data: $params , 14264 contentType : $content_type.json , 14265 timeout: $timeout, 14266 crossDomain: true, 14267 beforeSend: data => { 14268 this.is_loading = true; 14269 this.error = []; 14270 if(ajax_request[timenow] != null) { 14271 ajax_request[timenow].abort(); 14272 } 14273 } 14274 }); 14275 14276 ajax_request[timenow].done( data => { 14277 if ( data.code==1){ 14278 this.location_data.latitude = this.new_coordinates.lat; 14279 this.location_data.longitude = this.new_coordinates.lng; 14280 this.cmaps_full=false; 14281 this.removeMarker(); 14282 this.addMarker({ 14283 position: { lat: parseFloat(this.location_data.latitude) , lng: parseFloat(this.location_data.longitude) }, 14284 map: this.cmaps, 14285 icon : this.cmaps_config.icon, 14286 animation: this.cmaps_provider=="google.maps" ? google.maps.Animation.DROP : null, 14287 }); 14288 this.mapBoxResize(); 14289 } else { 14290 this.error = data.msg; 14291 } 14292 }); 14293 14294 ajax_request[timenow].always( data => { 14295 this.is_loading = false; 14296 }); 14297 14298 }, 14299 }, 14300}).mount('#vue-manage-address'); 14301 14302 14303/* 14304 CHANGE ADDRESS POPUP 14305 this is function for selecting checkout address 14306 target = vue-change-address 14307*/ 14308const vm_change_address = Vue.createApp({ 14309 components: { 14310 'component-change-address': changeAddressComponent, 14311 'component-address': ComponentsAddress, 14312 }, 14313 data(){ 14314 return { 14315 out_of_range : false, 14316 address_component : [], 14317 addresses : [] 14318 }; 14319 }, 14320 mounted () { 14321 //this.getAddresses(); 14322 }, 14323 methods :{ 14324 show(){ 14325 this.$refs.address.showModal(); 14326 this.getAddresses(); 14327 }, 14328 afterChangeAddress(data){ 14329 vue_cart.loadcart(); 14330 14331 if ((typeof vm_widget_nav !== "undefined") && ( vm_widget_nav !== null)) { 14332 vm_widget_nav.afterChangeAddress(); 14333 } 14334 14335 if ((typeof vm_merchant_details !== "undefined") && ( vm_merchant_details !== null)) { 14336 vm_merchant_details.$refs.ref_services.getMerchantServices(); 14337 } 14338 14339 }, 14340 afterSetAddress(){ 14341 this.$refs.address.closeModal(); 14342 vue_cart.loadcart(); 14343 }, 14344 afterDeleteAddress(){ 14345 this.getAddresses(); 14346 }, 14347 editAddress(data){ 14348 this.$refs.address.close(); 14349 this.$refs.addressform.show( data.address_uuid ); 14350 }, 14351 afterSaveAddForm(){ 14352 vue_cart.loadcart(); 14353 }, 14354 getAddresses(){ 14355 14356 var $params = { 14357 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 14358 }; 14359 var timenow = getTimeNow(); 14360 $params = JSON.stringify($params); 14361 14362 ajax_request[timenow] = $.ajax({ 14363 url: ajaxurl+"/getAddresses", 14364 method: "PUT", 14365 dataType: "json", 14366 data: $params , 14367 contentType : $content_type.json , 14368 timeout: $timeout, 14369 crossDomain: true, 14370 beforeSend: data => { 14371 if(ajax_request[timenow] != null) { 14372 ajax_request[timenow].abort(); 14373 } 14374 } 14375 }); 14376 14377 ajax_request[timenow].done( data => { 14378 if ( data.code==1){ 14379 this.addresses = data.details.data; 14380 } else { 14381 this.addresses = []; 14382 } 14383 }); 14384 14385 }, 14386 }, 14387}).mount('#vue-change-address'); 14388 14389 14390/* 14391DIGITAL WALLET COMPONENTS 14392*/
14393const componentsDigitalWallet = { 14394 props :['ajax_url','amount_to_pay' ,'enabled_digital_wallet'], 14395 data() { 14396 return { 14397 use_wallet : false, 14398 data : [], 14399 loading : false, 14400 currency_code : '', 14401 message : '' 14402 } 14403 }, 14404 created() { 14405 let currency_code = getCookie('currency_code'); 14406 this.currency_code = !empty(currency_code)?currency_code:''; 14407 this.getCartWallet(); 14408 }, 14409 computed: { 14410 canUseWallet(){ 14411 if (Object.keys(this.data).length > 0) { 14412 if(this.data.balance_raw>0){ 14413 return true; 14414 } 14415 } 14416 return false; 14417 } 14418 }, 14419 watch: { 14420 use_wallet(newval,oldval){ 14421 this.applyDigitalWallet(newval==true?1:0,null); 14422 } 14423 }, 14424 methods: { 14425 getCartWallet(){ 14426 this.loading = true; 14427 axios({ 14428 method: 'POST', 14429 url: this.ajax_url+"/getCartWallet" , 14430 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&cart_uuid="+ getCookie('cart_uuid') + "¤cy_code=" + this.currency_code, 14431 timeout: $timeout, 14432 }).then( response => { 14433 if(response.data.code==1){ 14434 this.data = response.data.details; 14435 this.use_wallet = response.data.details.use_wallet; 14436 } else { 14437 this.data = []; 14438 this.use_wallet = false; 14439 } 14440 }).catch(error => { 14441 // 14442 }).then(data => { 14443 this.loading = false; 14444 }); 14445 }, 14446 applyDigitalWallet(use_wallet,amount_to_pay){ 14447 this.loading = true; 14448 let $amount_to_pay = this.amount_to_pay; 14449 if ((typeof amount_to_pay !== "undefined") && ( amount_to_pay !== null)) { 14450 $amount_to_pay = amount_to_pay; 14451 } 14452 axios({ 14453 method: 'POST', 14454 url: this.ajax_url+"/applyDigitalWallet" , 14455 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&cart_uuid="+ getCookie('cart_uuid') + 14456 "¤cy_code=" + this.currency_code + "&use_wallet=" + use_wallet + "&amount_to_pay="+ $amount_to_pay, 14457 timeout: $timeout, 14458 }).then( response => { 14459 if(response.data.code==1){ 14460 if(use_wallet){ 14461 this.message = response.data.msg; 14462 } else { 14463 this.message = ''; 14464 } 14465 this.$emit('afterApplywallet',response.data.details); 14466 } else { 14467 this.use_wallet = false; 14468 this.message = ''; 14469 ElementPlus.ElNotification({ 14470 title: "", 14471 message: response.data.msg, 14472 position: 'bottom-right', 14473 type: 'warning', 14474 }); 14475 } 14476 }).catch(error => { 14477 // 14478 }).then(data => { 14479 this.loading = false; 14480 }); 14481 }, 14482 }, 14483 template: '#xtemplate_digital_wallet', 14484}; 14485/* 14486END DIGITAL WALLET COMPONENTS 14487*/ 14488 14489/* 14490 PAYMENT LIST 14491 target = vue-payment-list 14492*/ 14493const app_payment_list = Vue.createApp({ 14494 data(){ 14495 return { 14496 error : [], 14497 data : [], 14498 data_saved_payment : [], 14499 saved_payment_error : [], 14500 default_payment_uuid : '', 14501 transaction_type : '', 14502 amount_to_pay : 0, 14503 cart_uuid : getCookie('cart_uuid'), 14504 saved_payment_loading : false, 14505 payment_list_loading : false, 14506 payment_change : 0, 14507 wallet_data : [] 14508 }; 14509 }, 14510 mounted () { 14511 this.PaymentList(); 14512 this.SavedPaymentList(); 14513 }, 14514 computed: { 14515 hasData(){ 14516 if(this.data.length>0){ 14517 return true; 14518 } 14519 return false; 14520 }, 14521 hasSavedPayment(){ 14522 if(this.data_saved_payment.length>0){ 14523 return true; 14524 } 14525 return false; 14526 }, 14527 validatePaymentChange(){ 14528 let $payment_change = parseFloat(this.payment_change); 14529 if( $payment_change>0){ 14530 return true; 14531 } 14532 return false; 14533 }, 14534 validatePaymentChangeValue(){ 14535 if(vue_cart.cart_total.raw<=this.payment_change){ 14536 return true; 14537 } 14538 return false; 14539 }, 14540 isWalletFullPayment(){ 14541 if (Object.keys(this.wallet_data).length > 0) { 14542 if(this.wallet_data.use_wallet && this.wallet_data.amount_due_raw<=0){ 14543 return true; 14544 } 14545 } 14546 return false; 14547 }, 14548 usePartialPayment(){ 14549 if (Object.keys(this.wallet_data).length > 0) { 14550 if(this.wallet_data.use_wallet && this.wallet_data.amount_due_raw>0){ 14551 vue_cart.use_partial_payment = true; 14552 return true; 14553 } 14554 } 14555 vue_cart.use_partial_payment = false;
14556 return false; 14557 }, 14558 getPayRemaining(){ 14559 if (Object.keys(this.wallet_data).length > 0) { 14560 if(this.wallet_data.use_wallet){ 14561 return this.wallet_data.pay_remaining; 14562 } 14563 } 14564 return false; 14565 }, 14566 }, 14567 methods :{ 14568 NumbersOnly(evt) { 14569 evt = (evt) ? evt : window.event; 14570 var charCode = (evt.which) ? evt.which : evt.keyCode; 14571 if ((charCode > 31 && (charCode < 48 || charCode > 57)) && charCode !== 46) { 14572 evt.preventDefault();; 14573 } else { 14574 return true; 14575 } 14576 }, 14577 showPayment(payment_code){ 14578 try { 14579 this.$refs[payment_code].showPaymentForm(); 14580 } catch(err) { 14581 vm_bootbox.alert( err , {} ); 14582 } 14583 }, 14584 PaymentRender(data){ 14585 this.$refs[ data.payment_code ].PaymentRender( data ); 14586 }, 14587 AfterCancelPayment(){ 14588 vue_cart.is_submit = false; 14589 }, 14590 Alert(message){ 14591 vm_bootbox.alert( message , {} ); 14592 }, 14593 showLoadingBox(message){ 14594 if(!empty(message)){ 14595 vm_loading.$refs.box.setMessage(message); 14596 } 14597 vm_loading.$refs.box.show(); 14598 }, 14599 closeLoadingBox(){ 14600 vm_loading.$refs.box.close(); 14601 }, 14602 PaymentList(){ 14603 14604 this.payment_list_loading = true; 14605 var $params; var timenow = getTimeNow(); 14606 let currency_code = getCookie('currency_code'); 14607 currency_code = !empty(currency_code)?currency_code:''; 14608 14609 $params="cart_uuid=" + getCookie('cart_uuid'); 14610 $params+="¤cy_code="+ currency_code; 14611 $params+=addValidationRequest(); 14612 ajax_request[timenow] = $.ajax({ 14613 url: ajaxurl+"/PaymentList", 14614 method: "POST", 14615 dataType: "json", 14616 data: $params, 14617 contentType : $content_type.form , 14618 timeout: $timeout, 14619 crossDomain: true, 14620 beforeSend: data => { 14621 if(ajax_request[timenow] != null) { 14622 ajax_request[timenow].abort(); 14623 } 14624 } 14625 }); 14626 14627 ajax_request[timenow].done( data => { 14628 if ( data.code==1){ 14629 this.data = data.details.data; 14630 } else { 14631 this.error[0] = data.msg; 14632 } 14633 }); // ajax done 14634 14635 ajax_request[timenow].always( data => { 14636 this.payment_list_loading = false; 14637 }); 14638 }, 14639 SavedPaymentList(){ 14640 14641 this.saved_payment_loading = true; 14642 var $params; var timenow = getTimeNow(); 14643 let currency_code = getCookie('currency_code'); 14644 currency_code = !empty(currency_code)?currency_code:''; 14645 $params="cart_uuid=" + getCookie('cart_uuid') ; 14646 $params+="¤cy_code="+ currency_code; 14647 $params+=addValidationRequest(); 14648 ajax_request[timenow] = $.ajax({ 14649 url: ajaxurl+"/SavedPaymentList", 14650 method: "POST", 14651 dataType: "json", 14652 data: $params, 14653 contentType : $content_type.form , 14654 timeout: $timeout, 14655 crossDomain: true, 14656 beforeSend: data => { 14657 if(ajax_request[timenow] != null) { 14658 ajax_request[timenow].abort(); 14659 } 14660 } 14661 }); 14662 14663 ajax_request[timenow].done( data => { 14664 if ( data.code==1){ 14665 this.data_saved_payment = data.details.data; 14666 this.default_payment_uuid = data.details.default_payment_uuid; 14667 vue_cart.selected_payment_uuid = this.default_payment_uuid; 14668 if ((typeof vue_cart !== "undefined") && ( vue_cart !== null)) { 14669 // THIS IS FOR CARD FEE 14670 //vue_cart.loadcart(); 14671 } 14672 } else { 14673 this.error[0] = data.msg; 14674 this.data_saved_payment = []; 14675 this.default_payment_uuid = ''; 14676 vue_cart.selected_payment_uuid = ''; 14677 } 14678 }); // ajax done 14679 14680 ajax_request[timenow].always( data => { 14681 this.saved_payment_loading = false; 14682 updateStickyCart(); 14683 }); 14684 }, 14685 deleteSavedPaymentMethod(payment_uuid,payment_code){ 14686 14687 var $params = { 14688 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 14689 'payment_uuid' : payment_uuid, 14690 'payment_code' : payment_code 14691 }; 14692
14693 var timenow = 1; 14694 $params = JSON.stringify($params); 14695 14696 ajax_request[timenow] = $.ajax({ 14697 url: ajaxurl+"/deleteSavedPaymentMethod", 14698 method: "PUT", 14699 dataType: "json", 14700 data: $params , 14701 contentType : $content_type.json , 14702 timeout: $timeout, 14703 crossDomain: true, 14704 beforeSend: function( xhr ) { 14705 if(ajax_request[timenow] != null) { 14706 ajax_request[timenow].abort(); 14707 } 14708 } 14709 }); 14710 14711 ajax_request[timenow].done( data => { 14712 if ( data.code==1){ 14713 this.SavedPaymentList(); 14714 } else { 14715 this.saved_payment_error[0] = data.msg; 14716 } 14717 }); 14718 14719 }, 14720 setDefaultPayment(payment_uuid){ 14721 14722 var $params = { 14723 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 14724 'payment_uuid' : payment_uuid 14725 }; 14726 14727 var timenow = 1; 14728 $params = JSON.stringify($params); 14729 14730 ajax_request[timenow] = $.ajax({ 14731 url: ajaxurl+"/setDefaultPayment", 14732 method: "PUT", 14733 dataType: "json", 14734 data: $params , 14735 contentType : $content_type.json , 14736 timeout: $timeout, 14737 crossDomain: true, 14738 beforeSend: function( xhr ) { 14739 if(ajax_request[timenow] != null) { 14740 ajax_request[timenow].abort(); 14741 } 14742 } 14743 }); 14744 14745 ajax_request[timenow].done( data => { 14746 if ( data.code==1){ 14747 this.SavedPaymentList(); 14748 if ((typeof vue_cart !== "undefined") && ( vue_cart !== null)) { 14749 // THIS IS FOR CARD FEE 14750 //vue_cart.loadcart(); 14751 } 14752 } else { 14753 this.saved_payment_error[0] = data.msg; 14754 } 14755 }); 14756 14757 }, 14758 afterApplywallet(data){ 14759 this.wallet_data = data; 14760 if (Object.keys(this.wallet_data).length > 0) { 14761 vue_cart.use_digital_wallet = data.use_wallet; 14762 } 14763 }, 14764 refreshWallet(data){ 14765 if ((typeof this.$refs.digital_wallet !== "undefined") && ( this.$refs.digital_wallet !== null)) { 14766 if(data.use_digital_wallet){ 14767 let usewallet = data.use_digital_wallet?1:0; 14768 this.$refs.digital_wallet.applyDigitalWallet(usewallet,data.cart_total); 14769 } 14770 } 14771 }, 14772 }, 14773}); 14774 14775if ((typeof components_bundle !== "undefined") && ( components_bundle !== null)) { 14776 $.each(components_bundle,function(components_name, components_value) { 14777 app_payment_list.component(components_name, components_value ); 14778 }); 14779} 14780 14781app_payment_list.component('components-digital-wallet',componentsDigitalWallet); 14782 14783app_payment_list.use(Maska); 14784app_payment_list.use(ElementPlus); 14785const vm_payment_lists = app_payment_list.mount('#vue-payment-list'); 14786 14787/*END PAYMENT LIST*/ 14788 14789 14790/* 14791 COMPONENTS ORER TRACKING 14792*/ 14793 14794const ComponentsOrderTracking = { 14795 props: ['ajax_url' ,'realtime'], 14796 data(){ 14797 return { 14798 ably : undefined, 14799 channel : undefined, 14800 piesocket : undefined, 14801 pusher : undefined, 14802 }; 14803 }, 14804 mounted() { 14805 if(this.realtime.enabled){ 14806 this.initRealTime(); 14807 } 14808 }, 14809 methods:{ 14810 initRealTime(){ 14811 14812 if(this.realtime.provider == "pusher"){ 14813 14814 Pusher.logToConsole = false; 14815 this.pusher = new Pusher( this.realtime.key , { 14816 cluster: this.realtime.cluster 14817 }); 14818 14819 this.channel = this.pusher.subscribe( this.realtime.channel ); 14820 this.channel.bind( this.realtime.event , (data)=> { 14821 dump("receive tracking"); 14822 dump(data); 14823 this.$emit('afterReceive', data ); 14824 }); 14825 14826 } else if ( this.realtime.provider =="ably" ){ 14827 14828 this.ably = new Ably.Realtime(this.realtime.ably_apikey); 14829 this.ably.connection.on('connected', () => { 14830 14831 this.channel = this.ably.channels.get( this.realtime.channel ); 14832 14833 this.channel.subscribe( this.realtime.event , (data) => { 14834 dump("receive ably"); 14835 dump(data); 14836 this.$emit('afterReceive', data ); 14837 }); 14838 14839 }); 14840 14841 } else if ( this.realtime.provider =="piesocket" ){ 14842 14843 this.piesocket = new PieSocket({ 14844 clusterId: this.realtime.piesocket_clusterid , 14845 apiKey: this.realtime.piesocket_api_key 14846 }); 14847 this.channel = this.piesocket.subscribe(this.realtime.channel); 14848 14849 this.channel.listen( this.realtime.event , (data)=> { 14850 dump("receive piesocket"); 14851 dump(data); 14852 this.$emit('afterReceive', data ); 14853 }); 14854 14855 } 14856 14857 } // end real time 14858 }, 14859}; 14860 14861 14862const ComponentsReviewDriver = { 14863 template: '#review_driver', 14864 props : ['order_id','driver_id','driver_info'], 14865 data() { 14866 return { 14867 modal : false, 14868 rating : 0, 14869 data : null, 14870 review_text : null, 14871 loading : false 14872 } 14873 }, 14874 computed: { 14875 hasDriver(){ 14876 if (Object.keys(this.driver_info).length > 0) { 14877 return true; 14878 } 14879 return false;
14880 }, 14881 hasRating(){ 14882 if(this.rating>0){ 14883 return true; 14884 } 14885 return false; 14886 }, 14887 }, 14888 methods: { 14889 whenOpenDialog(){ 14890 if(!this.data){ 14891 this.ReviewAttributes(); 14892 } 14893 }, 14894 ReviewAttributes(){ 14895 axios.get(ajaxurl+"/ReviewAttributes" ).then(response => { 14896 if(response.data.code==1){ 14897 this.data = response.data.details; 14898 } 14899 }) 14900 .catch(error => { 14901 console.error('Error:', error); 14902 }).then(data => { 14903 14904 }); 14905 }, 14906 submitReview(){ 14907 this.loading = true; 14908 let params = "&rating="+this.rating + "&review_text="+this.review_text + "&order_id="+this.order_id + "&driver_id="+this.driver_id; 14909 axios({ 14910 method: 'POST', 14911 url: ajaxurl+"/addRiderReview", 14912 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + params , 14913 }).then( response => { 14914 if(response.data.code==1){ 14915 this.modal = false; 14916 ElementPlus.ElNotification({ 14917 title: "", 14918 message: response.data.msg, 14919 position: 'bottom-right', 14920 type: 'success', 14921 }); 14922 } else { 14923 ElementPlus.ElNotification({ 14924 title: "", 14925 message: response.data.msg, 14926 position: 'bottom-right', 14927 type: 'warning', 14928 }); 14929 } 14930 }).catch(error => { 14931 // 14932 }).then(data => { 14933 this.loading = false; 14934 }); 14935 } 14936 // 14937 }, 14938}; 14939 14940 14941/* 14942 ORDERS 14943 target = vue-orders-track 14944*/ 14945let track_marker = []; 14946let track_bounds; 14947let directionsService, directionsRenderer; 14948const vm_orders_track = Vue.createApp({ 14949 components: { 14950 'component-order-tracking' : ComponentsOrderTracking, 14951 'components-review' : ComponentsReview, 14952 'components-reviewdriver': ComponentsReviewDriver 14953 }, 14954 data(){ 14955 return { 14956 order_uuid : php_order_uuid, 14957 merchant_info : [], 14958 items : [], 14959 meta : [], 14960 error : [], 14961 maps_config : [], 14962 maps_provider : '', 14963 cmaps : null, 14964 items_count : 0, 14965 order_progress : -1, 14966 order_status : '', 14967 order_status_details : '', 14968 order_info : [], 14969 instructions : [], 14970 points_label : '', 14971 enabled_review : true, 14972 cancel_loading : false, 14973 estimated_time : '', 14974 is_order_need_cancellation : false, 14975 request_interval : 50000, 14976 timer : null, 14977 is_order_ongoing : false, 14978 driver_info : null, 14979 modal_chat : false, 14980 chat_link : null, 14981 isMobile: false, 14982 order_type : null, 14983 whatsapp_data : [] 14984 }; 14985 }, 14986 mounted () { 14987 this.getOrder(); 14988 if ((typeof request_interval !== "undefined") && ( request_interval !== null)) { 14989 this.request_interval = request_interval; 14990 } 14991 this.checkIfMobile(); 14992 window.addEventListener('resize', this.checkIfMobile); 14993 }, 14994 unmounted() { 14995 this.stopTimer(); 14996 window.removeEventListener('resize', this.checkIfMobile); 14997 }, 14998 watch: { 14999 order_progress(newval,oldval){ 15000 console.log("order_progress change",newval); 15001 if(this.order_type=="delivery"){ 15002 this.doFirebaseTrack(); 15003 this.addDriverRoute(1000); 15004 this.UpdateDriverMarker(); 15005 } else { 15006 if(this.order_progress===3 && !this.driver_info){ 15007 console.log("add route for pickup"); 15008 this.addCustomerRoute(1000); 15009 } 15010 } 15011 }, 15012 is_order_ongoing(newval,oldval){ 15013 console.log("is_order_ongoing",newval); 15014 if(!newval){ 15015 this.removeMap(); 15016 } 15017 }, 15018 }, 15019 computed: { 15020 isActive(){ 15021 return { 15022 'active': true 15023 } 15024 }, 15025 hasInstructions(){ 15026 if(this.instructions){ 15027 if(!empty(this.instructions.text)){ 15028 if(this.order_progress>=3){ 15029 return true; 15030 } 15031 } 15032 } 15033 return false; 15034 }, 15035 getEstimatetime(){ 15036 let estimate = ''; 15037 switch (this.order_progress) { 15038 case 1: 15039 case 2: 15040 case 3: 15041 estimate = this.estimated_time; 15042 break; 15043 default: 15044 break; 15045 } 15046 return estimate; 15047 }, 15048 showReview(){ 15049 // if(this.order_progress===4 && this.enabled_review){ 15050 // return true; 15051 // } else if ( this.order_progress===3 && !this.driver_info){ 15052 // return true; 15053 // } else { 15054 // return false;
15055 // } 15056 if(this.order_type=="delivery"){ 15057 if(this.order_progress===4 && this.enabled_review){ 15058 return true; 15059 } 15060 } else { 15061 if(this.order_progress===3 && !this.driver_info){ 15062 return true; 15063 } 15064 } 15065 return false; 15066 }, 15067 }, 15068 methods :{ 15069 checkIfMobile() { 15070 this.isMobile = window.matchMedia("(max-width: 768px)").matches; 15071 }, 15072 callDriver(){ 15073 const phoneLink = `tel:${this.driver_info.phone}`; 15074 window.location.href = phoneLink; 15075 }, 15076 openChatDriver(){ 15077 const view_mode = this.isMobile?'mobile':'desktop'; 15078 this.chat_link = chat_driver_url +"/?id=CORD-"+this.order_info.order_uuid+"&view=" + view_mode ; 15079 if(!this.isMobile){ 15080 this.modal_chat = true; 15081 } else { 15082 location.href = this.chat_link; 15083 } 15084 }, 15085 doFirebaseTrack(){ 15086 console.log("doFirebaseTrack",this.driver_info); 15087 if(!window.vm_track_order.driver_uuid && this.driver_info && this.order_progress==3){ 15088 window.vm_track_order.driver_uuid = this.driver_info.driver_uuid; 15089 } 15090 }, 15091 removeMap(){ 15092 console.log("removeMap"); 15093 switch(this.maps_provider){ 15094 case "google.maps": 15095 document.getElementById('cmaps').innerHTML = ''; 15096 break; 15097 case "mapbox": 15098 this.cmaps.remove(); 15099 this.cmaps = null; 15100 break; 15101 } 15102 }, 15103 updateImage(){ 15104 updateLazyImage(); 15105 }, 15106 afterAddreview(){ 15107 console.log("afterAddreview"); 15108 if(this.driver_info){ 15109 this.$refs.ref_driverreview.modal = true; 15110 } 15111 }, 15112 getOrder(){ 15113 var $params; var timenow = getTimeNow(); 15114 $params="order_uuid=" + this.order_uuid; 15115 $params+=addValidationRequest(); 15116 ajax_request[timenow] = $.ajax({ 15117 url: ajaxurl+"/getOrder", 15118 method: "POST", 15119 dataType: "json", 15120 data: $params, 15121 contentType : $content_type.form , 15122 timeout: $timeout, 15123 crossDomain: true, 15124 beforeSend: function( xhr ) { 15125 if(ajax_request[timenow] != null) { 15126 ajax_request[timenow].abort(); 15127 } 15128 } 15129 }); 15130 15131 ajax_request[timenow].done( data => { 15132 if(data.code==1){ 15133 this.merchant_info = data.details.merchant_info; 15134 this.order_info = data.details.order_info; 15135 this.order_type = this.order_info.service_code; 15136 this.items = data.details.items; 15137 this.meta = data.details.meta; 15138 this.updateImage(); 15139 this.maps_config = data.details.maps_config; 15140 this.items_count = data.details.items_count; 15141 15142 this.order_progress = data.details.progress.order_progress; 15143 this.order_status = data.details.progress.order_status; 15144 this.order_status_details = data.details.progress.order_status_details; 15145 15146 this.driver_info = data.details.progress.driver_info; 15147 15148 this.instructions = data.details.instructions; 15149 this.points_label = data.details.points_label; 15150 15151 this.enabled_review = data.details.enabled_review; 15152 15153 this.estimated_time = data.details.order_info.estimated_time; 15154 this.is_order_need_cancellation = data.details.order_info.is_order_need_cancellation; 15155 this.is_order_ongoing = data.details.order_info.is_order_ongoing; 15156 15157 this.whatsapp_data = data.details.whatsapp_data; 15158 15159 if(this.is_order_ongoing){ 15160 this.timer = setInterval(() => { 15161 this.trackOrder(); 15162 }, this.request_interval); 15163 } 15164 15165 } else { 15166 this.error = data.msg; 15167 this.items_count = 0; 15168 this.order_info = []; 15169 this.points_label = ''; 15170 } 15171 15172 if ((typeof this.maps_config.provider !== "undefined") && ( this.maps_config.provider !== null) && this.is_order_ongoing ) { 15173 this.loadTrackMap(); 15174 } 15175 15176 }); // ajax done 15177 15178 ajax_request[timenow].always( data => { 15179 15180 }); 15181 }, 15182 afterProgress(data){ 15183 console.log("afterProgress",data); 15184 if(data.order_id!=this.order_info.order_id){ 15185 return; 15186 } 15187 15188 this.driver_info = data.driver_info; 15189 this.is_order_ongoing = data.is_order_ongoing; 15190 15191 if(data.order_progress==0){ 15192 this.order_progress = data.order_progress; 15193 this.order_status = data.order_status; 15194 this.order_status_details = data.order_status_details; 15195 } else if( data.order_progress==-1){ 15196 // do nothing 15197 } else { 15198 this.order_progress = data.order_progress; 15199 this.order_status = data.order_status; 15200 this.order_status_details = data.order_status_details; 15201 this.estimated_time = data.estimated_time; 15202 this.is_order_need_cancellation = data.is_order_need_cancellation; 15203 } 15204 }, 15205 writeReview(order_uuid){ 15206 dump('writeReview 123=>' + order_uuid); 15207 this.$refs.ReviewRef.order_uuid = order_uuid; 15208 this.$refs.ReviewRef.show(); 15209 }, 15210 loadTrackMap(){ 15211 15212 this.maps_provider = this.maps_config.provider; 15213 15214 let customer_address = this.order_info.address_label + " - " + this.order_info.complete_delivery_address + " " + this.order_info.location_name; 15215 15216 switch(this.maps_provider){ 15217 case "google.maps": 15218 track_bounds = new google.maps.LatLngBounds(); 15219 this.cmaps = new google.maps.Map(document.getElementById("cmaps"), { 15220 center: { lat: parseFloat(this.merchant_info.latitude), lng: parseFloat(this.merchant_info.longitude) }, 15221 zoom: this.maps_config.zoom , 15222 disableDefaultUI: true, 15223 }); 15224 15225 directionsService = new google.maps.DirectionsService(); 15226 directionsRenderer = new google.maps.DirectionsRenderer({ 15227 map: this.cmaps, 15228 suppressMarkers: true , 15229 polylineOptions: { 15230 strokeColor: 'blue', 15231 strokeWeight: 7, 15232 strokeOpacity: 0.8 15233 } 15234 }); 15235 15236 15237 if(!empty(this.merchant_info.latitude)){ 15238 this.addMarker({ 15239 position: { lat: parseFloat(this.merchant_info.latitude) , lng: parseFloat(this.merchant_info.longitude) }, 15240 map: this.cmaps, 15241 icon : { 15242 url : this.maps_config.icon_merchant, 15243 scaledSize: new google.maps.Size(45, 45), 15244 }, 15245 animation: google.maps.Animation.DROP, 15246 title : this.merchant_info.restaurant_name + " - " + this.merchant_info.address 15247 },1); 15248 } 15249 15250 if(!empty(this.meta.latitude)){ 15251 this.addMarker({ 15252 position: { lat: parseFloat(this.meta.latitude) , lng: parseFloat(this.meta.longitude) }, 15253 map: this.cmaps, 15254 icon : { 15255 url : this.maps_config.icon_destination, 15256 scaledSize: new google.maps.Size(45, 45), 15257 }, 15258 animation: google.maps.Animation.DROP, 15259 title : customer_address 15260 },2); 15261 } 15262 15263 this.FitBounds(); 15264 15265 break; 15266 15267 case "mapbox": 15268 track_bounds = new mapboxgl.LngLatBounds(); 15269 15270 15271 mapboxgl.accessToken = this.maps_config.key; 15272 this.cmaps = new mapboxgl.Map({ 15273 container: this.$refs.cmaps , 15274 style: 'mapbox://styles/mapbox/streets-v12', 15275 center: [ parseFloat(this.maps_config.default_lng) , parseFloat(this.maps_config.default_lat)], 15276 zoom: 14 15277 }); 15278 15279 this.cmaps.on('error', (response) => { 15280 console.log("map error",response.error.message); 15281 }); 15282 15283 this.mapBoxResize(); 15284 15285 if(!empty(this.merchant_info.latitude && this.order_progress<=2)){ 15286 this.addMarker({ 15287 position: { lat: parseFloat(this.merchant_info.latitude) , lng: parseFloat(this.merchant_info.longitude) }, 15288 map: this.cmaps, 15289 icon : 'marker_icon_merchant', 15290 animation: null, 15291 title : this.merchant_info.restaurant_name + " - " + this.merchant_info.address 15292 },1); 15293 } else if ( this.order_progress >2 && !this.driver_info) { 15294 this.addMarker({ 15295 position: { lat: parseFloat(this.merchant_info.latitude) , lng: parseFloat(this.merchant_info.longitude) }, 15296 map: this.cmaps, 15297 icon : 'marker_icon_merchant', 15298 animation: null, 15299 title : this.merchant_info.restaurant_name + " - " + this.merchant_info.address 15300 },1); 15301 } 15302 15303 if(!empty(this.meta.latitude)){ 15304 this.addMarker({ 15305 position: { lat: parseFloat(this.meta.latitude) , lng: parseFloat(this.meta.longitude) }, 15306 map: this.cmaps, 15307 icon : 'marker_icon_destination', 15308 animation: null, 15309 title : customer_address 15310 },2); 15311 } 15312 15313 if(this.driver_info && this.order_progress>2){ 15314 this.addMarker({ 15315 position: { lat: parseFloat(this.driver_info.latitude) , lng: parseFloat(this.driver_info.lontitude) }, 15316 map: this.cmaps, 15317 icon : 'marker_icon_rider', 15318 animation: null, 15319 title : this.driver_info.full_name 15320 },3); 15321 } 15322 15323 this.FitBounds(); 15324 break; 15325 15326 case "yandex": 15327 this.initYandexTrackMap(); 15328 break; 15329 } 15330 },
15331 async initYandexTrackMap(){ 15332 console.debug("initYandexTrackMap"); 15333 await ymaps3.ready; 15334 const {YMap, YMapDefaultSchemeLayer,YMapMarker,YMapDefaultFeaturesLayer } = ymaps3; 15335 15336 const LOCATION = { 15337 center: [ parseFloat(this.maps_config.default_lng), parseFloat(this.maps_config.default_lat) ], 15338 zoom: yandex_zoom 15339 }; 15340 15341 if(yandex_map){ 15342 yandex_map.destroy(); 15343 yandex_map = null; 15344 } 15345 15346 if (!yandex_map) { 15347 yandex_map = new YMap( 15348 this.$refs.cmaps, 15349 { 15350 location: LOCATION, 15351 showScaleInCopyrights: false, 15352 behaviors: ['drag','scrollZoom'] 15353 }, 15354 [ 15355 new YMapDefaultSchemeLayer({}), 15356 new YMapDefaultFeaturesLayer({}) 15357 ] 15358 ); 15359 15360 let yandex_bounds = []; 15361 15362 if(!empty(this.merchant_info.latitude)){ 15363 let location1 = [ 15364 parseFloat(this.merchant_info.longitude), parseFloat(this.merchant_info.latitude) 15365 ]; 15366 yandex_bounds.push(location1); 15367 const markerElement = document.createElement('img'); 15368 markerElement.className = 'icon-marker'; 15369 markerElement.src = this.maps_config.icon_merchant; 15370 yandex_map.addChild(new YMapMarker({coordinates: location1 }, markerElement)); 15371 } 15372 15373 if(!empty(this.meta.latitude)){ 15374 let location2 = [ 15375 parseFloat(this.meta.longitude), parseFloat(this.meta.latitude) 15376 ]; 15377 yandex_bounds.push(location2); 15378 const markerElement = document.createElement('img'); 15379 markerElement.className = 'icon-marker'; 15380 markerElement.src = this.maps_config.icon_destination; 15381 yandex_map.addChild(new YMapMarker({coordinates: location2 }, markerElement)); 15382 } 15383 15384 const NEWLOCATION = { 15385 center : yandex_bounds[0], 15386 zoom: yandex_zoom 15387 }; 15388 yandex_map.update({ 15389 location : NEWLOCATION 15390 }); 15391 15392 } 15393 }, 15394 mapBoxResize(){ 15395 if(this.maps_config.provider=="mapbox"){ 15396 setTimeout(()=>{ 15397 this.cmaps.resize(); 15398 }, 500); 15399 } 15400 }, 15401 addMarker(properties,index){ 15402 switch(this.maps_provider){ 15403 case "google.maps": 15404 track_marker[index] = new google.maps.Marker(properties); 15405 15406 const infoWindow = new google.maps.InfoWindow({ 15407 content: properties.title, 15408 }); 15409 15410 track_marker[index].addListener("click", () => { 15411 infoWindow.open(this.cmaps, track_marker[index] ); 15412 }); 15413 15414 track_bounds.extend(track_marker[index].position); 15415 break; 15416 case "mapbox": 15417 const el = document.createElement('div'); 15418 el.className = properties.icon; 15419 track_marker[index] = new mapboxgl.Marker(el) 15420 .setLngLat([properties.position.lng, properties.position.lat]) 15421 .addTo(this.cmaps); 15422 15423 const popup = new mapboxgl.Popup({ offset: 25 }).setText(properties.title); 15424 track_marker[index].setPopup(popup); 15425 //popup.addTo(this.cmaps); 15426 15427 track_bounds.extend(new mapboxgl.LngLat(properties.position.lng, properties.position.lat)); 15428 break; 15429 } 15430 }, 15431 async addDriverRoute(timeoutValue){ 15432 if(!this.is_order_ongoing){ 15433 return ; 15434 } 15435 setTimeout(async ()=>{ 15436 if(this.driver_info && this.order_progress>2){ 15437 console.log("addDriverRoute"); 15438 15439 if(track_marker[1]){ 15440 if(this.maps_provider=="mapbox"){ 15441 track_marker[1].remove(); 15442 } else if ( this.maps_provider=="google.maps" ){ 15443 console.log("remove marker mapbox"); 15444 track_marker[1].setMap(null); 15445 track_marker[1] = null; 15446 } 15447 } 15448 15449 let startLocation,endLocation; 15450 if(this.maps_provider=="mapbox"){ 15451 startLocation = [ parseFloat(this.driver_info.lontitude), parseFloat(this.driver_info.latitude) ]; 15452 endLocation = [ parseFloat(this.meta.longitude) , parseFloat(this.meta.latitude) ]; 15453 } else if ( this.maps_provider=="google.maps" ){ 15454 startLocation = { lat: parseFloat(this.driver_info.latitude), lng: parseFloat(this.driver_info.lontitude) }; 15455 endLocation = { lat:parseFloat(this.meta.latitude) , lng: parseFloat(this.meta.longitude) }; 15456 } 15457 this.addRoute(startLocation,endLocation); 15458 } 15459 }, timeoutValue); 15460 }, 15461 addCustomerRoute(timeoutValue){ 15462 let startLocation,endLocation; 15463 if(this.maps_provider=="mapbox"){ 15464 startLocation = [ parseFloat(this.meta.longitude), parseFloat(this.meta.latitude) ]; 15465 endLocation = [ parseFloat(this.merchant_info.longitude) , parseFloat(this.merchant_info.latitude) ]; 15466 } else if ( this.maps_provider=="google.maps" ){ 15467 startLocation = { lat: parseFloat(this.meta.latitude), lng: parseFloat(this.meta.longitude) }; 15468 endLocation = { lat:parseFloat(this.merchant_info.latitude) , lng: parseFloat(this.merchant_info.longitude) }; 15469 } 15470 setTimeout(()=>{ 15471 this.addRoute(startLocation,endLocation); 15472 }, timeoutValue); 15473 }, 15474 async addRoute(start, end){ 15475 console.log("start",start);
15476 console.log("end",end); 15477 if(this.maps_provider=="mapbox"){ 15478 const query = await fetch(`https://api.mapbox.com/directions/v5/mapbox/driving/${start[0]},${start[1]};${end[0]},${end[1]}?geometries=geojson&access_token=${mapboxgl.accessToken}`, 15479 { method: 'GET' }); 15480 const json = await query.json(); 15481 const data = json.routes[0]; 15482 const route = data.geometry; 15483 15484 if (this.cmaps.getSource('route')) { 15485 this.cmaps.getSource('route').setData(route); 15486 } else { 15487 this.cmaps.addLayer({ 15488 id: 'route', 15489 type: 'line', 15490 source: { 15491 type: 'geojson', 15492 data: route, 15493 }, 15494 layout: { 15495 'line-join': 'round', 15496 'line-cap': 'round', 15497 }, 15498 paint: { 15499 'line-color': '#76adeb', 15500 'line-width': 7, 15501 }, 15502 }); 15503 } 15504 this.FitBounds(); 15505 } else if ( this.maps_provider=="google.maps" ){ 15506 directionsRenderer.setDirections({ routes: [] }); 15507 directionsService.route( 15508 { 15509 origin: start, 15510 destination: end, 15511 travelMode: 'DRIVING', 15512 },(response, status) => { 15513 console.log("status",status); 15514 if (status === 'OK') { 15515 console.log("response",response); 15516 directionsRenderer.setDirections(response); 15517 } else { 15518 console.error('Directions request failed due to ' + status); 15519 } 15520 } 15521 ); 15522 } 15523 }, 15524 FitBounds(){ 15525 switch(this.maps_provider){ 15526 case "google.maps": 15527 this.cmaps.fitBounds(track_bounds,); 15528 break; 15529 case "mapbox": 15530 this.cmaps.fitBounds(track_bounds,{ 15531 padding: 30 15532 }); 15533 break; 15534 } 15535 }, 15536 CancelOrder(){ 15537 console.log("CancelOrder",this.order_uuid); 15538 let $some_words = JSON.parse(some_words); 15539 ElementPlus.ElMessageBox.confirm( 15540 $some_words.cancel_order_descriptions, 15541 $some_words.cancel_order, 15542 { 15543 confirmButtonText: $some_words.confirm, 15544 cancelButtonText: $some_words.cancel, 15545 type: 'info', 15546 } 15547 ) 15548 .then(() => { 15549 this.applyCancelOrder(); 15550 }) 15551 .catch(() => { 15552 // 15553 }); 15554 }, 15555 applyCancelOrder(){ 15556 this.cancel_loading = true; 15557 axios({ 15558 method: 'POST', 15559 url: ajaxurl+"/CancelOrder", 15560 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&order_uuid="+this.order_uuid, 15561 }).then( response => { 15562 if(response.data.code==1){ 15563 ElementPlus.ElNotification({ 15564 title: "", 15565 message: response.data.msg, 15566 position: 'bottom-right', 15567 type: 'success', 15568 }); 15569 this.getOrder(); 15570 } else { 15571 ElementPlus.ElNotification({ 15572 title: "", 15573 message: response.data.msg, 15574 position: 'bottom-right', 15575 type: 'warning', 15576 }); 15577 } 15578 }).catch(error => { 15579 // 15580 }).then(data => { 15581 this.cancel_loading = false; 15582 }); 15583 }, 15584 trackOrder(){ 15585 console.log("trackOrder"); 15586 axios.get(ajaxurl+"/trackOrder?" + "order_uuid="+ this.order_uuid ).then(response => { 15587 if(response.data.code==1){ 15588 this.afterProgress(response.data.details.data); 15589 if(!response.data.details.data.is_order_ongoing){ 15590 this.stopTimer(); 15591 } 15592 } else { 15593 this.stopTimer(); 15594 } 15595 }) 15596 .catch(error => { 15597 console.error('Error:', error); 15598 }).then(data => { 15599 }); 15600 }, 15601 stopTimer(){
15602 console.log("stopTimer"); 15603 clearInterval(this.timer); 15604 }, 15605 setDriverLocation(data){ 15606 if(this.driver_info && this.order_progress>2){ 15607 console.log("setDriverLocation",data); 15608 this.driver_info.latitude = data.lat; 15609 this.driver_info.lontitude = data.lng; 15610 this.UpdateDriverMarker(); 15611 this.addDriverRoute(0); 15612 } 15613 }, 15614 UpdateDriverMarker(){ 15615 if(!this.cmaps){ 15616 return; 15617 } 15618 if(!this.is_order_ongoing){ 15619 return ; 15620 } 15621 if(!this.driver_info){ 15622 return; 15623 } 15624 if(this.driver_info && this.order_progress>2){ 15625 console.log("UpdateDriverMarker"); 15626 if(track_marker[3]){ 15627 if(this.maps_provider=="mapbox"){ 15628 const driverCoordinates = [ parseFloat(this.driver_info.lontitude) , parseFloat(this.driver_info.latitude) ]; 15629 track_marker[3].setLngLat(driverCoordinates); 15630 } else if (this.maps_provider=="google.maps" ) { 15631 console.log("move google marker"); 15632 const driverCoordinates = { lat: parseFloat(this.driver_info.latitude) , lng: parseFloat(this.driver_info.lontitude) }; 15633 track_marker[3].setPosition(driverCoordinates); 15634 } 15635 } else { 15636 if(this.maps_provider=="mapbox"){ 15637 this.addMarker({ 15638 position: { lat: parseFloat(this.driver_info.latitude) , lng: parseFloat(this.driver_info.lontitude) }, 15639 map: this.cmaps, 15640 icon : 'marker_icon_rider', 15641 animation: null, 15642 title : this.driver_info.full_name 15643 },3); 15644 } else if (this.maps_provider=="google.maps" ) { 15645 this.addMarker({ 15646 position: { lat: parseFloat(this.driver_info.latitude) , lng: parseFloat(this.driver_info.lontitude) }, 15647 map: this.cmaps, 15648 icon : { 15649 url : this.maps_config.icon_rider, 15650 scaledSize: new google.maps.Size(35, 35), 15651 }, 15652 animation: null, 15653 title : this.driver_info.full_name 15654 },3); 15655 } 15656 } 15657 } 15658 }, 15659 // 15660 }, 15661}); 15662vm_orders_track.use(ElementPlus); 15663window.app_orders_track = vm_orders_track.mount('#vue-orders-track'); 15664 15665 15666/* 15667COMPONENTS CART PREVIEW 15668*/ 15669const ComponentCartPreview = { 15670 props: ['payload','label','cart_preview','drawer'], 15671 data(){ 15672 return { 15673 cart_loading : true, 15674 cart_uuid : '', 15675 cart_items : [], 15676 cart_summary : [], 15677 cart_merchant : [], 15678 cart_total : [], 15679 error : [], 15680 go_checkout : [], 15681 subtotal : [], 15682 items_count : 0, 15683 update_cart_loading : false, 15684 // Local copy of the drawer prop â avoids mutating a read-only prop via 15685 // el-drawer's v-model, which would block closing in Vue 3 and leave 15686 // overflow:hidden on the body (stopping page scroll). 15687 localDrawer : false 15688 }; 15689 }, 15690 watch: { 15691 drawer(val) { 15692 this.localDrawer = val; 15693 } 15694 }, 15695 computed: { 15696 hasError(){ 15697 if(this.error.length>0){ 15698 return true; 15699 } 15700 return false; 15701 } 15702 }, 15703 methods:{ 15704 getCartPreview(){ 15705 15706 if(!this.cart_preview){ 15707 this.getCartCount(); 15708 return ; 15709 } 15710 15711 var timenow = getTimeNow(); 15712 let currency_code = getCookie('currency_code'); 15713 currency_code = !empty(currency_code)?currency_code:''; 15714 15715 const location = getLocation(); 15716 const selectedAddress = getFromLocalStorageStore(StoreMapName,"selectedAddress"); 15717 var $params = { 15718 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 15719 'cart_uuid':getCookie('cart_uuid'), 15720 'currency_code': currency_code, 15721 'payload': this.payload, 15722 'location':location, 15723 'latitude': selectedAddress?selectedAddress.latitude :'', 15724 'longitude': selectedAddress?selectedAddress.longitude :'', 15725 }; 15726 15727 ajax_request[timenow] = $.ajax({ 15728 url: ajaxurl+"/getCart", 15729 method: "PUT", 15730 dataType: "json", 15731 data: JSON.stringify($params), 15732 contentType : $content_type.json , 15733 timeout: $timeout, 15734 crossDomain: true, 15735 beforeSend: data => { 15736 if(ajax_request[timenow] != null) { 15737 ajax_request[timenow].abort(); 15738 } 15739 } 15740 }); 15741 15742 ajax_request[timenow].done( data => { 15743 this.cart_loading = false; 15744 if (data.code==1){ 15745 15746 this.cart_merchant = data.details.data.merchant; 15747 this.cart_uuid = data.details.cart_uuid; 15748 this.cart_items = data.details.data.items; 15749 this.cart_summary = data.details.data.summary; 15750 this.cart_total = data.details.data.total; 15751 this.error = data.details.error; 15752 this.go_checkout = data.details.go_checkout; 15753 this.subtotal = data.details.data.subtotal; 15754 this.items_count = data.details.items_count; 15755 } else { 15756 this.cart_items = []; 15757 this.cart_summary = []; 15758 this.cart_total = []; 15759 this.error = []; 15760 this.subtotal = 0; 15761 this.items_count = 0; 15762 } 15763 15764 this.updateImage(); 15765 this.$emit('setCartcount',this.items_count); 15766 15767 if ((typeof vm !== "undefined") && ( vm !== null)) { 15768 vm.hasItemInCart(this.items_count , this.cart_merchant); 15769 } 15770 15771 }); // ajax done 15772 15773 }, 15774 getCartCount(){ 15775 var timenow = getTimeNow(); 15776 let currency_code = getCookie('currency_code'); 15777 currency_code = !empty(currency_code)?currency_code:''; 15778 var $params = { 15779 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 15780 'cart_uuid':getCookie('cart_uuid'), 15781 'currency_code': currency_code, 15782 'payload': ['items_count'] 15783 }; 15784 15785 ajax_request[timenow] = $.ajax({ 15786 url: ajaxurl+"/getCart", 15787 method: "PUT", 15788 dataType: "json", 15789 data: JSON.stringify($params), 15790 contentType : $content_type.json , 15791 timeout: $timeout, 15792 crossDomain: true, 15793 beforeSend: data => { 15794 if(ajax_request[timenow] != null) { 15795 ajax_request[timenow].abort(); 15796 } 15797 } 15798 }); 15799 15800 ajax_request[timenow].done( data => { 15801 if (data.code==1){ 15802 this.items_count = data.details.items_count; 15803 } else this.items_count = 0; 15804 15805 this.$emit('setCartcount',this.items_count); 15806 15807 }); // ajax done 15808 15809 },
15810 updateCartQty(addOrSubract,item_qty,cart_row,cart_uuid){ 15811 if(addOrSubract==1){ 15812 item_qty++; 15813 } else item_qty--; 15814 15815 if(item_qty<=0){ 15816 this.remove(cart_row,cart_uuid); 15817 } else { 15818 this.updateCartItems( item_qty,cart_row,cart_uuid ); 15819 } 15820 },// 15821 updateCartItems(item_qty,cart_row,cart_uuid){ 15822 15823 var $params; var timenow = 1; 15824 $params="cart_uuid=" + cart_uuid; 15825 $params+="&cart_row=" + cart_row; 15826 $params+="&item_qty=" + item_qty; 15827 15828 this.update_cart_loading = true; 15829 15830 $params+=addValidationRequest(); 15831 ajax_request[timenow] = $.ajax({ 15832 url: ajaxurl+"/updateCartItems", 15833 method: "POST", 15834 dataType: "json", 15835 data: $params, 15836 contentType : $content_type.form , 15837 timeout: $timeout, 15838 crossDomain: true, 15839 beforeSend: function( xhr ) { 15840 if(ajax_request[timenow] != null) { 15841 ajax_request[timenow].abort(); 15842 } 15843 } 15844 }); 15845 15846 ajax_request[timenow].done( data => { 15847 if (data.code==1){ 15848 this.getCartPreview(); 15849 } 15850 15851 if ((typeof homeWidgets !== "undefined") && ( homeWidgets !== null)) { 15852 homeWidgets.$refs.ref_featured_list.getFeaturedItems(); 15853 } 15854 15855 }); // ajax done 15856 15857 ajax_request[timenow].always( data => { 15858 this.update_cart_loading = false; 15859 }); 15860 15861 }, // 15862 remove(cart_row,cart_uuid){ 15863 var $params; var timenow = 1; 15864 $params="row=" + cart_row +"&cart_uuid="+cart_uuid; 15865 $params+=addValidationRequest(); 15866 ajax_request[timenow] = $.ajax({ 15867 url: ajaxurl+"/removeCartItem", 15868 method: "POST", 15869 dataType: "json", 15870 data: $params, 15871 contentType : 'application/x-www-form-urlencoded; charset=UTF-8' , 15872 timeout: $timeout, 15873 crossDomain: true, 15874 beforeSend: function( xhr ) { 15875 if(ajax_request[timenow] != null) { 15876 ajax_request[timenow].abort(); 15877 } 15878 } 15879 }); 15880 15881 ajax_request[timenow].done( data => { 15882 dump(data); 15883 if (data.code==1){ 15884 this.getCartPreview(); 15885 } 15886 }); // ajax done 15887 15888 },// 15889 clear(cart_uuid){ 15890 15891 var $params; var timenow = 1; 15892 $params="cart_uuid=" + cart_uuid; 15893 $params+=addValidationRequest(); 15894 ajax_request[timenow] = $.ajax({ 15895 url: ajaxurl+"/clearCart", 15896 method: "POST", 15897 dataType: "json", 15898 data: $params, 15899 contentType : $content_type.form , 15900 timeout: $timeout, 15901 crossDomain: true, 15902 beforeSend: function( xhr ) { 15903 if(ajax_request[timenow] != null) { 15904 ajax_request[timenow].abort(); 15905 } 15906 } 15907 }); 15908 15909 ajax_request[timenow].done( data => { 15910 if (data.code==1){ 15911 this.getCartPreview(); 15912 } 15913 }); // ajax done 15914 15915 }, // 15916 updateImage(){ 15917 updateLazyImage(); 15918 }, 15919 beforeClose(done){ 15920 this.localDrawer = false; 15921 this.$emit('afterDrawerclose',false); 15922 done(); 15923 }, 15924 }, 15925 template: ` 15926 15927 <el-drawer 15928 v-model="localDrawer" 15929 direction="rtl" 15930 size="320px" 15931 append-to-body="true" 15932 :with-header="true" 15933 :before-close="beforeClose" 15934 custom-class="drawer-preview-cart" 15935 > 15936 15937 <template v-if="cart_loading==false"> 15938 <template v-if="cart_items.length>0"> 15939 15940 <div class="mt-3 mb-0"> 15941 <p class="m-0 bold">{{label.your_cart}}</p> 15942 <a :href="cart_merchant.restaurant_slug" class="m-0 p-0"><h5 class="m-0 chevron d-inline position-relative">{{cart_merchant.restaurant_name}}</h5></a> 15943 <p class="m-0 text-muted">{{cart_merchant.merchant_address}}</p> 15944 </div> 15945 15946 <div class="d-flex justify-content-between align-items-center mb-1"> 15947 <div><h6 class="m-0">{{label.summary}}</h6></div> 15948 <div> 15949 <a href="javascript:;" @click="clear(cart_uuid)" class="javascript:;"> 15950 <p class="m-0"><u>{{label.clear}}</u></p> 15951 </a> 15952 </div> 15953 </div> 15954 </template> 15955 15956 <template v-else> 15957 <h5 class="mt-3 mb-0">{{label.cart}}</h5> 15958 <div class="cart-empty text-center" > 15959 <div class="mt-5"> 15960 <div class="no-results m-auto"></div> 15961 <h6 class="m-0 mt-3">{{label.no_order}}</h6> 15962 <p>{{label.lets_change_that}}</p> 15963 </div>
15964 </div> 15965 </template> 15966 15967 </template> 15968 15969 <!--section-cart--> 15970 <DIV class="section-cart"> 15971 15972 <div v-cloak class="items" v-for="(items, index) in cart_items" > 15973 15974 <div class="line-items row mb-1"> 15975 <div class="col-3"> 15976 <el-image 15977 style="width: 50px; height: 50px" 15978 :src="items.url_image" 15979 :fit="contain" 15980 lazy 15981 ></el-image> 15982 </div> <!--col--> 15983 15984 <div class="col-6 p-0 d-flex justify-content-start flex-column"> 15985 15986 <p class="mb-1"> 15987 {{ items.item_name }} 15988 <template v-if=" items.price.size_name!='' "> 15989 ({{items.price.size_name}}) 15990 </template> 15991 </p> 15992 15993 <template v-if="items.is_free"> 15994 <div class="mb-1"> 15995 <el-tag effect="plain" type="success" size="small" style="white-space: nowrap !important;" > 15996 {{ label.free }} 15997 </el-tag> 15998 </div> 15999 </template> 16000 <template v-else> 16001 <template v-if="items.price.discount>0"> 16002 <p class="m-0 font11"><del>{{items.price.pretty_price}}</del> {{items.price.pretty_price_after_discount}}</p> 16003 </template> 16004 <template v-else> 16005 <p class="m-0 font11">{{items.price.pretty_price}}</p> 16006 </template> 16007 </template> 16008 16009 <!--quantity--> 16010 <div class="quantity d-flex justify-content-between"> 16011 16012 <div> 16013 <a href="javascript:;" @click="updateCartQty(0,items.qty,items.cart_row,cart_uuid)" class="rounded-pill qty-btn" data-id="less"> 16014 <i class="zmdi zmdi-minus"></i> 16015 </a> 16016 </div> 16017 16018 <div class="qty">{{ items.qty }}</div> 16019 16020 <div> 16021 <a href="javascript:;" @click="updateCartQty(1,items.qty,items.cart_row,cart_uuid)" class="rounded-pill qty-btn" data-id="plus"> 16022 <i class="zmdi zmdi-plus"></i> 16023 </a> 16024 </div> 16025 16026 </div> 16027 <!--quantity--> 16028 16029 <p class="mb-0" v-if=" items.special_instructions!='' ">{{ items.special_instructions }}</p> 16030 16031 <template v-if=" items.attributes!='' "> 16032 <template v-for="(attributes, attributes_key) in items.attributes"> 16033 <p class="mb-0"> 16034 <template v-for="(attributes_data, attributes_index) in attributes"> 16035 {{attributes_data}}<template v-if=" attributes_index<(attributes.length-1) ">, </template> 16036 </template> 16037 </p> 16038 </template> 16039 </template> 16040 16041 16042 </div> <!--col--> 16043 16044 <div class="col-3 quantity d-flex justify-content-start flex-column text-right"> 16045 <a href="javascript:;" @click="remove(items.cart_row,cart_uuid)" class="rounded-pill ml-auto mb-1"><i class="zmdi zmdi-close"></i></a> 16046 <template v-if="items.price.discount<=0 "> 16047 <p class="mb-0">{{ items.price.pretty_total }}</p> 16048 </template> 16049 <template v-else> 16050 <p class="mb-0">{{ items.price.pretty_total_after_discount }}</p> 16051 </template> 16052 </div> <!--col--> 16053 16054 </div><!-- line-items--> 16055 16056 <!--addon-items--> 16057 <div class="addon-items row mb-1" v-for="(addons, index_addon) in items.addons" > 16058 <div class="col-3"><!--empty--></div> <!--col--> 16059 <div class="col-9 pl-0 d-flex justify-content-start flex-column"> 16060 <p class="m-0 bold">{{ addons.subcategory_name }}</p> 16061 16062 <template v-cloak v-for="addon_items in addons.addon_items"> 16063 <div class="d-flex justify-content-between mb-1"> 16064 <div class="flexrow"><p class="m-0">{{addon_items.qty}} x {{addon_items.pretty_price}} {{addon_items.sub_item_name}}</p></div> 16065 <div class="flexrow"><p class="m-0">{{addon_items.pretty_addons_total}}</p></div> 16066 </div> <!--flex--> 16067 </template> 16068 16069 </div> <!--col--> 16070 </div> 16071 <!-- addon-items--> 16072 16073 </div> <!--items--> 16074 16075 </DIV> 16076 16077 <template v-if="cart_items.length>0"> 16078 <div class="divider"></div> 16079 <a class="btn btn-green w-100 pointer position-relative" :disabled="hasError" 16080 :href="hasError?'javascript:;':go_checkout.link" 16081 :class="{ loading: update_cart_loading }" 16082 > 16083 <div class="d-flex justify-content-between"> 16084 <div>{{label.go_checkout}}</div> 16085 <div v-if="!update_cart_loading">{{subtotal.value}}</div> 16086 <div class="m-auto circle-loader" data-loader="circle-side"></div> 16087 </div> 16088 </a> 16089 </template> 16090 16091 <div v-cloak class="alert alert-warning m-0 mt-2" v-if="error.length>0"> 16092 <p class="m-0" v-for="error_msg in error"> 16093 {{ error_msg }} 16094 </p> 16095 </div> 16096 16097 </el-drawer> 16098 ` 16099}; 16100 16101/* 16102 COMPONENTS ComponentsWebPush 16103*/ 16104 16105const ComponentsWebPush = { 16106 props: ['ajax_url' , 'message'], 16107 data(){ 16108 return { 16109 settings : [], 16110 beams : undefined, 16111 }; 16112 }, 16113 mounted() { 16114 this.getWebpushSettings(); 16115 }, 16116 methods:{ 16117 getWebpushSettings(){ 16118 axios({ 16119 method: 'POST', 16120 url: this.ajax_url+"/getWebpushSettings" , 16121 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') , 16122 timeout: $timeout, 16123 }).then( response => { 16124 if(response.data.code==1){ 16125 this.settings = response.data.details; 16126 if(this.settings.enabled==1){
16127 this.webPushInit(); 16128 } 16129 } else { 16130 this.settings = []; 16131 } 16132 }).catch(error => { 16133 // 16134 }).then(data => { 16135 16136 }); 16137 }, 16138 webPushInit(){ 16139 if ( this.settings.provider=="pusher" && this.settings.user_settings.enabled==1 ){ 16140 16141 this.beams = new PusherPushNotifications.Client({ 16142 instanceId: this.settings.pusher_instance_id , 16143 }); 16144 16145 this.beams.start() 16146 .then(() => { 16147 this.beams.setDeviceInterests( this.settings.user_settings.interest ) 16148 .then(() =>{ 16149 console.log('Device interests have been set'); 16150 }) 16151 .then(() => this.beams.getDeviceInterests()) 16152 .then((interests) => console.log("Current interests:", interests)) 16153 .catch(e => { 16154 var data = { 16155 notification_type :"push", 16156 message : "Beams " + e, 16157 date : '', 16158 image_type : 'icon', 16159 image : 'zmdi zmdi-info-outline' 16160 }; 16161 vm_cart_preview.$refs.notification.addData(data); 16162 }); 16163 }).catch(e => { 16164 var data = { 16165 notification_type :"push", 16166 message : "Beams " + e, 16167 date : '', 16168 image_type : 'icon', 16169 image : 'zmdi zmdi-info-outline' 16170 }; 16171 vm_cart_preview.$refs.notification.addData(data); 16172 }); 16173 16174 16175 } else if ( this.settings.provider=="onesignal" ){ 16176 // 16177 } 16178 }, 16179 }, 16180 template:` 16181 ` 16182}; 16183 16184 16185/* 16186 COMPONENTS NOTIFICATIONS 16187*/ 16188const ComponentsNotification = { 16189 components: { 16190 'components-webpush': ComponentsWebPush, 16191 }, 16192 props: ['ajax_url','label','realtime','view_url','avatar','image_background'], 16193 data(){ 16194 return { 16195 data : [], 16196 count : 0, 16197 new_message : false, 16198 player : undefined, 16199 ably : undefined, 16200 channel : undefined, 16201 piesocket : undefined, 16202 observer : undefined, 16203 pusher : undefined, 16204 sounds_order : null, 16205 sounds_chat : null 16206 }; 16207 }, 16208 mounted() { 16209 this.getAllNotification(); 16210 if(this.realtime.enabled){ 16211 this.initRealTime(); 16212 } 16213 16214 this.observer = lozad('.lozad',{ 16215 loaded: function(el) { 16216 el.classList.add('loaded'); 16217 } 16218 }); 16219 16220 if ((typeof sounds_order !== "undefined") && ( sounds_order !== null)) { 16221 this.sounds_order = sounds_order; 16222 } 16223 if ((typeof sounds_chat !== "undefined") && ( sounds_chat !== null)) { 16224 this.sounds_chat = sounds_chat; 16225 } 16226 }, 16227 updated () { 16228 this.observer.observe(); 16229 }, 16230 computed: { 16231 hasData(){ 16232 if(this.data.length>0){ 16233 return true; 16234 } 16235 return false; 16236 }, 16237 ReceiveMessage(){ 16238 if(this.new_message){ 16239 return true; 16240 } 16241 return false; 16242 }, 16243 }, 16244 methods:{ 16245 initRealTime(){ 16246 dump(this.realtime.event_tracking_order); 16247 if(this.realtime.provider == "pusher"){ 16248 16249 Pusher.logToConsole = false; 16250 this.pusher = new Pusher( this.realtime.key , { 16251 cluster: this.realtime.cluster 16252 }); 16253 16254 this.channel = this.pusher.subscribe( this.realtime.channel ); 16255 16256 this.channel.bind( this.realtime.event , (data)=> { 16257 dump("receive pusher"); 16258 dump(data); 16259 if(data.notification_type=="silent"){ 16260 // do nothing 16261 } else if (data.notification_type=="order_update"){ 16262 this.playAlert(this.sounds_order); 16263 } else if (data.notification_type=="chat-message"){ 16264 this.playAlert(this.sounds_chat); 16265 } else { 16266 this.playAlert(); 16267 } 16268 this.addData(data); 16269 }); 16270 16271 } else if ( this.realtime.provider =="ably" ){ 16272 16273 this.ably = new Ably.Realtime(this.realtime.ably_apikey); 16274 this.ably.connection.on('connected', () => { 16275 16276 this.channel = this.ably.channels.get( this.realtime.channel ); 16277 16278 this.channel.subscribe( this.realtime.event , (message) => { 16279 dump("receive ably"); 16280 dump(message.data); 16281 this.playAlert(); 16282 this.addData(message.data); 16283 }); 16284 16285 }); 16286 16287 } else if ( this.realtime.provider =="piesocket" ){ 16288 16289 this.piesocket = new PieSocket({ 16290 clusterId: this.realtime.piesocket_clusterid , 16291 apiKey: this.realtime.piesocket_api_key 16292 }); 16293 this.channel = this.piesocket.subscribe(this.realtime.channel); 16294 16295 this.channel.listen( this.realtime.event , (data)=> { 16296 dump("receive piesocket"); 16297 dump(data); 16298 this.playAlert(); 16299 this.addData( data ); 16300 }); 16301 16302 } 16303 16304 }, 16305 playAlert(soundsFile){ 16306 let defaultSounds = [site_url+'/assets/sound/notify.mp3', site_url+'/assets/sound/notify.ogg' ]; 16307 if(soundsFile){ 16308 defaultSounds = [soundsFile]; 16309 } 16310 this.player = new Howl({ 16311 src: defaultSounds, 16312 html5: true, 16313 }); 16314 this.player.play(); 16315 }, 16316 getAllNotification(){ 16317 16318 axios({ 16319 method: 'POST', 16320 url: this.ajax_url+"/getNotifications" , 16321 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content'), 16322 timeout: $timeout, 16323 }).then( response => { 16324 if(response.data.code==1){ 16325 this.data = response.data.details.data; 16326 this.count = response.data.details.count; 16327 } else { 16328 this.data = []; 16329 this.count = 0; 16330 } 16331 }).catch(error => { 16332 // 16333 }).then(data => { 16334 16335 }); 16336 16337 }, 16338 addData($data){ 16339 this.data.unshift($data); 16340 this.count++; 16341 this.new_message = true; 16342 16343 setTimeout(()=>{ 16344 this.new_message = false;
16345 this.player.stop(); 16346 }, 1000); 16347 16348 }, 16349 clearAll(){ 16350 16351 axios({ 16352 method: 'POST', 16353 url: this.ajax_url+"/clearNotifications" , 16354 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content'), 16355 timeout: $timeout, 16356 }).then( response => { 16357 if(response.data.code==1){ 16358 this.data = []; 16359 this.count = 0; 16360 } else { 16361 notify( response.data.msg ,'error') 16362 } 16363 16364 this.new_message = false; 16365 16366 }).catch(error => { 16367 // 16368 }).then(data => { 16369 16370 }); 16371 }, 16372 }, 16373 template: ` 16374 16375 <components-webpush 16376 :ajax_url="ajax_url" 16377 :message='label' 16378 /> 16379 </components-webpush> 16380 16381 <div class="btn-group pull-right notification-dropdown"> 16382 <button type="button" class="btn p-0 btn-default" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> 16383 <img class="img-30 rounded-pill lozad" :src="avatar" :data-background-image="image_background" /> 16384 <span v-if="count>0" :class="{'shake-constant shake-chunk' : ReceiveMessage }" class="badge rounded-circle badge-danger count">{{count}}</span> 16385 </button> 16386 <div class="dropdown-menu dropdown-menu-right"> 16387 <div class="dropdown-header d-flex justify-content-between"> 16388 <div class="flex-col"> 16389 <div class="d-flex align-items-center"> 16390 <h5 class="m-0 mr-2">{{label.title}}</h5> 16391 <span class="badge rounded-circle badge-green badge-25">{{count}}</span> 16392 </div> 16393 </div> 16394 <div class="flex-col" v-if="hasData"> 16395 <a @click="clearAll">{{label.clear}}</a> 16396 </div> 16397 </div> 16398 <!--header--> 16399 16400 <!--content--> 16401 <ul v-if="hasData" class="list-unstyled m-0"> 16402 <li v-for="(item,index) in data"> 16403 <a :class="{ active: index<=0 }" > 16404 <div class="d-flex"> 16405 <div v-if="item.image!=''" class="flex-col mr-3"> 16406 <template v-if="item.image_type=='icon'"> 16407 <div class="notify-icon rounded-circle bg-soft-primary"> 16408 <i :class="item.image"></i> 16409 </div> 16410 </template> 16411 <template v-else> 16412 <div class="notify-icon"> 16413 <img class="img-40 rounded-circle" :src="item.image" /> 16414 </div> 16415 </template> 16416 </div> 16417 <div class="flex-col"> 16418 <div class="text-heading" v-html="item.message"></div> 16419 <div class="dropdown-text-light">{{item.date}}</div> 16420 </div> 16421 </div> 16422 </a> 16423 </li> 16424 </ul> 16425 <!--content--> 16426 16427 <div v-if="!hasData" class="none-notification text-center"> 16428 <div class="image-notification m-auto"></div> 16429 <h5 class="m-0 mb-1 mt-2">{{label.no_notification}}</h5> 16430 <p class="m-0 font11 text-muted">{{label.no_notification_content}}</p> 16431 </div> 16432 16433 <div v-if="hasData" class="footer-dropdown text-center"> 16434 <a :href="view_url" targe="_blank" class="text-primary">{{label.view}}</a> 16435 </div> 16436 16437 </div> <!--dropdown-menu--> 16438 </div> 16439 <!--btn-group--> 16440 ` 16441}; 16442 16443const ComponentsLanguage = { 16444 props : ['ajax_url'], 16445 data(){ 16446 return { 16447 data : [], 16448 is_loading : false 16449 }; 16450 }, 16451 mounted () { 16452 this.getLanguage(); 16453 }, 16454 methods :{ 16455 getLanguage(){ 16456 this.is_loading = true; 16457 axios({ 16458 method: 'POST', 16459 url: this.ajax_url+"/getLanguage" , 16460 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content'), 16461 timeout: $timeout, 16462 }).then( response => { 16463 if(response.data.code==1){ 16464 this.data = response.data.details; 16465 } else { 16466 this.data = []; 16467 } 16468 }).catch(error => { 16469 // 16470 }).then(data => { 16471 this.is_loading = false;
16472 }); 16473 }, 16474 setLang(link){ 16475 window.location.href = link; 16476 } 16477 }, 16478 template : ` 16479 <el-skeleton style="width: 150px" :loading="is_loading" animated> 16480 <template #template> 16481 <el-skeleton-item variant="image" style="width: 150px; height: 20px" /> 16482 </template> 16483 <template #default> 16484 16485 <el-dropdown trigger="click" v-if="data.enabled"> 16486 <span class="el-dropdown-link"> 16487 16488 <div class="d-flex align-items-center"> 16489 <div class="mr-2"> 16490 <el-image 16491 style="width: 30px; height: 25px" 16492 :src="data.default.flag" 16493 :fit="contain" 16494 lazy 16495 ></el-image> 16496 </div> 16497 <div class="mr-2">{{data.default.title}}</div> 16498 <div><i class="zmdi zmdi-chevron-down"></i></div> 16499 </div> 16500 </span> 16501 <template #dropdown> 16502 <el-dropdown-menu> 16503 <el-dropdown-item v-for="item in data.data" > 16504 16505 <el-dropdown-item @click="setLang(item.link)"> 16506 <div class="row no-gutters align-items-center"> 16507 <div class="col mr-3"> 16508 <el-image 16509 style="width: 30px; height: 25px" 16510 :src="item.flag" 16511 :fit="contain" 16512 ></el-image> 16513 </div> 16514 <div class="col">{{item.title}}</div> 16515 </div> 16516 </el-dropdown-item> 16517 16518 </el-dropdown-item> 16519 </el-dropdown-menu> 16520 </template> 16521 </el-dropdown> 16522 16523 </template> 16524 </el-skeleton> 16525 ` 16526}; 16527 16528const ComponentsNotificationCart = { 16529 props : ['ajax_url','realtime'], 16530 data() { 16531 return { 16532 merchant_uuid : '' 16533 } 16534 }, 16535 created() { 16536 this.getMerchantByCart(); 16537 }, 16538 methods: { 16539 getMerchantByCart(){ 16540 axios({ 16541 method: 'POST', 16542 url: this.ajax_url+"/getMerchantByCart" , 16543 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&cart_uuid="+ getCookie('cart_uuid'), 16544 timeout: $timeout, 16545 }).then( response => { 16546 if(response.data.code==1){ 16547 this.merchant_uuid = response.data.details.merchant_uuid; 16548 this.initRealTime(); 16549 } else { 16550 this.merchant_uuid = ''; 16551 } 16552 }).catch(error => { 16553 // 16554 }).then(data => { 16555 }); 16556 }, 16557 initRealTime(){ 16558 if(this.realtime.provider == "pusher" && this.realtime.enabled==1){ 16559 Pusher.logToConsole = false; 16560 this.pusher = new Pusher( this.realtime.key , { 16561 cluster: this.realtime.cluster 16562 }); 16563 this.channel = this.pusher.subscribe( this.merchant_uuid ); 16564 this.channel.bind( this.realtime.event , (data)=> { 16565 let message = JSON.parse(data.message); 16566 this.$emit('afterReceiveitemupdate', message ); 16567 }); 16568 } 16569 } 16570 // 16571 }, 16572}; 16573 16574 16575const ComponentsCurrencySelection = { 16576 data() { 16577 return { 16578 data : [], 16579 loading : false, 16580 based_currency : '' 16581 } 16582 }, 16583 created() { 16584 this.getCurrencyList(); 16585 }, 16586 methods: { 16587 getCurrencyList(){ 16588 this.loading = true; 16589 let currency_code = getCookie('currency_code'); 16590 currency_code = !empty(currency_code)?currency_code:''; 16591 axios({ 16592 method: 'POST', 16593 url: ajaxurl +"/getCurrencyList" , 16594 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "¤cy_code="+currency_code, 16595 timeout: $timeout, 16596 }).then( response => { 16597 if(response.data.code==1){ 16598 this.data = response.data.details.data; 16599 this.based_currency = response.data.details.based_currency; 16600 } else { 16601 this.data = []; 16602 this.based_currency = ''; 16603 } 16604 }).catch(error => { 16605 // 16606 }).then(data => { 16607 this.loading = false; 16608 }); 16609 }, 16610 setCurrency(currencyCode){ 16611 this.based_currency = currencyCode; 16612 this.$emit('afterSelectcurrency',currencyCode); 16613 }, 16614 }, 16615 template: ` 16616 <div class="dropdown language-bar d-inline" v-if="!loading" > 16617 <a class="dropdown-toggle text-truncate" href="javascript:;" 16618 role="button" id="currencySelection" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> 16619 {{based_currency}} 16620 </a> 16621 <div class="dropdown-menu" aria-labelledby="currencySelection"> 16622 <template v-for="(items,code) in data"> 16623 <a @click="setCurrency(code)" class="dropdown-item" :class="{active : based_currency==code}" > 16624 <div class="d-flex align-items-center"> 16625 <div class="text-truncate">{{items}}</div> 16626 </div> 16627 </a> 16628 </template> 16629 </div> 16630 </div> 16631 `, 16632}; 16633 16634 16635/* 16636 CART PREVIEW 16637 target = vue-cart-preview 16638*/ 16639const app_cart_preview = Vue.createApp({ 16640 components: { 16641 'component-cart-preview': ComponentCartPreview, 16642 'components-notification': ComponentsNotification, 16643 'components-language': ComponentsLanguage, 16644 'component-notification-cart': ComponentsNotificationCart, 16645 'component-currency-selection': ComponentsCurrencySelection, 16646 }, 16647 mounted () { 16648 this.getCartPreview(); 16649 }, 16650 data(){ 16651 return { 16652 items_count:0, 16653 drawer : false, 16654 drawer_preview_cart : false, 16655 }; 16656 }, 16657 methods :{ 16658 getCartPreview(){ 16659 this.$refs.childref.getCartPreview(); 16660 }, 16661 cartCount(items){ 16662 this.items_count = items; 16663 }, 16664 showCartPreview(){ 16665 this.drawer_preview_cart = true; 16666 }, 16667 afterDrawerclose(){ 16668 this.drawer_preview_cart = false;
16669 }, 16670 afterReceiveitemupdate(data){ 16671 axios({ 16672 method: 'POST', 16673 url: ajaxurl+"/validateCartItems" , 16674 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&cart_uuid="+ getCookie('cart_uuid')+"&item_id="+data.item_id, 16675 timeout: $timeout, 16676 }).then( response => { 16677 if(response.data.code==1){ 16678 let $some_words = JSON.parse(some_words); 16679 ElementPlus.ElMessageBox.alert( response.data.msg, '', { 16680 confirmButtonText: $some_words.ok, 16681 callback: (action) => { 16682 if ((typeof vm_cart_preview !== "undefined") && ( vm_cart_preview !== null)) { 16683 vm_cart_preview.getCartPreview(); 16684 } 16685 if ((typeof vue_cart !== "undefined") && ( vue_cart !== null)) { 16686 vue_cart.loadcart(); 16687 } 16688 if ((typeof vm !== "undefined") && ( vm !== null)) { 16689 vm.geStoreMenu(); 16690 } 16691 }, 16692 }); 16693 } 16694 }).catch(error => { 16695 // 16696 }).then(data => { 16697 }); 16698 }, 16699 afterSelectcurrency(data){ 16700 setCookie('currency_code',data,30); 16701 if ((typeof vm_cart_preview !== "undefined") && ( vm_cart_preview !== null)) { 16702 vm_cart_preview.getCartPreview(); 16703 } 16704 if ((typeof vue_cart !== "undefined") && ( vue_cart !== null)) { 16705 vue_cart.loadcart(); 16706 } 16707 if ((typeof vm !== "undefined") && ( vm !== null)) { 16708 vm.geStoreMenu(); 16709 } 16710 if ((typeof vm_app_search !== "undefined") && ( vm_app_search !== null)) { 16711 if ((typeof vm_app_search.$refs.food_list_recommended !== "undefined") && ( vm_app_search.$refs.food_list_recommended !== null)) { 16712 vm_app_search.$refs.food_list_recommended.getFoodList(); 16713 vm_app_search.$refs.food_list.getFoodList(); 16714 } 16715 } 16716 16717 if ((typeof homeWidgets !== "undefined") && ( homeWidgets !== null)) { 16718 homeWidgets.$refs.ref_featured_list.getFeaturedItems(); 16719 } 16720 16721 if ((typeof vm_subscription !== "undefined") && ( vm_subscription !== null)) { 16722 vm_subscription.getPlan(); 16723 } 16724 16725 }, 16726 }, 16727}); 16728app_cart_preview.use(ElementPlus); 16729const vm_cart_preview = app_cart_preview.mount('#vue-cart-preview'); 16730 16731 16732 16733/* 16734COMPONENTS ALERT 16735*/ 16736const ComponentsAlert = { 16737 props: ['title','button'], 16738 data(){ 16739 return { 16740 data:[] 16741 }; 16742 }, 16743 methods :{ 16744 show(){ 16745 $('#ModalAlert').modal('show'); 16746 }, 16747 close(){ 16748 $('#ModalAlert').modal('hide'); 16749 }, 16750 alert(data){ 16751 this.data = data; 16752 dump(this.data); 16753 this.show(); 16754 }, 16755 }, 16756 template: ` 16757 <div class="modal" id="ModalAlert" tabindex="-1" role="dialog" aria-labelledby="ModalAlert" aria-hidden="true"> 16758 <div class="modal-dialog modal-dialog-centered" role="document"> 16759 <div class="modal-content"> 16760 16761 <div class="modal-header"> 16762 <h5 class="modal-title" id="exampleModalLabel">{{ title }}</h5> 16763 <button type="button" class="close" aria-label="Close" @click="close" > 16764 <span aria-hidden="true">×</span> 16765 </button> 16766 </div> 16767 16768 <div class="modal-body" > 16769 <div v-for="item in data.text" > 16770 {{ item }} 16771 </div> 16772 </div> 16773 16774 <div class="modal-footer justify-content-center"> 16775 <button class="btn btn-black w-25" @click="close" > 16776 {{button}} 16777 </button> 16778 </div> <!--footer--> 16779 16780 </div> <!--content--> 16781 </div> <!--dialog--> 16782 </div> <!--modal--> 16783 `, 16784}; 16785 16786 16787const component_alert = Vue.createApp({ 16788 components: { 16789 'component-alert': ComponentsAlert, 16790 }, 16791 methods :{ 16792 alert(message){ 16793 this.$refs.Alertref.alert( {'text': message } ); 16794 }, 16795 }, 16796}).mount('#component_alert'); 16797 16798/* 16799COMPONENTS CANCEL ORDER 16800*/ 16801const ComponentsCancelOrder = { 16802 props: ['label'], 16803 data(){ 16804 return { 16805 data:[], 16806 loading : false, 16807 merchant_name : '', 16808 cancel_status : false, 16809 cancel_msg : '', 16810 order_uuid : '', 16811 error : [], 16812 is_loading : false, 16813 cancel_response : [] 16814 }; 16815 }, 16816 methods :{ 16817 show(){ 16818 $('#ModalCancelOrder').modal('show'); 16819 }, 16820 close(){ 16821 $('#ModalCancelOrder').modal('hide'); 16822 this.order_uuid = ''; 16823 }, 16824 cancel(data){ 16825 this.merchant_name = data.merchant_name; 16826 this.show(); 16827 16828 this.order_uuid = data.order_uuid; 16829 16830 var $params = { 16831 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 16832 'order_uuid' : this.order_uuid 16833 }; 16834 16835 var timenow = 1; 16836 $params = JSON.stringify($params); 16837 16838 ajax_request[timenow] = $.ajax({ 16839 url: ajaxurl+"/cancelOrderStatus", 16840 method: "PUT", 16841 dataType: "json", 16842 data: $params , 16843 contentType : $content_type.json , 16844 timeout: $timeout, 16845 crossDomain: true, 16846 beforeSend: data => { 16847 this.loading = true; 16848 this.cancel_status = false; 16849 this.cancel_msg = ''; 16850 if(ajax_request[timenow] != null) { 16851 ajax_request[timenow].abort(); 16852 } 16853 } 16854 }); 16855 16856 ajax_request[timenow].done( data => { 16857 if ( data.code==1){ 16858 this.cancel_status = data.details.cancel_status; 16859 this.cancel_msg = data.details.cancel_msg; 16860 this.cancel_response = data.details; 16861 } else { 16862 this.cancel_status = false;
16863 this.cancel_response = []; 16864 } 16865 }); 16866 16867 ajax_request[timenow].always( data => { 16868 this.loading = false; 16869 }); 16870 16871 }, 16872 applyCancelOrder(){ 16873 16874 var $params = { 16875 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 16876 'order_uuid' : this.order_uuid 16877 }; 16878 16879 var timenow = 1; 16880 $params = JSON.stringify($params); 16881 16882 ajax_request[timenow] = $.ajax({ 16883 url: ajaxurl+"/applyCancelOrder", 16884 method: "PUT", 16885 dataType: "json", 16886 data: $params , 16887 contentType : $content_type.json , 16888 timeout: $timeout, 16889 crossDomain: true, 16890 beforeSend: data => { 16891 this.error = []; 16892 this.is_loading = true; 16893 if(ajax_request[timenow] != null) { 16894 ajax_request[timenow].abort(); 16895 } 16896 } 16897 }); 16898 16899 ajax_request[timenow].done( data => { 16900 if ( data.code==1){ 16901 notify(data.msg,'success'); 16902 this.close(); 16903 vm_my_order.page = 0; 16904 vm_my_order.data = []; 16905 vm_my_order.orderHistory(); 16906 } else { 16907 this.error = data.msg; 16908 } 16909 }); 16910 16911 ajax_request[timenow].always( data => { 16912 this.is_loading = false; 16913 }); 16914 }, 16915 }, 16916 template: ` 16917 <div class="modal" id="ModalCancelOrder" tabindex="-1" role="dialog" aria-labelledby="ModalCancelOrder" aria-hidden="true" data-backdrop="static" data-keyboard="false" > 16918 <div class="modal-dialog modal-dialog-centered" role="document"> 16919 <div class="modal-content"> 16920 16921 <div class="modal-header"> 16922 <h5 class="modal-title" id="exampleModalLabel">{{merchant_name}}</h5> 16923 <button type="button" class="close" aria-label="Close" @click="close" :disabled="is_loading" > 16924 <span aria-hidden="true">×</span> 16925 </button> 16926 </div> 16927 16928 <DIV v-if="loading"> 16929 <div class="loading mt-5 mb-5"> 16930 <div class="m-auto circle-loader" data-loader="circle-side"></div> 16931 </div> 16932 </DIV> 16933 16934 <DIV v-else> 16935 16936 <div class="modal-body" > 16937 16938 <h5 v-if="cancel_response.refund_status==='full_refund'">{{label.are_you_sure}}</h5> 16939 <h5 v-else>{{label.how}}</h5> 16940 16941 <div class="mt-3"> 16942 <p>{{cancel_msg}}</p> 16943 </div> 16944 16945 <div class="mt-3 mb-2" v-if="cancel_response.refund_msg"> 16946 <p>{{cancel_response.refund_msg}}</p> 16947 </div> 16948 16949 <div v-cloak v-if="error.length>0" class="alert alert-warning mb-2" role="alert"> 16950 <p v-cloak v-for="err in error" class="m-0">{{err}}</p> 16951 </div> 16952 16953 </div> <!--body--> 16954 16955 <div class="modal-footer justify-content-center"> 16956 <button class="btn btn-black w-100" @click="close" :disabled="is_loading" > 16957 {{label.dont}} 16958 </button> 16959 <button class="btn btn-green w-100" :disabled="!cancel_status" @click="applyCancelOrder()" 16960 :class="{ loading: is_loading }" > 16961 <span class="label">{{label.cancel}}</span> 16962 <div class="m-auto circle-loader" data-loader="circle-side"></div> 16963 </button> 16964 </div> <!--footer--> 16965 16966 </DIV> <!--end if--> 16967 16968 </div> <!--content--> 16969 </div> <!--dialog--> 16970 </div> <!--modal--> 16971 `, 16972}; 16973 16974 16975/* 16976 MY ORDER 16977 target = vue-my-order 16978*/ 16979const app_my_order = Vue.createApp({ 16980 components: { 16981 'component-cancel-order' : ComponentsCancelOrder, 16982 'components-review' : ComponentsReview, 16983 'components-reviewdriver': ComponentsReviewDriver 16984 }, 16985 mounted () { 16986 this.orderHistory(); 16987 this.orderSummary(); 16988 }, 16989 data(){ 16990 return { 16991 show_next_page : false, 16992 loading : false, 16993 load_more : false, 16994 page : 0, 16995 data : [], 16996 merchants : [], 16997 items : [], 16998 size : [], 16999 status : [], 17000 services : [], 17001 show_details : false, 17002 order_loading : false, 17003 order_merchant : [], 17004 order_items : [], 17005 order_summary : [], 17006 order_info : [], 17007 order_status : [], 17008 order_services : [], 17009 order_label : [], 17010 status_allowed_cancelled : [], 17011 status_allowed_review : [], 17012 q : '', 17013 awaitingSearch : false, 17014 search_found : false, 17015 summary_data : [], 17016 total_qty : 0, 17017 animated_total_qty : 0, 17018 total_order_raw : 0, 17019 animated_total_order : 0, 17020 refund_transaction : [], 17021 order_table_data : [], 17022 order_info_data :null 17023 }; 17024 }, 17025 watch: { 17026 q(newsearch,oldsearch){ 17027 if (!this.awaitingSearch) { 17028 if(empty(newsearch)){ 17029 return false;
17030 } 17031 17032 setTimeout(() => { 17033 17034 var $params; var timenow = getTimeNow(); 17035 $params="page=0"; 17036 $params+="&q="+ this.q; 17037 $params+=addValidationRequest(); 17038 ajax_request[timenow] = $.ajax({ 17039 url: ajaxurl+"/orderHistory", 17040 method: "POST", 17041 dataType: "json", 17042 data: $params, 17043 contentType : $content_type.form , 17044 timeout: $timeout, 17045 crossDomain: true, 17046 beforeSend: function( xhr ) { 17047 if(ajax_request[timenow] != null) { 17048 ajax_request[timenow].abort(); 17049 } 17050 } 17051 }); 17052 17053 ajax_request[timenow].done( data => { 17054 if (data.code==1){ 17055 this.data = []; 17056 this.show_next_page = data.details.show_next_page; 17057 this.page = data.details.page; 17058 //this.data = data.details.data.data; 17059 this.data.push(data.details.data.data); 17060 this.merchants = data.details.data.merchants; 17061 this.items = data.details.data.items; 17062 this.size = data.details.data.size; 17063 this.status = data.details.data.status; 17064 this.services = data.details.data.services; 17065 this.status_allowed_cancelled = data.details.data.status_allowed_cancelled; 17066 this.status_allowed_review = data.details.data.status_allowed_review; 17067 this.search_found = true; 17068 } else { 17069 this.data = []; 17070 this.search_found = true; 17071 } 17072 }); // ajax done 17073 17074 ajax_request[timenow].always( data => { 17075 this.awaitingSearch = false; 17076 }); 17077 17078 }, 1000); // 1 sec delay 17079 17080 this.awaitingSearch = true; 17081 } 17082 }, 17083 17084 total_qty(newValue){ 17085 gsap.to(this.$data, { duration: 0.6, animated_total_qty : newValue }); 17086 }, 17087 17088 total_order_raw(newValue){ 17089 gsap.to(this.$data, { duration: 0.6, animated_total_order : newValue }); 17090 }, 17091 17092 }, 17093 computed: { 17094 hasData(){ 17095 if(this.search_found){ 17096 return true; 17097 } 17098 return false; 17099 }, 17100 hasResults(){ 17101 if(this.data.length>0){ 17102 return true; 17103 } 17104 return false; 17105 }, 17106 hasRefund(){ 17107 if(this.refund_transaction.length>0){ 17108 return true; 17109 } 17110 return false; 17111 }, 17112 animatedNumber() { 17113 return this.animated_total_qty.toFixed(0); 17114 }, 17115 animatedTotal() { 17116 return this.animated_total_order.toFixed(2); 17117 }, 17118 hasBooking(){ 17119 if (Object.keys(this.order_table_data).length > 0) { 17120 return true; 17121 } 17122 return false; 17123 } 17124 }, 17125 methods :{ 17126 clearData(){ 17127 this.search_found = false; 17128 this.q = ''; 17129 this.page = 0; 17130 this.data = []; 17131 this.orderHistory(); 17132 }, 17133 orderHistory(){ 17134 17135 if(!this.load_more){ 17136 this.loading = true; 17137 } 17138 17139 var $params; var timenow = getTimeNow(); 17140 $params="page="+ this.page; 17141 $params+=addValidationRequest(); 17142 ajax_request[timenow] = $.ajax({ 17143 url: ajaxurl+"/orderHistory", 17144 method: "POST", 17145 dataType: "json", 17146 data: $params, 17147 contentType : $content_type.form , 17148 timeout: $timeout, 17149 crossDomain: true, 17150 beforeSend: data => { 17151 if(ajax_request[timenow] != null) { 17152 ajax_request[timenow].abort(); 17153 } 17154 } 17155 }); 17156 17157 ajax_request[timenow].done( data => { 17158 if (data.code==1){ 17159 this.show_next_page = data.details.show_next_page; 17160 this.page = data.details.page; 17161 17162 /*this.data = data.details.data.data; 17163 this.merchants = data.details.data.merchants; 17164 this.items = data.details.data.items; 17165 this.size = data.details.data.size; 17166 this.status = data.details.data.status; 17167 this.services = data.details.data.services; 17168 this.status_allowed_cancelled = data.details.data.status_allowed_cancelled; 17169 this.status_allowed_review = data.details.data.status_allowed_review;*/ 17170 17171 this.data.push(data.details.data.data); 17172 this.merchants = this.addObjectToArray( this.merchants, data.details.data.merchants ); 17173 this.items = this.addObjectToArray( this.items, data.details.data.items ); 17174 this.status = data.details.data.status; 17175 this.services = data.details.data.services; 17176 this.status_allowed_cancelled = data.details.data.status_allowed_cancelled; 17177 this.status_allowed_review = data.details.data.status_allowed_review; 17178 17179 } else { 17180 17181 } 17182 }); // ajax done 17183 17184 ajax_request[timenow].always( data => { 17185 this.loading = false;
17186 this.load_more = false; 17187 }); 17188 17189 }, 17190 addObjectToArray(element, element_new){ 17191 var new_object = {}; 17192 Object.entries(element).forEach(([key,value]) => { new_object[key] = value }); 17193 Object.entries(element_new).forEach(([key,value]) => { new_object[key] = value }); 17194 return new_object; 17195 }, 17196 loadMoreOrders(page){ 17197 this.page = page; 17198 this.load_more = true; 17199 this.orderHistory(); 17200 }, 17201 orderDetails(order_uuid){ 17202 this.show_details = true; 17203 17204 var $params = { 17205 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 17206 'order_uuid' : order_uuid 17207 }; 17208 17209 var timenow = 1; 17210 $params = JSON.stringify($params); 17211 17212 ajax_request[timenow] = $.ajax({ 17213 url: ajaxurl+"/orderDetails", 17214 method: "PUT", 17215 dataType: "json", 17216 data: $params , 17217 contentType : $content_type.json , 17218 timeout: $timeout, 17219 crossDomain: true, 17220 beforeSend: data => { 17221 17222 this.order_loading = true; 17223 this.order_merchant = []; 17224 this.order_items = []; 17225 this.order_summary = []; 17226 this.order_info = []; 17227 this.order_status = []; 17228 this.order_services = []; 17229 this.order_label = []; 17230 17231 if(ajax_request[timenow] != null) { 17232 ajax_request[timenow].abort(); 17233 } 17234 } 17235 }); 17236 17237 ajax_request[timenow].done( data => { 17238 if ( data.code==1){ 17239 this.order_merchant = data.details.data.merchant; 17240 this.order_items = data.details.data.items; 17241 this.order_summary = data.details.data.summary; 17242 this.order_info = data.details.data.order.order_info; 17243 this.order_label = data.details.data.label; 17244 this.refund_transaction = data.details.data.refund_transaction; 17245 17246 this.order_status = data.details.data.order.status; 17247 this.order_services = data.details.data.order.services; 17248 17249 this.order_table_data = data.details.data.order_table_data; 17250 17251 if(!empty(this.order_services[this.order_info.service_code])){ 17252 this.order_services = this.order_services[this.order_info.service_code]; 17253 } 17254 if(!empty(this.order_status[this.order_info.status])){ 17255 this.order_status = this.order_status[this.order_info.status]; 17256 } 17257 17258 } 17259 }); 17260 17261 ajax_request[timenow].always( data => { 17262 this.order_loading = false; 17263 this.updateImage(); 17264 }); 17265 17266 }, 17267 closeOrderDetails(){ 17268 this.show_details = false; 17269 }, 17270 updateImage(){ 17271 updateLazyImage(); 17272 }, 17273 buyAgain(order_uuid , close_view){ 17274 var $params = { 17275 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 17276 'order_uuid' : order_uuid, 17277 'cart_uuid' : getCookie('cart_uuid') 17278 }; 17279 17280 var timenow = 1; 17281 $params = JSON.stringify($params); 17282 17283 ajax_request[timenow] = $.ajax({ 17284 url: ajaxurl+"/orderBuyAgain", 17285 method: "PUT", 17286 dataType: "json", 17287 data: $params , 17288 contentType : $content_type.json , 17289 timeout: $timeout, 17290 crossDomain: true, 17291 beforeSend: data => { 17292 if(ajax_request[timenow] != null) { 17293 ajax_request[timenow].abort(); 17294 } 17295 } 17296 }); 17297 17298 ajax_request[timenow].done( data => { 17299 if ( data.code==1){ 17300 setCookie('cart_uuid',data.details.cart_uuid,30); 17301 17302 if(close_view==1){ 17303 this.show_details = false; 17304 } 17305 17306 vm_cart_preview.getCartPreview(); 17307 if ((typeof vm_cart_preview !== "undefined") && ( vm_cart_preview !== null)) { 17308 vm_cart_preview.showCartPreview(); 17309 } 17310 } else { 17311 ElementPlus.ElNotification({ 17312 title: "", 17313 message: data.msg, 17314 position: 'bottom-right', 17315 type: 'warning', 17316 }); 17317 } 17318 }); 17319 17320 }, 17321 callCancel(order_uuid,merchant_name){ 17322 this.$refs.orderCancelRef.cancel( {'merchant_name': merchant_name ,'order_uuid' : order_uuid } ); 17323 }, 17324 writeReview(order_uuid,order_info){ 17325 this.order_info_data = order_info; 17326 this.$refs.ReviewRef.order_uuid = order_uuid; 17327 this.$refs.ReviewRef.show(); 17328 }, 17329 afterAddreview(){ 17330 if(this.order_info_data.driver_id>0){ 17331 this.$refs.ref_driverreview.modal = true; 17332 } 17333 }, 17334 orderSummary(){ 17335 17336 var $params = { 17337 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 17338 }; 17339 17340 var timenow = getTimeNow(); 17341 $params = JSON.stringify($params); 17342 17343 ajax_request[timenow] = $.ajax({ 17344 url: ajaxurl+"/orderSummary", 17345 method: "PUT", 17346 dataType: "json", 17347 data: $params , 17348 contentType : $content_type.json , 17349 timeout: $timeout, 17350 crossDomain: true, 17351 beforeSend: data => { 17352 if(ajax_request[timenow] != null) { 17353 ajax_request[timenow].abort(); 17354 } 17355 } 17356 }); 17357 17358 ajax_request[timenow].done( data => { 17359 this.summary_data = data.details.summary; 17360 this.total_qty = data.details.summary.total_qty; 17361 this.total_order_raw = data.details.summary.total_order_raw>0?data.details.summary.total_order_raw:0; 17362 }); 17363 17364 }, 17365 }, 17366}); 17367app_my_order.use(ElementPlus); 17368const vm_my_order = app_my_order.mount('#vue-my-order'); 17369 17370 17371 17372const vm_bootbox = Vue.createApp({ 17373 components: { 17374 'component-bootbox': Componentsbootbox, 17375 }, 17376 data(){ 17377 return { 17378 resolvePromise: undefined, 17379 rejectPromise: undefined, 17380 } 17381 }, 17382 methods :{ 17383 confirm(){ 17384 return new Promise((resolve, reject) => { 17385 this.resolvePromise = resolve 17386 this.rejectPromise = reject 17387 this.$refs.bootbox.confirm(); 17388 }); 17389 }, 17390 Callback(result){ 17391 this.resolvePromise(result); 17392 }, 17393 alert(message,options){ 17394 this.$refs.bootbox.alert(message,options); 17395 }, 17396 }, 17397}).mount('#vue-bootbox'); 17398 17399 17400 17401 17402/* 17403CUSTOMER ADDRESS 17404*/ 17405const app_address = Vue.createApp({ 17406 components: { 17407 'component-new-address': changeAddressComponent, 17408 'component-address': ComponentsAddress, 17409 }, 17410 mounted () { 17411 this.getAddresses(false); 17412 }, 17413 data(){ 17414 return { 17415 data : [], 17416 error : [], 17417 is_loading : false, 17418 reload_loading : false, 17419 total_address : 0, 17420 total_address_animated : 0, 17421 }; 17422 }, 17423 watch: { 17424 total_address(newValue) { 17425 gsap.to(this.$data, { duration: 0.5, total_address_animated: newValue }) 17426 }, 17427 }, 17428 computed: { 17429 animatedTotal() { 17430 return this.total_address_animated.toFixed(0) 17431 } 17432 }, 17433 methods :{ 17434 getAddresses($reload){ 17435 17436 this.reload_loading = $reload; 17437 17438 var $params = { 17439 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 17440 }; 17441 var timenow = getTimeNow(); 17442 $params = JSON.stringify($params); 17443 17444 ajax_request[timenow] = $.ajax({ 17445 url: ajaxurl+"/getAddresses", 17446 method: "PUT", 17447 dataType: "json", 17448 data: $params , 17449 contentType : $content_type.json , 17450 timeout: $timeout, 17451 crossDomain: true, 17452 beforeSend: data => { 17453 if(!$reload) { this.is_loading = true; } else { this.reload_loading = true; } 17454 if(ajax_request[timenow] != null) { 17455 ajax_request[timenow].abort(); 17456 } 17457 } 17458 }); 17459 17460 ajax_request[timenow].done( data => { 17461 if ( data.code==1){ 17462 this.data = data.details.data; 17463 this.total_address = this.data.length; 17464 } else { 17465 this.data = []; 17466 this.total_address = 0; 17467 } 17468 }); 17469 17470 ajax_request[timenow].always( data => { 17471 this.is_loading = false;
17472 this.reload_loading = false; 17473 }); 17474 17475 }, 17476 showNewAddress(){ 17477 this.$refs.refnewaddress.autosaved_addres = false; 17478 this.$refs.refnewaddress.showModal(); 17479 }, 17480 ShowAddress(address_uuid){ 17481 this.$refs.address.show( address_uuid ); 17482 }, 17483 setLocationDetails(data){ 17484 this.$refs.address.showWithData( data ); 17485 }, 17486 ConfirmDelete(address_uuid){ 17487 this.$refs.address.ConfirmDelete( address_uuid ); 17488 }, 17489 }, 17490}); 17491app_address.use(ElementPlus); 17492const vm_addresses = app_address.mount('#vue-my-address'); 17493 17494 17495 17496/* 17497COMPONENTS PAYMENT METHOD 17498*/ 17499const ComponentsPaymentMethod = { 17500 props: ['label','payment_type','show_payment'], 17501 data() { 17502 return { 17503 data : [], 17504 display : false, 17505 } 17506 }, 17507 mounted () { 17508 this.getPaymentMethod(); 17509 this.display = this.show_payment; 17510 }, 17511 methods :{ 17512 getPaymentMethod(){ 17513 17514 var $params = { 17515 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 17516 'payment_type' : this.payment_type 17517 }; 17518 17519 var timenow = getTimeNow(); 17520 $params = JSON.stringify($params); 17521 17522 ajax_request[timenow] = $.ajax({ 17523 url: ajaxurl+"/PaymentMethod", 17524 method: "PUT", 17525 dataType: "json", 17526 data: $params , 17527 contentType : $content_type.json , 17528 timeout: $timeout, 17529 crossDomain: true, 17530 beforeSend: function( xhr ) { 17531 if(ajax_request[timenow] != null) { 17532 ajax_request[timenow].abort(); 17533 } 17534 } 17535 }); 17536 17537 ajax_request[timenow].done( data => { 17538 if ( data.code==1){ 17539 this.data = data.details.data; 17540 } else { 17541 this.data = []; 17542 } 17543 }); 17544 17545 }, 17546 showPayment(payment_code){ 17547 this.$emit('setPayment',payment_code); 17548 }, 17549 }, 17550 template: ` 17551 <!--PAYMENT METHODS--> 17552 <transition name="slide-fade"> 17553 <div class="card mb-3" v-if="display" > 17554 <div class="card-body"> 17555 17556 <h5 class="mb-3">{{label.add_new_payment}}</h5> 17557 17558 <a v-for="payment in data" @click="showPayment(payment.payment_code)" 17559 href="javascript:;" class="d-block chevron-section medium d-flex align-items-center rounded mb-2"> 17560 <div class="flexcol mr-2 payment-logo-wrap"> 17561 <i v-if="payment.logo_type=='icon'" :class="payment.logo_class"></i> 17562 <img v-else class="img-35" :src="payment.logo_image" /> 17563 </div> 17564 17565 <div class="flexcol" > 17566 <span class="mr-1">{{payment.payment_name}}</span> 17567 </div> 17568 </a> 17569 17570 </div> <!--card body--> 17571 </div> <!--card--> 17572 </transition> 17573 <!--END PAYMENT METHODS--> 17574 `, 17575}; 17576 17577 17578/* 17579CUSTOMER PAYMENTS 17580*/ 17581const app_payments = Vue.createApp({ 17582 data(){ 17583 return { 17584 data : [], 17585 default_payment_uuid : '', 17586 error : [], 17587 is_loading : false, 17588 reload_loading : false, 17589 payment_method : false, 17590 }; 17591 }, 17592 mounted () { 17593 this.getMyPayments(false); 17594 }, 17595 watch: { 17596 payment_method(newdata,olddata){ 17597 this.$refs.payment_method.display = newdata; 17598 } 17599 }, 17600 methods :{ 17601 getMyPayments($reload){ 17602 17603 this.reload_loading = $reload; 17604 17605 var $params = { 17606 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 17607 }; 17608 var timenow = getTimeNow(); 17609 $params = JSON.stringify($params); 17610 17611 ajax_request[timenow] = $.ajax({ 17612 url: ajaxurl+"/MyPayments", 17613 method: "PUT", 17614 dataType: "json", 17615 data: $params , 17616 contentType : $content_type.json , 17617 timeout: $timeout, 17618 crossDomain: true, 17619 beforeSend: data => { 17620 if(!$reload) { this.is_loading = true; } else { this.reload_loading = true; } 17621 if(ajax_request[timenow] != null) { 17622 ajax_request[timenow].abort(); 17623 } 17624 } 17625 }); 17626 17627 ajax_request[timenow].done( data => { 17628 if ( data.code==1){ 17629 this.data = data.details.data; 17630 this.default_payment_uuid = data.details.default_payment_uuid; 17631 } else { 17632 this.data = []; 17633 this.default_payment_uuid = ''; 17634 } 17635 }); 17636 17637 ajax_request[timenow].always( data => { 17638 this.is_loading = false;
17639 this.reload_loading = false; 17640 }); 17641 17642 }, 17643 ConfirmDelete(payment_uuid){ 17644 vm_bootbox.confirm().then((result) => { 17645 if(result){ 17646 this.deletePayment(payment_uuid); 17647 } 17648 }); 17649 }, 17650 deletePayment(payment_uuid){ 17651 17652 var $params = { 17653 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 17654 'payment_uuid' : payment_uuid 17655 }; 17656 var timenow = getTimeNow(); 17657 $params = JSON.stringify($params); 17658 17659 ajax_request[timenow] = $.ajax({ 17660 url: ajaxurl+"/deletePayment", 17661 method: "PUT", 17662 dataType: "json", 17663 data: $params , 17664 contentType : $content_type.json , 17665 timeout: $timeout, 17666 crossDomain: true, 17667 beforeSend: data => { 17668 if(ajax_request[timenow] != null) { 17669 ajax_request[timenow].abort(); 17670 } 17671 } 17672 }); 17673 17674 ajax_request[timenow].done( data => { 17675 if ( data.code==1){ 17676 this.getMyPayments(true); 17677 } else { 17678 vm_bootbox.alert( data.msg , {} ); 17679 } 17680 }); 17681 17682 ajax_request[timenow].always( data => { 17683 17684 }); 17685 17686 }, 17687 editPayment(data){ 17688 this.$refs[data.payment_code].Get(data.reference_id); 17689 }, 17690 SavedPaymentList(){ 17691 this.getMyPayments(true); 17692 }, 17693 showPayment(payment_code){ 17694 try { 17695 this.$refs[payment_code].showPaymentForm(); 17696 } catch(err) { 17697 vm_bootbox.alert( err , {} ); 17698 } 17699 }, 17700 setDefaultPayment(payment_uuid){ 17701 17702 var $params = { 17703 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 17704 'payment_uuid' : payment_uuid 17705 }; 17706 17707 var timenow = 1; 17708 $params = JSON.stringify($params); 17709 17710 ajax_request[timenow] = $.ajax({ 17711 url: ajaxurl+"/setDefaultPayment", 17712 method: "PUT", 17713 dataType: "json", 17714 data: $params , 17715 contentType : $content_type.json , 17716 timeout: $timeout, 17717 crossDomain: true, 17718 beforeSend: function( xhr ) { 17719 if(ajax_request[timenow] != null) { 17720 ajax_request[timenow].abort(); 17721 } 17722 } 17723 }); 17724 17725 ajax_request[timenow].done( data => { 17726 if ( data.code==1){ 17727 this.getMyPayments(true); 17728 } else { 17729 vm_bootbox.alert( data.msg , {} ); 17730 } 17731 }); 17732 17733 }, 17734 }, 17735}); 17736//.mount('#vue-my-payments'); 17737 17738if ((typeof components_bundle !== "undefined") && ( components_bundle !== null)) { 17739 $.each(components_bundle,function(components_name, components_value) { 17740 app_payments.component(components_name, components_value ); 17741 }); 17742} 17743 17744app_payments.component("components-payment-method",ComponentsPaymentMethod); 17745 17746app_payments.use(Maska); 17747app_payments.use(ElementPlus); 17748const vm_my_payments = app_payments.mount('#vue-my-payments'); 17749 17750 17751/* 17752LIST SAVED STORES 17753*/ 17754const app_my_store = Vue.createApp({ 17755 components: { 17756 'component-save-store' : ComponentsSaveStore, 17757 }, 17758 data(){ 17759 return { 17760 data : [], 17761 is_loading : false, 17762 reload_loading : false, 17763 services : [], 17764 estimation : [], 17765 }; 17766 }, 17767 mounted () { 17768 this.saveStoreList(false); 17769 }, 17770 updated () { 17771 dump("updated"); 17772 17773 $('.list-items .lazy').each(function(index, $obj){ 17774 if ( !empty($(this).attr("src")) && !empty($(this).attr("data-src")) ){ 17775 $(this).attr("src", $(this).attr("data-src") ); 17776 } 17777 }); 17778 17779 }, 17780 methods :{ 17781 17782 saveStoreList($reload) { 17783 17784 this.reload_loading = $reload; 17785 17786 var $params = { 17787 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 17788 }; 17789 var timenow = getTimeNow(); 17790 $params = JSON.stringify($params); 17791 17792 ajax_request[timenow] = $.ajax({ 17793 url: ajaxurl+"/saveStoreList", 17794 method: "PUT", 17795 dataType: "json", 17796 data: $params , 17797 contentType : $content_type.json , 17798 timeout: $timeout, 17799 crossDomain: true, 17800 beforeSend: data => { 17801 if(!$reload) { this.is_loading = true; } else { this.reload_loading = true; } 17802 if(ajax_request[timenow] != null) { 17803 ajax_request[timenow].abort(); 17804 } 17805 } 17806 }); 17807 17808 ajax_request[timenow].done( data => { 17809 if ( data.code==1){ 17810 this.data = data.details.data; 17811 this.services = data.details.services; 17812 this.estimation = data.details.estimation; 17813 } else { 17814 this.data = []; this.services = []; this.estimation = []; 17815 } 17816 }); 17817 17818 ajax_request[timenow].always( data => { 17819 this.is_loading = false; 17820 this.reload_loading = false; 17821 17822 }); 17823 17824 }, 17825 afterSaveStore(item){ 17826 item.saved_store = item.saved_store==1?false:true; 17827 }, 17828 }, 17829}); 17830app_my_store.use(ElementPlus); 17831const vm_my_store = app_my_store.mount('#vue-saved-store'); 17832 17833 17834 17835/* 17836 COMPONENTS MAPS AUTO COMPLETE 17837*/ 17838const ComponentsAutoComplete = { 17839 props: ['label','modelValue'],
17840 emits: ['update:modelValue'], 17841 data(){ 17842 return { 17843 q: '', 17844 awaitingSearch : false, 17845 show_list : false, 17846 data : [], 17847 error : [], 17848 hasSelected : false, 17849 }; 17850 }, 17851 watch: { 17852 q(newsearch,oldsearch){ 17853 17854 this.$emit('update:modelValue', newsearch); 17855 17856 if (!this.awaitingSearch) { 17857 17858 if(empty(newsearch)){ 17859 return false; 17860 } 17861 17862 if(this.q.length>20){ 17863 return false; 17864 } 17865 17866 this.show_list = true; 17867 17868 setTimeout(() => { 17869 17870 var $params; var timenow = 2; 17871 $params="q=" + this.q; 17872 $params+=addValidationRequest(); 17873 ajax_request[timenow] = $.ajax({ 17874 url: ajaxurl+"/getlocation_autocomplete", 17875 method: "POST", 17876 dataType: "json", 17877 data: $params, 17878 contentType : $content_type.form , 17879 timeout: $timeout, 17880 crossDomain: true, 17881 beforeSend: data => { 17882 if(ajax_request[timenow] != null) { 17883 ajax_request[timenow].abort(); 17884 } 17885 } 17886 }); 17887 17888 ajax_request[timenow].done( data => { 17889 if ( data.code==1){ 17890 this.data = data.details.data; 17891 } else { 17892 this.data = []; 17893 } 17894 }); // ajax done 17895 17896 ajax_request[timenow].always( data => { 17897 this.awaitingSearch = false; 17898 }); 17899 17900 }, 1000); // 1 sec delay 17901 } 17902 17903 this.data = []; 17904 this.awaitingSearch = true; 17905 }, 17906 }, 17907 methods: { 17908 showList(){ 17909 this.show_list = true; 17910 }, 17911 clearData(){ 17912 this.data = []; 17913 this.q = ''; 17914 }, 17915 setData(data){ 17916 this.clearData(); 17917 this.q = data.description; 17918 this.$emit('update:modelValue', data.description); 17919 this.$emit('afterChoose',data); 17920 }, 17921 }, 17922 computed: { 17923 hasData(){ 17924 if(this.data.length>0){ 17925 return true; 17926 } 17927 return false; 17928 }, 17929 }, 17930 template: ` 17931 <div class="position-relative search-geocomplete"> 17932 <div v-if="!awaitingSearch" class="img-20 m-auto pin_placeholder icon"></div> 17933 <div v-if="awaitingSearch" class="icon" data-loader="circle"></div> 17934 17935 <input @click="showList" v-model="q" class="form-control form-control-text" 17936 :placeholder="label.enter_address" > 17937 17938 <div v-if="hasData" @click="clearData" class="icon-remove"><i class="zmdi zmdi-close"></i></div> 17939 17940 </div> 17941 17942 <div class="search-geocomplete-results" v-if="show_list"> 17943 <ul class="list-unstyled m-0 border"> 17944 <li v-for="items in data"> 17945 <a href="javascript:;" @click="setData(items)" > 17946 <h6 class="m-0">{{items.description}}</h6> 17947 </a> 17948 </li> 17949 </ul> 17950 </div> 17951 ` 17952}; 17953/*END AUTO COMPLETE*/ 17954 17955 17956 17957/* 17958 MERCHANT SIGNUP 17959*/ 17960const app_merchant_signup = Vue.createApp({ 17961 components: { 17962 'component-auto-complete' : ComponentsAutoComplete, 17963 'component-phone' : ComponentsPhoneNumber, 17964 'vue-recaptcha' : componentsRecaptcha, 17965 }, 17966 data(){ 17967 return { 17968 data : [], 17969 loading : false, 17970 mobile_prefixes : [], 17971 restaurant_name : '', 17972 address : '', 17973 contact_email : '', 17974 mobile_prefix : '', 17975 mobile_number : '', 17976 membership_type : '2', 17977 membership_list : [], 17978 response : [], 17979 recaptcha_response : '', 17980 show_recaptcha : true, 17981 membership_commission : [], 17982 services_list : [], 17983 services : ['delivery','pickup'], 17984 currency_list : [], 17985 currency : '', 17986 first_name : '', 17987 last_name : '', 17988 username : '', 17989 password : '', 17990 cpassword : '', 17991 show_password : false, 17992 password_type : 'password', 17993 // Stripe embedded onboarding state 17994 show_stripe : false, 17995 stripe_publish_key : '', 17996 stripe_client_secret : '', 17997 merchant_uuid_embed : '', 17998 stripe_account_id_embed : '' 17999 }; 18000 }, 18001 mounted () {
18002 this.getSignupAttributes(); 18003 }, 18004 computed: { 18005 checkForm(){ 18006 18007 if(empty(this.restaurant_name)){ 18008 return true; 18009 } 18010 if(empty(this.address)){ 18011 return true; 18012 } 18013 if(empty(this.contact_email)){ 18014 return true; 18015 } 18016 if(!this.validEmail(this.contact_email)){ 18017 return true; 18018 } 18019 if(empty(this.mobile_number)){ 18020 return true; 18021 } 18022 if(empty(this.mobile_prefix)){ 18023 return true; 18024 } 18025 if(empty(this.first_name)){ 18026 return true; 18027 } 18028 if(empty(this.last_name)){ 18029 return true; 18030 } 18031 if(empty(this.username)){ 18032 return true; 18033 } 18034 if(empty(this.password)){ 18035 return true; 18036 } 18037 if(empty(this.cpassword)){ 18038 return true; 18039 } 18040 if(this.password!==this.cpassword){ 18041 return true; 18042 } 18043 18044 return false; 18045 }, 18046 }, 18047 methods :{ 18048 showPassword(){ 18049 this.show_password = this.show_password==true?false:true; 18050 if(this.show_password){ 18051 this.password_type = 'text'; 18052 } else this.password_type = 'password'; 18053 }, 18054 getSignupAttributes(){ 18055 var $params; var timenow = getTimeNow(); 18056 $params+=addValidationRequest(); 18057 ajax_request[timenow] = $.ajax({ 18058 url: ajaxurl+"/getSignupAttributes", 18059 method: "POST", 18060 dataType: "json", 18061 data: $params, 18062 contentType : $content_type.form , 18063 timeout: $timeout, 18064 crossDomain: true, 18065 beforeSend: function( xhr ) { 18066 if(ajax_request[timenow] != null) { 18067 ajax_request[timenow].abort(); 18068 } 18069 } 18070 }); 18071 18072 ajax_request[timenow].done( data => { 18073 if(data.code==1){ 18074 this.mobile_prefixes = data.details.mobile_prefixes; 18075 this.membership_list = data.details.membership_list; 18076 this.show_recaptcha = data.details.capcha; 18077 this.membership_commission = data.details.membership_commission; 18078 this.services_list = data.details.services_list; 18079 this.currency_list = data.details.currency_list; 18080 } else { 18081 this.mobile_prefixes = []; 18082 this.membership_list = ''; 18083 this.show_recaptcha = false; 18084 this.membership_commission = []; 18085 this.services_list = []; 18086 this.currency_list = []; 18087 } 18088 }); // ajax done 18089 }, 18090 verifyForms(){ 18091 if ( this.show_recaptcha){ 18092 this.verifyRecaptcha(); 18093 } else { 18094 this.submit(); 18095 } 18096 }, 18097 verifyRecaptcha(){ 18098 18099 var $params = { 18100 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 18101 'recaptcha_response': this.recaptcha_response, 18102 }; 18103 var timenow = 11; 18104 $params = JSON.stringify($params); 18105 18106 ajax_request[timenow] = $.ajax({ 18107 url: ajaxurl+"/verifyRecaptcha", 18108 method: "PUT", 18109 dataType: "json", 18110 data: $params , 18111 contentType : $content_type.json , 18112 timeout: $timeout, 18113 crossDomain: true, 18114 beforeSend: data => { 18115 this.loading = true; 18116 if(ajax_request[timenow] != null) { 18117 ajax_request[timenow].abort(); 18118 } 18119 } 18120 }); 18121 18122 ajax_request[timenow].done( data => { 18123 if(data.code==1){ 18124 this.submit(); 18125 } else if ( data.code==3){ 18126 this.recaptchaExpired(); 18127 this.response.code = 2; 18128 this.response.msg = data.msg; 18129 } else { 18130 this.response = data; 18131 } 18132 }); // ajax done 18133 18134 ajax_request[timenow].always( data => { 18135 this.loading = false; 18136 }); 18137 }, 18138 submit(){ 18139 18140 var $params = { 18141 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 18142 'restaurant_name': this.restaurant_name, 18143 'address': this.address, 18144 'contact_email': this.contact_email, 18145 'mobile_prefix': this.mobile_prefix, 18146 'mobile_number': this.mobile_number, 18147 'username' : this.username, 18148 'first_name' : this.first_name, 18149 'last_name' : this.last_name, 18150 'membership_type' : this.membership_type, 18151 'services': this.services, 18152 'currency' : this.currency 18153 }; 18154 var timenow = 22; 18155 $params = JSON.stringify($params); 18156 18157 ajax_request[timenow] = $.ajax({ 18158 url: ajaxurl+"/CreateAccountMerchant", 18159 method: "PUT", 18160 dataType: "json", 18161 data: $params , 18162 contentType : $content_type.json , 18163 timeout: $timeout, 18164 crossDomain: true, 18165 beforeSend: data => { 18166 this.loading = true; 18167 if(ajax_request[timenow] != null) { 18168 ajax_request[timenow].abort(); 18169 } 18170 } 18171 }); 18172 18173 ajax_request[timenow].done( data => { 18174 this.response = data; 18175 if(data.code==1){ 18176 // Always create the main merchant user immediately after merchant creation 18177 // This ensures Backoffice auto-login works and credentials are linked to the merchant 18178 this.createMerchantUser(data.details.redirect); 18179 } 18180 }); // ajax done 18181 18182 ajax_request[timenow].always( data => { 18183 this.loading = false;
18184 }); 18185 18186 }, 18187 // Embedded Stripe Connect onboarding helpers 18188 createMerchantUser(redirectUrl){ 18189 try{ 18190 const url = new URL(redirectUrl, window.location.origin); 18191 const merchant_uuid = url.searchParams.get('uuid'); 18192 if(!merchant_uuid){ 18193 window.location.href = redirectUrl; // fallback 18194 return; 18195 } 18196 axios({ 18197 method: 'PUT', 18198 url: ajaxurl+"/createMerchantUser" , 18199 data : { 18200 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 18201 'username' : this.username, 18202 'password' : this.password, 18203 'cpassword' : this.cpassword, 18204 'first_name' : this.first_name, 18205 'last_name' : this.last_name, 18206 'contact_email' : this.contact_email, 18207 'mobile_number' : this.mobile_number, 18208 'mobile_prefix' : this.mobile_prefix, 18209 'merchant_uuid' : merchant_uuid, 18210 }, 18211 timeout: $timeout, 18212 }).then( response => { 18213 if(response.data.code==1){ 18214 const _base = (typeof site_url !== 'undefined' && site_url) ? site_url : ''; 18215 window.location.href = _base+"/merchant/stripeconnect?uuid="+merchant_uuid; 18216 } else { 18217 this.response = response.data; 18218 } 18219 }).catch(error => {}).then(() => {}); 18220 }catch(e){ 18221 window.location.href = redirectUrl; // fallback 18222 } 18223 }, 18224 createStripeEmbeddedSession(){ 18225 const params = { 18226 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 18227 'uuid': this.merchant_uuid_embed 18228 }; 18229 axios({ 18230 method: 'PUT', 18231 url: ajaxurl+"/createStripeEmbeddedSession" , 18232 data: params, 18233 timeout: $timeout, 18234 }).then( response => { 18235 if(response.data.code==1){ 18236 this.stripe_publish_key = response.data.details.publishable_key; 18237 this.stripe_client_secret = response.data.details.client_secret; 18238 this.stripe_account_id_embed = response.data.details.account_id; 18239 this.initEmbeddedOnboarding(); 18240 } else { 18241 this.response = response.data; 18242 } 18243 }).catch((err)=>{ 18244 // Surface API error to UI for debugging 18245 try{ 18246 this.response = err.response && err.response.data ? err.response.data : { code:0, msg:['Stripe onboarding error'] }; 18247 }catch(e){/* ignore */} 18248 }); 18249 }, 18250 initEmbeddedOnboarding(){ 18251 const init = () => { 18252 const stripeConnectInstance = StripeConnect.init({ 18253 publishableKey: this.stripe_publish_key, 18254 fetchClientSecret: async () => this.stripe_client_secret, 18255 }); 18256 const container = document.getElementById("embedded-onboarding-container"); 18257 if(!container) return; 18258 const component = stripeConnectInstance.create("account-onboarding"); 18259 component.setOnExit(() => { 18260 const payload = { 18261 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 18262 'uuid': this.merchant_uuid_embed, 18263 'accountid': this.stripe_account_id_embed 18264 }; 18265 axios({ 18266 method: 'PUT', 18267 url: ajaxurl+"/updateMerchantStripeConnectId", 18268 data: payload, 18269 timeout: $timeout, 18270 }).then(res=>{ 18271 if(res.data.code==1 && res.data.details && res.data.details.redirect){ 18272 window.location.href = res.data.details.redirect; 18273 } 18274 }); 18275 }); 18276 container.innerHTML = ''; 18277 container.appendChild(component); 18278 }; 18279 if(window.StripeConnect && typeof StripeConnect.init==='function'){ 18280 init(); 18281 } else { 18282 window.StripeConnect = window.StripeConnect || {}; 18283 window.StripeConnect.onLoad = () => init(); 18284 } 18285 }, 18286 validEmail: function (email) { 18287 var re = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; 18288 return re.test(email); 18289 }, 18290 recaptchaVerified(response) { 18291 this.recaptcha_response = response; 18292 }, 18293 recaptchaExpired() { 18294 this.$refs.vueRecaptcha.reset(); 18295 }, 18296 recaptchaFailed() { 18297 18298 }, 18299 replaceText(text,replace1,replace2){ 18300 let result = text.replace("{transaction_type}", replace1); 18301 result = result.replace("{site_name}", replace2); 18302 return result; 18303 }, 18304 }, 18305}); 18306 18307app_merchant_signup.use(Maska); 18308app_merchant_signup.use(ElementPlus); 18309const vm_merchant_signup = app_merchant_signup.mount('#vue-merchant-signup'); 18310 18311 18312/* 18313 MERCHANT USER SIGNUP 18314*/ 18315 18316const app_merchant_user = Vue.createApp({ 18317 components: { 18318 'component-phone' : ComponentsPhoneNumber,
18319 'vue-recaptcha' : componentsRecaptcha, 18320 }, 18321 data(){ 18322 return { 18323 is_loading : false, 18324 show_password : false, 18325 agree_terms : false, 18326 password_type: 'password', 18327 first_name : '', 18328 last_name : '', 18329 contact_email : '', 18330 mobile_number : '', 18331 mobile_prefix :'', 18332 password : '', 18333 cpassword :'', 18334 mobile_prefixes : [], 18335 error : [], 18336 success : '', 18337 redirect : '', 18338 next_url : '', 18339 recaptcha_response : '', 18340 show_recaptcha : false, 18341 merchant_uuid : '', 18342 username : '' 18343 }; 18344 }, 18345 mounted () { 18346 this.merchant_uuid = _merchant_uuid; 18347 }, 18348 computed: { 18349 DataValid(){ 18350 if(!empty(this.first_name) && empty(!this.last_name) && empty(!this.contact_email) && empty(!this.mobile_number) 18351 && empty(!this.password) && empty(!this.cpassword) && empty(!this.username) ){ 18352 return true; 18353 } 18354 return false; 18355 }, 18356 }, 18357 methods: { 18358 showPassword() 18359 { 18360 this.show_password = this.show_password==true?false:true; 18361 if(this.show_password){ 18362 this.password_type = 'text'; 18363 } else this.password_type = 'password'; 18364 }, 18365 onRegister(){ 18366 18367 this.is_loading = true; 18368 this.error = []; 18369 axios({ 18370 method: 'PUT', 18371 url: ajaxurl+"/createMerchantUser" , 18372 data : { 18373 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 18374 'username' : this.username, 18375 'password' : this.password, 18376 'cpassword' : this.cpassword, 18377 'first_name' : this.first_name, 18378 'last_name' : this.last_name, 18379 'contact_email' : this.contact_email, 18380 'mobile_number' : this.mobile_number, 18381 'mobile_prefix' : this.mobile_prefix, 18382 'merchant_uuid' : this.merchant_uuid, 18383 }, 18384 timeout: $timeout, 18385 }).then( response => { 18386 if(response.data.code==1){ 18387 window.location.href = response.data.details.redirect; 18388 } else { 18389 this.data = []; 18390 this.error = response.data.msg; 18391 } 18392 }).catch(error => { 18393 // 18394 }).then(data => { 18395 this.is_loading = false; 18396 }); 18397 18398 }, 18399 }, 18400}); 18401app_merchant_user.use(Maska); 18402const vm_merchant_user = app_merchant_user.mount('#vue-merchant-user'); 18403 18404 18405 18406/* 18407 COMPONENTS PAYMENT PLANS 18408*/ 18409const ComponentsPaymentPlans = { 18410 props: ['label','payment_type','ajax_url','actions'], 18411 data() { 18412 return { 18413 is_loading : false, 18414 data : [], 18415 payment_code : '' 18416 } 18417 }, 18418 mounted () { 18419 this.getPaymentMethod(); 18420 }, 18421 methods :{ 18422 getPaymentMethod(){ 18423 18424 this.is_loading = true; 18425 axios({ 18426 method: 'POST', 18427 url: this.ajax_url+"/" + this.actions , 18428 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content'), 18429 timeout: $timeout, 18430 }).then( response => { 18431 if(response.data.code==1){ 18432 this.data = response.data.details; 18433 } else { 18434 this.data = []; 18435 } 18436 }).catch(error => { 18437 // 18438 }).then(data => { 18439 this.is_loading = false; 18440 }); 18441 18442 }, 18443 isActive(data){ 18444 return { 18445 'border-vertical-green': data.payment_code==this.payment_code 18446 } 18447 }, 18448 setPayment(payment_code){ 18449 this.payment_code = payment_code; 18450 this.$emit('setPayment', this.payment_code ); 18451 }, 18452 }, 18453 template: ` 18454 <!--PAYMENT METHODS--> 18455 <div class="card mb-3" > 18456 <div class="card-body"> 18457 18458 <h4 class="mb-3">{{label.select_payment}}</h4> 18459 18460 <a v-for="payment in data" 18461 @click="setPayment(payment.payment_code)" 18462 :class="isActive(payment)" 18463 class="d-block chevron-section medium d-flex align-items-center rounded mb-2"> 18464 <div class="flexcol mr-2 payment-logo-wrap"> 18465 <i v-if="payment.logo_type=='icon'" :class="payment.logo_class"></i> 18466 <img v-else class="img-35" :src="payment.logo_image" /> 18467 </div> 18468 18469 <div class="flexcol" > 18470 <span class="mr-1">{{payment.payment_name}}</span> 18471 </div> 18472 </a> 18473 18474 </div> <!--card body--> 18475 </div> <!--card--> 18476 <!--END PAYMENT METHODS--> 18477 `, 18478}; 18479 18480 18481/* 18482 SUBSCRIPTION 18483*/ 18484const app_subscription = Vue.createApp({ 18485 data(){ 18486 return { 18487 data : [], 18488 plan_details : [], 18489 is_loading : true, 18490 }; 18491 }, 18492 mounted () { 18493 this.getPlan(); 18494 }, 18495 methods :{ 18496 getPlan(){ 18497 this.is_loading = true; 18498 let currency_code = getCookie('currency_code'); 18499 currency_code = !empty(currency_code)?currency_code:''; 18500 axios({ 18501 method: 'POST', 18502 url: site_url +"/apisubscriptions/getsubscriptionlist" , 18503 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') +"¤cy_code="+currency_code, 18504 }).then( response => { 18505 if(response.data.code==1){ 18506 this.data = response.data.details.data; 18507 this.plan_details = response.data.details.plan_details; 18508 } else { 18509 this.data = []; 18510 this.plan_details = []; 18511 } 18512 }).catch(error => { 18513 // 18514 }).then(data => { 18515 this.is_loading = false;
18516 }); 18517 }, 18518 setChoosePlan(package_id){ 18519 this.is_loading = true; 18520 let data = 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&subscriber_id="+ subscriber_id + "&package_id="+ package_id; 18521 data+="&subscription_type="+ subscription_type; 18522 data+="&success_url="+ success_url; 18523 data+="&failed_url="+ failed_url; 18524 axios({ 18525 method: 'POST', 18526 url: site_url +"/apisubscriptions/createPaymentPlan" , 18527 data : data , 18528 }).then( response => { 18529 if(response.data.code==1){ 18530 window.location.href = payment_url + "?payment_id="+ response.data.details.payment_id; 18531 } else { 18532 ElementPlus.ElNotification({ 18533 title: "", 18534 message: response.data.msg, 18535 position: 'bottom-right', 18536 type: 'warning', 18537 }); 18538 } 18539 }).catch(error => { 18540 // 18541 }).then(data => { 18542 this.is_loading = false; 18543 }); 18544 }, 18545 }, 18546}); 18547app_subscription.use(ElementPlus); 18548const vm_subscription = app_subscription.mount('#vue-subscription'); 18549 18550const app_payment_plan = Vue.createApp({ 18551 data(){ 18552 return { 18553 data : [], 18554 loading : false, 18555 merchant_uuid : null, 18556 package_uuid : null, 18557 plan_details : [], 18558 payment_list : [], 18559 payment_code : '', 18560 subscriber_id : null, 18561 payment_id : null, 18562 subscription_type : null 18563 }; 18564 }, 18565 mounted () { 18566 // if ((typeof plan_merchant_uuid !== "undefined") && ( plan_merchant_uuid !== null)) { 18567 // this.merchant_uuid = plan_merchant_uuid; 18568 // } 18569 // if ((typeof plan_uuid !== "undefined") && ( plan_uuid !== null)) { 18570 // this.package_uuid = plan_uuid; 18571 // } 18572 // if ((typeof subscriber_id !== "undefined") && ( subscriber_id !== null)) { 18573 // this.subscriber_id = subscriber_id; 18574 // } 18575 if ((typeof payment_id !== "undefined") && ( payment_id !== null)) { 18576 this.payment_id = payment_id; 18577 } 18578 if ((typeof subscription_type !== "undefined") && ( subscription_type !== null)) { 18579 this.subscription_type = subscription_type; 18580 } 18581 this.getSelectPaymentPlan(); 18582 }, 18583 computed: { 18584 hasPaymentSelected(){ 18585 return empty(this.payment_code)? false : true; 18586 }, 18587 }, 18588 methods: { 18589 isActive(data){ 18590 return this.payment_code==data?true:false; 18591 }, 18592 getSelectPaymentPlan(){ 18593 this.loading = true; 18594 let currency_code = getCookie('currency_code'); 18595 currency_code = !empty(currency_code)?currency_code:''; 18596 axios({ 18597 method: 'GET', 18598 url: site_url +"/apisubscriptions/getCreatePayment?payment_id="+payment_id + "¤cy_code="+currency_code , 18599 }).then( response => { 18600 if(response.data.code==1){ 18601 this.plan_details = response.data.details.plan_details; 18602 this.payment_list = response.data.details.payment_list; 18603 } else { 18604 this.plan_details = []; 18605 this.payment_list = []; 18606 } 18607 }).catch(error => { 18608 // 18609 }).then(data => { 18610 this.loading = false; 18611 }); 18612 }, 18613 showPayment(){ 18614 console.log("this.payment_code",this.payment_code); 18615 console.log("this.subscription_type",this.subscription_type); 18616 try { 18617 this.$refs[this.payment_code][this.subscription_type](); 18618 } catch(err) { 18619 console.log("error",err); 18620 ElementPlus.ElNotification({ 18621 title: "", 18622 message: 'This payment is not available for plan', 18623 position: 'bottom-right', 18624 type: 'warning', 18625 }); 18626 } 18627 }, 18628 showLoader(){ 18629 this.loading = true; 18630 }, 18631 closeLoader(){ 18632 this.loading = false; 18633 }, 18634 errorMessage(data){ 18635 ElementPlus.ElNotification({ 18636 title: "", 18637 message: data, 18638 position: 'bottom-right', 18639 type: 'warning', 18640 }); 18641 }, 18642 // 18643 }, 18644}); 18645 18646if ((typeof components_bundle !== "undefined") && ( components_bundle !== null)) { 18647 $.each(components_bundle,function(components_name, components_value) { 18648 app_payment_plan.component(components_name, components_value ); 18649 }); 18650} 18651 18652app_payment_plan.use(ElementPlus); 18653const vm_payment_plan = app_payment_plan.mount('#payment-plan'); 18654 18655 18656/* 18657 UPDATE PROFILE 18658*/ 18659const app_update_profle = Vue.createApp({ 18660 components: { 18661 'component-phone' : ComponentsPhoneNumber, 18662 'component-change-phoneverify' : ComponentsChangePhoneVerification, 18663 }, 18664 data(){ 18665 return { 18666 is_loading: false, 18667 data : [], 18668 first_name : '', 18669 last_name : '', 18670 email_address :'', 18671 mobile_prefix : '', 18672 mobile_number :'', 18673 original_email_address : '', 18674 original_mobile_number : '', 18675 error : [], 18676 success : '', 18677 original_mobile_prefix :'', 18678 custom_fields : {} 18679 }; 18680 }, 18681 computed: { 18682 DataValid(){ 18683 if(!empty(this.first_name) && empty(!this.last_name) && empty(!this.email_address) && empty(!this.mobile_number) ){ 18684 return true; 18685 } 18686 return false;
18687 }, 18688 }, 18689 mounted () { 18690 this.getProfile(); 18691 }, 18692 methods :{ 18693 getProfile(){ 18694 var $params = { 18695 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 18696 }; 18697 var timenow = 11; 18698 $params = JSON.stringify($params); 18699 18700 ajax_request[timenow] = $.ajax({ 18701 url: ajaxurl+"/getProfile", 18702 method: "PUT", 18703 dataType: "json", 18704 data: $params , 18705 contentType : $content_type.json , 18706 timeout: $timeout, 18707 crossDomain: true, 18708 beforeSend: data => { 18709 this.is_loading = true; 18710 if(ajax_request[timenow] != null) { 18711 ajax_request[timenow].abort(); 18712 } 18713 } 18714 }); 18715 18716 ajax_request[timenow].done( data => { 18717 if(data.code==1){ 18718 this.first_name = data.details.first_name; 18719 this.last_name = data.details.last_name; 18720 this.email_address = data.details.email_address; 18721 this.mobile_prefix = data.details.mobile_prefix; 18722 this.mobile_number = data.details.mobile_number; 18723 this.original_mobile_prefix = data.details.mobile_prefix; 18724 this.original_email_address = data.details.email_address; 18725 this.original_mobile_number = data.details.mobile_number; 18726 18727 // CUSTOM FIELDS 18728 const customFields = data.details.custom_fields; 18729 if(customFields){ 18730 Object.keys(customFields).forEach((key) => { 18731 const value = customFields[key]; 18732 this.addCustomField(key, value); 18733 }); 18734 } 18735 } else { 18736 this.msg = data.msg; 18737 } 18738 }); // ajax done 18739 18740 ajax_request[timenow].always( data => { 18741 this.is_loading = false; 18742 }); 18743 }, 18744 18745 addCustomField(id, value) { 18746 this.custom_fields[id] = value; 18747 }, 18748 18749 checkForm(){ 18750 var _change = false; 18751 if( this.email_address != this.original_email_address ) { 18752 _change = true; 18753 } 18754 if( this.mobile_number != this.original_mobile_number ) { 18755 _change = true; 18756 } 18757 if( this.original_mobile_prefix != this.mobile_prefix ) { 18758 _change = true; 18759 } 18760 18761 this.success =''; 18762 this.error = []; 18763 18764 console.log("_change",_change); 18765 if(_change){ 18766 this.$refs.cphoneverify.show({ 18767 mobile_prefix : this.mobile_prefix, 18768 mobile_number : this.mobile_number, 18769 message : _message 18770 }); 18771 this.$refs.cphoneverify.resendCode(); 18772 } else { 18773 this.saveProfile(''); 18774 } 18775 }, 18776 18777 saveProfile(code){ 18778 18779 var $params = { 18780 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 18781 'code': code, 18782 'first_name' : this.first_name, 18783 'last_name' : this.last_name, 18784 'email_address' : this.email_address, 18785 'mobile_prefix' : this.mobile_prefix, 18786 'mobile_number' : this.mobile_number, 18787 'custom_fields':this.custom_fields 18788 }; 18789 var timenow = getTimeNow(); 18790 $params = JSON.stringify($params); 18791 18792 ajax_request[timenow] = $.ajax({ 18793 url: ajaxurl+"/saveProfile", 18794 method: "PUT", 18795 dataType: "json", 18796 data: $params , 18797 contentType : $content_type.json , 18798 timeout: $timeout, 18799 crossDomain: true, 18800 beforeSend: data => { 18801 if (!empty(code)){ 18802 this.$refs.cphoneverify.is_loading = true; 18803 } else { 18804 this.is_loading = true; 18805 } 18806 if(ajax_request[timenow] != null) { 18807 ajax_request[timenow].abort(); 18808 } 18809 } 18810 }); 18811 18812 ajax_request[timenow].done( data => { 18813 if(data.code==1){ 18814 this.$refs.cphoneverify.close(); 18815 this.success = data.msg; 18816 this.original_email_address = this.email_address; 18817 this.original_mobile_number = this.mobile_number; 18818 } else { 18819 if (!empty(code)){ 18820 this.$refs.cphoneverify.error = data.msg; 18821 } else this.error = data.msg; 18822 } 18823 }); 18824 18825 ajax_request[timenow].always( data => { 18826 if (!empty(code)){ 18827 this.$refs.cphoneverify.is_loading = false;
18828 } else { 18829 this.is_loading = false; 18830 } 18831 }); 18832 }, 18833 }, 18834}); 18835 18836app_update_profle.use(Maska); 18837app_update_profle.use(ElementPlus); 18838const vm_update_profle = app_update_profle.mount('#vue-update-profile'); 18839 18840/* 18841 UPDATE PASSWORD 18842*/ 18843const app_update_password = Vue.createApp({ 18844 components: { 18845 'component-change-phoneverify' : ComponentsChangePhoneVerification, 18846 }, 18847 data(){ 18848 return { 18849 is_loading: false, 18850 data : [], 18851 error : [], 18852 success : '', 18853 old_password : '', 18854 new_password : '', 18855 confirm_password : '', 18856 }; 18857 }, 18858 computed: { 18859 DataValid(){ 18860 if(!empty(this.old_password) && empty(!this.new_password) && empty(!this.confirm_password) ){ 18861 return true; 18862 } 18863 return false; 18864 }, 18865 }, 18866 methods :{ 18867 updatePassword(){ 18868 18869 var $params = { 18870 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 18871 'old_password' : this.old_password, 18872 'new_password' : this.new_password, 18873 'confirm_password' : this.confirm_password, 18874 }; 18875 var timenow = getTimeNow(); 18876 $params = JSON.stringify($params); 18877 18878 ajax_request[timenow] = $.ajax({ 18879 url: ajaxurl+"/updatePassword", 18880 method: "PUT", 18881 dataType: "json", 18882 data: $params , 18883 contentType : $content_type.json , 18884 timeout: $timeout, 18885 crossDomain: true, 18886 beforeSend: data => { 18887 this.is_loading = true; 18888 this.error = ''; this.success = ''; 18889 if(ajax_request[timenow] != null) { 18890 ajax_request[timenow].abort(); 18891 } 18892 } 18893 }); 18894 18895 ajax_request[timenow].done( data => { 18896 if(data.code==1){ 18897 this.success = data.msg; 18898 this.old_password =''; 18899 this.new_password =''; 18900 this.confirm_password =''; 18901 } else this.error = data.msg; 18902 }); 18903 18904 ajax_request[timenow].always( data => { 18905 this.is_loading = false; 18906 }); 18907 18908 }, 18909 }, 18910}).mount('#vue-update-password'); 18911 18912 18913/* 18914 MANAGE MY ACCOUNT 18915*/ 18916 18917const app_manage_account = Vue.createApp({ 18918 components: { 18919 'component-change-phoneverify' : ComponentsChangePhoneVerification, 18920 }, 18921 data(){ 18922 return { 18923 is_loading: false, 18924 error : [], 18925 success : '', 18926 steps : 1, 18927 steps_request_data : 1, 18928 }; 18929 }, 18930 methods :{ 18931 requestArchive(){ 18932 18933 var $params = { 18934 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 18935 }; 18936 var timenow = getTimeNow(); 18937 $params = JSON.stringify($params); 18938 18939 ajax_request[timenow] = $.ajax({ 18940 url: ajaxurl+"/requestData", 18941 method: "PUT", 18942 dataType: "json", 18943 data: $params , 18944 contentType : $content_type.json , 18945 timeout: $timeout, 18946 crossDomain: true, 18947 beforeSend: data => { 18948 this.is_loading = true; 18949 this.steps_request_data = 1; 18950 this.error = ''; 18951 if(ajax_request[timenow] != null) { 18952 ajax_request[timenow].abort(); 18953 } 18954 } 18955 }); 18956 18957 ajax_request[timenow].done( data => { 18958 if(data.code==1){ 18959 this.steps_request_data = 2; 18960 } else { 18961 this.error = data.msg; 18962 } 18963 }); 18964 18965 ajax_request[timenow].always( data => { 18966 this.is_loading = false; 18967 }); 18968 18969 }, 18970 confirm(){ 18971 this.$refs.cphoneverify.show({ 18972 mobile_prefix : _phone_prefix, 18973 mobile_number : _contact_phone, 18974 message : _message 18975 }); 18976 this.$refs.cphoneverify.resendCode(); 18977 }, 18978 verifyAccountDelete(code){ 18979 18980 var $params = { 18981 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 18982 'code' : code, 18983 }; 18984 var timenow = getTimeNow(); 18985 $params = JSON.stringify($params); 18986 18987 ajax_request[timenow] = $.ajax({ 18988 url: ajaxurl+"/verifyAccountDelete", 18989 method: "PUT", 18990 dataType: "json", 18991 data: $params , 18992 contentType : $content_type.json , 18993 timeout: $timeout, 18994 crossDomain: true, 18995 beforeSend: data => { 18996 this.$refs.cphoneverify.is_loading = true; 18997 this.$refs.cphoneverify.error = []; 18998 if(ajax_request[timenow] != null) { 18999 ajax_request[timenow].abort(); 19000 } 19001 } 19002 }); 19003 19004 ajax_request[timenow].done( data => { 19005 if(data.code==1){ 19006 this.$refs.cphoneverify.close(); 19007 19008 vm_bootbox.confirm().then((result) => { 19009 if(result){ 19010 this.deleteAccount( code ); 19011 } 19012 }); 19013 19014 } else this.$refs.cphoneverify.error = data.msg; 19015 }); 19016 19017 ajax_request[timenow].always( data => { 19018 this.$refs.cphoneverify.is_loading = false;
19019 }); 19020 19021 }, 19022 19023 deleteAccount(code){ 19024 19025 var $params = { 19026 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 19027 'code' : code, 19028 }; 19029 var timenow = getTimeNow(); 19030 $params = JSON.stringify($params); 19031 19032 ajax_request[timenow] = $.ajax({ 19033 url: ajaxurl+"/deleteAccount", 19034 method: "PUT", 19035 dataType: "json", 19036 data: $params , 19037 contentType : $content_type.json , 19038 timeout: $timeout, 19039 crossDomain: true, 19040 beforeSend: data => { 19041 this.is_loading = true; 19042 this.error = ''; this.success = ''; 19043 if(ajax_request[timenow] != null) { 19044 ajax_request[timenow].abort(); 19045 } 19046 } 19047 }); 19048 19049 ajax_request[timenow].done( data => { 19050 if(data.code==1){ 19051 this.steps = 2; 19052 setTimeout(() => { 19053 window.location.href = data.details.redirect; 19054 }, 4000); 19055 } else vm_bootbox.alert( data.msg , {} ); 19056 }); 19057 19058 ajax_request[timenow].always( data => { 19059 this.is_loading = false; 19060 }); 19061 }, 19062 } 19063}); 19064app_manage_account.use(Maska); 19065const vm_manage_account = app_manage_account.mount('#vue-manage-account'); 19066 19067 19068/* 19069 COMPONENTS PROFILE PHOTO 19070*/ 19071const ComponentsProfilePhoto = { 19072 components: { 19073 Cropper: VueAdvancedCropper.Cropper 19074 }, 19075 props: ['label'], 19076 data(){ 19077 return { 19078 upload_images : '', 19079 filename : '', 19080 required_message :[], 19081 is_loading : false, 19082 error : [], 19083 steps: 1, 19084 photo : undefined, 19085 }; 19086 }, 19087 mounted () { 19088 this.initDropZone(this.label , this); 19089 }, 19090 methods :{ 19091 show(){ 19092 this.steps=1; 19093 $('#photoModal').modal('show'); 19094 }, 19095 close(){ 19096 $('#photoModal').modal('hide'); 19097 }, 19098 closeReset(){ 19099 this.reset(); 19100 $('#photoModal').modal('hide'); 19101 }, 19102 reset(){ 19103 Dropzone.forElement('#dropzone_multiple').removeAllFiles(true); 19104 this.removeUpload(this.filename); 19105 this.upload_images = []; 19106 this.filename = ''; 19107 this.error = []; 19108 }, 19109 initDropZone(label, object){ 19110 var $upload_params = { 19111 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 19112 }; 19113 Dropzone.autoDiscover = false; 19114 //$dropzone = $("#dropzone_multiple").dropzone({ 19115 $dropzone = $( this.$refs.profile_dropzone ).dropzone({ 19116 dictDefaultMessage : label.dictDefaultMessage, 19117 dictFallbackMessage : label.dictFallbackMessage , 19118 dictFallbackText : label.dictFallbackText, 19119 dictFileTooBig : label.dictFileTooBig, 19120 dictInvalidFileType : label.dictInvalidFileType, 19121 dictResponseError : label.dictResponseError, 19122 dictCancelUpload : label.dictCancelUpload, 19123 dictCancelUploadConfirmation : label.dictCancelUploadConfirmation, 19124 dictRemoveFile : label.dictRemoveFile, 19125 dictMaxFilesExceeded : label.dictMaxFilesExceeded, 19126 paramName: "file", 19127 url: ajaxurl+"/uploadProfilePhoto" , 19128 maxFiles: 20, 19129 params: $upload_params, 19130 addRemoveLinks : true, 19131 maxFiles : 2, 19132 init: function() { 19133 this.on("maxfilesexceeded", function(file) { 19134 vm_bootbox.alert( label.max_file_exceeded , {} ); 19135 }); 19136 this.on("removedfile", function (file) { 19137 }); 19138 }, 19139 success: (file,response) => { 19140 var $resp = JSON.parse(response); 19141 if($resp.code==1){ 19142 this.upload_images = $resp.details.url_image; 19143 this.filename = $resp.details.filename; 19144 this.steps = 2; 19145 } else { 19146 vm_bootbox.alert( $resp.msg , {} ); 19147 this.reset(); 19148 } 19149 } 19150 }); 19151 }, 19152 removeUpload(id){ 19153 19154 return new Promise((resolve, reject) => { 19155 19156 var $params = { 19157 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 19158 'id':id, 19159 }; 19160 var timenow = getTimeNow(); 19161 19162 ajax_request[timenow] = $.ajax({ 19163 url: ajaxurl+"/removeProfilePhoto", 19164 method: "PUT", 19165 dataType: "json", 19166 data: JSON.stringify($params) , 19167 contentType : $content_type.json , 19168 timeout: $timeout, 19169 crossDomain: true, 19170 beforeSend: data => { 19171 this.is_loading = true; 19172 if(ajax_request[timenow] != null) { 19173 ajax_request[timenow].abort(); 19174 this.is_loading = false;
19175 } 19176 } 19177 }); 19178 19179 ajax_request[timenow].done( data => { 19180 this.is_loading = false; 19181 resolve(true); 19182 if(data.code==1){ 19183 //this.remove(data.details); 19184 } 19185 }); // ajax done 19186 19187 ajax_request[timenow].always( data => { 19188 this.is_loading = false; 19189 }); 19190 19191 }); 19192 }, 19193 change({coordinates, canvas}) { 19194 this.photo = canvas.toDataURL('image/png'); 19195 }, 19196 save(){ 19197 this.$emit('onSave', this.photo , this.filename ); 19198 }, 19199 }, 19200 template: ` 19201 <div class="modal" id="photoModal" tabindex="-1" role="dialog" aria-labelledby="photoModal" aria-hidden="true" 19202 data-backdrop="static" data-keyboard="false" > 19203 <div class="modal-dialog modal-dialog-centered" role="document"> 19204 <div class="modal-content"> 19205 19206 <div class="modal-body" style="overflow-y:inherit !important;" > 19207 19208 <a href="javascript:;" @click="closeReset" 19209 class="btn btn-black btn-circle rounded-pill"><i class="zmdi zmdi-close font20"></i></a> 19210 19211 <template :class="{ 'd-block': steps==1 }"> 19212 <h5 class="m-0 mt-3 mb-2">{{label.add_photo}}</h5> 19213 <div class="mb-3"> 19214 <div class="dropzone dropzone_container" id="dropzone_multiple" ref="profile_dropzone" > 19215 <div class="dz-default dz-message"> 19216 <i class="fas fa-cloud-upload-alt"></i> 19217 <p>{{label.drop_files_here}}</p> 19218 </div> 19219 </div> 19220 </div> 19221 </template> 19222 19223 <template v-if="steps==2"> 19224 <h5 class="m-0 mt-3 mb-2">{{label.crop_photo}}</h5> 19225 19226 <div class="crop-images-wrap"> 19227 <cropper 19228 :src="upload_images" 19229 @change="change" 19230 :stencil-props="{ 19231 handlers: {}, 19232 movable: false, 19233 scalable: false, 19234 }" 19235 :stencil-size="{ 19236 width: 120, 19237 height: 120 19238 }" 19239 image-restriction="stencil" 19240 ></cropper> 19241 </div> 19242 19243 </template> 19244 19245 19246 </div> <!--modal body--> 19247 19248 <template v-if="steps==2"> 19249 19250 <div v-cloak v-if="error.length>0" class="alert alert-warning mb-2" role="alert"> 19251 <p v-cloak v-for="err in error" class="m-0">{{err}}</p> 19252 </div> 19253 19254 <div class="modal-footer justify-content-start"> 19255 <button class="btn btn-green w-100" @click="save" :class="{ loading: is_loading }" > 19256 <span class="label">{{label.save_photo}}</span> 19257 <div class="m-auto circle-loader" data-loader="circle-side"></div> 19258 </button> 19259 </div> <!--footer--> 19260 </template> 19261 19262 </div> <!--content--> 19263 </div> <!--dialog--> 19264 </div> <!--modal--> 19265 `, 19266}; 19267 19268 19269/* 19270 CUSTOMER PROFILE PHOTO 19271*/ 19272const app_profile_photo = Vue.createApp({ 19273 components: { 19274 'components-profile-photo' : ComponentsProfilePhoto, 19275 }, 19276 data(){ 19277 return { 19278 avatar : '' 19279 }; 19280 }, 19281 methods :{ 19282 showUpload(){ 19283 this.$refs.profile_photo.show(); 19284 }, 19285 SavePhoto(photo,filename){ 19286 19287 var $params; var timenow = 1; 19288 $params="photo=" + photo; 19289 $params+="&filename=" + filename; 19290 $params+=addValidationRequest(); 19291 ajax_request[timenow] = $.ajax({ 19292 url: ajaxurl+"/saveProfilePhoto", 19293 method: "POST", 19294 dataType: "json", 19295 data: $params, 19296 contentType : $content_type.form , 19297 timeout: $timeout, 19298 crossDomain: true, 19299 beforeSend: data => { 19300 this.$refs.profile_photo.is_loading = true; 19301 if(ajax_request[timenow] != null) { 19302 ajax_request[timenow].abort(); 19303 } 19304 } 19305 }); 19306 19307 ajax_request[timenow].done( data => { 19308 if(data.code==1){ 19309 this.$refs.profile_photo.close(); 19310 this.avatar = data.details.url_image; 19311 this.updateImage(); 19312 } else { 19313 this.$refs.profile_photo.error = data.msg; 19314 } 19315 }); // ajax done 19316 19317 ajax_request[timenow].always( data => { 19318 this.$refs.profile_photo.is_loading = false;
19319 }); 19320 19321 }, 19322 updateImage(){ 19323 var el = this.$refs.refavatar.getElementsByTagName("img"); 19324 el[0].src = this.avatar; 19325 }, 19326 }, 19327}); 19328app_profile_photo.use(ElementPlus); 19329const vm_profile_photo = app_profile_photo.mount('#vue-profile-photo'); 19330 19331 19332/* 19333 CHECK MERCHANT OPEN HOURS 19334 vue-schedule-order 19335*/ 19336const vm_schedule_order = Vue.createApp({ 19337 components: { 19338 'component-select-time' : ComponenstTransactionOptions, 19339 }, 19340 data(){ 19341 return { 19342 store_close : false, 19343 time_required : false, 19344 time_required_message : '', 19345 time_selection : 1, 19346 store_open_data : null, 19347 show_schedule_order : true, 19348 store_open_message : '' 19349 }; 19350 }, 19351 mounted () { 19352 // 19353 }, 19354 methods:{ 19355 checkStoreOpen(){ 19356 var $merchant_id = 0; 19357 if ((typeof merchant_id !== "undefined") && ( merchant_id !== null)) { 19358 $merchant_id = merchant_id; 19359 } 19360 var $choosen_delivery = !empty(getCookie('choosen_delivery'))? JSON.parse(getCookie('choosen_delivery')) : [] ; 19361 19362 var $params = { 19363 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 19364 'merchant_id' : $merchant_id, 19365 'cart_uuid' : getCookie('cart_uuid'), 19366 'choosen_delivery' : $choosen_delivery, 19367 }; 19368 var timenow = getTimeNow(); 19369 $params = JSON.stringify($params); 19370 19371 ajax_request[timenow] = $.ajax({ 19372 url: ajaxurl+"/checkStoreOpen", 19373 method: "PUT", 19374 dataType: "json", 19375 data: $params , 19376 contentType : $content_type.json , 19377 timeout: $timeout, 19378 crossDomain: true, 19379 beforeSend: data => { 19380 if(ajax_request[timenow] != null) { 19381 ajax_request[timenow].abort(); 19382 } 19383 } 19384 }).done( data => { 19385 if(data.code==1){ 19386 19387 this.store_open_data = data.details; 19388 this.show_schedule_order = data.details.show_schedule !== false; 19389 this.store_open_message = data.details.store_open_message || ''; 19390 if(data.details.merchant_open_status<=0){ 19391 this.store_close = true; 19392 vue_cart.error.push(data.msg); 19393 } else { 19394 this.store_close = false; 19395 } 19396 19397 this.time_required = data.details.time_required; 19398 if (typeof data.details.time_selection !== "undefined" && data.details.time_selection !== null) { 19399 this.time_selection = data.details.time_selection; 19400 } 19401 19402 if(this.time_required){ 19403 vue_cart.error.push(data.details.time_required_message); 19404 } 19405 19406 if(data.details.time_already_passed){ 19407 setCookie('choosen_delivery', [] ,30); 19408 } 19409 } else { 19410 this.store_close = true; 19411 vue_cart.error.push(data.msg); 19412 } 19413 if ((typeof vm !== "undefined") && ( vm !== null)) { 19414 vm.checkout_blocked = Array.isArray(vue_cart.error) && vue_cart.error.length > 0; 19415 } 19416 }).always( data => { 19417 19418 }); 19419 }, 19420 show(){ 19421 this.$refs.select_time.show(); 19422 }, 19423 afterSaveTransOptions(data){ 19424 this.$refs.select_time.close(); 19425 19426 if ((typeof vm_feed !== "undefined") && ( vm_feed !== null)) { 19427 vm_feed.whento_deliver = data.whento_deliver; 19428 vm_feed.delivery_date = data.delivery_date; 19429 vm_feed.delivery_time = data.delivery_time; 19430 vm_feed.Search(false); 19431 } 19432 19433 if ((typeof vue_cart !== "undefined") && ( vue_cart !== null)) { 19434 vue_cart.loadcart(); 19435 } 19436 19437 if ((typeof vm_widget_nav !== "undefined") && ( vm_widget_nav !== null)) { 19438 if(vm_widget_nav.$refs.transaction_info){ 19439 vm_widget_nav.$refs.transaction_info.whento_deliver = data.whento_deliver; 19440 vm_widget_nav.$refs.transaction_info.delivery_datetime = data.delivery_datetime; 19441 } 19442 } 19443 19444 }, 19445 storeAvailable(){ 19446 19447 var $merchant_uuid = ''; 19448 if ((typeof merchant_uuid !== "undefined") && ( merchant_uuid !== null)) { 19449 $merchant_uuid = merchant_uuid; 19450 } 19451 19452 axios({ 19453 method: 'POST', 19454 url: ajaxurl +"/storeAvailable" , 19455 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&merchant_uuid=" + $merchant_uuid, 19456 timeout: $timeout, 19457 }).then( response => { 19458 if(response.data.code==1){ 19459 // 19460 } else { 19461 vue_cart.error.push(response.data.msg); 19462 } 19463 }).catch(error => { 19464 // 19465 }).then(data => { 19466 19467 }); 19468 }, 19469 }, 19470}).mount('#vue-schedule-order'); 19471 19472
19473/* 19474 UTENSILS 19475 vue-utensils 19476*/ 19477const vm_utensils = Vue.createApp({ 19478 data(){ 19479 return { 19480 visible : false, 19481 include_utensils : false, 19482 is_loading : false, 19483 }; 19484 }, 19485 watch: { 19486 include_utensils(new_value,old_value){ 19487 setStorage('include_utensils',new_value); 19488 this.setUtensils(new_value); 19489 } 19490 }, 19491 mounted () { 19492 this.setUtensils( getStorage("include_utensils") ); 19493 }, 19494 methods : { 19495 setTransaction(trans_type){ 19496 if(trans_type=="delivery"){ 19497 this.visible = true; 19498 } else this.visible = false; 19499 }, 19500 setUtensils(is_include){ 19501 is_include = empty(is_include)? false : is_include; 19502 this.include_utensils = is_include; 19503 }, 19504 } 19505}).mount('#vue-utensils'); 19506 19507 19508/* 19509 COMPONENTS ITEM SUGGESTION 19510*/ 19511const ComponentsItemSuggestion = { 19512 props: ['title','merchant_id','settings','image_use' , 'responsive'], 19513 components : { 19514 'money-format': ComponentsMoney, 19515 }, 19516 data(){ 19517 return { 19518 owl : undefined, 19519 menu_data: [], 19520 items : [], 19521 item_addons : [], 19522 item_addons_load : false, 19523 size_id : 0, 19524 disabled_cart : true, 19525 item_qty : 1, 19526 item_total : 0, 19527 add_to_cart : false, 19528 meta : [], 19529 special_instructions : '', 19530 sold_out_options : [], 19531 if_sold_out : 'substitute', 19532 transaction_type : '', 19533 item_loading :false, 19534 item_gallery : [], 19535 image_featured : '', 19536 money_config : '' 19537 }; 19538 }, 19539 mounted () { 19540 this.itemSuggestion(); 19541 }, 19542 updated () { 19543 if(this.item_addons_load==true){ 19544 this.ItemSummary(); 19545 $('.item_s .lazy').each(function(index, $obj){ 19546 if ( !empty($(this).attr("src")) && !empty($(this).attr("data-src")) ){ 19547 $(this).attr("src", $(this).attr("data-src") ); 19548 } 19549 }); 19550 } 19551 19552 if ((typeof vm_checkout_transaction !== "undefined") && ( vm_checkout_transaction !== null)) { 19553 this.transaction_type = vm_checkout_transaction.transaction_type; 19554 } 19555 19556 }, // 19557 computed: { 19558 getItemGallery(){ 19559 return this.item_gallery; 19560 } 19561 }, 19562 methods: { 19563 itemSuggestion(){ 19564 let currency_code = getCookie('currency_code'); 19565 currency_code = !empty(currency_code)?currency_code:''; 19566 var $params = { 19567 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 19568 'merchant_id' : this.merchant_id, 19569 'image_use' : this.image_use, 19570 'currency_code': currency_code 19571 }; 19572 var timenow = getTimeNow(); 19573 $params = JSON.stringify($params); 19574 ajax_request[timenow] = $.ajax({ 19575 url: ajaxurl+"/geStoreMenu", 19576 method: "PUT", 19577 dataType: "json", 19578 data: $params , 19579 contentType : $content_type.json , 19580 timeout: $timeout, 19581 crossDomain: true, 19582 beforeSend: data => { 19583 this.is_loading = true; 19584 if(ajax_request[timenow] != null) { 19585 ajax_request[timenow].abort(); 19586 } 19587 } 19588 }).done( data => { 19589 if ( data.code==1){ 19590 19591 var $category = data.details.data.category; 19592 var $items = data.details.data.items; 19593 var $new_category = []; var $new_items = []; 19594 19595 if($category.length>0){ 19596 $.each($category, function(key, val){ 19597 $.each(val.items, function(items_key, $item_id){ 19598 $new_items.push( $items[$item_id] ); 19599 }); // loop 19600 $new_category.push({ 19601 'cat_id': val.cat_id, 19602 'category_name': val.category_name, 19603 'category_uiid': val.category_uiid, 19604 'items':$new_items 19605 }); 19606 $new_items = []; 19607 }); // loop 19608 } 19609 this.menu_data = $new_category; 19610 19611 setTimeout(() => { 19612 this.RenderCarousel(); 19613 }, 10); 19614 19615 } else this.menu_data = []; 19616 }).always( data => { 19617 this.is_loading = false; 19618 }); 19619 }, 19620 RenderCarousel(){ 19621 let $is_rtl = false; 19622 if ((typeof is_rtl !== "undefined") && ( is_rtl !== null)) { 19623 $is_rtl = is_rtl=='1'?true:false; 19624 } 19625 this.owl = $("#item-suggestion-list").owlCarousel({ 19626 items: parseInt(this.settings.items), 19627 lazyLoad: this.settings.lazyLoad=="1"?true:false , 19628 loop: this.settings.loop=="1"?true:false , 19629 margin: parseInt(this.settings.margin) , 19630 nav: this.settings.nav=="1"?true:false , 19631 dots: this.settings.dots=="1"?true:false , 19632 stagePadding: parseInt(this.settings.stagePadding), 19633 autoWidth:true, 19634 rtl : $is_rtl 19635 }); 19636 }, 19637 SlideNext(){ 19638 this.owl.trigger('next.owl.carousel'); 19639 }, 19640 SlidePrev(){ 19641 this.owl.trigger('prev.owl.carousel', [300]); 19642 }, 19643 viewItem(data){ 19644 this.item_loading = true; 19645 NProgress.start(); 19646 19647 let currency_code = getCookie('currency_code'); 19648 currency_code = !empty(currency_code)?currency_code:''; 19649 19650 var $params = { 19651 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 19652 'merchant_id': this.merchant_id, 19653 'item_uuid' : data.item_uuid, 19654 'cat_id' : data.cat_id, 19655 'currency_code': currency_code 19656 }; 19657 var timenow = 1; 19658 $params = JSON.stringify($params); 19659 19660 ajax_request[timenow] = $.ajax({ 19661 url: ajaxurl+"/getMenuItem", 19662 method: "PUT", 19663 dataType: "json", 19664 data: $params , 19665 contentType : $content_type.json , 19666 timeout: $timeout, 19667 crossDomain: true, 19668 beforeSend: data => { 19669 if(ajax_request[timenow] != null) { 19670 ajax_request[timenow].abort(); 19671 } 19672 } 19673 }).done( data => { 19674 19675 if(data.code==1){ 19676 19677 $global_items = data.details.data.items; 19678 $global_addons = data.details.data.addons; 19679 $global_addon_items = data.details.data.addon_items; 19680 $global_item_addons = data.details.data.items.item_addons; 19681 19682 this.money_config = data.details.money_config; 19683 this.item_gallery = data.details.data.meta.item_gallery; 19684 this.image_featured = ''; 19685 this.renderGallery(); 19686 19687 var $meta = data.details.data.meta; 19688 var $meta_details = data.details.data.meta_details; 19689 var $new_meta = { 19690 'cooking_ref' : [], 19691 'ingredients' : [], 19692 'dish' : [], 19693 }; 19694 19695 let $ingredients_preselected = data.details.data.items.ingredients_preselected; 19696 19697 if( !empty($meta)){ 19698 $.each($meta,function(key, item) { 19699 $.each(item,function(key2, item2) { 19700 if(!empty($meta_details[key])){ 19701 if(!empty($meta_details[key][item2])){ 19702 let $defaul_check = false;
19703 if(key=="ingredients" && $ingredients_preselected){ 19704 $defaul_check = true; 19705 } 19706 $new_meta[key].push({ 19707 'meta_id': $meta_details[key][item2].meta_id, 19708 'meta_name': $meta_details[key][item2].meta_name, 19709 'checked': $defaul_check 19710 }); 19711 } 19712 } 19713 }); 19714 }); 19715 } 19716 19717 var $price = $global_items.price; 19718 var $size_id = Object.keys($price)[0]; 19719 19720 this.item_qty = 1; 19721 this.items = $global_items; 19722 this.size_id = $size_id; 19723 this.meta = $new_meta; 19724 this.getSizeData($size_id); 19725 this.sold_out_options = data.details.sold_out_options; 19726 19727 $( this.$refs.modal_item_details ).modal('show'); 19728 this.updateImage(); 19729 19730 } /*end if*/ 19731 19732 }).always( data => { 19733 this.item_loading = false; 19734 NProgress.done(); 19735 }); 19736 }, 19737 renderGallery(){ 19738 setTimeout(() => { 19739 let $is_rtl = false; 19740 if ((typeof is_rtl !== "undefined") && ( is_rtl !== null)) { 19741 $is_rtl = is_rtl=='1'?true:false; 19742 } 19743 $(this.$refs.owl_item_gallery).owlCarousel({ 19744 loop:false, 19745 margin:10, 19746 nav:false, 19747 dots:false, 19748 rtl : $is_rtl, 19749 responsive:{ 19750 0:{ 19751 items:1 19752 }, 19753 600:{ 19754 items:3 19755 }, 19756 1000:{ 19757 items:5 19758 } 19759 } 19760 }); 19761 }, 10); 19762 }, 19763 setImage(data){ 19764 this.image_featured = data; 19765 }, 19766 updateImage(){ 19767 updateLazyImage(); 19768 }, 19769 setItemSize(event){ 19770 var $size_id = event.currentTarget.firstElementChild.value; 19771 this.size_id = $size_id; 19772 this.getSizeData($size_id); 19773 }, // end setItemSize 19774 getSizeData($size_id){ 19775 19776 $new_item_addons = []; var $sub_items=[]; 19777 19778 if( !empty($global_item_addons[$size_id]) ){ 19779 $.each($global_item_addons[$size_id],function(key, item) { 19780 if(!empty($global_addons[$size_id])){ 19781 if(!empty($global_addons[$size_id][item])){ 19782 19783 $global_addons[$size_id][item].subcat_id 19784 $.each($global_addons[$size_id][item].sub_items,function(key2, item2) { 19785 $sub_items.push({ 19786 'sub_item_id':$global_addon_items[item2].sub_item_id, 19787 'sub_item_name':$global_addon_items[item2].sub_item_name, 19788 'item_description':$global_addon_items[item2].item_description, 19789 'price':$global_addon_items[item2].price, 19790 'pretty_price':$global_addon_items[item2].pretty_price, 19791 'checked':false, 19792 'disabled':false, 19793 'qty':1 19794 }); 19795 }); 19796 19797 $new_item_addons.push({ 19798 'subcat_id' : $global_addons[$size_id][item].subcat_id, 19799 'subcategory_name' : $global_addons[$size_id][item].subcategory_name, 19800 'subcategory_description' : $global_addons[$size_id][item].subcategory_description, 19801 'multi_option' : $global_addons[$size_id][item].multi_option, 19802 'multi_option_min' : $global_addons[$size_id][item].multi_option_min, 19803 'multi_option_value' : $global_addons[$size_id][item].multi_option_value, 19804 'require_addon' : $global_addons[$size_id][item].require_addon, 19805 'pre_selected' : $global_addons[$size_id][item].pre_selected, 19806 'sub_items_checked':'', 19807 'sub_items':$sub_items 19808 }); 19809 $sub_items = [] ; 19810 } 19811 } 19812 }); 19813 } 19814 19815 this.item_addons = $new_item_addons; 19816 this.item_addons_load = true; 19817 }, // end getSizeData 19818 19819 ItemSummary(data){ 19820 19821 $item_total = 0; 19822 var $required_addon = []; 19823 var $required_addon_added = []; 19824 let $min_addon = []; 19825 let $min_addon_added = []; 19826 19827 if(!empty(this.items.price)){ 19828 if(!empty(this.items.price[this.size_id])){ 19829 var item = this.items.price[this.size_id]; 19830 if( item.discount>0){ 19831 $item_total+=( this.item_qty * parseFloat(item.price_after_discount) ); 19832 } else $item_total+=( this.item_qty * parseFloat(item.price) ); 19833 } 19834 } 19835 19836 dump("item_total=>" + $item_total); 19837 19838 this.item_addons.forEach((item,index) => { 19839 19840 //dump("=>" + item.multi_option); 19841 if ( item.require_addon==1){ 19842 $required_addon.push(item.subcat_id); 19843 } 19844 19845 if(item.multi_option=="custom"){ 19846 var total_check = 0; 19847 let multi_option_min = item.multi_option_min; 19848 var multi_option_value = item.multi_option_value; 19849 var item_index=[]; var item_index2=[]; 19850 19851 if(multi_option_value>0){ 19852 $min_addon.push({ 19853 'subcat_id': item.subcat_id, 19854 'min':multi_option_min, 19855 'max':multi_option_value 19856 }); 19857 } 19858
19859 item.sub_items.forEach((item2,index2) => { 19860 if(item2.checked==true){ 19861 total_check++; 19862 $item_total+=( this.item_qty * parseFloat(item2.price) ); 19863 $required_addon_added.push( item.subcat_id ); 19864 } else item_index.push(index2); 19865 19866 if(item2.disabled==true){ 19867 item_index2.push(index2); 19868 } 19869 19870 }) 19871 19872 $min_addon_added[item.subcat_id] = { 19873 'total' : total_check 19874 }; 19875 19876 if(total_check>=multi_option_value){ 19877 item_index.forEach((item3,index3) => { 19878 this.item_addons[index].sub_items[item3].disabled = true; 19879 }); 19880 } else { 19881 item_index2.forEach((item3,index3) => { 19882 this.item_addons[index].sub_items[item3].disabled = false; 19883 }); 19884 } 19885 19886 } else if ( item.multi_option=="one" ){ 19887 item.sub_items.forEach((item2,index2) => { 19888 if( item2.sub_item_id == item.sub_items_checked ) { 19889 $item_total+=( this.item_qty * parseFloat(item2.price) ); 19890 $required_addon_added.push( item.subcat_id ); 19891 } 19892 }); 19893 } else if ( item.multi_option=="multiple" ){ 19894 19895 var item_index=[]; 19896 let multi_option_min = item.multi_option_min; 19897 var multi_option_value = item.multi_option_value; 19898 var limit = 0; 19899 19900 if(multi_option_value>0){ 19901 $min_addon.push({ 19902 'subcat_id': item.subcat_id, 19903 'min':multi_option_min, 19904 'max':multi_option_value 19905 }); 19906 } 19907 19908 item.sub_items.forEach((item2,index2) => { 19909 if(item2.checked==true){ 19910 $item_total+=( item2.qty * parseFloat(item2.price) ); 19911 $required_addon_added.push( item.subcat_id ); 19912 limit += item2.qty; 19913 } 19914 item_index.push(index2); 19915 }); 19916 19917 $min_addon_added[item.subcat_id] = { 19918 'total' : limit 19919 }; 19920 19921 this.item_addons[index].qty_selected =limit; 19922 if ( this.item_addons[index].qty_selected>= multi_option_value){ 19923 item_index.forEach((item3,index2) => { 19924 this.item_addons[index].sub_items[item3].disabled = true; 19925 }); 19926 } else { 19927 item_index.forEach((item3,index2) => { 19928 this.item_addons[index].sub_items[item3].disabled = false; 19929 }); 19930 } 19931 19932 19933 } /*endif custom*/ 19934 19935 });/* end loop*/ 19936 19937 19938 this.item_total = $item_total; 19939 19940 var $required_meet=true; 19941 if($required_addon.length>0){ 19942 $.each($required_addon, function(i, val){ 19943 if($required_addon_added.includes(val)===false){ 19944 $required_meet = false; 19945 return false; 19946 } 19947 }); 19948 } 19949 19950 // CHECK COOKING REF 19951 if(this.items.cooking_ref_required){ 19952 let $cooking_ref_check = false; 19953 if (Object.keys(this.meta.cooking_ref).length > 0) { 19954 Object.entries(this.meta.cooking_ref).forEach(([cooking_key, cooking_items]) => { 19955 if(cooking_items.checked){ 19956 $cooking_ref_check = true; 19957 } 19958 }); 19959 } 19960 if(!$cooking_ref_check){ 19961 $required_meet = false; 19962 } 19963 } 19964 19965 if (Object.keys($min_addon).length > 0) { 19966 let min_value,min_selected; 19967 Object.entries($min_addon).forEach(([key_min_addon, items_min_addon]) => { 19968 min_value = parseInt(items_min_addon.min); 19969 if($min_addon_added[items_min_addon.subcat_id]){ 19970 min_selected = parseInt($min_addon_added[items_min_addon.subcat_id].total); 19971 } 19972 if(min_selected>0){ 19973 if(min_value>min_selected){ 19974 $required_meet = false; 19975 } 19976 } 19977 }); 19978 } 19979 19980 if($required_meet){ 19981 this.disabled_cart = false; 19982 } else this.disabled_cart = true; 19983 19984 }, // end ItemSummary 19985 19986 CheckaddCartItems(){ 19987 this.addCartItems(); 19988 }, 19989 19990 addCartItems(event){ 19991 if (event) { 19992 event.preventDefault() 19993 } 19994 19995 this.add_to_cart = true; 19996 19997 var $params = { 19998 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 19999 'merchant_id' : this.items.merchant_id, 20000 'cat_id' : this.items.cat_id, 20001 'item_token': this.items.item_token, 20002 'item_size_id': this.size_id,
20003 'item_qty': this.item_qty, 20004 'item_addons': this.item_addons, 20005 'special_instructions': this.special_instructions, 20006 'meta' : this.meta, 20007 'cart_uuid':getCookie('cart_uuid'), 20008 'transaction_type': this.transaction_type , 20009 'if_sold_out' : this.if_sold_out, 20010 }; 20011 20012 var timenow = 1; 20013 $params = JSON.stringify($params); 20014 20015 ajax_request[timenow] = $.ajax({ 20016 url: ajaxurl+"/addCartItems", 20017 method: "PUT", 20018 dataType: "json", 20019 data: $params , 20020 contentType : $content_type.json , 20021 timeout: $timeout, 20022 crossDomain: true, 20023 beforeSend: function( xhr ) { 20024 if(ajax_request[timenow] != null) { 20025 ajax_request[timenow].abort(); 20026 } 20027 } 20028 }); 20029 20030 ajax_request[timenow].done( data => { 20031 if ( data.code==1){ 20032 $( this.$refs.modal_item_details ).modal('hide'); 20033 vue_cart.loadcart(); 20034 } 20035 }); 20036 20037 ajax_request[timenow].always( data => { 20038 this.add_to_cart = false; 20039 }); 20040 20041 } // end addCartItems 20042 // 20043 20044 }, 20045 template: '#item_suggestion', 20046}; 20047 20048/* 20049 ITEM SUGGESTION 20050 vue-item-suggestion 20051 vm_item_suggestion 20052*/ 20053const app_item_suggestion = Vue.createApp({ 20054 components: { 20055 'components-item-suggestion' : ComponentsItemSuggestion 20056 }, 20057 data(){ 20058 return { 20059 data : [] 20060 }; 20061 }, 20062}) 20063app_item_suggestion.use(ElementPlus); 20064const vm_item_suggestion = app_item_suggestion.mount('#vue-item-suggestion'); 20065 20066 20067/* 20068 CHANGE ADDRESS POPUP 20069 this is function for selecting checkout address 20070 target = 20071*/ 20072const app_addres_needed = Vue.createApp({ 20073 components: { 20074 'component-change-address': changeAddressComponent, 20075 'components-address-form' : ComponentsAddressForm, 20076 'components-select-address': ComponentsSelectAddress, 20077 }, 20078 data(){ 20079 return { 20080 addresses : [], 20081 address_needed : false, 20082 out_of_range : false, 20083 location_data : [], 20084 deliveryAddress : [], 20085 address_component : [] 20086 }; 20087 }, 20088 created() { 20089 this.addressNeeded(); 20090 }, 20091 methods: { 20092 addressNeeded(){ 20093 axios({ 20094 method: 'POST', 20095 url: ajaxurl + "/addressNeeded" , 20096 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&merchant_id="+ merchant_id + "&cart_uuid="+ getCookie('cart_uuid'), 20097 timeout: $timeout, 20098 }).then( response => { 20099 if(response.data.code==1){ 20100 this.address_needed = response.data.details.address_needed; 20101 } else { 20102 this.address_needed = false; 20103 } 20104 }).catch(error => { 20105 // 20106 }).then(data => { 20107 20108 }); 20109 }, 20110 show(){ 20111 this.$refs.address.showModal(); 20112 }, 20113 afterChangeAddress(data){ 20114 if(isGuest==='1'){ 20115 this.deliveryAddress = data; 20116 this.$refs.address_modal.visible = true; 20117 } else { 20118 dump('not guest'); 20119 this.location_data = data; 20120 } 20121 }, 20122 onSavelocation(data,addressData){ 20123 console.log('onSavelocation here1',data); 20124 this.$refs.address_form.setLoading(true); 20125 let params = { 20126 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 20127 'cart_uuid':getCookie('cart_uuid'), 20128 'data': data, 20129 'location_name' : addressData.location_name, 20130 'delivery_instructions' : addressData.delivery_instructions, 20131 'delivery_options' : addressData.delivery_options, 20132 'address_label' : addressData.address_label, 20133 'formatted_address' : addressData.formatted_address, 20134 'address1' : addressData.address1, 20135 'address2' : addressData.address2, 20136 'postal_code' : addressData.postal_code, 20137 'company' : addressData.company, 20138 }; 20139 axios({ 20140 method: 'PUT', 20141 url: ajaxurl+"/checkoutSaveAddress" , 20142 data : params, 20143 timeout: $timeout, 20144 }).then( response => { 20145 if(response.data.code==1){ 20146 setInLocalStorageStore(StoreMapName,"selectedAddress",data); 20147 this.address_needed = false; 20148 this.$refs.address_form.close(); 20149 this.refreshWidget(); 20150 } else { 20151 ElementPlus.ElNotification({ 20152 title: "", 20153 message: response.data.msg, 20154 position: 'bottom-right', 20155 type: 'warning', 20156 }); 20157 } 20158 }).catch(error => { 20159 ElementPlus.ElNotification({ 20160 title: "", 20161 message: error, 20162 position: 'bottom-right', 20163 type: 'warning', 20164 }); 20165 }).then(data => { 20166 this.$refs.address_form.setLoading(false); 20167 }); 20168 },
20169afterPointaddress(data){ 20170 console.log('afterPointaddress',data); 20171 // Include user's long-form description for storage 20172 if(data.userSelectedDescription){ 20173 setInLocalStorageStore(StoreMapName,"userSelectedDescription", data.userSelectedDescription); 20174 } 20175 setInLocalStorageStore(StoreMapName,"selectedAddress",data); 20176 20177 this.$refs.address_modal.setLoading(true); 20178 20179 // Build request params including the user's selected description 20180 let requestData = 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&place_id="+ data.place_id; 20181 if(data.userSelectedDescription){ 20182 requestData += "&user_description=" + encodeURIComponent(data.userSelectedDescription); 20183 } 20184 20185 axios({ 20186 method: 'POST', 20187 url: ajaxurl+"/setPlaceID" , 20188 data : requestData, 20189 timeout: $timeout, 20190 }).then( response => { 20191 this.address_needed = false; 20192 this.refreshWidget(); 20193 //this.$refs.address_modal.show(false); 20194 this.$refs.address_modal.visible = false; 20195 }).catch(error => { 20196 ElementPlus.ElNotification({ 20197 title: "", 20198 message: error, 20199 position: 'bottom-right', 20200 type: 'warning', 20201 }); 20202 }).then(data => { 20203 this.$refs.address_modal.setLoading(false); 20204 }); 20205 }, 20206 refreshWidget(){ 20207 if ((typeof vm_widget_nav !== "undefined") && ( vm_widget_nav !== null)) { 20208 //vm_widget_nav.afterChangeAddress(); 20209 vm_widget_nav.afterSetAddress(); 20210 } else { 20211 if ((typeof vm_merchant_details !== "undefined") && ( vm_merchant_details !== null)) { 20212 vm_merchant_details.$refs.ref_services.getMerchantServices(); 20213 } 20214 } 20215 }, 20216 afterChangeAddressOLD(data){ 20217 this.location_data = data; 20218 this.visible = false; 20219 this.$refs.address.closeModal(); 20220 if ((typeof vm_widget_nav !== "undefined") && ( vm_widget_nav !== null)) { 20221 vm_widget_nav.afterChangeAddress(); 20222 } 20223 20224 if ((typeof vm_merchant_details !== "undefined") && ( vm_merchant_details !== null)) { 20225 vm_merchant_details.$refs.ref_services.getMerchantServices(); 20226 } 20227 }, 20228 // 20229 }, 20230}); 20231app_addres_needed.use(ElementPlus); 20232const vm_addres_needed = app_addres_needed.mount('#vue-address-needed'); 20233 20234 20235 20236/* 20237 COMPONENTS ComponentsWebpushSettings 20238*/ 20239const ComponentsWebpushSettings = { 20240 template: '#xtemplate_webpushsettings', 20241 props: ['ajax_url','settings','iterest_list', 'message'], 20242 data(){ 20243 return { 20244 beams: undefined, 20245 is_loading : false, 20246 is_submitted : false, 20247 webpush_enabled : '', 20248 interest : [], 20249 device_id : '' 20250 }; 20251 }, 20252 mounted() { 20253 this.initBeam(); 20254 }, 20255 methods :{ 20256 initBeam(){ 20257 this.beams = new PusherPushNotifications.Client({ 20258 instanceId: this.settings.instance_id, 20259 }); 20260 20261 this.is_loading = true; 20262 axios({ 20263 method: 'POST', 20264 url: this.ajax_url+"/getwebnotifications" , 20265 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content'), 20266 timeout: $timeout, 20267 }).then( response => { 20268 if(response.data.code==1){ 20269 this.webpush_enabled = response.data.details.enabled==1?true:false; 20270 this.device_id = response.data.details.device_token; 20271 this.interest = response.data.details.interest; 20272 } else { 20273 this.webpush_enabled = false; 20274 this.device_id = ''; 20275 this.interest = []; 20276 } 20277 }).catch(error => { 20278 // 20279 }).then(data => { 20280 this.is_loading = false; 20281 }); 20282 20283 }, 20284 enabledWebPush(){ 20285 this.is_loading = true; 20286 if( this.webpush_enabled){ 20287 this.beams.start().then(() => { 20288 dump("start"); 20289 this.beams.getDeviceId().then( (device_id)=>{ 20290 this.device_id = device_id; 20291 }); 20292 }).catch(e => { 20293 notify( this.message.notification_start ,'error'); 20294 }).then(data => { 20295 this.is_loading = false; 20296 }); 20297 } else { 20298 this.beams.stop().then(() => { 20299 dump("stop"); 20300 this.device_id = ''; 20301 }).catch(e => { 20302 notify( this.message.notification_stop ,'error'); 20303 }).then(data => { 20304 this.is_loading = false; 20305 }); 20306 } 20307 }, 20308 saveWebNotifications(){ 20309 this.is_submitted = true; 20310 axios({ 20311 method: 'PUT', 20312 url: this.ajax_url+"/savewebnotifications" , 20313 data : { 20314 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 20315 'webpush_enabled' : this.webpush_enabled, 20316 'interest' : this.interest, 20317 'device_id' : this.device_id, 20318 }, 20319 timeout: $timeout, 20320 }).then( response => { 20321 if(response.data.code==1){ 20322 notify( response.data.msg); 20323 } else { 20324 notify( response.data.msg ,'error'); 20325 } 20326 }).catch(error => { 20327 // 20328 }).then(data => { 20329 this.is_submitted = false;
20330 }); 20331 20332 }, 20333 }, 20334}; 20335 20336 20337 20338/* 20339 PUSH SETTINGS 20340*/ 20341const app_webpushsettings = Vue.createApp({ 20342 components: { 20343 'components-web-pusher': ComponentsWebpushSettings, 20344 }, 20345}); 20346const vm_webpushsettings = app_webpushsettings.mount('#vue-webpush-settings'); 20347 20348 20349/* 20350 ALL NOTIFICATION LIST 20351*/ 20352const app_notification_list = Vue.createApp({ 20353 data(){ 20354 return { 20355 is_loading : false, 20356 data : [] , 20357 page: 0, 20358 show_next_page : false, 20359 }; 20360 }, 20361 mounted() { 20362 this.getData(this.page); 20363 }, 20364 computed: { 20365 hasData(){ 20366 if(this.data.length>0){ 20367 return true; 20368 } 20369 return false; 20370 }, 20371 isFirstLoad(){ 20372 if(this.is_loading && this.page<=0){ 20373 return true; 20374 } 20375 return false; 20376 }, 20377 }, 20378 methods: { 20379 getData(page){ 20380 this.is_loading = true; 20381 axios({ 20382 method: 'POST', 20383 url: ajaxurl +"/notificationList" , 20384 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&page=" + page , 20385 timeout: $timeout, 20386 }).then( response => { 20387 if(response.data.code==1){ 20388 //this.data = response.data.details.data; 20389 this.data.push(response.data.details.data); 20390 this.show_next_page = response.data.details.show_next_page; 20391 this.page = response.data.details.page; 20392 } else { 20393 this.data = []; 20394 } 20395 }).catch(error => { 20396 // 20397 }).then(data => { 20398 this.is_loading = false; 20399 }); 20400 } 20401 }, 20402}); 20403app_notification_list.use(ElementPlus); 20404const vm_notification_list = app_notification_list.mount('#vue-notifications-list'); 20405 20406 20407/* 20408 COMPONENTS PAYMENT LIST 20409*/ 20410const ComponentsPaymentList = { 20411 props: ['ajax_url' , 'label' ,'payment_type' ], 20412 data(){ 20413 return { 20414 data : [], 20415 is_loading : true, 20416 error_message : '' 20417 }; 20418 }, 20419 mounted() { 20420 this.getPaymentList(); 20421 }, 20422 computed: { 20423 hasData(){ 20424 if(this.data.length>0){ 20425 return true; 20426 } 20427 return false; 20428 }, 20429 }, 20430 methods: { 20431 getPaymentList(){ 20432 this.is_loading = true; 20433 axios({ 20434 method: 'POST', 20435 url: this.ajax_url + "/getPaymentList" , 20436 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&payment_type=" + this.payment_type, 20437 timeout: $timeout, 20438 }).then( response => { 20439 if(response.data.code==1){ 20440 this.data = response.data.details.data; 20441 this.error_message = ''; 20442 } else { 20443 this.data = []; 20444 this.error_message = response.data.msg; 20445 } 20446 }).catch(error => { 20447 // 20448 }).then(data => { 20449 this.is_loading = false; 20450 }); 20451 }, 20452 }, 20453 template: ` 20454 <DIV class="position-relative"> 20455 <div v-if="is_loading" class="loading cover-loader d-flex align-items-center justify-content-center"> 20456 <div> 20457 <div class="m-auto circle-loader medium" data-loader="circle-side"></div> 20458 </div> 20459 </div> 20460 20461 <h5 class="mb-3 mt-4">Add New Payment Method</h5> 20462 20463 <template v-if="!is_loading && hasData"> 20464 here 20465 <a v-for="items in data" @click="$emit('afterClickpayment',items.payment_code)" 20466 class="d-block chevron-section medium d-flex align-items-center rounded mb-2"> 20467 <div class="flexcol mr-2 payment-logo-wrap"> 20468 <i v-if="items.logo_type=='icon'" :class="items.logo_class"></i> 20469 <img v-else class="img-35" :src="items.logo_image" /> 20470 </div> 20471 <div class="flexcol"> 20472 <span class="mr-1">{{items.payment_name}}</span> 20473 </div> 20474 </a> 20475 </template> 20476 20477 <template v-if="!is_loading && !hasData"> 20478 <div class="alert alert-warning mb-2" role="alert"> 20479 <p class="m-0">{{error_message}}</p> 20480 </div> 20481 </template> 20482 20483 20484 </DIV> 20485 ` 20486}; 20487 20488 20489/* 20490 COMPONENTS SAVED PAYMENT LIST 20491*/ 20492const ComponentsMerchantSavedPayment = { 20493 props: ['ajax_url' , 'merchant_uuid' ], 20494 data(){ 20495 return { 20496 data : [], 20497 default_payment_uuid : '', 20498 is_loading : false, 20499 message : '' 20500 }; 20501 }, 20502 computed: { 20503 hasData(){ 20504 if(this.data.length>0){ 20505 return true; 20506 } 20507 return false;
20508 }, 20509 }, 20510 mounted() { 20511 this.MerchantSavedPayment(); 20512 }, 20513 methods: { 20514 MerchantSavedPayment(){ 20515 this.is_loading = true; 20516 axios({ 20517 method: 'POST', 20518 url: this.ajax_url + "/MerchantSavedPayment" , 20519 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&merchant_uuid=" + this.merchant_uuid , 20520 timeout: $timeout, 20521 }).then( response => { 20522 if(response.data.code==1){ 20523 this.data = response.data.details.data; 20524 this.default_payment_uuid = response.data.details.default_payment_uuid; 20525 this.$emit('setDefaultpayment',response.data.details.default_payment); 20526 } else { 20527 this.data = []; 20528 this.message = response.data.msg; 20529 } 20530 }).catch(error => { 20531 // 20532 }).then(data => { 20533 this.is_loading = false; 20534 }); 20535 }, 20536 setDefaultPayment(data){ 20537 axios({ 20538 method: 'POST', 20539 url: this.ajax_url + "/MerchantsetDefaultPayment" , 20540 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&payment_uuid=" + data.payment_uuid , 20541 timeout: $timeout, 20542 }).then( response => { 20543 if(response.data.code==1){ 20544 this.MerchantSavedPayment(); 20545 } else { 20546 notify( response.data.msg ,'error'); 20547 } 20548 }).catch(error => { 20549 // 20550 }).then(data => { 20551 20552 }); 20553 }, 20554 deleteSavedPaymentMethod(data){ 20555 axios({ 20556 method: 'POST', 20557 url: this.ajax_url + "/MerchantDeleteSavedPaymentMethod" , 20558 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&payment_uuid=" + data.payment_uuid , 20559 timeout: $timeout, 20560 }).then( response => { 20561 if(response.data.code==1){ 20562 this.MerchantSavedPayment(); 20563 } else { 20564 notify( response.data.msg ,'error'); 20565 } 20566 }).catch(error => { 20567 // 20568 }).then(data => { 20569 20570 }); 20571 }, 20572 }, 20573 template: ` 20574 <DIV class="position-relative"> 20575 20576 <div v-if="is_loading" class="loading cover-loader d-flex align-items-center justify-content-center"> 20577 <div> 20578 <div class="m-auto circle-loader medium" data-loader="circle-side"></div> 20579 </div> 20580 </div> 20581 20582 <template v-if="hasData"> 20583 <h5 class="mb-3">Saved Payment Methods</h5> 20584 20585 <div v-for="saved_payment in data" class="row no-gutters align-items-center chevron-section medium rounded mb-2" :class="{ selected: saved_payment.as_default==1 }" > 20586 20587 <div class="col-md-8 d-flex align-items-center"> 20588 <div class="flexcol mr-2 payment-logo-wrap"> 20589 <i v-if="saved_payment.logo_type=='icon'" :class="saved_payment.logo_class"></i> 20590 <img v-else class="img-35" :src="saved_payment.logo_image" /> 20591 </div> <!--flex-col--> 20592 <div class="flexcol" > 20593 <span class=" mr-1">{{saved_payment.attr1}}</span> 20594 <p class="m-0 text-muted">{{saved_payment.attr2}}</p> 20595 </div> 20596 </div> <!--col--> 20597 <div class="col-md-4 d-flex align-items-center justify-content-end"> 20598 20599 <template v-if="saved_payment.as_default==1"> 20600 <div class="mr-1"><i class="zmdi zmdi-check text-success"></i></div> 20601 <div class="mr-3"><p class="m-0">Default</p></div> 20602 </template> 20603 20604 <div class="dropdown"> 20605 <a href="javascript:;" class="rounded-pill rounded-button-icon d-inline-block" 20606 id="dropdownMenuLink" data-toggle="dropdown" > 20607 <i class="zmdi zmdi-more" style="font-size: inherit;"></i> 20608 </a> 20609 <div class="dropdown-menu" aria-labelledby="dropdownMenuLink"> 20610 <a v-if="saved_payment.as_default!=1" 20611 @click="setDefaultPayment(saved_payment)" 20612 class="dropdown-item a-12" href="javascript:;">Set Default</a> 20613 <a @click="deleteSavedPaymentMethod(saved_payment)" class="dropdown-item a-12" href="javascript:;"> 20614 Delete 20615 </a> 20616 </div> 20617 </div> <!--dropdown--> 20618 20619 </div> <!--col--> 20620 </div> <!--row--> 20621 </template> 20622 </DIV> 20623 ` 20624}; 20625 20626 20627/*
20628 CASH IN PAYMENT 20629*/ 20630const ComponentsCashinPayment = { 20631 props: ['ajax_url' ,'amount' , 'label' ,'default_payment' , 'merchant_uuid' ], 20632 data(){ 20633 return { 20634 data : [], 20635 is_loading : false, 20636 }; 20637 }, 20638 computed: { 20639 ValidAmount(){ 20640 if(this.amount<=0){ 20641 return true; 20642 } 20643 if(empty(this.default_payment.payment_uuid)){ 20644 return true; 20645 } 20646 return false; 20647 }, 20648 }, 20649 mounted() { 20650 dump(this.amount); 20651 }, 20652 methods: { 20653 DoCashin(){ 20654 20655 bootbox.confirm({ 20656 size: "small", 20657 title : this.label.confirm , 20658 message: this.label.are_you_sure, 20659 centerVertical: true, 20660 animate: false, 20661 buttons: { 20662 cancel: { 20663 label: this.label.cancel, 20664 className: 'btn btn-black small pl-4 pr-4' 20665 }, 20666 confirm: { 20667 label: this.label.yes, 20668 className: 'btn btn-green small pl-4 pr-4' 20669 }, 20670 }, 20671 callback: result => { 20672 if(result){ 20673 var data = { 20674 'payment_uuid' : this.default_payment.payment_uuid, 20675 'payment_code' : this.default_payment.payment_code, 20676 'merchant_uuid' : this.merchant_uuid, 20677 'amount' : this.amount, 20678 }; 20679 try { 20680 vm_cashin.$refs[ this.default_payment.payment_code ].DoPaymentRender( data ,'PaymentIntentCashin' ); 20681 } catch(err) { 20682 notify(err.message,'error'); 20683 } 20684 } 20685 } 20686 }); 20687 }, 20688 }, 20689 template: ` 20690 <button class="btn btn-green w-100 pointer mt-3" 20691 :disabled="ValidAmount" 20692 @click="DoCashin" 20693 > 20694 <span class="label">{{label.continue}}</span> 20695 <div class="m-auto circle-loader" data-loader="circle-side"></div> 20696 </button> 20697 ` 20698}; 20699 20700 20701/* 20702 CASHIN 20703*/ 20704const app_cashin = Vue.createApp({ 20705 data(){ 20706 return { 20707 data : [], 20708 default_payment : '' 20709 }; 20710 }, 20711 mounted() { 20712 dump(this.amount_cashin); 20713 }, 20714 methods: { 20715 afterClickpayment(payment_code){ 20716 try { 20717 this.$refs[payment_code].showPaymentForm(); 20718 } catch(err) { 20719 notify(err.message,'error'); 20720 } 20721 }, 20722 SavedPaymentList(){ 20723 this.$refs.merchant_saved_payment.MerchantSavedPayment(); 20724 }, 20725 setDefaultpayment(data){ 20726 this.default_payment = data; 20727 }, 20728 showLoadingBox(message){ 20729 if(!empty(message)){ 20730 vm_loading.$refs.box.setMessage(message); 20731 } 20732 vm_loading.$refs.box.show(); 20733 }, 20734 closeLoadingBox(){ 20735 vm_loading.$refs.box.close(); 20736 }, 20737 Alert(message){ 20738 notify(message,'error'); 20739 }, 20740 }, 20741}); 20742app_cashin.component('components-payment-list', ComponentsPaymentList ); 20743app_cashin.component('components-merchant-saved-payment', ComponentsMerchantSavedPayment ); 20744app_cashin.component('components-cashin-payment', ComponentsCashinPayment ); 20745if ((typeof components_bundle !== "undefined") && ( components_bundle !== null)) { 20746 $.each(components_bundle,function(components_name, components_value) { 20747 app_cashin.component(components_name, components_value ); 20748 }); 20749} 20750const vm_cashin = app_cashin.mount('#vue-cashin'); 20751 20752 20753/* 20754 CAROUSEL RESTAURANT 20755*/ 20756const vm_carousel = Vue.createApp({ 20757 components: { 20758 'component-carousel' : ComponentsCarousel, 20759 }, 20760}).mount('#vue-carousel'); 20761 20762 20763const ComponentsProfileMenu = { 20764 props: ['data','index_selected'], 20765 data(){ 20766 return { 20767 owl : undefined, 20768 }; 20769 }, 20770 mounted() { 20771 setTimeout(() => { 20772 this.renderCarousel(); 20773 }, 1); 20774 }, 20775 methods: { 20776 renderCarousel(){ 20777 let $is_rtl = false; 20778 if ((typeof is_rtl !== "undefined") && ( is_rtl !== null)) { 20779 $is_rtl = is_rtl=='1'?true:false; 20780 } 20781 this.owl = $(this.$refs.menu).owlCarousel({ 20782 loop:false, 20783 dots:false, 20784 nav:false, 20785 autoWidth:true, 20786 rtl : $is_rtl 20787 }); 20788 }, 20789 }, 20790 template : ` 20791 <div ref="menu" class="owl-carousel owl-theme menu-carousel"> 20792 <div v-for="(item, index) in data" class="mr-2"> 20793 <a :href="item.url" class="d-block" 20794 :class="{active : index==index_selected }" 20795 > 20796 {{item.label}} 20797 </a> 20798 </div> 20799 </div> 20800 ` 20801}; 20802const vm_profile_menu = Vue.createApp({ 20803 components: { 20804 'component-profile-menu' : ComponentsProfileMenu, 20805 }, 20806}).mount('#vue-profile-menu'); 20807 20808const vm_captcha = Vue.createApp({ 20809 data() { 20810 return { 20811 recaptcha_response : '' 20812 } 20813 }, 20814 components: { 20815 'components-recapcha' : componentsRecaptcha, 20816 }, 20817 methods: { 20818 recaptchaVerified(response) { 20819 this.recaptcha_response = response; 20820 }, 20821 recaptchaExpired() { 20822 if( this.$refs.vueRecaptcha.is_enabled ){ 20823 this.$refs.vueRecaptcha.reset(); 20824 } 20825 }, 20826 recaptchaFailed() { 20827 20828 }, 20829 }, 20830}).mount('#vue-captcha'); 20831 20832 20833/** 20834 GUEST REGISTRATION 20835 target = vue-guest-register 20836*/ 20837const app_guest_register = Vue.createApp({ 20838 components: { 20839 'component-phone' : ComponentsPhoneNumber,
20840 'vue-recaptcha' : componentsRecaptcha, 20841 }, 20842 data(){ 20843 return { 20844 loading : false, 20845 ready : false, 20846 show_password : false, 20847 agree_terms : false, 20848 password_type: 'password', 20849 firstname : '', 20850 lastname : '', 20851 email_address : '', 20852 mobile_number : '', 20853 mobile_prefix :'', 20854 password : '', 20855 cpassword :'', 20856 mobile_prefixes : [], 20857 error : [], 20858 success : '', 20859 redirect : '', 20860 next_url : '', 20861 recaptcha_response : '', 20862 show_recaptcha : false, 20863 }; 20864 }, 20865 mounted () { 20866 dump("mounted"); 20867 this.redirect = redirect_to; 20868 this.next_url = next_url; 20869 if ((typeof _capcha !== "undefined") && ( _capcha !== null)) { 20870 this.show_recaptcha = _capcha==1?true:false; 20871 } 20872 }, 20873 updated () { 20874 this.validate(); 20875 }, 20876 methods: { 20877 validate(){ 20878 if( !empty(this.firstname) && !empty(this.lastname) && !empty(this.mobile_number) ){ 20879 this.ready = true; 20880 } else this.ready = false; 20881 }, 20882 showPassword() 20883 { 20884 this.show_password = this.show_password==true?false:true; 20885 if(this.show_password){ 20886 this.password_type = 'text'; 20887 } else this.password_type = 'password'; 20888 }, 20889 onRegister(){ 20890 20891 var timenow = getTimeNow(); 20892 var $params = { 20893 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 20894 'firstname' : this.firstname, 20895 'lastname' : this.lastname, 20896 'email_address' : this.email_address, 20897 'mobile_number' : this.mobile_number, 20898 'mobile_prefix': this.mobile_prefix, 20899 'password': this.password, 20900 'cpassword': this.cpassword, 20901 'redirect': this.redirect, 20902 'recaptcha_response': this.recaptcha_response, 20903 }; 20904 20905 ajax_request[timenow] = $.ajax({ 20906 url: ajaxurl+"/registerGuestUser", 20907 method: "PUT", 20908 dataType: "json", 20909 data: JSON.stringify($params) , 20910 contentType : $content_type.json , 20911 timeout: $timeout, 20912 crossDomain: true, 20913 beforeSend: data => { 20914 this.loading = true; 20915 this.error = []; 20916 this.success = ''; 20917 if(ajax_request[timenow] != null) { 20918 ajax_request[timenow].abort(); 20919 } 20920 } 20921 }); 20922 20923 ajax_request[timenow].done( data => { 20924 if ( data.code==1){ 20925 this.success = data.msg; 20926 window.location.href = data.details.redirect; 20927 } else { 20928 this.error = data.msg; 20929 this.recaptchaExpired(); 20930 } 20931 }); // ajax done 20932 20933 ajax_request[timenow].always( data => { 20934 this.loading = false; 20935 }); 20936 20937 }, 20938 recaptchaVerified(response) { 20939 this.recaptcha_response = response; 20940 }, 20941 recaptchaExpired() { 20942 if ( this.show_recaptcha){ 20943 this.$refs.vueRecaptcha.reset(); 20944 } 20945 }, 20946 recaptchaFailed() { 20947 20948 }, 20949 20950 }, 20951}); 20952app_guest_register.use(Maska); 20953const vm_guest_register = app_guest_register.mount('#vue-guest-register'); 20954 20955 20956// START NEW JS 1.0.8 20957const app_delivery_details = Vue.createApp({ 20958 components: { 20959 'components-maps' : ComponentsMaps, 20960 'components-select-address': ComponentsSelectAddress, 20961 'components-saveaddress' : ComponentsSavedAddress 20962 }, 20963 data() { 20964 return { 20965 loading : false, 20966 loading_save : false, 20967 data :[], 20968 address1 : '', 20969 location_name : '', 20970 delivery_options :'Hand it to me', 20971 delivery_instructions :'', 20972 address_label :'Home', 20973 markers : [], 20974 address_data : [], 20975 address_found : false, 20976 address_uuid : '', 20977 isEdit : false, 20978 isAdd : false, 20979 formatted_address : '', 20980 save_address_data : [], 20981 default_address : [], 20982 count_address : 0, 20983 address_needed : true, 20984 address_label_list : [], 20985 address2 : '', 20986 postal_code : '', 20987 company : '', 20988 custom_field1 : '', 20989 custom_field2 : '', 20990 formattedAddress :'', 20991 silent_detect_enabled : false 20992 } 20993 }, 20994 created() { 20995 // Read the PHP-injected JS variable set by AccountController 20996 if ((typeof silent_address_detection !== 'undefined') && silent_address_detection && silent_address_detection !== 'false') { 20997 this.silent_detect_enabled = true; 20998 } 20999 this.addressNeeded(); 21000 }, 21001 computed: { 21002 hasDeliveryAddress(){ 21003 if (Object.keys(this.address_data).length > 0) { 21004 return true; 21005 } 21006 return false;
21007 }, 21008 deliveryAddress(){ 21009 return this.address_data; 21010 }, 21011 hasSavedAddress(){ 21012 return this.address_found; 21013 }, 21014 hasAddressList(){ 21015 return this.count_address>0?true:false; 21016 }, 21017 isAddressNeeded(){ 21018 return this.address_needed; 21019 }, 21020 getAddressLabel(){ 21021 return this.address_label_list; 21022 } 21023 }, 21024 watch: { 21025 address_data(newval,oldval){ 21026 this.setMarker(newval.latitude,newval.longitude); 21027 }, 21028 }, 21029 methods: { 21030 addressNeeded(){ 21031 this.loading = true; 21032 axios({ 21033 method: 'POST', 21034 url: ajaxurl + "/checkoutAddressNeeded" , 21035 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&merchant_id="+ merchant_id + "&cart_uuid="+ getCookie('cart_uuid'), 21036 timeout: $timeout, 21037 }).then( response => { 21038 if(response.data.code==1){ 21039 this.address_needed = response.data.details.address_needed; 21040 this.getAddress(); 21041 } else { 21042 this.address_needed = false; 21043 } 21044 }).catch(error => { 21045 // 21046 }).then(data => { 21047 this.loading = false; 21048 }); 21049 }, 21050 setMarker(lat,lng){ 21051 this.markers = [ 21052 { 21053 id: 0, 21054 lat: parseFloat(lat), 21055 lng: parseFloat(lng), 21056 draggable: false, 21057 } 21058 ]; 21059 }, 21060 afterClosemodal(provider){ 21061 console.debug("afterClosemodal xx",provider); 21062 if(provider=="yandex"){ 21063 if(yandex_map){ 21064 yandex_map.destroy(); 21065 yandex_map = null; 21066 } 21067 this.$refs.maps.renderMap(); 21068 } 21069 }, 21070 getAddress(){ 21071 this.loading = true; 21072 axios({ 21073 method: 'POST', 21074 url: ajaxurl+"/getAddressDetails" , 21075 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content'), 21076 timeout: $timeout, 21077 }).then( response => { 21078 if(response.data.code==1){ 21079 this.data = response.data.details; 21080 this.address_found = response.data.details.address_found; 21081 this.address_data = response.data.details.data; 21082 this.default_address = this.address_data; 21083 this.save_address_data = this.address_data; 21084 this.address_uuid = response.data.details.data.address_uuid; 21085 this.count_address = response.data.details.count_address; 21086 this.address_label_list = response.data.details.address_label; 21087 // Check localStorage for user's selected long-form description 21088 let storedDescription = getFromLocalStorageStore(StoreMapName, "userSelectedDescription"); 21089 let rawAddress = storedDescription 21090 ?? this.address_data?.address?.formattedAddress 21091 ?? this.address_data?.address?.formatted_address; 21092 // Get postcode from address data to append if missing 21093 const postcode = this.address_data?.address?.postal_code || ''; 21094 // Remove UK and ensure postcode is at end 21095 this.formattedAddress = reorderAddressPostcode(rawAddress, postcode); 21096 } else { 21097 this.data = response.data.details; 21098 this.address_data = response.data.details.data; 21099 this.default_address = this.address_data; 21100 this.save_address_data = ''; 21101 this.formatted_address = this.address_data?.parsed_address?.street_name; 21102 this.address1 = this.address_data?.parsed_address?.street_number; 21103 // Remove UK and ensure postcode is at end 21104 let rawAddr = this.address_data?.parsed_address?.formatted_address ?? this.formatted_address; 21105 // Get postcode from address data to append if missing 21106 const defaultPostcode = this.address_data?.address?.postal_code || this.address_data?.parsed_address?.postal_code || ''; 21107 this.formattedAddress = reorderAddressPostcode(rawAddr, defaultPostcode); 21108 21109 this.address_found = response.data.details.address_found; 21110 this.count_address = response.data.details.count_address; 21111 this.address_label_list = response.data.details.address_label; 21112 21113 // No saved address found â try to detect the customer's real location 21114 this.autoDetectLocation(); 21115 } 21116 21117 if (Object.keys(this.data).length > 0) { 21118 if(!empty(this.data.custom_field1_data)){ 21119 this.custom_field1 = Object.keys(this.data.custom_field1_data)[0]; 21120 } 21121 } 21122 21123 }).catch(error => { 21124 // 21125 }).then(data => { 21126 this.loading = false;
21127 }); 21128 }, 21129 /** 21130 * Automatically detect the customer's current location using the browser 21131 * Geolocation API. Only runs when the admin has enabled auto-detect and 21132 * when the customer has no saved address yet (new signup flow). 21133 * 21134 * On success â shows a confirmation dialog, then pre-fills address fields. 21135 * On denial â silently falls back to the default map location. 21136 */ 21137 autoDetectLocation() { 21138 // Respect the admin "Silent Address Detection" toggle 21139 if ( 21140 (typeof silent_address_detection === 'undefined') || 21141 !silent_address_detection || 21142 silent_address_detection == 'false' 21143 ) { 21144 return; 21145 } 21146 21147 if (!navigator.geolocation) { 21148 return; 21149 } 21150 21151 navigator.geolocation.getCurrentPosition( 21152 (position) => { 21153 const lat = position.coords.latitude; 21154 const lng = position.coords.longitude; 21155 21156 axios({ 21157 method: 'POST', 21158 url: ajaxurl + "/reverseGeocoding", 21159 data: 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&lat=" + lat + "&lng=" + lng, 21160 timeout: $timeout, 21161 }).then(response => { 21162 if (response.data.code == 1) { 21163 const geodata = response.data.details.data; 21164 21165 // Directly update map and address fields â no confirmation step needed 21166 this.address_data = geodata; 21167 this.default_address = geodata; 21168 // Set Google's formatted address (read-only display) 21169 // Use long-form address (formattedAddress has long street names like "Ravey Street") 21170 // Fall back to parsed_address.formatted_address_long, then formatted_address 21171 let rawAddress = geodata?.address?.formattedAddress 21172 ?? geodata?.parsed_address?.formatted_address_long 21173 ?? geodata?.parsed_address?.formatted_address 21174 ?? geodata?.address?.formatted_address 21175 ?? ''; 21176 // Get postcode from geodata to append if missing 21177 const geoPostcode = geodata?.address?.postal_code || geodata?.parsed_address?.postal_code || ''; 21178 this.formattedAddress = reorderAddressPostcode(rawAddress, geoPostcode); 21179 // Clear user addition fields for new address 21180 this.address1 = ''; // User can add their Flat or Number 21181 this.formatted_address = ''; // Not used in new approach 21182 this.location_name = ''; // User can add apartment/floor 21183 } 21184 }).catch(() => { 21185 // Reverse geocoding failed â silently keep default map 21186 }); 21187 }, 21188 (error) => { 21189 // Show a localized, user-friendly message for each error type 21190 const $sw = JSON.parse(some_words); 21191 let msg; 21192 switch (error.code) { 21193 case error.PERMISSION_DENIED: 21194 msg = $sw.location_permission_denied; 21195 break; 21196 case error.POSITION_UNAVAILABLE: 21197 msg = $sw.location_position_unavailable; 21198 break; 21199 case error.TIMEOUT: 21200 msg = $sw.location_requesttimeout; 21201 break; 21202 default: 21203 msg = $sw.location_uknown; 21204 } 21205 ElementPlus.ElNotification({ 21206 title: "", 21207 message: msg, 21208 position: 'bottom-right', 21209 type: 'warning', 21210 }); 21211 }, 21212 {
21213 enableHighAccuracy: false, 21214 timeout: 8000, 21215 maximumAge: 300000, // re-use cached position for up to 5 minutes 21216 } 21217 ); 21218 }, 21219 saveAddress(){ 21220 confirmIncompleteAddressSave({ 21221 formattedAddress: this.formattedAddress, 21222 address1: this.address1, 21223 location_name: this.location_name 21224 }, () => { 21225 const visiblePostcode = visibleUkPostcode({ 21226 formattedAddress: this.formattedAddress, 21227 address1: this.address1, 21228 location_name: this.location_name 21229 }); 21230 this.postal_code = visiblePostcode; 21231 if (this.address_data) { 21232 if (!this.address_data.address) { 21233 this.address_data.address = {}; 21234 } 21235 this.address_data.address.postal_code = visiblePostcode; 21236 if (this.address_data.parsed_address) { 21237 this.address_data.parsed_address.postal_code = visiblePostcode; 21238 } 21239 } 21240 this.loading_save = true; 21241 axios({ 21242 method: 'PUT', 21243 url: ajaxurl+"/SaveAddress" , 21244 data : { 21245 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 21246 'address_uuid': this.address_uuid, 21247 'location_name' : this.location_name, 21248 'delivery_instructions' : this.delivery_instructions, 21249 'delivery_options' : this.delivery_options, 21250 'address_label' : this.address_label, 21251 'latitude' : this.address_data.latitude, 21252 'longitude' : this.address_data.longitude, 21253 'address1' : this.address1, 21254 'formatted_address' : this.formatted_address, 21255 'formattedAddress' : this.formattedAddress, 21256 'set_place_id' : this.address_data.place_id, 21257 'data': this.address_data, 21258 'address2' : this.address2, 21259 'postal_code' : this.postal_code, 21260 'company' : this.company, 21261 'custom_field1':this.custom_field1, 21262 'custom_field2':this.custom_field2, 21263 }, 21264 timeout: $timeout, 21265 }).then( response => { 21266 if(response.data.code==1){ 21267 if(yandex_map){ 21268 yandex_map.destroy(); 21269 yandex_map = null; 21270 } 21271 ElementPlus.ElNotification({ 21272 title: "", 21273 message: response.data.msg, 21274 position: 'bottom-right', 21275 type: 'success', 21276 }); 21277 if ((typeof redirect_to !== 'undefined') && (redirect_to !== null)) { 21278 window.location.href = redirect_to; 21279 } else { 21280 this.isEdit = false; 21281 this.isAdd = false; 21282 this.getAddress(); 21283 this.$refs.save_address.getSavedAddress(); 21284 if ((typeof vue_cart !== "undefined") && ( vue_cart !== null)) { 21285 vue_cart.loadcart(); 21286 } 21287 } 21288 } else { 21289 ElementPlus.ElNotification({ 21290 title: "", 21291 message: response.data.msg, 21292 position: 'bottom-right', 21293 type: 'warning', 21294 }); 21295 } 21296 }).catch(error => { 21297 // 21298 }).then(data => { 21299 this.loading_save = false; 21300 }); 21301 }); 21302 }, 21303 showSelectAddress(){ 21304 dump("showSelectAddress"); 21305 this.$refs.address_modal.setInitialMarker(); 21306 this.$refs.address_modal.visible = true; 21307 }, 21308 afterChangeaddress(data){ 21309 console.debug("afterChangeaddress xx1",data); 21310 21311 if(yandex_map){ 21312 yandex_map.destroy(); 21313 yandex_map = null; 21314 } 21315 this.address_data = data; 21316 21317 // Set Google's formatted address (read-only display) 21318 // Use user's selected long-form description if available 21319 // Apply reorderAddressPostcode to remove UK and ensure postcode is at end 21320 let rawAddress = data?.userSelectedDescription 21321 ?? this.address_data?.parsed_address?.formatted_address 21322 ?? this.address_data?.address?.formattedAddress 21323 ?? ''; 21324 // Get postcode from address data to append if missing 21325 const postcode = this.address_data?.address?.postal_code || this.address_data?.parsed_address?.postal_code || ''; 21326 this.formattedAddress = reorderAddressPostcode(rawAddress, postcode); 21327 // Clear user addition fields - user can enter Flat/Unit and Apartment 21328 this.address1 = ''; 21329 this.formatted_address = ''; 21330 this.location_name = ''; 21331 21332 // if ((typeof data.parsed_address !== "undefined") && ( data.parsed_address !== null)) { 21333 // if(!empty(data.parsed_address.street_name)){ 21334 // this.formatted_address = data.parsed_address.street_name; 21335 // this.address1 = data.parsed_address.street_number; 21336 // } else { 21337 // this.formatted_address = this.address_data.address.formatted_address; 21338 // this.address1 = this.address_data.address.address1; 21339 // } 21340 // } else { 21341 // this.formatted_address = this.address_data.address.formatted_address; 21342 // this.address1 = this.address_data.address.address1; 21343 // } 21344 21345 this.$refs.address_modal.visible = false;
21346 }, 21347 editSaveAddress(){ 21348 this.isEdit = true; 21349 this.address_data = this.save_address_data; 21350 this.address_uuid = this.save_address_data.address_uuid; 21351 21352 this.formatted_address = this.address_data.address.formatted_address; 21353 this.address1 = this.address_data.address.address1; 21354 this.location_name = this.address_data.attributes.location_name; 21355 this.delivery_options = this.address_data.attributes.delivery_options; 21356 this.delivery_instructions = this.address_data.attributes.delivery_instructions; 21357 this.address_label = this.address_data.attributes.address_label; 21358 21359 this.address2 = this.address_data.address.address2; 21360 this.postal_code = this.address_data.address.postal_code; 21361 this.company = this.address_data.address.company; 21362 // Preserve Google Maps formattedAddress when editing, fallback to formatted_address for old addresses 21363 // Remove UK and ensure postcode is at end 21364 let editRawAddress = this.address_data.address.formattedAddress || this.address_data.address.formatted_address || ''; 21365 this.formattedAddress = reorderAddressPostcode(editRawAddress); 21366 21367 this.custom_field1 = this.address_data.attributes.custom_field1; 21368 this.custom_field2 = this.address_data.attributes.custom_field2; 21369 }, 21370 CancelEdit(){ 21371 if(yandex_map){ 21372 yandex_map.destroy(); 21373 yandex_map = null; 21374 } 21375 21376 this.isEdit = false; 21377 this.address_data = this.default_address; 21378 this.formatted_address = ''; 21379 this.address1 = ''; 21380 this.location_name = ''; 21381 this.delivery_options = ''; 21382 this.delivery_instructions = ''; 21383 this.address_label = ''; 21384 this.address2 = ''; 21385 this.postal_code = ''; 21386 this.company = ''; 21387 }, 21388 AddNewAddress(){ 21389 this.isAdd = true; 21390 this.address_data = this.default_address; 21391 this.formatted_address = this.address_data.address.formatted_address; 21392 this.address1 = this.address_data.address.address1; 21393 this.address_uuid = ''; 21394 this.location_name = ''; 21395 this.delivery_instructions = ''; 21396 this.address2 = ''; 21397 this.postal_code = ''; 21398 this.company = ''; 21399 }, 21400 CanceAdd(){ 21401 console.log('CanceAdd'); 21402 this.isAdd = false; 21403 this.address_data = this.default_address; 21404 }, 21405 /** 21406 * Called when user manually edits the delivery address field 21407 * Clears the Flat/Number field to prevent duplication 21408 */ 21409 onAddressEdited(){ 21410 // Clear Flat/Number field when user edits the main address 21411 // This prevents duplication if user adds door number to main address 21412 this.address1 = ''; 21413 }, 21414 afterSelectaddress(data){ 21415 this.setPlaceID(data.place_id); 21416 this.address_found = true; 21417 this.save_address_data = data; 21418 this.address_data = this.save_address_data; 21419 this.address_uuid = this.save_address_data.address_uuid; 21420 21421 this.formatted_address = this.address_data.address.formatted_address; 21422 this.address1 = this.address_data.address.address1; 21423 this.location_name = this.address_data.attributes.location_name; 21424 this.delivery_options = this.address_data.attributes.delivery_options; 21425 this.delivery_instructions = this.address_data.attributes.delivery_instructions; 21426 this.address_label = this.address_data.attributes.address_label; 21427 }, 21428 setPlaceID(place_id){ 21429 axios({ 21430 method: 'POST', 21431 url: ajaxurl+"/setPlaceID" , 21432 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&place_id="+ place_id , 21433 timeout: $timeout, 21434 }).then( response => { 21435 if ((typeof vue_cart !== "undefined") && ( vue_c
21435art !== null)) { 21436 vue_cart.loadcart(); 21437 } 21438 }).catch(error => { 21439 // 21440 }).then(data => { 21441 21442 }); 21443 }, 21444 confirmDelete(address_uuid){ 21445 21446 let $some_words = JSON.parse(some_words); 21447 21448 ElementPlus.ElMessageBox.confirm( 21449 $some_words.confirm_delete_address, 21450 $some_words.delete, 21451 { 21452 confirmButtonText: $some_words.delete_adress, 21453 cancelButtonText: $some_words.cancel, 21454 type: 'info', 21455 } 21456 ) 21457 .then(() => { 21458 this.deleteAddress(address_uuid); 21459 }) 21460 .catch(() => { 21461 // 21462 }); 21463 }, 21464 deleteAddress(address_uuid){ 21465 axios({ 21466 method: 'POST', 21467 url: ajaxurl+"/deleteAddress" , 21468 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&address_uuid="+ address_uuid , 21469 timeout: $timeout, 21470 }).then( response => { 21471 this.getAddress(); 21472 this.$refs.save_address.getSavedAddress(); 21473 }).catch(error => { 21474 // 21475 }).then(data => { 21476 21477 }); 21478 } 21479 // 21480 }, 21481}); 21482app_delivery_details.use(ElementPlus); 21483// Exposed on window so that external scripts (e.g. checkout.php wallet 21484// validation) can inspect whether a delivery address has been confirmed. 21485window.vm_delivery_details = app_delivery_details.mount('#vm_delivery_details'); 21486 21487 21488const app_home_search = Vue.createApp({ 21489 components: { 21490 'component-auto-complete' : ComponentsAutoCompleteAdress, 21491 'components-select-address': ComponentsSelectAddress, 21492 'components-address-form' : ComponentsAddressForm, 21493 }, 21494 data() { 21495 return { 21496 deliveryAddress : [], 21497 location_data : [] 21498 } 21499 }, 21500 methods: { 21501 afterChoose(data){ 21502 console.log("afterChoosexx",data); 21503 const provider = data?.provider ?? null; 21504 console.log("provider",provider); 21505 let placeID = data.id; 21506 if(provider=='mapbox'){ 21507 placeID = `${data?.longitude},${data?.latitude}` 21508 } 21509 this.$refs.auto_complete.setLoading(true); 21510 axios({ 21511 method: 'POST', 21512 url: ajaxurl+"/getLocationDetails" , 21513 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&id="+ placeID + "&saveplace=0" + "&description="+data.description, 21514 timeout: $timeout, 21515 }).then( response => { 21516 if(response.data.code==1){ 21517 this.$refs.auto_complete.setAddressData(response.data.details.data); 21518 } else { 21519 ElementPlus.ElNotification({ 21520 title: "", 21521 message: response.data.msg, 21522 position: 'bottom-right', 21523 type: 'warning', 21524 }); 21525 } 21526 }).catch(error => { 21527 // 21528 }).then(data => { 21529 this.$refs.auto_complete.setLoading(false); 21530 }); 21531 }, 21532 afterFormclose(){ 21533 dump('afterFormclose'); 21534 this.location_data = []; 21535 }, 21536 afterGetcurrentlocation(data){ 21537 console.log("afterGetcurrentlocation",data); 21538 console.log("isGuest=>"+isGuest); 21539 21540 if(isGuest==='1'){ 21541 this.deliveryAddress = data; 21542 this.$refs.address_modal.visible = true; 21543 } else { 21544 //this.location_data = data; 21545 this.afterPointaddress(data); 21546 } 21547 }, 21548 afterPointaddress(data){ 21549 this.$refs.address_modal.setLoading(true); 21550 // Include user's long-form description for storage 21551 let dataWithDescription = {...data}; 21552 if(data.userSelectedDescription){ 21553 setInLocalStorageStore(StoreMapName,"userSelectedDescription", data.userSelectedDescription); 21554 } 21555 setInLocalStorageStore(StoreMapName,"selectedAddress",data); 21556 21557 // Build request params including the user's selected description 21558 let requestData = 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&place_id="+ data.place_id; 21559 if(data.userSelectedDescription){ 21560 requestData += "&user_description=" + encodeURIComponent(data.userSelectedDescription); 21561 } 21562 21563 axios({ 21564 method: 'POST', 21565 url: ajaxurl+"/setPlaceID" , 21566 data : requestData, 21567 timeout: $timeout, 21568 }).then( response => { 21569 window.location.href = next_url; 21570 }).catch(error => { 21571 ElementPlus.ElNotification({ 21572 title: "", 21573 message: error, 21574 position: 'bottom-right', 21575 type: 'warning', 21576 }); 21577 }).then(data => { 21578 this.$refs.address_modal.setLoading(false); 21579 }); 21580 }, 21581 onSavelocation(data,addressData){ 21582 console.log("onSavelocation",data); 21583 setInLocalStorageStore(StoreMapName,"selectedAddress",data); 21584 this.$refs.address_form.setLoading(true); 21585 let params = { 21586 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 21587 'cart_uuid':getCookie('cart_uuid'), 21588 'data': data, 21589 'location_name' : addressData.location_name, 21590 'delivery_instructions' : addressData.delivery_instructions, 21591 'delivery_options' : addressData.delivery_options, 21592 'address_label' : addressData.address_label, 21593 'latitude' : data.latitude, 21594 'longitude' : data.longitude, 21595 'formatted_address' : addressData.formatted_address, 21596 'address1' : addressData.address1, 21597 'address2' : addressData.address2, 21598 'postal_code' : addressData.postal_code, 21599 'company' : addressData.company, 21600 'address_format_use': addressData.address_format_use, 21601 'custom_field1': addressData.custom_field1, 21602 'custom_field2': addressData.custom_field2, 21603 }; 21604 axios({ 21605 method: 'PUT', 21606 url: ajaxurl+"/SaveAddress" , 21607 data : params, 21608 timeout: $timeout, 21609 }).then( response => { 21610 if(response.data.code==1){ 21611 ElementPlus.ElNotification({ 21612 title: "", 21613 message: response.data.msg, 21614 position: 'bottom-right', 21615 type: 'success', 21616 }); 21617 window.location.href = next_url; 21618 } else { 21619 ElementPlus.ElNotification({ 21620 title: "", 21621 message: response.data.msg, 21622 position: 'bottom-right', 21623 type: 'warning', 21624 }); 21625 } 21626 }).catch(error => { 21627 ElementPlus.ElNotification({ 21628 title: "", 21629 message: error, 21630 position: 'bottom-right', 21631 type: 'warning', 21632 }); 21633 }).then(data => { 21634 this.$refs.address_form.setLoading(false); 21635 }); 21636 }, 21637 // 21638 }, 21639}); 21640app_home_search.use(ElementPlus);
21641const vm_home_search = app_home_search.mount('#vm_home_search'); 21642 21643 21644const app_cart_notifiations = Vue.createApp({ 21645 components: { 21646 'component-notification-cart': ComponentsNotificationCart 21647 }, 21648 methods: { 21649 afterReceiveitemupdate(data){ 21650 axios({ 21651 method: 'POST', 21652 url: ajaxurl+"/validateCartItems" , 21653 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&cart_uuid="+ getCookie('cart_uuid')+"&item_id="+data.item_id, 21654 timeout: $timeout, 21655 }).then( response => { 21656 if(response.data.code==1){ 21657 let $some_words = JSON.parse(some_words); 21658 ElementPlus.ElMessageBox.alert( response.data.msg, '', { 21659 confirmButtonText: $some_words.ok, 21660 callback: (action) => { 21661 if ((typeof vm_cart_preview !== "undefined") && ( vm_cart_preview !== null)) { 21662 vm_cart_preview.getCartPreview(); 21663 } 21664 if ((typeof vue_cart !== "undefined") && ( vue_cart !== null)) { 21665 vue_cart.loadcart(); 21666 } 21667 if ((typeof vm_item_suggestion !== "undefined") && ( vm_item_suggestion !== null)) { 21668 vm_item_suggestion.$refs.ref_item_suggestion.itemSuggestion(); 21669 } 21670 }, 21671 }); 21672 } 21673 }).catch(error => { 21674 // 21675 }).then(data => { 21676 }); 21677 } 21678 // 21679 }, 21680}); 21681app_cart_notifiations.use(ElementPlus); 21682const vm_cart_notifiations = app_cart_notifiations.mount('#vue-notification-cart'); 21683 21684 21685const ComponentsRiderVerifyCode = { 21686 props : ['resend_counter','uuid','label'], 21687 data() { 21688 return { 21689 loading : false, 21690 counter :0, 21691 timer:undefined, 21692 } 21693 }, 21694 created() { 21695 this.startTimer(); 21696 }, 21697 watch: { 21698 counter(newval, oldval) { 21699 if (newval <= 0) { 21700 this.stopTimer(); 21701 } 21702 }, 21703 }, 21704 methods: { 21705 startTimer() { 21706 this.counter = this.resend_counter; 21707 this.stopTimer(); 21708 this.timer = setInterval(() => { 21709 this.counter--; 21710 }, 1000); 21711 }, 21712 stopTimer() { 21713 clearInterval(this.timer); 21714 }, 21715 resendCode(){ 21716 this.loading = true; 21717 axios({ 21718 method: 'POST', 21719 url: ajaxurl+"/ResendRiderverificationcode" , 21720 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&uuid=" + this.uuid, 21721 timeout: $timeout, 21722 }).then( response => { 21723 if(response.data.code==1){ 21724 this.startTimer(); 21725 ElementPlus.ElNotification({ 21726 title: "", 21727 message: response.data.msg, 21728 position: 'bottom-right', 21729 type: 'success', 21730 }); 21731 window.location.href = response.data.details.redirect; 21732 } else { 21733 ElementPlus.ElNotification({ 21734 title: "", 21735 message: response.data.msg, 21736 position: 'bottom-right', 21737 type: 'warning', 21738 }); 21739 } 21740 }).catch(error => { 21741 // 21742 }).then(data => { 21743 this.loading = false; 21744 }); 21745 }, 21746 }, 21747 template : ` 21748 <div class="d-flex justify-content-between align-items-center"> 21749 <div><b>{{label.resend_code}} {{ counter }}</b></div> 21750 <div> 21751 <el-button type="text" 21752 :loading="loading" 21753 :disabled="counter != 0" 21754 @click="resendCode" 21755 > 21756 {{label.resend}} 21757 </el-button> 21758 </div> 21759 </div> 21760 `, 21761}; 21762 21763const app_rider_register = Vue.createApp({ 21764 components: { 21765 'component-phone' : ComponentsPhoneNumber, 21766 'component-rider-verifycode' : ComponentsRiderVerifyCode, 21767 }, 21768 data() { 21769 return { 21770 loading : false, 21771 mobile_number : '', 21772 mobile_prefix :'', 21773 first_name : '', 21774 last_name : '', 21775 email : '', 21776 address : '', 21777 password :'', 21778 cpassword : '', 21779 show_password : false, 21780 password_type: 'password', 21781 } 21782 }, 21783 computed: { 21784 validForm(){ 21785 if(empty(this.first_name)){ 21786 return false; 21787 } 21788 if(empty(this.last_name)){ 21789 return false; 21790 } 21791 if(empty(this.email)){ 21792 return false; 21793 } 21794 if(empty(this.password)){ 21795 return false; 21796 } 21797 if(empty(this.cpassword)){ 21798 return false; 21799 } 21800 if(empty(this.address)){ 21801 return false; 21802 } 21803 return true; 21804 } 21805 }, 21806 methods: { 21807 onRegister(){ 21808 this.loading = true; 21809 let data = "&mobile_prefix="+ this.mobile_prefix; 21810 data+="&mobile_number=" + this.mobile_number; 21811 data+="&first_name=" + this.first_name; 21812 data+="&last_name=" + this.last_name; 21813 data+="&email=" + this.email; 21814 data+="&address=" + this.address; 21815 data+="&password=" + this.password; 21816 data+="&cpassword=" + this.cpassword; 21817 axios({ 21818 method: 'POST', 21819 url: ajaxurl+"/riderRegistration" , 21820 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + data, 21821 timeout: $timeout, 21822 }).then( response => { 21823 if(response.data.code==1){ 21824 this.loading = true; 21825 ElementPlus.ElNotification({ 21826 title: "", 21827 message: response.data.msg, 21828 position: 'bottom-right', 21829 type: 'success', 21830 }); 21831 window.location.href = response.data.details.redirect; 21832 } else { 21833 ElementPlus.ElNotification({ 21834 title: "", 21835 message: response.data.msg, 21836 position: 'bottom-right', 21837 type: 'warning', 21838 }); 21839 } 21840 }).catch(error => { 21841 // 21842 }).then(data => { 21843 this.loading = false;
21844 }); 21845 }, 21846 showPassword() 21847 { 21848 this.show_password = this.show_password==true?false:true; 21849 if(this.show_password){ 21850 this.password_type = 'text'; 21851 } else this.password_type = 'password'; 21852 }, 21853 }, 21854}); 21855app_rider_register.use(Maska); 21856app_rider_register.use(ElementPlus); 21857const vm_rider_register = app_rider_register.mount('#vue-rider-registration'); 21858 21859// END JS 1.0.8 21860 21861 21862const ComponentsAvailablePoints = { 21863 data() { 21864 return { 21865 total : 0, 21866 total_animated: 0, 21867 loading : true, 21868 } 21869 }, 21870 watch: { 21871 total(newValue){ 21872 gsap.to(this.$data, { duration: 0.6, total_animated : newValue }); 21873 }, 21874 }, 21875 computed: { 21876 animatedTotal() { 21877 return this.total_animated.toFixed(0); 21878 }, 21879 }, 21880 mounted() { 21881 this.getAvailablePoints(); 21882 }, 21883 methods: { 21884 getAvailablePoints(){ 21885 this.loading = true; 21886 axios({ 21887 method: 'POST', 21888 url: ajaxurl+"/getAvailablePoints" , 21889 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content'), 21890 timeout: $timeout, 21891 }).then( response => { 21892 this.total = response.data.details.total; 21893 }).catch(error => { 21894 // 21895 }).then(data => { 21896 this.loading = false; 21897 }); 21898 }, 21899 }, 21900 template : `{{animatedTotal}}` 21901}; 21902 21903const app_points = Vue.createApp({ 21904 components: { 21905 'component-available-points' : ComponentsAvailablePoints, 21906 }, 21907 data() { 21908 return { 21909 loading : false, 21910 data :[], 21911 has_data : false, 21912 show_next : false, 21913 tab : 'transaction', 21914 loading1 : false, 21915 data1 : [], 21916 show_next1 : false, 21917 page : 1, 21918 page2 : 1, 21919 loading_next : false, 21920 loading_next1 : false, 21921 } 21922 }, 21923 created() { 21924 this.getPointsTransaction(false); 21925 }, 21926 mounted() { 21927 this.getPointsTransactionMerchant(false); 21928 }, 21929 computed: { 21930 hasData(){ 21931 return this.has_data; 21932 }, 21933 getData(){ 21934 return this.data; 21935 }, 21936 showNext(){ 21937 return this.show_next; 21938 }, 21939 getData1(){ 21940 return this.data1; 21941 }, 21942 showNext1(){ 21943 return this.show_next1; 21944 }, 21945 }, 21946 methods: { 21947 getPointsTransaction(data){ 21948 this.has_data = false; 21949 if(data){ 21950 this.loading_next = true; 21951 } else this.loading = true; 21952 axios({ 21953 method: 'POST', 21954 url: ajaxurl+"/getPointsTransaction" , 21955 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&page="+this.page, 21956 timeout: $timeout, 21957 }).then( response => { 21958 this.data.push(response.data.details.data); 21959 this.has_data = true; 21960 this.show_next = response.data.details.show_next_page; 21961 this.page = response.data.details.page; 21962 }).catch(error => { 21963 // 21964 }).then(data => { 21965 this.loading = false; 21966 this.loading_next = false; 21967 }); 21968 }, 21969 getPointsTransactionMerchant(data){ 21970 if(data){ 21971 this.loading_next1 = true; 21972 } else this.loading1 = true; 21973 axios({ 21974 method: 'POST', 21975 url: ajaxurl+"/getPointsTransactionMerchant" , 21976 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&page="+this.page2, 21977 timeout: $timeout, 21978 }).then( response => { 21979 this.data1.push(response.data.details.data); 21980 this.show_next1 = response.data.details.show_next_page; 21981 this.page2 = response.data.details.page; 21982 }).catch(error => { 21983 // 21984 }).then(data => { 21985 this.loading1 = false; 21986 this.loading_next1 = false; 21987 }); 21988 }, 21989 nextPage(data){ 21990 this.getPointsTransaction(true); 21991 }, 21992 nextPage2(data){ 21993 this.getPointsTransactionMerchant(true); 21994 } 21995 }, 21996}); 21997app_points.use(ElementPlus); 21998const vm_points = app_points.mount('#vue-my-points'); 21999 22000 22001const formatTest = (percentage) => (percentage === 100 ? 'Full' : `${percentage}%`) 22002 22003 22004const ComponentsApplyPoints = { 22005 props : ['title', 'is_mobile' , 'apply_text' , 'enter_points' ,'data' ,'use_thresholds'], 22006 data() { 22007 return { 22008 points : 0, 22009 is_submit : false, 22010 points_tab : undefined, 22011 data_points: [], 22012 balance: 0, 22013 points_id: 0, 22014 loading : false 22015 } 22016 }, 22017 computed: { 22018 hasData(){ 22019 if(this.points>0){ 22020 return false; 22021 } 22022 return true; 22023 } 22024 }, 22025 watch: { 22026 points_tab(newval,oldval){ 22027 dump(this.balance +"=>"+ newval.points); 22028 if(this.balance > newval.points){ 22029 this.points = newval.points; 22030 this.points_id = newval.id; 22031 } else { 22032 this.points = 0; 22033 this.points_id = 0 22034 } 22035 } 22036 }, 22037 created() { 22038 }, 22039 methods: { 22040 showModal(data){ 22041 if(data){ 22042 $(this.$refs.modal).modal('show'); 22043 } else { 22044 $(this.$refs.modal).modal('hide'); 22045 } 22046 22047 if(this.use_thresholds && data){ 22048 this.getPointsthresholds(); 22049 } 22050 }, 22051 applyPoints(){ 22052 this.is_submit = true; 22053 let currency_code = getCookie('currency_code'); 22054 currency_code = !empty(currency_code)?currency_code:''; 22055 axios({ 22056 method: 'POST', 22057 url: ajaxurl+"/applyPoints" , 22058 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&points=" + this.points + "&cart_uuid="+ getCookie('cart_uuid') + "¤cy_code=" + currency_code + "&points_id="+this.points_id, 22059 timeout: $timeout, 22060 }).then( response => { 22061 22062 if(response.data.code==1){ 22063 this.showModal(false); 22064 this.$emit('afterApplypoints'); 22065 } else { 22066 ElementPlus.ElNotification({ 22067 title: "", 22068 message: response.data.msg, 22069 position: 'bottom-right', 22070 type: 'warning', 22071 }); 22072 } 22073 22074 }).catch(error => { 22075 // 22076 }).then(data => { 22077 this.is_submit = false;
22078 }); 22079 }, 22080 getPointsthresholds(){ 22081 this.loading = true; 22082 let currency_code = getCookie('currency_code'); 22083 currency_code = !empty(currency_code)?currency_code:''; 22084 axios({ 22085 method: 'POST', 22086 url: ajaxurl+"/getPointsthresholds" , 22087 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&cart_uuid="+ getCookie('cart_uuid') + "¤cy_code=" + currency_code, 22088 timeout: $timeout, 22089 }).then( response => { 22090 if(response.data.code==1){ 22091 this.data_points = response.data.details.data; 22092 this.balance = response.data.details.balance; 22093 } 22094 }).catch(error => { 22095 // 22096 }).then(data => { 22097 this.loading = false; 22098 }); 22099 }, 22100 }, 22101 template : ` 22102 <div class="modal" ref="modal" tabindex="-1" role="dialog" 22103 aria-labelledby="promocodeModal" aria-hidden="true" data-backdrop="static" > 22104 <div class="modal-dialog" role="document"> 22105 <div class="modal-content" :class="{ 'modal-mobile' : is_mobile==1 }" > 22106 22107 <div class="modal-header border-bottom-0" style="padding-bottom:0px !important;"> 22108 <h5 class="modal-title" id="exampleModalLongTitle"> 22109 {{title}} 22110 </h5> 22111 <div class="close"> 22112 <a href="javascript:;" data-dismiss="modal" class="btn btn-black btn-circle rounded-pill"><i class="zmdi zmdi-close font20"></i></a> 22113 </div> 22114 </div> 22115 22116 <div class="modal-body"> 22117 22118 <form class="forms mt-2 apply-points-form" @submit.prevent="applyCode" > 22119 22120 22121 <template v-if="use_thresholds"> 22122 22123 <div v-loading="loading"> 22124 22125 <el-tabs 22126 v-model="points_tab" 22127 stretch 22128 > 22129 <template v-for="items in data_points" :keys="items"> 22130 <el-tab-pane label="User" :name="items" > 22131 <template #label> 22132 <Div v-if="balance < items.points" class="disabled-class"></Div> 22133 <span class="custom-tabs-label"> 22134 <div class="font13 font-weight-light">{{ items.label }}</div> 22135 <div class="font-weight-bold font20">{{ items.amount }}</div> 22136 <div> 22137 <el-progress 22138 :text-inside="true" 22139 :stroke-width="20" 22140 :percentage=" ((balance / items.points)*100)>100?100: (balance / items.points)*100 " 22141 :status="balance >= items.points ? 'success' : 'primary'" 22142 > 22143 <span> 22144 <template v-if="balance >= items.points"> 22145 REDEEM 22146 </template> 22147 </span> 22148 </el-progress> 22149 </div> 22150 </span> 22151 </template> 22152 </el-tab-pane> 22153 </template> 22154 </el-tabs> 22155 22156 </div> 22157 22158 </template> 22159 <template v-else> 22160 <div class="form-label-group"> 22161 <input v-model="points" class="form-control form-control-text" placeholder="" 22162 id="points" type="text" maxlength="20" > 22163 <label for="points" class="required">{{enter_points}}</label> 22164 </div> 22165 </template> 22166 22167 </form> <!--forms--> 22168 22169 </div> <!--modal body--> 22170 22171 <div class="modal-footer"> 22172 <button type="button" class="btn btn-black pl-4 pr-4" @click="showModal(false)" >Cancel</button> 22173 <button type="button" class="btn btn btn-green pl-4 pr-4" 22174 @click="applyPoints" :class="{ loading: is_submit }" :disabled="hasData" 22175 > 22176 <span class="label">{{apply_text}}</span><div class="m-auto circle-loader" data-loader="circle-side"></div> 22177 </button> 22178 </div> 22179 22180 </div> <!--content--> 22181 </div> <!--dialog--> 22182 </div> <!--modal--> 22183 ` 22184}; 22185 22186const app_checkout_points = Vue.createApp({ 22187 components: { 22188 'components-apply-points' : ComponentsApplyPoints, 22189 }, 22190 data() { 22191 return { 22192 loading : true, 22193 loading_remove : false, 22194 data : [], 22195 } 22196 }, 22197 created() { 22198 this.getAvailablePoints(); 22199 }, 22200 methods: { 22201 getAvailablePoints(){ 22202 this.loading = true; 22203 let currency_code = getCookie('currency_code'); 22204 currency_code = !empty(currency_code)?currency_code:''; 22205 axios({ 22206 method: 'POST', 22207 url: ajaxurl+"/getCartpoints" , 22208 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&cart_uuid="+ getCookie('cart_uuid') + "¤cy_code=" + currency_code, 22209 timeout: $timeout, 22210 }).then( response => { 22211 this.data = response.data.details; 22212 }).catch(error => { 22213 // 22214 }).then(data => { 22215 this.loading = false;
22216 }); 22217 }, 22218 showApplyPoints(){ 22219 this.$refs.apply_points.showModal(true); 22220 }, 22221 afterApplypoints(){ 22222 if ((typeof vue_cart !== "undefined") && ( vue_cart !== null)) { 22223 vue_cart.loadcart(); 22224 } 22225 this.getAvailablePoints(); 22226 }, 22227 removePoints(){ 22228 this.loading_remove = true; 22229 axios({ 22230 method: 'POST', 22231 url: ajaxurl+"/removePoints" , 22232 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&cart_uuid="+ getCookie('cart_uuid'), 22233 timeout: $timeout, 22234 }).then( response => { 22235 if ((typeof vue_cart !== "undefined") && ( vue_cart !== null)) { 22236 vue_cart.loadcart(); 22237 } 22238 this.getAvailablePoints(); 22239 }).catch(error => { 22240 // 22241 }).then(data => { 22242 this.loading_remove = false; 22243 }); 22244 }, 22245 }, 22246}); 22247app_checkout_points.use(ElementPlus); 22248const vm_checkout_points = app_checkout_points.mount('#vue-checkout-points'); 22249 22250 22251const ComponentSearchFood = { 22252 props : ['label'], 22253 data() { 22254 return { 22255 q :'', 22256 data : [] 22257 } 22258 }, 22259 computed: { 22260 hasSearch(){ 22261 if(this.q==''){ 22262 return false; 22263 } 22264 return true; 22265 } 22266 }, 22267 methods: { 22268 async querySearch(queryString,callbackfn){ 22269 axios({ 22270 method: 'POST', 22271 url: ajaxurl+"/SearchSuggestion" , 22272 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') +"&q=" + queryString, 22273 timeout: $timeout, 22274 }).then( response => { 22275 if(response.data.code==1){ 22276 callbackfn(response.data.details); 22277 } else { 22278 callbackfn([]); 22279 } 22280 }).catch(error => { 22281 callbackfn([]); 22282 }).then(data => { 22283 22284 }); 22285 }, 22286 handleSelect(data){ 22287 this.$emit("afterSuggestion",data.name); 22288 } 22289 }, 22290 template : ` 22291 <el-autocomplete 22292 v-model="q" 22293 :fetch-suggestions="querySearch" 22294 @select="handleSelect" 22295 :placeholder="label.search" 22296 :trigger-on-focus="false" 22297 :fit-input-width="false" 22298 class="w-100" 22299 size="large" 22300 value-key="name" 22301 :clearable="true" 22302 :select-when-unmatched="true" 22303 :highlight-first-item="true" 22304 > 22305 <template #default="{ item }"> 22306 <div class="value" v-html="item.name"></div> 22307 </template> 22308 </el-autocomplete> 22309 ` 22310}; 22311 22312const ComponentsItemList = { 22313 props : ['data','items_not_available', 'category_not_available'], 22314 template: '#xtemplate_item_list', 22315 methods: { 22316 viewItem(data){ 22317 this.$emit('handleView',{ 22318 cat_id : data.cat_id, 22319 item_uuid : data.item_uuid, 22320 merchant_id : data.merchant_id, 22321 }); 22322 }, 22323 itemAvailable(item_id,cat_id){ 22324 if(this.items_not_available.includes(parseInt(item_id))===false){ 22325 if(this.category_not_available.includes(parseInt(cat_id))===false){ 22326 return true; 22327 } 22328 } 22329 return false; 22330 }, 22331 }, 22332}; 22333 22334const ComponentSearchFoodResult = { 22335 props : ['q'], 22336 components : { 22337 'components-item-list' : ComponentsItemList 22338 }, 22339 data() { 22340 return { 22341 tabs : 'searchFood', 22342 loading : false, 22343 food_list : [], 22344 merchant_list : [], 22345 total_food : 0, 22346 merchant_data : [], 22347 total_merchant : 0, 22348 cuisine : [], 22349 items_not_available : [], 22350 category_not_available : [] 22351 } 22352 }, 22353 watch: { 22354 q(newval,oldval){ 22355 this.doSearch(newval,this.tabs); 22356 } 22357 }, 22358 computed: { 22359 hasDataFood(){ 22360 if (Object.keys(this.food_list).length > 0) { 22361 return true; 22362 } 22363 return false; 22364 }, 22365 getFood(){ 22366 return this.food_list; 22367 }, 22368 getFoodCount(){ 22369 return this.total_food; 22370 }, 22371 hasQ(){ 22372 return !empty(this.q) ? true: false; 22373 }, 22374 hasMerchant(){ 22375 if (Object.keys(this.merchant_data).length > 0) { 22376 return true; 22377 } 22378 return false; 22379 }, 22380 getMerchant(){ 22381 return this.merchant_data; 22382 }, 22383 getMerchantCount(){ 22384 return this.total_merchant; 22385 }, 22386 }, 22387 methods: { 22388 tabClick(tab,Event){ 22389 this.doSearch(this.q,tab.paneName); 22390 }, 22391 doSearch(data,tabName){ 22392 let currency_code = getCookie('currency_code'); 22393 currency_code = !empty(currency_code)?currency_code:''; 22394 this.loading = true; 22395 axios({ 22396 method: 'POST', 22397 url: ajaxurl+"/"+tabName , 22398 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') +"&q=" + data + "¤cy_code=" + currency_code, 22399 timeout: $timeout, 22400 }).then( response => { 22401 if(response.data.code==1){ 22402 if(tabName=="searchFood"){ 22403 this.food_list = response.data.details.food_list; 22404 this.merchant_list = response.data.details.merchant_list; 22405 this.total_food = response.data.details.total; 22406 this.items_not_available = response.data.details.items_not_available; 22407 this.category_not_available = response.data.details.category_not_available; 22408 } else { 22409 this.merchant_data = response.data.details.merchant_data; 22410 this.cuisine = response.data.details.cuisine; 22411 this.total_merchant = response.data.details.total; 22412 } 22413 this.$emit('setSearch',true) 22414 } else { 22415 this.clearData(); 22416 } 22417 }).catch(error => { 22418 this.clearData(); 22419 }).then(data => { 22420 this.loading = false; 22421 }); 22422 }, 22423 clearData(){ 22424 this.food_list = []; 22425 this.merchant_list = []; 22426 this.total_food = 0; 22427 }, 22428 handleView(data){ 22429 this.$emit('handleView',{ 22430 cat_id : data.cat_id, 22431 item_uuid : data.item_uuid, 22432 merchant_id : data.merchant_id, 22433 }); 22434 } 22435 }, 22436 template: '#xtemplate_search_food_result', 22437}; 22438 22439const ComponentItemDetails = { 22440 template: '#xtemplate_item_details', 22441 components : { 22442 'money-format': ComponentsMoney, 22443 }, 22444 data() { 22445 return { 22446 merchant_id : 0, 22447 menu_loading : true, 22448 menu_data: [], 22449 items : [], 22450 item_addons : [], 22451 item_addons_load : false, 22452 size_id : 0, 22453 disabled_cart : true, 22454 item_qty : 1, 22455 item_total : 0, 22456 add_to_cart : false, 22457 meta : [], 22458 special_instructions : '', 22459 sold_out_options : [], 22460 if_sold_out : 'substitute', 22461 view_data : [] , 22462 item_loading : false, 22463 item_in_cart : 0, 22464 merchant_data : [], 22465 items_not_available : [], 22466 category_not_available : [], 22467 menu_layout :'list', 22468 q: '', 22469 search_menu_data : [], 22470 allergen : [], 22471 allergen_data : [], 22472 item_gallery : [], 22473 image_featured : '', 22474 title : '', 22475 new_order_label : '', 22476 money_config : [] 22477 } 22478 }, 22479 mounted() { 22480 let $some_words = JSON.parse(some_words); 22481 if (Object.keys($some_words).length > 0) { 22482 this.title = $some_words.created_new_order + "?"; 22483 this.new_order_label = $some_words.new_order_label; 22484 } 22485 }, 22486 updated () { 22487 if(this.item_addons_load==true){ 22488 this.ItemSummary(); 22489 } 22490 }, // 22491 computed: { 22492 getAllergen(){ 22493 return this.allergen; 22494 }, 22495 hasAllergen(){ 22496 if (Object.keys(this.allergen).length > 0) { 22497 return true; 22498 } 22499 return false;
22500 }, 22501 getItemGallery(){ 22502 return this.item_gallery; 22503 } 22504 }, 22505 methods: { 22506 getMenuItem(data){ 22507 let currency_code = getCookie('currency_code'); 22508 currency_code = !empty(currency_code)?currency_code:''; 22509 22510 let parameters = 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') +"&merchant_id=" + data.merchant_id; 22511 parameters+="&cat_id="+data.cat_id; 22512 parameters+="&item_uuid="+data.item_uuid; 22513 parameters+="¤cy_code="+currency_code; 22514 22515 22516 this.item_loading = true; 22517 NProgress.start(); 22518 axios({ 22519 method: 'POST', 22520 url: ajaxurl+"/getMenuItem" , 22521 data : parameters, 22522 timeout: $timeout, 22523 }).then( response => { 22524 //dump(response.data.details); 22525 if(response.data.code==1){ 22526 $('#itemModal').modal('show'); 22527 22528 $global_items = response.data.details.data.items; 22529 $global_addons = response.data.details.data.addons; 22530 $global_addon_items = response.data.details.data.addon_items; 22531 $global_item_addons = response.data.details.data.items.item_addons; 22532 22533 var $meta = response.data.details.data.meta; 22534 this.money_config = response.data.details.money_config; 22535 this.item_gallery = response.data.details.data.meta.item_gallery; 22536 this.image_featured = ''; 22537 this.renderGallery(); 22538 22539 var $meta_details = response.data.details.data.meta_details; 22540 var $new_meta = { 22541 'cooking_ref' : [], 22542 'ingredients' : [], 22543 'dish' : [], 22544 }; 22545 22546 let $ingredients_preselected = response.data.details.data.items.ingredients_preselected; 22547 22548 if( !empty($meta)){ 22549 $.each($meta,function(key, item) { 22550 $.each(item,function(key2, item2) { 22551 if(!empty($meta_details[key])){ 22552 if(!empty($meta_details[key][item2])){ 22553 let $defaul_check = false; 22554 if(key=="ingredients" && $ingredients_preselected){ 22555 $defaul_check = true; 22556 } 22557 $new_meta[key].push({ 22558 'meta_id': $meta_details[key][item2].meta_id, 22559 'meta_name': $meta_details[key][item2].meta_name, 22560 'checked': $defaul_check 22561 }); 22562 } 22563 } 22564 }); 22565 }); 22566 } 22567 22568 var $price = $global_items.price; 22569 var $size_id = Object.keys($price)[0]; 22570 22571 this.item_qty = 1; 22572 this.items = $global_items; 22573 // dump("=>"); 22574 // dump(this.items); 22575 this.size_id = $size_id; 22576 this.meta = $new_meta; 22577 this.getSizeData($size_id); 22578 this.sold_out_options = response.data.details.sold_out_options; 22579 22580 } else { 22581 $('#itemModal').modal('hide'); 22582 } 22583 }).catch(error => { 22584 22585 }).then(data => { 22586 this.item_loading = false; 22587 NProgress.done(); 22588 }); 22589 }, 22590 setItemSize(event){ 22591 var $size_id = event.currentTarget.firstElementChild.value; 22592 this.size_id = $size_id; 22593 this.getSizeData($size_id); 22594 22595 }, // end setItemSize 22596 getSizeData($size_id){ 22597 22598 $new_item_addons = []; var $sub_items=[]; 22599 22600 if( !empty($global_item_addons[$size_id]) ){ 22601 $.each($global_item_addons[$size_id],function(key, item) { 22602 if(!empty($global_addons[$size_id])){ 22603 if(!empty($global_addons[$size_id][item])){ 22604 22605 $global_addons[$size_id][item].subcat_id 22606 $.each($global_addons[$size_id][item].sub_items,function(key2, item2) { 22607 if ((typeof $global_addon_items[item2] !== "undefined") && ( $global_addon_items[item2] !== null)) { 22608 $sub_items.push({ 22609 'sub_item_id':$global_addon_items[item2].sub_item_id, 22610 'sub_item_name':$global_addon_items[item2].sub_item_name, 22611 'item_description':$global_addon_items[item2].item_description, 22612 'price':$global_addon_items[item2].price, 22613 'pretty_price':$global_addon_items[item2].pretty_price, 22614 'checked':false, 22615 'disabled':false, 22616 'qty':1 22617 }); 22618 } 22619 }); 22620 22621 $new_item_addons.push({ 22622 'subcat_id' : $global_addons[$size_id][item].subcat_id, 22623 'subcategory_name' : $global_addons[$size_id][item].subcategory_name, 22624 'subcategory_description' : $global_addons[$size_id][item].subcategory_description, 22625 'multi_option' : $global_addons[$size_id][item].multi_option, 22626 'multi_option_min' : $global_addons[$size_id][item].multi_option_min, 22627 'multi_option_value' : $global_addons[$size_id][item].multi_option_value, 22628 'require_addon' : $global_addons[$size_id][item].require_addon, 22629 'pre_selected' : $global_addons[$size_id][item].pre_selected, 22630 'sub_items_checked':'', 22631 'sub_items':$sub_items 22632 }); 22633 $sub_items = [] ; 22634 } 22635 } 22636 }); 22637 } 22638 22639 22640 this.item_addons = $new_item_addons; 22641 this.item_addons_load = true; 22642 }, // end getSizeData 22643 renderGallery(){ 22644 setTimeout(() => { 22645 let $is_rtl = false;
22646 if ((typeof is_rtl !== "undefined") && ( is_rtl !== null)) { 22647 $is_rtl = is_rtl=='1'?true:false; 22648 } 22649 $(this.$refs.owl_item_gallery).owlCarousel({ 22650 loop:false, 22651 margin:10, 22652 nav:false, 22653 dots:false, 22654 rtl : $is_rtl, 22655 responsive:{ 22656 0:{ 22657 items:1 22658 }, 22659 600:{ 22660 items:3 22661 }, 22662 1000:{ 22663 items:5 22664 } 22665 } 22666 }); 22667 }, 10); 22668 }, 22669 setImage(data){ 22670 this.image_featured = data; 22671 }, 22672 ItemSummary(data){ 22673 $item_total = 0; 22674 var $required_addon = []; 22675 var $required_addon_added = []; 22676 let $min_addon = []; 22677 let $min_addon_added = []; 22678 22679 if(!empty(this.items.price)){ 22680 if(!empty(this.items.price[this.size_id])){ 22681 var item = this.items.price[this.size_id]; 22682 if( item.discount>0){ 22683 $item_total+=( this.item_qty * parseFloat(item.price_after_discount) ); 22684 } else $item_total+=( this.item_qty * parseFloat(item.price) ); 22685 } 22686 } 22687 22688 this.item_addons.forEach((item,index) => { 22689 22690 //dump("=>" + item.multi_option); 22691 if ( item.require_addon==1){ 22692 $required_addon.push(item.subcat_id); 22693 } 22694 22695 if(item.multi_option=="custom"){ 22696 var total_check = 0; 22697 let multi_option_min = item.multi_option_min; 22698 var multi_option_value = item.multi_option_value; 22699 22700 if(multi_option_value>0){ 22701 $min_addon.push({ 22702 'subcat_id': item.subcat_id, 22703 'min':multi_option_min, 22704 'max':multi_option_value 22705 }); 22706 } 22707 22708 var item_index=[]; var item_index2=[]; 22709 item.sub_items.forEach((item2,index2) => { 22710 if(item2.checked==true){ 22711 total_check++; 22712 $item_total+=( this.item_qty * parseFloat(item2.price) ); 22713 $required_addon_added.push( item.subcat_id ); 22714 } else item_index.push(index2); 22715 22716 if(item2.disabled==true){ 22717 item_index2.push(index2); 22718 } 22719 22720 }); 22721 22722 22723 $min_addon_added[item.subcat_id] = { 22724 'total' : total_check 22725 }; 22726 22727 if(total_check>=multi_option_value){ 22728 item_index.forEach((item3,index3) => { 22729 this.item_addons[index].sub_items[item3].disabled = true; 22730 }); 22731 } else { 22732 item_index2.forEach((item3,index3) => { 22733 this.item_addons[index].sub_items[item3].disabled = false; 22734 }); 22735 } 22736 22737 } else if ( item.multi_option=="one" ){ 22738 item.sub_items.forEach((item2,index2) => { 22739 if( item2.sub_item_id == item.sub_items_checked ) { 22740 $item_total+=( this.item_qty * parseFloat(item2.price) ); 22741 $required_addon_added.push( item.subcat_id ); 22742 } 22743 }); 22744 } else if ( item.multi_option=="multiple" ){ 22745 var item_index=[]; 22746 let multi_option_min = item.multi_option_min; 22747 var multi_option_value = item.multi_option_value; 22748 var limit = 0; 22749 22750 if(multi_option_value>0){ 22751 $min_addon.push({ 22752 'subcat_id': item.subcat_id, 22753 'min':multi_option_min, 22754 'max':multi_option_value 22755 }); 22756 } 22757 22758 item.sub_items.forEach((item2,index2) => { 22759 if(item2.checked==true){ 22760 $item_total+=( item2.qty * parseFloat(item2.price) ); 22761 $required_addon_added.push( item.subcat_id ); 22762 limit += item2.qty; 22763 } 22764 item_index.push(index2); 22765 }); 22766 22767 $min_addon_added[item.subcat_id] = { 22768 'total' : limit 22769 }; 22770 22771 this.item_addons[index].qty_selected =limit; 22772 if ( this.item_addons[index].qty_selected>= multi_option_value){ 22773 item_index.forEach((item3,index2) => { 22774 this.item_addons[index].sub_items[item3].disabled = true; 22775 }); 22776 } else { 22777 item_index.forEach((item3,index2) => { 22778 this.item_addons[index].sub_items[item3].disabled = false; 22779 }); 22780 } 22781 22782 } /*endif custom*/ 22783 22784 });/* end loop*/ 22785 22786 22787 this.item_total = $item_total; 22788 22789 var $required_meet=true; 22790 if($required_addon.length>0){ 22791 $.each($required_addon, function(i, val){ 22792 if($required_addon_added.includes(val)===false){ 22793 $required_meet = false;
22794 return false; 22795 } 22796 }); 22797 } 22798 22799 // CHECK COOKING REF 22800 if(this.items.cooking_ref_required){ 22801 let $cooking_ref_check = false; 22802 if (Object.keys(this.meta.cooking_ref).length > 0) { 22803 Object.entries(this.meta.cooking_ref).forEach(([cooking_key, cooking_items]) => { 22804 if(cooking_items.checked){ 22805 $cooking_ref_check = true; 22806 } 22807 }); 22808 } 22809 if(!$cooking_ref_check){ 22810 $required_meet = false; 22811 } 22812 } 22813 22814 if (Object.keys($min_addon).length > 0) { 22815 let min_value,min_selected; 22816 Object.entries($min_addon).forEach(([key_min_addon, items_min_addon]) => { 22817 min_value = parseInt(items_min_addon.min); 22818 if($min_addon_added[items_min_addon.subcat_id]){ 22819 min_selected = parseInt($min_addon_added[items_min_addon.subcat_id].total); 22820 } 22821 if(min_selected>0){ 22822 if(min_value>min_selected){ 22823 $required_meet = false; 22824 } 22825 } 22826 }); 22827 } 22828 22829 //dump("required_meet=>"+$required_meet); 22830 if($required_meet){ 22831 this.disabled_cart = false; 22832 } else this.disabled_cart = true; 22833 22834 }, // end ItemSummary 22835 CheckaddCartItems(){ 22836 if ((typeof vm_cart_preview !== "undefined") && ( vm_cart_preview !== null)) { 22837 let cart_merchant_id = vm_cart_preview.$refs.childref.cart_merchant.merchant_id; 22838 if ((typeof cart_merchant_id !== "undefined") && ( cart_merchant_id !== null)) { 22839 if ( this.items.merchant_id != vm_cart_preview.$refs.childref.cart_merchant.merchant_id ){ 22840 $('#itemModal').modal('hide'); 22841 22842 ElementPlus.ElMessageBox.confirm( 22843 vm_cart_preview.$refs.childref.cart_merchant.confirm_add_item, 22844 this.title, 22845 { 22846 confirmButtonText: this.new_order_label,
22847 showCancelButton: false, 22848 type: 'info', 22849 buttonSize : 'large' 22850 } 22851 ).then(() => { 22852 this.clearCart( vm_cart_preview.$refs.childref.cart_uuid ); 22853 }).catch(() => { 22854 // 22855 }); 22856 } else this.addCartItems(); 22857 } else this.addCartItems(); 22858 } else this.addCartItems(); 22859 }, 22860 clearCart(cart_uuid){ 22861 NProgress.start(); 22862 axios({ 22863 method: 'POST', 22864 url: ajaxurl+"/clearCart" , 22865 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') +"&cart_uuid=" + cart_uuid, 22866 timeout: $timeout, 22867 }).then( response => { 22868 if(response.data.code==1){ 22869 this.addCartItems(); 22870 } else { 22871 ElementPlus.ElNotification({ 22872 title: "", 22873 message: response.data.msg, 22874 position: 'bottom-right', 22875 type: 'warning', 22876 }); 22877 } 22878 }).catch(error => { 22879 22880 }).then(data => { 22881 NProgress.done(); 22882 }); 22883 }, 22884 addCartItems(event){ 22885 if (event) { 22886 event.preventDefault() 22887 } 22888 22889 this.add_to_cart = true; 22890 22891 var $params = { 22892 'YII_CSRF_TOKEN':$('meta[name=YII_CSRF_TOKEN]').attr('content'), 22893 'merchant_id' : this.items.merchant_id, 22894 'cat_id' : this.items.cat_id, 22895 'item_token': this.items.item_token, 22896 'item_size_id': this.size_id, 22897 'item_qty': this.item_qty, 22898 'item_addons': this.item_addons, 22899 'special_instructions': this.special_instructions, 22900 'meta' : this.meta, 22901 'cart_uuid':getCookie('cart_uuid'), 22902 'transaction_type': 'delivery', 22903 'if_sold_out' : this.if_sold_out, 22904 }; 22905 22906 var timenow = 1; 22907 $params = JSON.stringify($params); 22908 22909 ajax_request[timenow] = $.ajax({ 22910 url: ajaxurl+"/addCartItems", 22911 method: "PUT", 22912 dataType: "json", 22913 data: $params , 22914 contentType : $content_type.json , 22915 timeout: $timeout, 22916 crossDomain: true, 22917 beforeSend: function( xhr ) { 22918 if(ajax_request[timenow] != null) { 22919 ajax_request[timenow].abort(); 22920 } 22921 } 22922 }); 22923 22924 ajax_request[timenow].done( data => { 22925 if ( data.code==1){ 22926 setCookie('cart_uuid',data.details.cart_uuid,30); 22927 $('#itemModal').modal('hide'); 22928 if ((typeof vm_cart_preview !== "undefined") && ( vm_cart_preview !== null)) { 22929 vm_cart_preview.getCartPreview(); 22930 } 22931 } 22932 }); 22933 22934 ajax_request[timenow].always( data => { 22935 dump('always'); 22936 this.add_to_cart = false; 22937 }); 22938 22939 } , 22940 // end addCartItems 22941 // 22942 }, 22943}; 22944 22945const ComponentsFoodList = { 22946 props : ['meta_name','sub_title'], 22947 components : { 22948 'components-item-list' : ComponentsItemList 22949 }, 22950 data() { 22951 return { 22952 loading : false, 22953 food_list : [], 22954 merchant_list : [], 22955 items_not_available : [], 22956 category_not_available : [], 22957 title : '' 22958 } 22959 }, 22960 created() { 22961 this.getFoodList() 22962 }, 22963 computed: { 22964 hasDataFood(){ 22965 if (Object.keys(this.food_list).length > 0) { 22966 return true; 22967 } 22968 return false; 22969 }, 22970 getFood(){ 22971 return this.food_list; 22972 }, 22973 }, 22974 methods: { 22975 getFoodList(){ 22976 let currency_code = getCookie('currency_code'); 22977 currency_code = !empty(currency_code)?currency_code:''; 22978 this.loading = true; 22979 axios({ 22980 method: 'POST', 22981 url: ajaxurl+"/getFoodList" , 22982 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') +"&meta_name="+this.meta_name + "¤cy_code="+currency_code, 22983 timeout: $timeout, 22984 }).then( response => { 22985 if(response.data.code==1){ 22986 this.title = response.data.details.title; 22987 this.food_list = response.data.details.food_list; 22988 this.merchant_list = response.data.details.merchant_list; 22989 this.total_food = response.data.details.total; 22990 this.items_not_available = response.data.details.items_not_available; 22991 this.category_not_available = response.data.details.category_not_available; 22992 this.renderSlide(); 22993 } 22994 }).catch(error => { 22995 // 22996 }).then(data => { 22997 this.loading = false; 22998 }); 22999 }, 23000 renderSlide(){ 23001 setTimeout(() => { 23002 let $is_rtl = false; 23003 if ((typeof is_rtl !== "undefined") && ( is_rtl !== null)) { 23004 $is_rtl = is_rtl=='1'?true:false; 23005 } 23006 $(this.$refs.owl_item_slide).owlCarousel({ 23007 loop:false, 23008 margin:10, 23009 nav:true, 23010 dots:false, 23011 navText: [$( this.$refs.owl_next ),$( this.$refs.owl_previous )], 23012 rtl : $is_rtl, 23013 responsive:{ 23014 0:{ 23015 items:1 23016 }, 23017 600:{ 23018 items:3 23019 }, 23020 1000:{ 23021 items:5 23022 } 23023 } 23024 }); 23025 }, 10); 23026 }, 23027 viewItem(data){ 23028 this.$emit('handleView',{ 23029 cat_id : data.cat_id, 23030 item_uuid : data.item_uuid, 23031 merchant_id : data.merchant_id, 23032 }); 23033 }, 23034 itemAvailable(item_id,cat_id){ 23035 if(this.items_not_available.includes(parseInt(item_id))===false){ 23036 if(this.category_not_available.includes(parseInt(cat_id))===false){ 23037 return true; 23038 } 23039 } 23040 return false;
23041 }, 23042 }, 23043 template: '#xtemplate_food_carousel', 23044}; 23045 23046//vue-search 23047const app_search = Vue.createApp({ 23048 data() { 23049 return { 23050 searchString : '', 23051 isSearch : false 23052 } 23053 }, 23054 components: { 23055 'components-search-food' : ComponentSearchFood, 23056 'components-search-food-result' : ComponentSearchFoodResult, 23057 'components-item-details' : ComponentItemDetails, 23058 'components-food-list' : ComponentsFoodList 23059 }, 23060 computed: { 23061 getisSearch(){ 23062 return this.isSearch; 23063 } 23064 }, 23065 methods: { 23066 afterSuggestion(data){ 23067 this.searchString = data; 23068 }, 23069 handleView(data){ 23070 this.$refs.item_details.getMenuItem(data); 23071 }, 23072 setSearch(data){ 23073 this.isSearch = data; 23074 } 23075 }, 23076}); 23077app_search.use(ElementPlus); 23078const vm_app_search = app_search.mount('#vue-search'); 23079 23080const app_checkout_booking = Vue.createApp({ 23081 data() { 23082 return { 23083 loading : false, 23084 room_list : [], 23085 table_list : [], 23086 room_uuid :"", 23087 table_uuid :"", 23088 transaction_type :'', 23089 guest_number : 1, 23090 booking_enabled : false, 23091 } 23092 }, 23093 created() { 23094 this.getTableAttributes(); 23095 }, 23096 methods: { 23097 getTableAttributes(){ 23098 this.loading = true; 23099 axios({ 23100 method: 'POST', 23101 url: ajaxurl+"/getTableAttributes" , 23102 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&cart_uuid=" + getCookie('cart_uuid'), 23103 timeout: $timeout, 23104 }).then( response => { 23105 if(response.data.code==1){ 23106 this.room_list = response.data.details.room_list; 23107 this.table_list = response.data.details.table_list; 23108 this.booking_enabled = response.data.details.booking_enabled; 23109 if(response.data.details.default_room_uuid){ 23110 this.room_uuid = response.data.details.default_room_uuid; 23111 } 23112 } 23113 }).catch(error => { 23114 // 23115 }).then(data => { 23116 this.loading = false; 23117 }); 23118 }, 23119 clearTableList(){ 23120 this.table_uuid = ''; 23121 }, 23122 // 23123 }, 23124}); 23125app_checkout_booking.use(ElementPlus); 23126const vm_checkout_booking = app_checkout_booking.mount('#vue-checkout-booking'); 23127 23128const ComponentsWalletBalance = { 23129 data() { 23130 return { 23131 total : 0, 23132 total_animated: 0, 23133 loading : true, 23134 } 23135 }, 23136 watch: { 23137 total(newValue){ 23138 gsap.to(this.$data, { duration: 0.6, total_animated : newValue }); 23139 }, 23140 }, 23141 computed: { 23142 animatedTotal() { 23143 return this.total_animated; 23144 }, 23145 }, 23146 mounted() { 23147 this.getBalance(); 23148 }, 23149 methods: { 23150 getBalance(){ 23151 this.loading = true; 23152 axios({ 23153 method: 'POST', 23154 url: ajaxurl+"/getWalletBalance" , 23155 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content'), 23156 timeout: $timeout, 23157 }).then( response => { 23158 this.total = response.data.details.total; 23159 }).catch(error => { 23160 // 23161 }).then(data => { 23162 this.loading = false; 23163 }); 23164 }, 23165 }, 23166 template : `{{animatedTotal}}` 23167}; 23168 23169const ComponentsWalletTransaction = { 23170 props:['data','has_data','loading','show_next'], 23171 template: '#xtemplate_wallet_transaction', 23172}; 23173 23174const componentsTopupForm = { 23175 props:['label', 'topup_minimum' ,'topup_maximum'], 23176 data() { 23177 return { 23178 modal:false, 23179 amount :1, 23180 loading : false, 23181 default_payment : [], 23182 loading_submit : false, 23183 loading_payment : false, 23184 } 23185 }, 23186 created() { 23187 this.getCustomerDefaultPayment() 23188 }, 23189 computed: { 23190 getPayment(){ 23191 return this.default_payment; 23192 } 23193 }, 23194 methods: { 23195 show(){ 23196 this.modal = true; 23197 }, 23198 close(){ 23199 this.modal = false; 23200 }, 23201 getCustomerDefaultPayment(){ 23202 this.loading = true; 23203 axios({ 23204 method: 'POST', 23205 url: ajaxurl+"/getCustomerDefaultPayment" , 23206 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content'), 23207 timeout: $timeout, 23208 }).then( response => { 23209 if(response.data.code==1){ 23210 this.default_payment = response.data.details.data; 23211 } 23212 }).catch(error => { 23213 // 23214 }).then(data => { 23215 this.loading = false; 23216 }); 23217 }, 23218 onAddfunds(){ 23219 this.loading_submit = true; 23220 let currency_code = getCookie('currency_code'); 23221 currency_code = !empty(currency_code)?currency_code:''; 23222 axios({ 23223 method: 'POST', 23224 url: ajaxurl+"/prepareAddFunds" , 23225 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&amount="+this.amount + 23226 "&payment_code="+this.default_payment.payment_code + "&payment_uuid="+ this.default_payment.payment_uuid + "¤cy_code="+currency_code, 23227 timeout: $timeout, 23228 }).then( response => { 23229 if(response.data.code==1){ 23230 this.$emit('afterPreparepayment',response.data.details); 23231 } else { 23232 ElementPlus.ElNotification({ 23233 title: "", 23234 message: response.data.msg, 23235 position: 'bottom-right', 23236 type: 'warning', 23237 }); 23238 } 23239 }).catch(error => { 23240 // 23241 }).then(data => { 23242 this.loading_submit = false; 23243 }); 23244 }, 23245 }, 23246 template: '#xtemplate_topupform', 23247}; 23248 23249const componentSuccesfulModal = { 23250 props : ['data'], 23251 data() { 23252 return { 23253 modal:false 23254 } 23255 }, 23256 template: '#xtemplate_succesful_modal', 23257}; 23258 23259const componentBonusFunds = { 23260 props : ['transaction_type'], 23261 data(){ 23262 return { 23263 owl : undefined, 23264 data :[], 23265 loading :false 23266 }; 23267 }, 23268 mounted(){ 23269 this.bonusFunds(); 23270 }, 23271 computed: { 23272 hasData(){ 23273 if (Object.keys(this.data).length > 0) { 23274 return true; 23275 } 23276 return false;
23277 }, 23278 }, 23279 watch: { 23280 data(new_data,old_data){ 23281 setTimeout(() => { 23282 this.renderCarousel(); 23283 }, 1); 23284 } 23285 }, 23286 methods: { 23287 bonusFunds(){ 23288 this.loading = true; 23289 axios({ 23290 method: 'POST', 23291 url: ajaxurl+"/getDiscount" , 23292 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&transaction_type="+this.transaction_type, 23293 timeout: $timeout, 23294 }).then( response => { 23295 if(response.data.code==1){ 23296 this.data = response.data.details; 23297 } else { 23298 this.data = []; 23299 } 23300 }).catch(error => { 23301 // 23302 }).then(data => { 23303 this.loading = false; 23304 }); 23305 }, 23306 renderCarousel(){ 23307 let $is_rtl = false; 23308 if ((typeof is_rtl !== "undefined") && ( is_rtl !== null)) { 23309 $is_rtl = is_rtl=='1'?true:false; 23310 } 23311 this.owl = $(this.$refs.carousel_bonusfunds).owlCarousel({ 23312 loop:true, 23313 dots:false, 23314 nav:false, 23315 autoWidth:true, 23316 rtl : $is_rtl 23317 }); 23318 }, 23319 }, 23320 template: ` 23321 <div ref="carousel_bonusfunds" class="owl-carousel owl-theme carousel_bonusfunds"> 23322 <div v-for="(items, index) in data" class="mr-2"> 23323 <el-card shadow="hover" class="gradient-yellow-bg" style="max-width:350px;"> 23324 <h6>{{items.title}}</h6> 23325 <div class="mb-1">{{items.discount_details}}</div> 23326 <div class="font-weight-bold">{{items.valid_discount}}</div> 23327 </el-card> 23328 </div> 23329 </div> 23330 ` 23331}; 23332
23333const app_wallet = Vue.createApp({ 23334 components: { 23335 'component-wallet-balance' : ComponentsWalletBalance, 23336 'components-wallet-transaction':ComponentsWalletTransaction, 23337 'components-topup-form' : componentsTopupForm, 23338 'components-succesful-modal' : componentSuccesfulModal, 23339 'component-bonusfunds' : componentBonusFunds 23340 }, 23341 created() { 23342 this.getWalletTransaction(); 23343 }, 23344 data() { 23345 return { 23346 loading : false, 23347 tab : 'all', 23348 data:[], 23349 page : 1, 23350 show_next : false, 23351 loading :false, 23352 loading_next : false, 23353 payment_data : [] 23354 } 23355 }, 23356 computed: { 23357 hasData(){ 23358 if (Object.keys(this.data).length > 0) { 23359 return true; 23360 } 23361 return false; 23362 }, 23363 getData(){ 23364 return this.data; 23365 }, 23366 showNext(){ 23367 return this.show_next; 23368 }, 23369 }, 23370 methods: { 23371 showFundsForm(){ 23372 this.$refs.topup.show(); 23373 }, 23374 tabChange(){ 23375 this.data = []; 23376 this.page = 1; 23377 this.getWalletTransaction(false); 23378 }, 23379 nextPage(data){ 23380 this.getWalletTransaction(true); 23381 }, 23382 showLoadingBox(message){ 23383 this.$refs.topup.loading_payment = true; 23384 }, 23385 closeLoadingBox(){ 23386 this.$refs.topup.loading_payment = false; 23387 }, 23388 closeTopup(){ 23389 this.$refs.topup.close(); 23390 }, 23391 getWalletTransaction(data){ 23392 if(data){ 23393 this.loading_next = true; 23394 } else this.loading = true; 23395 axios({ 23396 method: 'POST', 23397 url: ajaxurl+"/getWalletTransaction" , 23398 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&page="+this.page + "&transaction_type="+this.tab, 23399 timeout: $timeout, 23400 }).then( response => { 23401 if(response.data.code==1){ 23402 this.data.push(response.data.details.data); 23403 this.show_next = response.data.details.show_next_page; 23404 this.page = response.data.details.page; 23405 } else { 23406 this.show_next = false; 23407 } 23408 }).catch(error => { 23409 // 23410 }).then(data => { 23411 this.loading = false; 23412 this.loading_next = false; 23413 }); 23414 }, 23415 afterPreparepayment(data){ 23416 try { 23417 this.$refs[ data.payment_code ].Dopayment( data.data, data ); 23418 } catch(err) { 23419 ElementPlus.ElNotification({ 23420 title: "", 23421 message: err, 23422 position: 'bottom-right', 23423 type: 'warning', 23424 }); 23425 } 23426 }, 23427 AfterCancelPayment(data){ 23428 if(!empty(data)){ 23429 ElementPlus.ElNotification({ 23430 title: "", 23431 message: data, 23432 position: 'bottom-right', 23433 type: 'warning', 23434 }); 23435 } 23436 }, 23437 afterSuccessfulpayment(data){ 23438 this.payment_data = data; 23439 this.$refs.topup.close(); 23440 23441 if ((typeof this.$refs.wallet_balance !== "undefined") && ( this.$refs.wallet_balance !== null)) { 23442 this.$refs.wallet_balance.getBalance(); 23443 } 23444 23445 if ((typeof this.$refs.wallet_balance_mobile !== "undefined") && ( this.$refs.wallet_balance_mobile !== null)) { 23446 this.$refs.wallet_balance_mobile.getBalance(); 23447 } 23448 23449 this.$refs.succesful_modal.modal =true 23450 if(this.tab!="all"){ 23451 this.tab = "all"; 23452 } else { 23453 this.tabChange(); 23454 } 23455 }, 23456 }, 23457}); 23458 23459if ((typeof components_bundle !== "undefined") && ( components_bundle !== null)) { 23460 $.each(components_bundle,function(components_name, components_value) { 23461 app_wallet.component(components_name, components_value ); 23462 }); 23463} 23464 23465app_wallet.use(ElementPlus); 23466app_wallet.use(Maska); 23467const vm_wallet = app_wallet.mount('#vue-my-wallet'); 23468 23469 23470const app_esubscription = Vue.createApp({ 23471 data() { 23472 return { 23473 email_address :'', 23474 loading : false, 23475 } 23476 }, 23477 methods: { 23478 submit(){ 23479 this.loading = true; 23480 axios({ 23481 method: 'POST', 23482 url: ajaxurl+"/subscribetoemail" , 23483 data : 'YII_CSRF_TOKEN=' + $('meta[name=YII_CSRF_TOKEN]').attr('content') + "&email_address="+ this.email_address, 23484 timeout: $timeout, 23485 }).then( response => { 23486 if(response.data.code==1){ 23487 this.email_address = ''; 23488 ElementPlus.ElNotification({ 23489 title: "", 23490 message: response.data.msg, 23491 position: 'bottom-right', 23492 type: 'success', 23493 }); 23494 } else { 23495 ElementPlus.ElNotification({ 23496 title: "", 23497 message: response.data.msg, 23498 position: 'bottom-right', 23499 type: 'warning', 23500 }); 23501 } 23502 }).catch(error => { 23503 // 23504 }).then(data => { 23505 this.loading = false; 23506 }); 23507 } 23508 }, 23509}); 23510app_esubscription.use(ElementPlus); 23511const vm_esubscription = app_esubscription.mount('#vue-esubscription'); 23512 23513const uploadProfile = Vue.createApp({ 23514 data() { 23515 return { 23516 loading : false, 23517 imageUrl : null, 23518 upload_url : site_url+"/api/updateprofilephoto", 23519 data :{ 23520 YII_CSRF_TOKEN : $('meta[name=YII_CSRF_TOKEN]').attr('content') 23521 } 23522 } 23523 }, 23524 mounted() { 23525 if ((typeof profileAvatar !== "undefined") && ( profileAvatar !== null)) { 23526 this.imageUrl = profileAvatar; 23527 } 23528 }, 23529 methods: { 23530 beforeAvatarUpload(data){ 23531 this.loading = true; 23532 }, 23533 handleAvatarSuccess(data){ 23534 this.loading = false;
23535 if(data.code==1){ 23536 this.imageUrl = data.details.url_image; 23537 ElementPlus.ElNotification({ 23538 title: "", 23539 message: data.msg, 23540 position: 'bottom-right', 23541 type: 'success', 23542 }); 23543 } else { 23544 ElementPlus.ElNotification({ 23545 title: "", 23546 message: data.msg, 23547 position: 'bottom-right', 23548 type: 'warning', 23549 }); 23550 } 23551 }, 23552 }, 23553}); 23554uploadProfile.use(ElementPlus); 23555const vmUploadProfile = uploadProfile.mount('#upload-profile'); 23556 23557$(document).ready(function() { 23558 let SomeWords = JSON.parse(some_words); 23559 $('.read-more').on('click', function() { 23560 var $description = $(this).prev('.description'); 23561 23562 if ($description.hasClass('expanded')) { 23563 $description.removeClass('expanded'); 23564 $(this).text(SomeWords.read_more); 23565 } else { 23566 $description.addClass('expanded'); 23567 $(this).text(SomeWords.read_less); 23568 } 23569 }); 23570}); 23571 23572const walletPayment = Vue.createApp({ 23573 data() { 23574 return { 23575 amount : null, 23576 loading : false, 23577 loading_payment : false, 23578 loading_addfunds : false, 23579 data : null, 23580 modal_addfunds : false, 23581 payment_data : null, 23582 translation : null, 23583 is_redirect : false, 23584 cart_total : 0, 23585 payment_processsing : false, 23586 } 23587 }, 23588 mounted() { 23589 this.translation = JSON.parse(some_words); 23590 }, 23591 computed: { 23592 hasPayment(){ 23593 return Object.keys(this.payment_data?.data).length > 0; 23594 }, 23595 getPayment(){ 23596 return this.payment_data?.data; 23597 }, 23598 }, 23599 methods: { 23600 onInputNumber(val) { 23601 this.amount = val.replace(/[^0-9.]/g, '').replace(/(\..*)\./g, '$1'); 23602 }, 23603 async fetchWallet(cart_total){ 23604 try { 23605 this.cart_total = cart_total; 23606 this.loading = true; 23607 let cart_uuid = getCookie('cart_uuid'); 23608 let currency_code = getCookie('currency_code'); 23609 const params = new URLSearchParams({ 23610 cart_total : cart_total, 23611 cart_uuid: cart_uuid, 23612 currency_code : currency_code 23613 }).toString(); 23614 const response = await axios.get( 23615 `${ajaxurl}/fetchWallet?${params}` 23616 ); 23617 23618 if(response.data.code==1){ 23619 this.data = response.data.details; 23620 } else { 23621 this.data = null; 23622 } 23623 } catch (error) { 23624 23625 } finally { 23626 this.loading = false; 23627 } 23628 }, 23629 async fetchPayment(){ 23630 this.amount = null; 23631 this.payment_processsing = false; 23632 if(this.payment_data){ 23633 return; 23634 } 23635 //this.amount = this.data?.amount_due_raw ?? null; 23636 try { 23637 this.loading_payment = true; 23638 const response = await axios.get( 23639 `${ajaxurl}/getCustomerDefaultPayment` 23640 ); 23641 this.payment_data = response.data.details; 23642 } catch (error) { 23643 } finally { 23644 this.loading_payment = false; 23645 } 23646 }, 23647 async ConfirmTopup(){ 23648 23649 if(!this.amount || this.amount<=0){ 23650 ElementPlus.ElNotification({ 23651 title: "", 23652 message: this.translation.amount_required, 23653 position: 'bottom-right', 23654 type: 'warning', 23655 }); 23656 return; 23657 } 23658 if(!this.hasPayment){ 23659 ElementPlus.ElNotification({ 23660 title: "", 23661 message: this.translation.select_payment_method, 23662 position: 'bottom-right', 23663 type: 'warning', 23664 }); 23665 return; 23666 } 23667 23668 try { 23669 this.loading_addfunds = true; 23670 let currency_code = getCookie('currency_code'); 23671 currency_code = !empty(currency_code)?currency_code:''; 23672 const payment = this.getPayment; 23673 const params = new URLSearchParams({ 23674 YII_CSRF_TOKEN : $('meta[name=YII_CSRF_TOKEN]').attr('content'), 23675 is_checkout : true, 23676 amount : this.amount, 23677 currency_code : currency_code, 23678 payment_code : payment?.payment_code, 23679 payment_uuid : payment?.payment_uuid 23680 }).toString(); 23681 const response = await axios.post(`${ajaxurl}/prepareAddFunds`,params); 23682 if(response.data.code==1){ 23683 this.afterPreparepayment(response.data.details); 23684 } else { 23685 ElementPlus.ElNotification({ 23686 title: "", 23687 message: response.data.msg, 23688 position: 'bottom-right', 23689 type: 'warning', 23690 }); 23691 } 23692 } catch (error) { 23693 } finally { 23694 this.loading_addfunds = false;
23695 } 23696 }, 23697 afterPreparepayment(data){ 23698 try { 23699 console.debug("afterPreparepayment",data.payment_instructions?.redirect); 23700 this.is_redirect = data.payment_instructions?.redirect=='redirect' ? true : false; 23701 console.debug("is_redirect",this.is_redirect); 23702 this.payment_processsing = !this.is_redirect ? true : false; 23703 23704 const payment_code = data?.payment_code ?? null; 23705 if(payment_code=="paypal"){ 23706 this.modal_addfunds = false; 23707 } 23708 23709 this.$refs[ data.payment_code ].Dopayment( data.data, data ); 23710 } catch(err) { 23711 ElementPlus.ElNotification({ 23712 title: "", 23713 message: err, 23714 position: 'bottom-right', 23715 type: 'warning', 23716 }); 23717 } 23718 }, 23719 AfterCancelPayment(data){ 23720 console.debug("AfterCancelPayment",data); 23721 if(!empty(data)){ 23722 ElementPlus.ElNotification({ 23723 title: "", 23724 message: data, 23725 position: 'bottom-right', 23726 type: 'warning', 23727 }); 23728 } 23729 }, 23730 afterSuccessfulpayment(data){ 23731 console.debug("afterSuccessfulpayment",data); 23732 this.modal_addfunds = false; 23733 this.payment_processsing = false; 23734 this.fetchWallet(this.cart_total); 23735 }, 23736 }, 23737}); 23738if ((typeof components_bundle !== "undefined") && ( components_bundle !== null)) { 23739 $.each(components_bundle,function(components_name, components_value) { 23740 walletPayment.component(components_name, components_value ); 23741 }); 23742} 23743walletPayment.use(ElementPlus); 23744const vmWalletPayment = walletPayment.mount('#vue-wallet'); 23745 23746 23747})(jQuery); 23748/*end strict*/
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.