1/** 2 * serviceWorker 3 4if ('serviceWorker' in navigator) { 5 window.addEventListener('load', () => { 6 navigator.serviceWorker.register('/sw.js').then(res => {}, err => {}); 7 }); 8} 9 10/** 11 * pwa 12 13const Pwa = () => { 14 if (localStorage.getItem('install-pwa') == 'true') return; 15 16 let event, pwa, install, close; 17 18 const remove = item => { 19 item.remove(); 20 localStorage.setItem('install-pwa', true); 21 }; 22 23 const created = () => { 24 pwa = document.createElement('div'); 25 pwa.id = 'pwa-install-popup'; 26 pwa.innerHTML = ` 27 <div class="pwa-inner p-1 bg-white border-round"> 28 <div class="pwa-title">Uygulamayı Yükle</div> 29 <div class="d-flex align-items-center"> 30 <div class="pwa-icon mr-1"> 31 <img src="/theme/v5/images/pwa/48x48.png"> 32 </div> 33 <div class="pwa-text"> 34 <div>T-Soft</div> 35 <span>mangox.1ticaret.com</span> 36 </div> 37 </div> 38 <div class="pwa-buttons"> 39 <button class="btn btn-primary mr-1" id="pwa-install">Yükle</button> 40 <button class="btn btn-light" id="pwa-close">İptal</button> 41 </div> 42 </div>`; 43 document.body.append(pwa); 44 45 install = pwa.querySelector('#pwa-install'); 46 close = pwa.querySelector('#pwa-close'); 47 48 install.addEventListener("click", () => { 49 event.prompt(); 50 event.userChoice.then( result => { 51 result.outcome === 'accepted' ? pwa.remove() : remove(pwa); 52 }); 53 }); 54 55 close.addEventListener("click", () => { 56 remove(pwa); 57 }); 58 }; 59 60 window.addEventListener("beforeinstallprompt", e => { 61 e.preventDefault(); 62 event = e; 63 if (localStorage.getItem('install-pwa') != 'true') created(); 64 }); 65}; 66 67/** 68 * Flatpickr localize 69 */ 70var appendContent, autoCart, diff, elementHeight, elementOffsetTop, menu, windowHeight; 71window.flatpickr.localize({ 72 weekdays: { 73 shorthand: [TLANG.sun || "Paz", TLANG.mon || "Pzt", TLANG.tues || "Sal", TLANG.wed || "Ãar", TLANG.thurs || "Per", TLANG.fri || "Cum", TLANG.sat || "Cmt"], 74 longhand: [TLANG.sunday || "Pazar", TLANG.monday || "Pazartesi", TLANG.tuesday || "Salı", TLANG.wednesday || "ÃarÅamba", TLANG.thursday || "PerÅembe", TLANG.friday || "Cuma", TLANG.saturday || "Cumartesi"], 75 }, 76 months: { 77 shorthand: [TLANG.jan || "Oca", TLANG.feb || "Åub", TLANG.mar || "Mar", TLANG.apr || "Nis", TLANG.may || "May", TLANG.jun || "Haz", TLANG.jul || "Tem", TLANG.aug || "AÄu", TLANG.sep || "Eyl", TLANG.oct || "Eki", TLANG.nov || "Kas", TLANG.dec || "Ara" ], 78 longhand: [ 79 TLANG.january || "Ocak", TLANG.february || "Åubat", TLANG.march || "Mart", TLANG.april || "Nisan", TLANG.may || "Mayıs", TLANG.june || "Haziran", TLANG.july || "Temmuz", TLANG.august || "AÄustos", TLANG.september || "Eylül", TLANG.october || "Ekim", TLANG.november || "Kasım", TLANG.december || "Aralık"], 80 }, 81 firstDayOfWeek: 1, 82 ordinal: () => ".", 83 rangeSeparator: " - ", 84 weekAbbreviation: TLANG.wk || "Hf", 85 scrollTitle: TLANG.swipe_to_increase || "Artırmak için kaydırın", 86 toggleTitle: TLANG.on_off || "Aç/Kapa", 87 amPM: [TLANG.am || "ÃÃ", TLANG.pm || "ÃS"], 88 time_24hr: true, 89}); 90 91/* 92 TSOFT JavaScript Library v1 93 https://tsoft.com.tr/ 94*/ 95const fn = {}, 96 doc = document ? document : window.document, 97 indexOf = [].indexOf, 98 toString = {}.toString, 99 hasOwn = {}.hasOwnProperty, 100 fnToString = hasOwn.toString; 101 102const mouseClickEvents = { down: 'mousedown', up: 'mouseup' }; 103const mouseHoverEvents = ('onmouseleave' in document) ? [ 'mouseenter', 'mouseleave'] : [ 'mouseover', 'mouseout' ]; 104 105const isFunction = function isFunction(obj) { 106 return typeof obj === "function" && typeof obj.nodeType !== "number"; 107}; 108 109const isWindow = function isWindow(obj) { 110 return obj != null && obj === obj.window; 111}; 112 113const getUrlParam = function(key = '', url = document.location) { 114 if (key == '') return; 115 url = new URL(url); 116 const params = url.searchParams; 117 return params.get(key); 118} 119 120const setUrlParam = function(key = '', value = '' , url = document.location) { 121 if (key == '') return; 122 url = new URL(url); 123 const params = url.searchParams; 124 params.set(key, value); 125 return url; 126} 127 128const deleteUrlParam = function(key = '', url = document.location) { 129 if (key == '') return; 130 url = new URL(url); 131 const params = url.searchParams; 132 params.delete(key); 133 return url; 134} 135 136const LocalApi = { 137 get: (key, def = false) => { 138 try { 139 const obj = JSON.parse(localStorage.getItem(key)); 140 let now = new Date().getTime(); 141 if(Number.isNaN(obj.timeout) || obj.timeout < 1000000000) { 142 obj.timeout = 1000000000; 143 } else if (obj.timeout < 9000000000) { 144 obj.timeout = obj.timeout * 1000; 145 } 146 if (obj.timeout && obj.timeout < now) { 147 return def; 148 } 149 return typeof obj.value !== 'undefined' ? obj.value : def; 150 } catch (ex) { 151 return def; 152 } 153 }, 154 set: (key, val, timeout) => { 155 if(key === 'v5token') { 156 try { 157 timeout = Number.parseInt(timeout) > 0 ? timeout : 365 * 24 * 3600; 158 let obj = { value: val, timeout: timeout * 1000}; 159 localStorage.setItem(key, JSON.stringify(obj)); 160 return true; 161 } catch (ex) { 162 return false;
163 } 164 } else { 165 try { 166 timeout = Number.parseInt(timeout) > 0 ? timeout : 365 * 24 * 3600; 167 let obj = { value: val, timeout: new Date().getTime() + (1000 * timeout) }; 168 localStorage.setItem(key, JSON.stringify(obj)); 169 return true; 170 } catch (ex) { 171 return false; 172 } 173 } 174 175 }, 176 remove: key => { 177 try { 178 localStorage.removeItem(key); 179 return true; 180 } catch (ex) { 181 return false; 182 } 183 } 184}; 185 186/** 187 * Axios setting localize 188 */ 189 190axios.defaults.headers.common['Accept-Language'] = LANGUAGE || 'tr'; 191axios.interceptors.request.use( 192 async (config) => { 193 const token = bearerToken(); 194 if (token) config.headers.Authorization = `Bearer ${token}`; 195 return config; 196 }, 197 (error) => { 198 return Promise.reject(error); 199 } 200); 201axios.interceptors.response.use( 202 response => response, 203 error => { 204 const errorResponse = error.response; 205 if (!errorResponse) return; 206 207 const errorStatus = errorResponse.status || ''; 208 const errorCode = errorResponse.data?.errorCode || ''; 209 const errorUrl = errorResponse.config?.url || ''; 210 const errorMessage = errorResponse.data?.message || ''; 211 212 if(([403].includes(errorStatus) || [401].includes(errorCode)) && !errorResponse.data?.data[0]?.password_change) { 213 if (errorUrl.indexOf(getEndpoint('LOGIN')) > -1) { 214 T.notify({ 215 text: errorMessage, 216 className: 'danger', 217 duration: 5000, 218 stopOnFocus: true 219 }); 220 return; 221 } 222 } 223 return Promise.reject(errorResponse); 224 } 225); 226 227const tokenPadeId = document.getElementById('link_table_id').value; 228const bearerToken = function(){ 229 const tokenExpControl = JSON.parse(localStorage.getItem('v5token')); 230 if (!tokenExpControl) return; 231 232 if(tokenExpControl.timeout && (Number.isNaN(tokenExpControl.timeout) || tokenExpControl.timeout < 1000000000)) { 233 tokenExpControl.timeout = 1000000000; 234 } else if (tokenExpControl.timeout < 9000000000) { 235 tokenExpControl.timeout = tokenExpControl.timeout * 1000; 236 } 237 axios.defaults.headers.common['Authorization'] = `Bearer ${tokenExpControl.value}`; 238 if(((Math.floor(tokenExpControl.timeout - new Date().getTime())/1000)/60) < 10) { 239 fetch(getEndpoint('LOGIN'), { 240 method: 'POST', 241 cache: 'no-cache', 242 headers: { 243 'Content-Type': 'application/json', 244 'Authorization': `Bearer ${tokenExpControl.value}` 245 }, 246 referrerPolicy: 'no-referrer', 247 body: JSON.stringify({ 248 refresh: 1 249 }) 250 }).then(response => {return response.json(); }).then(result => { 251 let obj = { value: result.data[0].bearer, timeout: result.data[0].exp_at }; 252 LocalApi.remove('v5token'); 253 localStorage.setItem('v5token', JSON.stringify(obj)); 254 }).catch((e) => { 255 if(e.status === 403 || e.status === 401 || e.status === 500) { 256 axios.get('/srv/service/customer/logout').then(() => { 257 LocalApi.remove('v5token'); 258 window.location.href = '/'; 259 }); 260 } 261 }); 262 } 263 return tokenExpControl.value; 264}; 265 266if (LocalApi.get('v5token') !== false) { 267 if (MEMBER_INFO.ID == 0) { 268 if (tokenPadeId == '91') bearerToken(); 269 } else { 270 bearerToken(); 271 } 272} 273 274const LoginPageTracking = { 275 Callback: {}, 276 callbackArray: [] 277}; 278const SignPageTracking = { 279 Callback: () => {} 280}; 281const QuickViewObj = { 282 callback: { 283 open: [] 284 } 285}; 286 287const scrollBehavior = function(href = null, height) { 288 const top = height != null && typeof height == 'number' ? height : 0; 289 const element = typeof href == 'object' && href != null ? href : (href != null ? document.querySelector(href) : null); 290 if (element == null) return; 291 292 let elementRect = element.getBoundingClientRect(); 293 let bodyRect = document.body.getBoundingClientRect(); 294
295 let topRelativeToBody = elementRect.top - bodyRect.top - top; 296 297 scroll({ 298 top: topRelativeToBody, 299 behavior: "smooth" 300 }); 301} 302 303const scrollToElm = function(el, height = null) { 304 T(el).trigger('click'); 305 scrollBehavior(el, height); 306} 307 308let googleTokenClient; 309 310let multiCart = false, 311 multiCartItem = null; 312 313function toType(obj) { 314 let class2type = {}; 315 316 if (obj == null) { 317 return obj + ""; 318 } 319 320 return typeof obj === "object" || typeof obj === "function" ? 321 class2type[toString.call(obj)] || "object" : 322 typeof obj; 323} 324 325function isArrayLike(obj) { 326 let length = !!obj && "length" in obj && obj.length, 327 type = toType(obj); 328 329 if (isFunction(obj) || isWindow(obj)) { 330 return false; 331 } 332 333 return type === "array" || length === 0 || 334 typeof length === "number" && length > 0 && (length - 1) in obj; 335} 336 337function transitionCtrl(element, handler) { 338 const transitionEndEvent = 'webkitTransition' in document.body.style ? 'webkitTransitionEnd' : 'transitionend', 339 supportTransition = 'webkitTransition' in document.body.style || 'transition' in document.body.style, 340 transitionDuration = 'webkitTransition' in document.body.style ? 'webkitTransitionDuration' : 'transitionDuration'; 341 342 function getDuration(element) { 343 let duration = supportTransition ? window.getComputedStyle(element)[transitionDuration] : 0; 344 duration = Number.parseFloat(duration); 345 duration = typeof duration === 'number' && !Number.isNaN(Number(duration)) ? duration * 1000 : 0; 346 return duration; 347 } 348 349 let called = 0, 350 duration = getDuration(element); 351 352 duration ? T(element).one(transitionEndEvent, function(e) {!called && handler(e), called = 1; }) : 353 setTimeout(function() {!called && handler(), called = 1; }, 17); 354} 355 356function evalScripts(content) { 357 content = content.replaceAll(/\s+/g, ' '); 358 let startRegex = "<\s*script.*?>"; 359 let finishRegex = "<\s*\/\s*script\s*>"; 360 let mainRegex = new RegExp(startRegex + ".*?" + finishRegex, "ig"); 361 let res = content.match(mainRegex) || []; 362 363 let i=0; 364 let myscript = ''; 365 let callbackArr = []; 366 367 for(i=0;i<res.length; i++){ 368 myscript = res[i].replace(new RegExp(startRegex, "ig"), "").replace(new RegExp(finishRegex, "ig"), ""); 369 callbackArr.push(myscript); 370 } 371 372 for(i=0;i<callbackArr.length; i++){ 373 try{ 374 eval(callbackArr[i]); 375 }catch(ex){ 376 console.log(ex); 377 } 378 }; 379} 380 381function evalScriptsAppend(content, id) { 382 content = content.replaceAll(/\s+/g, ' '); 383 let startRegex = "<\s*script.*?>"; 384 let finishRegex = "<\s*\/\s*script\s*>"; 385 let mainRegex = new RegExp(startRegex + ".*?" + finishRegex, "ig"); 386 let res = content.match(mainRegex) || []; 387 388 for (let i=0; i<res.length; i++) { 389 if (T(`#${id}-${i}`).length > 0) T(`#${id}-${i}`)[0].remove(); 390 try{ 391 const parser = new DOMParser(); 392 const doc = parser.parseFromString(res[i], 'text/html'); 393 const src = doc.querySelector('script').getAttribute('src'); 394 395 const script = document.createElement('script'); 396 script.id = `${id}-${i}`; 397 if (src != undefined) script.src = src; 398 script.innerHTML = doc.querySelector('script').innerHTML || ''; 399 document.body.appendChild(script); 400 }catch(ex){ 401 console.log(ex); 402 } 403 } 404 if (res.length > 0) return true; 405}; 406 407function addToCompare(element = null, pageId = '', parentId = '') { 408 if (element == null) return; 409 410 const productId = element.dataset.id; 411 if (!productId) return; 412 413 let status; 414 const localCompare = LocalApi.get('compareProducts') || []; 415 const isActive = Array.from(localCompare).find(x => x == productId) || false; 416 417 if (!isActive && localCompare.length == 4) { 418 status = 3; 419 } else { 420 if (isActive) { 421 status = 2; 422 } else { 423 localCompare.push(productId); 424 LocalApi.set('compareProducts', localCompare); 425 T(`.add-to-compare-btn[data-id="${productId}"]`).addClass('active'); 426 status = 1; 427 } 428 } 429 430 loadSubFolder({ 431 pageId: pageId || 2, 432 blockParentId: parentId || 1003, 433 subFolder: 'compare', 434 params: { 435 product: localCompare.join('-'), 436 status: status 437 }, 438 success: function(loadRes){ 439 T.modal({ 440 id: 'product-compare-list-popup', 441 width: '1170px', 442 html: loadRes, 443 close: true 444 }); 445 } 446 }); 447} 448 449function compareSelectedProducts(pageId = '', parentId = '') { 450 if (pageId == '' || parentId == '') 451 return; 452 453 const elems = LocalApi.get('compareProducts') || []; 454 if (elems.length == 0 || elems.length == 1 || elems.length > 4) { 455 let message; 456 457 if (elems.length == 0) { 458 message = TLANG.no_comparison_products || 'Ãrün seçimi yapılmadıÄı için karÅılaÅtırılamamaktadır'; 459 } else if (elems.length == 1) {
460 message = TLANG.least_compare_warning || 'KarÅılaÅtırmak için en az 2 ürün seçmelisiniz'; 461 } else if (elems.length > 4) { 462 message = TLANG.most_compare_warning || 'KarÅılaÅtırmak için en fazla 4 ürün seçmelisiniz'; 463 } 464 465 T.notify({ 466 text: message, 467 className: 'danger product-compare-failed-notify', 468 duration: 1800, 469 }); 470 471 return; 472 } 473 474 loadSubFolder({ 475 pageId: pageId, 476 blockParentId: parentId, 477 subFolder: 'compare', 478 params: { 479 product: elems.join('-'), 480 }, 481 success: function(loadRes){ 482 T.modal({ 483 id: 'product-compare-list-popup', 484 width: '1170px', 485 html: loadRes, 486 close: true 487 }); 488 } 489 }); 490} 491 492function compareSet() { 493 const localCompare = LocalApi.get('compareProducts') || []; 494 if (localCompare.length == 0) return; 495 496 const compareBtns = T('.add-to-compare-btn'); 497 if (compareBtns.length == 0) return; 498 499 Array.from(compareBtns).forEach(item => { 500 const id = item.dataset.id; 501 const isCompareId = Array.from(localCompare).find(x => x == id); 502 isCompareId ? T(item).addClass('active') : T(item).removeClass('active'); 503 }); 504} 505 506function TSOFT(arr) { 507 let self = this; 508 for (let i = 0; i < arr.length; i += 1) { 509 self[i] = arr[i]; 510 } 511 self.length = arr.length; 512 return this; 513} 514 515function tInitFn(fn) { 516 try { fn(); } catch (e) { 517 console.error(((TLANG.function_not_found || "Fonksiyon bulunamadı: ") + ' ' + e)); 518 } 519} 520 521fn.TSOFT = function(dom, selector) { 522 return new TSOFT(dom, selector); 523}; 524 525fn.init = function(selector, context) { 526 let arr = []; 527 let i = 0; 528 if (selector && !context) { 529 if (selector instanceof TSOFT) { 530 return selector; 531 } 532 } 533 if (selector) { 534 if (typeof selector === 'string') { 535 let els; 536 let tempParent; 537 let html = selector.trim(); 538 if (html.indexOf('<') >= 0 && html.indexOf('>') >= 0) { 539 let toCreate = 'div'; 540 if (html.indexOf('<li') === 0) { toCreate = 'ul'; } 541 if (html.indexOf('<tr') === 0) { toCreate = 'tbody'; } 542 if (html.indexOf('<td') === 0 || html.indexOf('<th') === 0) { toCreate = 'tr'; } 543 if (html.indexOf('<tbody') === 0) { toCreate = 'table'; } 544 if (html.indexOf('<option') === 0) { toCreate = 'select'; } 545 tempParent = doc.createElement(toCreate); 546 tempParent.innerHTML = html; 547 for (i = 0; i < tempParent.childNodes.length; i += 1) { 548 arr.push(tempParent.childNodes[i]); 549 } 550 } else { 551 if (!context && selector[0] === '#' && !selector.match(/[ .<>:~]/)) { 552 els = [doc.getElementById(selector.trim().split('#')[1])]; 553 } else { 554 els = (context || doc).querySelectorAll(selector.trim()); 555 } 556 for (i = 0; i < els.length; i += 1) { 557 if (els[i]) { arr.push(els[i]); } 558 } 559 } 560 } else if (selector.nodeType || selector === window || selector === doc) { 561 arr.push(selector); 562 } else if (selector.length > 0 && selector[0].nodeType) { 563 for (i = 0; i < selector.length; i += 1) { 564 arr.push(selector[i]); 565 } 566 } 567 } 568 return new TSOFT(arr); 569}; 570 571TSOFT.prototype = { 572 addClass: function(cls) { 573 cls = cls.split(' '); 574 for (let i = 0; i < this.length; i++) { 575 this[i].classList.add(...cls); 576 } 577 }, 578 removeClass: function(cls) { 579 cls = cls.split(' '); 580 for (let i = 0; i < this.length; i++) { 581 this[i].classList.remove(...cls); 582 } 583 }, 584 toggleClass: function(cls) { 585 cls = cls.split(' '); 586 for (let i = 0; i < this.length; i++) { 587 cls.map(c => { 588 this[i].classList.toggle(c); 589 }); 590 } 591 }, 592 hasClass: function(cls) { 593 return this[0].classList['contains'](cls); 594 }, 595 index: function() { 596 return [...this[0].parentElement.children].indexOf(this[0]); 597 }, 598 on: function(event, handler) { 599 for (let i = 0; i < this.length; i++) { 600 this[i].addEventListener(event, handler, false); 601 } 602 }, 603 off: function(event, handler) { 604 for (let i = 0; i < this.length; i++) { 605 this[i].removeEventListener(event, handler, false); 606 } 607 }, 608 one: function(event, handler = function(){}) { 609 for (let i = 0; i < this.length; i++) { 610 this[i].addEventListener(event, handler, {once: true}); 611 } 612 }, 613 trigger: function(value) { 614 for (let i = 0; i < this.length; i++) { 615 let event = ''; 616 const el = this || data; 617 618 if(document.createEvent) { 619 event = document.createEvent("HTMLEvents"); 620 event.initEvent(value, true, true); 621 event.eventName = value; 622 this[i].dispatchEvent(event, {'bubbles': true}); 623 } else { 624 event = document.createEventObject(); 625 event.eventName = value; 626 event.eventType = value; 627 this[i].fireEvent("on" + event.eventType, event); 628 } 629 } 630 }, 631 html: function(value = null) { 632 if (value == null) { 633 return this[0].innerHTML; 634 } 635 for (let i = 0; i < this.length; i++) { 636 this[i].innerHTML = value; 637 } 638 }, 639 text: function(value = null) { 640 if (value == null) { 641 return this[0].innerText; 642 } 643 for (let i = 0; i < this.length; i++) { 644 this[i].textContent = value; 645 } 646 }, 647 height: function(value = '') { 648 if (!value) { 649 const all = []; 650 for (let i = 0; i < this.length; i++) { 651 all.push(this[i].clientHeight); 652 } 653 return all; 654 } else { 655 for (let i = 0; i < this.length; i++) { 656 this[i].style.height = Number.parseInt(value) > 0 ? `${value}px` : value; 657 } 658 } 659 }, 660 show: function(display = null) { 661 for (let i = 0; i < this.length; i++) { 662 if (display != null) { 663 this[i].style.display = display; 664 } else { 665 this[i].style.display = 'block'; 666 } 667 } 668 }, 669 hide: function() { 670 for (let i = 0; i < this.length; i++) { 671 this[i].style.display = 'none'; 672 } 673 }, 674 attr: function(name, value = null) { 675 if (value == null) { 676 return this[0].getAttribute(name); 677 } 678 if (name && value) { 679 for (let i = 0; i < this.length; i++) { 680 this[i].setAttribute(name, value); 681 } 682 } 683 } 684}; 685 686const T = function(sel, ctx) { 687 return fn.init(sel, ctx); 688}; 689 690T.extend = function() { 691 let options, name, src, copy, copyIsArray, clone, 692 target = arguments[0] || {}, 693 i = 1, 694 length = arguments.length, 695 deep = false;
696 697 if (typeof target === "boolean") { 698 deep = target; 699 target = arguments[i] || {}; 700 i++; 701 } 702 703 if (typeof target !== "object" && !isFunction(target)) { 704 target = {}; 705 } 706 707 if (i === length) { 708 target = this; 709 i--; 710 } 711 712 for (; i < length; i++) { 713 if ((options = arguments[i]) != null) { 714 for (name in options) { 715 copy = options[name]; 716 if (name === "__proto__" || target === copy) { 717 continue; 718 } 719 720 if (deep && copy && (T.isPlainObject(copy) || 721 (copyIsArray = Array.isArray(copy)))) { 722 src = target[name]; 723 724 if (copyIsArray && !Array.isArray(src)) { 725 clone = []; 726 } else if (!copyIsArray && !T.isPlainObject(src)) { 727 clone = {}; 728 } else { 729 clone = src; 730 } 731 732 copyIsArray = false; 733 target[name] = T.extend(deep, clone, copy); 734 } else if (copy !== undefined) { 735 target[name] = copy; 736 } 737 } 738 } 739 } 740 741 return target; 742}; 743 744T.extend({ 745 ready: (callback) => { 746 /* dom loaded */ 747 if (doc.readyState != 'loading') { 748 callback(); 749 } 750 /* modern browsers */ 751 else if (doc.addEventListener) { 752 doc.addEventListener('DOMContentLoaded', callback); 753 } 754 /* IE <= 8 */ 755 else { 756 doc.attachEvent('onreadystatechange', function() { 757 if (doc.readyState == 'complete') 758 callback(); 759 }); 760 } 761 }, 762 isPlainObject: function(obj) { 763 let proto, Ctor; 764 if (!obj || toString.call(obj) !== "[object Object]") { 765 return false; 766 } 767 768 proto = getProto(obj); 769 770 if (!proto) { 771 return true; 772 } 773 774 Ctor = hasOwn.call(proto, "constructor") && proto.constructor; 775 return typeof Ctor === "function" && fnToString.call(Ctor) === ObjectFunctionString; 776 }, 777 isEmptyObject: function(obj) { 778 let name; 779 780 for (name in obj) { 781 return false; 782 } 783 return true; 784 }, 785 each: function(obj, callback) { 786 let length, i = 0; 787 788 if (isArrayLike(obj)) { 789 length = obj.length; 790 for (; i < length; i++) { 791 if (callback.call(obj[i], i, obj[i]) === false) { 792 break; 793 } 794 } 795 } else { 796 for (i in obj) { 797 if (callback.call(obj[i], i, obj[i]) === false) { 798 break; 799 } 800 } 801 } 802 803 return obj; 804 }, 805 inArray: function(elem, arr, i) { 806 return arr == null ? -1 : indexOf.call(arr, elem, i); 807 }, 808 wrap: function(toWrap, wrapper, className = '') { 809 wrapper = wrapper || document.createElement('div'); 810 811 if (className != '') 812 wrapper.classList.add(className); 813 814 toWrap.parentNode.insertBefore(wrapper, toWrap); 815 return wrapper.appendChild(toWrap); 816 }, 817 setCookie: function(cookieName, cookieValue, exdays) { 818 let d = new Date(); 819 d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000)); 820 let expires = 'expires=' + d.toUTCString(); 821 document.cookie = cookieName + '=' + cookieValue + ';' + expires + ';path=/'; 822 }, 823 getCookie: function(cookieName) { 824 let name = cookieName + '='; 825 let decodedCookie = decodeURIComponent(document.cookie); 826 let ca = decodedCookie.split(';'); 827 for (let i = 0; i < ca.length; i++) { 828 let c = ca[i]; 829 while (c.charAt(0) == ' ') { 830 c = c.substring(1); 831 } 832 if (c.indexOf(name) == 0) { 833 return c.substring(name.length, c.length); 834 } 835 } 836 return ''; 837 }, 838 browser: function() { 839 const brwoser = navigator.userAgent; 840 if (brwoser.indexOf('Firefox') > -1) { 841 return 'Mozilla Firefox'; 842 } else if (brwoser.indexOf('Opera') > -1 || brwoser.indexOf('OPR') > -1) { 843 return 'Opera'; 844 } else if (brwoser.indexOf('Trident') > -1) { 845 return 'Microsoft Internet Explorer'; 846 } else if (brwoser.indexOf('Edge') > -1) { 847 return 'Microsoft Edge'; 848 } else if (brwoser.indexOf('Chrome') > -1) { 849 return 'Google Chrome'; 850 } else if (brwoser.indexOf('Safari') > -1) { 851 return 'Apple Safari'; 852 } else { 853 return 'unknown'; 854 } 855 }, 856 isMobile: function() {
857 if ((/Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i.test(navigator.userAgent)) && window.innerWidth < 768) { 858 return true; 859 } else { 860 return false; 861 } 862 }, 863 getLink: function(param, value, link) { 864 let re = new RegExp('[\?\&]' + param + '=', 'g'); 865 let url = link || window.location.href; 866 if (re.test(url)) { 867 re = new RegExp('([\?\&]' + param + '=)(.*?)&', 'g'); 868 if (re.test(url)) { 869 url = url.replace(re, '$1' + value + '&'); 870 } else { 871 re = new RegExp('([\?\&]' + param + '=)(.*?)$', 'g'); 872 url = url.replace(re, '$1' + value); 873 } 874 } else if (/\?/g.test(url)) { 875 url += '&' + param + '=' + value; 876 } else { 877 url += '?' + param + '=' + value; 878 } 879 if (value === '') { 880 re = new RegExp('([\?\&])' + param + '=[^?&]*&?', 'g'); 881 url = url.replace(re, '$1'); 882 } 883 url = url.replaceAll(/[?&]$/g, ''); 884 if (param !== 'pg') url = url.replaceAll(/(\?|\&)pg=\d+/ig, "$1pg=1"); 885 if (param !== 'ps') url = url.replaceAll(/(\?|\&)ps=\d+/ig, "$1ps=1"); 886 return url; 887 }, 888 accordion: function(element) { 889 let self = this, 890 accBody = null; 891 892 function openAction(collapseElement) { 893 T(collapseElement).addClass('show'); 894 } 895 896 function closeAction(collapseElement) { 897 T(collapseElement).removeClass('show'); 898 } 899 900 self.toggle = function(e) { 901 if (e && e.target.tagName === 'A') { e.preventDefault(); } 902 const accWrapper = element.closest('.accordion-wrapper'); 903 if (accWrapper) { 904 const items = Array.from(accWrapper.querySelectorAll('[data-toggle="accordion"]')); 905 items.forEach(item => { 906 if (element == item) return; 907 const itemBody = document.querySelector(item.getAttribute('data-target') || item.getAttribute('href')) || item.nextElementSibling; 908 if (itemBody) closeAction(itemBody); 909 T(item).removeClass('active'); 910 }); 911 } 912 if (T(element).hasClass('active')) { self.hide(); } else { self.show(); } 913 }; 914 915 self.hide = function() { 916 closeAction(accBody); 917 T(element).removeClass('active'); 918 }; 919 920 self.show = function() { 921 openAction(accBody); 922 T(element).addClass('active'); 923 }; 924 925 tInitFn(function() { 926 if (element.Accordion == 1) return; 927 accBody = document.querySelector(element.getAttribute('data-target') || element.getAttribute('href')) || element.nextElementSibling; 928 929 if(element.getAttribute('data-mobile') == 'true') { accBody.setAttribute('data-mobile', 'true'); } 930 if(element.getAttribute('data-mobile') == 'true' && !T.isMobile()) { return; } 931 932 if (T(element).hasClass('active')) { accBody.classList.add('show'); } 933 if (!element.Accordion) { T(element).on('click', self.toggle); } 934 935 self.element = element; 936 element.Accordion = 1; 937 }); 938 939 return; 940 }, 941 dropdown: function(element) { 942 let self = this, 943 parent; 944 945 function preventEmptyAnchor(anchor) { 946 (anchor.href && anchor.href.slice(-1) === '#' || anchor.parentNode && anchor.parentNode.href && 947 anchor.parentNode.href.slice(-1) === '#') && this.preventDefault(); 948 } 949 950 function toggleDismiss() { 951 if (element.open) 952 T(document).on('click', dismissHandler); 953 else 954 T(document).off('click', dismissHandler); 955 } 956 957 function dismissHandler(e) { 958 let eventTarget = e.target; 959 960 if (['A', 'BUTTON'].includes(eventTarget.nodeName)) { 961 self.hide(eventTarget); 962 } else if (!element.contains(eventTarget) && parent.contains(eventTarget)) { 963 return; 964 } 965 966 self.hide(eventTarget); 967 preventEmptyAnchor.call(e, eventTarget); 968 } 969 970 function clickHandler(e) { 971 self.show(); 972 preventEmptyAnchor.call(e, e.target); 973 } 974 975 self.show = function() { 976 parent.classList.add('show'); 977 element.open = true; 978 T(element).off('click', clickHandler); 979 setTimeout(function() { 980 toggleDismiss(); 981 }, 1); 982 }; 983 984 self.hide = function(eventTarget) { 985 parent.classList.remove('show'); 986 element.open = false;
987 toggleDismiss(); 988 setTimeout(function() { 989 element.Dropdown && T(element).on('click', clickHandler); 990 if (typeof element.dataset.callback === 'string' && typeof window[element.dataset.callback] === 'function') { 991 window[element.dataset.callback](element, eventTarget); 992 } 993 }, 1); 994 }; 995 996 tInitFn(function() { 997 if (element.Dropdown == 1) return; 998 parent = element.parentNode; 999 menu = parent.querySelector('.dropdown-menu'); 1000 if (!element.open) { 1001 T(element).on('click', clickHandler); 1002 } 1003 element.open = false; 1004 self.element = element; 1005 element.Dropdown = 1; 1006 }); 1007 }, 1008 tab: function(element) { 1009 const self = this; 1010 let next, activeTab, nextContent, activeContent, tabs, property; 1011 1012 function setActiveTab(next) { 1013 activeTab = tabs.getElementsByClassName('active')[0]; 1014 if (!activeTab) { 1015 console.warn(`activeTab element undefined`); 1016 return; 1017 } 1018 activeContent = document.querySelector(activeTab.querySelector('a').getAttribute('href')); 1019 if (!activeContent) { 1020 console.warn(`activeContent element undefined`); 1021 return; 1022 } 1023 T(activeTab).removeClass('active'); 1024 T(next.parentNode).addClass('active'); 1025 triggerHide(); 1026 } 1027 1028 function triggerHide() { 1029 T(nextContent).addClass('active'); 1030 T(activeContent).removeClass('active'); 1031 } 1032 1033 function clickHandler(e) { 1034 e.preventDefault(); 1035 next = e.currentTarget; 1036 self.show(); 1037 } 1038 1039 self.show = function() { 1040 next = next || element; 1041 nextContent = document.querySelector(next.getAttribute('href')); 1042 appendContent = document.querySelector(next.dataset.content) || document.querySelector(next.getAttribute('href')); 1043 property = next.dataset.property; 1044 if (!T(next.parentNode).hasClass('active') || T(next.parentNode).hasClass('load')) { 1045 if((next.dataset.href || '').trim() != '' && !T(next.parentNode).hasClass('loaded')) { 1046 T(nextContent).addClass('is-loading'); 1047 let url = next.dataset.href; 1048 if (!element.dataset?.endpoint == 'base') url = getEndpoint('', next.dataset.href); 1049 1050 axios.get(url).then(response => { 1051 appendContent.innerHTML = property ? response.data[property] : response.data; 1052 1053 T(next.parentNode).addClass('loaded'); 1054 T(next.parentNode).removeClass('load'); 1055 T(nextContent).removeClass('is-loading'); 1056 1057 if(typeof window[next.dataset.callback] == 'function'){ 1058 window[next.dataset.callback](next, nextContent, appendContent); 1059 } 1060 1061 evalScripts(appendContent.innerHTML); 1062 try { 1063 favouriteProducts.set(); 1064 compareSet(); 1065 } catch (error) {} 1066 }).catch(error => console.log(`Tab content not loaded => ${error}`)); 1067 } 1068 } 1069 if (!T(next.parentNode).hasClass('active')) setActiveTab(next); 1070 }; 1071 1072 tInitFn(function() { 1073 if (element.Tab == 1) return; 1074 tabs = element.closest('.tab-nav'); 1075 T(element).on('click', clickHandler); 1076 self.element = element; 1077 element.Tab = 1; 1078 }); 1079 }, 1080 placeholder: { 1081 createPlaceholder: function(element) { 1082 const parentNode = element.parentNode; 1083 const isRequired = element.required || T(element).hasClass('required') || String(element.getAttribute('data-validate')).includes('required'); 1084 const span = (parentNode.querySelector('.input-placeholder')) ? parentNode.querySelector('.input-placeholder') : document.createElement('span'); 1085 span.className = "input-placeholder" + (element.value != '' ? ' focused' : ''); 1086 1087 let text = element.getAttribute('data-placeholder') || element.getAttribute('placeholder'); 1088 if (text == null) return false;
1089 1090 text += isRequired ? '<span class="input-placeholder-required fw-bold text-danger">*</span>' : ''; 1091 1092 span.innerHTML = text; 1093 1094 return span; 1095 }, 1096 show: function(e) { 1097 const parentNode = e.parentNode; 1098 T(e).removeClass('form-control-placeholder-hidden'); 1099 T(parentNode.querySelector('.input-placeholder')).addClass('focused'); 1100 }, 1101 hide: function(e) { 1102 const parentNode = e.parentNode; 1103 if (e.value === '') T(parentNode.querySelector('.input-placeholder')).removeClass('focused'); 1104 }, 1105 visible: function(e) { 1106 T(e).addClass('form-control-placeholder-hidden'); 1107 }, 1108 reset: function(element) { 1109 if (element && element.Reset != 1) return; 1110 1111 if (element) { 1112 if (element.value === '') { 1113 T.placeholder.hide(element); 1114 T.placeholder.visible(element); 1115 } else { 1116 T.placeholder.show(element); 1117 } 1118 } 1119 1120 const selectItem = T('.form-control-placeholder[data-toggle="placeholder"]'); 1121 if (selectItem.length > 0) { 1122 Array.from(selectItem).forEach(item => { 1123 if (item.value === '') { 1124 T.placeholder.hide(item); 1125 T.placeholder.visible(item); 1126 } else { 1127 T.placeholder.show(item); 1128 } 1129 }); 1130 } 1131 }, 1132 init: function(element = null) { 1133 if (element.Placeholder == 1 || T.placeholder.createPlaceholder(element) == false) return; 1134 1135 setTimeout(() => { 1136 element.parentNode.insertBefore(T.placeholder.createPlaceholder(element), element.nextSibling); 1137 T(element.parentNode).addClass('position-relative'); 1138 T(element).addClass('loaded form-control-placeholder'); 1139 element.Reset = 1; 1140 1141 if (element.tagName == 'SELECT') { 1142 T(element).on('change', () => { 1143 T.placeholder.reset(element); 1144 }); 1145 } else { 1146 1147 T(element).on('paste', () => { 1148 setTimeout(() => { 1149 if (element.value !== '') T.placeholder.show(element); 1150 }, 11); 1151 }); 1152 1153 T(element).on('input', () => { 1154 if (element.value !== '') T.placeholder.show(element); 1155 }); 1156 1157 T(element).on('blur', () => { 1158 T.placeholder.reset(element); 1159 }); 1160 } 1161 1162 T.placeholder.reset(element); 1163 1164 element = element; 1165 element.Placeholder = 1; 1166 }, 250); 1167 }, 1168 }, 1169 notify: function(options) { 1170 const self = this; 1171 let defaults = { 1172 text: "", 1173 stopOnFocus: false, 1174 duration: 6000, 1175 gravity: "top", /* top || bottom */ 1176 position: 'right', /* left || right */ 1177 className: '', /* default : success || danger */ 1178 iconClass : '', 1179 }; 1180 const nameRule = { 1181 wrapId: 'tsoft-notify-' + defaults.gravity + '-' + defaults.position, 1182 wrapClass: 'tsoft-notify-wrapper notify-' + defaults.gravity + ' notify-' + defaults.position, 1183 notify: 'notify-item' 1184 }; 1185 1186 /*Extend options*/ 1187 if (typeof options === 'object') { 1188 defaults = T.extend(defaults, options); 1189 } 1190 1191 self.createWrap = function() { 1192 let notifyWrapEl = document.querySelector(`.tsoft-notify-wrapper.notify-${defaults.gravity}.notify-${defaults.position}`); 1193 if (notifyWrapEl == null) { 1194 notifyWrapEl = document.createElement('div'); 1195 notifyWrapEl.id = nameRule.wrapId; 1196 notifyWrapEl.className = nameRule.wrapClass; 1197 document.body.appendChild(notifyWrapEl); 1198 } 1199 1200 return notifyWrapEl; 1201 } 1202 1203 self.build = function() { 1204 let myNotify = document.createElement('div'); 1205 myNotify.className = nameRule.notify + ' ' + defaults.className + ' fade-in'; 1206 myNotify.innerHTML = `<div class="notify-text">${defaults.text}</div>`; 1207 1208 if (defaults.iconClass) { 1209 const iconEl = document.createElement('span'); 1210 iconEl.className = 'notify-icon'; 1211 iconEl.innerHTML = `<i class="${defaults.iconClass}"></i>`; 1212 myNotify.prepend(iconEl); 1213 } 1214 1215 const closeEl = document.createElement('span'); 1216 closeEl.className = 'notify-close'; 1217 closeEl.innerHTML = '<i class="ti-close"></i>'; 1218 1219 closeEl.addEventListener('click', function(event) { 1220 event.stopPropagation(); 1221 self.removeEl(myNotify); 1222 window.clearTimeout(myNotify.timeOutValue); 1223 }.bind(this)); 1224 1225 myNotify.appendChild(closeEl); 1226 1227 if (defaults.duration > 0) { 1228 myNotify.timeOutValue = window.setTimeout(function() { 1229 this.removeEl(myNotify); 1230 }.bind(this), 1231 defaults.duration 1232 ); 1233 } 1234 1235 if (defaults.stopOnFocus && defaults.duration > 0) { 1236 /* Stop duration */ 1237 myNotify.addEventListener('mouseover', event => { 1238 window.clearTimeout(myNotify.timeOutValue); 1239 }); 1240 1241 /* Add back the timeout */ 1242 myNotify.addEventListener('mouseleave', event => { 1243 myNotify.timeOutValue = window.setTimeout(e => { 1244 self.removeEl(myNotify); 1245 }, defaults.duration); 1246 }); 1247 } 1248 1249 return myNotify; 1250 } 1251 1252 self.removeEl = function(el) {
1253 const wrapper = document.querySelector('#' + nameRule.wrapId); 1254 if (wrapper.querySelectorAll('.' + nameRule.notify).length > 1) { 1255 wrapper.removeChild(el); 1256 } else { 1257 document.body.removeChild(wrapper); 1258 } 1259 } 1260 1261 tInitFn(function() { 1262 const wrapper = self.createWrap(); 1263 wrapper.appendChild(self.build()); 1264 }); 1265 }, 1266 mask: function(element, validate, regex, max = null) { 1267 const self = this; 1268 if (typeof element == 'string') element = T(element); 1269 if (!element) return; 1270 1271 Array.from(element).forEach(item => { 1272 validate = item.dataset.type ? item.dataset.type : validate; 1273 regex = item.dataset.mask ? item.dataset.mask : regex; 1274 1275 if (!validate) 1276 return; 1277 1278 function run(event) { 1279 let re; 1280 switch (validate) { 1281 case 'string': 1282 re = /[^\p{L}\s\-]/gu; 1283 break; 1284 case 'number': 1285 re = /[^0-9]/g; 1286 break; 1287 case 'price': 1288 re = /[^0-9.,]/g; 1289 break; 1290 case 'password' : 1291 re = /^\s+|\s+$/; 1292 break; 1293 case 'email' : 1294 re = /^\s+|(?:^|\s|,|;|!|:|-|\.|\?)[ÄçÅüöı]/g; 1295 break; 1296 case 'custom' : 1297 if (regex) re = new RegExp(`[${regex}]`,"g"); 1298 break; 1299 default: 1300 console.log(validate + ', undefined mask...'); 1301 } 1302 1303 if (event.type == 'paste') { 1304 setTimeout(() => { 1305 const value = event?.target?.value || null; 1306 if (!re || value == null) return; 1307 if (re.test(String(value))) event.target.value = event.target.value.replace(re, ''); 1308 }, 10); 1309 } else if (event.type == 'keypress') { 1310 let value = event.target.value; 1311 if (event.target.closest('.t-phone-masked')) value = event.target.value.replaceAll(/\D+/g, ''); 1312 if (max != null && value.length >= max) event.preventDefault(); 1313 if (re && re.test(String(event.key))) event.preventDefault(); 1314 1315 } 1316 } 1317 1318 tInitFn(function() { 1319 if (item.Mask == 1) return; 1320 1321 T(item).on('paste', (event) => { 1322 run(event); 1323 }); 1324 1325 T(item).on('keypress', (event) => { 1326 run(event); 1327 }); 1328 1329 self.item = item; 1330 item.Mask = 1; 1331 }); 1332 }); 1333 1334 return; 1335 }, 1336 zoomImage: function(element, options) { 1337 if (T.isMobile()) return; 1338 1339 if (element == '' || T(element).length < 1) 1340 return console.log('zoom image undefined'); 1341 1342 if (!element.dataset.image) 1343 return console.log('zoom image "data-image" undefined'); 1344 1345 const self = this; 1346 let lens, image, result, maxSize, control = 0; 1347 1348 const defaults = T.extend({ 1349 target: element.dataset.target || '#product-right', 1350 type: 'zoom', /* zoom or magnifier */ 1351 width: element.dataset.width || element.clientWidth, 1352 height: element.dataset.height || element.clientHeight, 1353 }, options); 1354 1355 function zoomPos() { 1356 if (T(defaults.target).length < 1) return; 1357 1358 const targetEl = T(defaults.target)[0].getBoundingClientRect();; 1359 let top = targetEl.top; 1360 if (document.body.scrollTop > targetEl.top || document.documentElement.scrollTop > targetEl.top) { 1361 const fark = document.documentElement.scrollTop - top; 1362 if (fark > 0) top = top + fark; 1363 } else { 1364 top = targetEl.top; 1365 } 1366 return top; 1367 } 1368 1369 function createZoom() { 1370 element = T(element)[0]; 1371 1372 lens = document.createElement('div'); 1373 lens.className = 't-zoom-lens'; 1374 element.parentElement.classList.add('t-zoom-image'); 1375 element.parentElement.style.height = `${element.height + 1}px`; 1376 element.parentElement.insertBefore(lens, element); 1377 1378 lens.addEventListener('mousemove', zoomEnable); 1379 element.addEventListener('mousemove', zoomEnable); 1380 lens.addEventListener('touchmove', zoomEnable); 1381 element.addEventListener('touchmove', zoomEnable); 1382 } 1383 1384 function createImg() { 1385 if (T(defaults.target).length < 1) return;
1386 const targetEl = T(defaults.target)[0]; 1387 1388 control = 1; 1389 result = document.createElement('div'); 1390 result.className = 't-zoom-result'; 1391 result.style.backgroundImage = "url('" + image.src + "')"; 1392 result.style.position = "absolute"; 1393 result.style.pointerEvents = "none"; 1394 document.body.appendChild(result); 1395 1396 result.style.width = `${defaults.width}px`; 1397 result.style.height = `${defaults.height}px`; 1398 result.style.top = `${zoomPos()}px`; 1399 result.style.left = LANGUAGE == 'ar' ? `${targetEl.offsetLeft + targetEl.clientWidth - defaults.width}px` : `${targetEl.offsetLeft}px`; 1400 1401 window.onscroll = () => { 1402 result.style.top = `${zoomPos()}px`; 1403 }; 1404 1405 image.onload = function() { 1406 result.style.backgroundSize = `${image.width}px ${image.height}px`; 1407 } 1408 } 1409 1410 function zoomEnable(e) { 1411 lens.style.height = `${element.height / (image.height / defaults.height)}px`; 1412 lens.style.width = `${element.width / (image.width / defaults.width)}px`; 1413 1414 let pos, x, y; 1415 e.preventDefault(); 1416 pos = getCursorPos(e); 1417 x = pos.x - (lens.offsetWidth / 2); 1418 y = pos.y - (lens.offsetHeight / 2); 1419 1420 if (pos.x <= 0) { 1421 return; 1422 } else if (control == 0) { 1423 createImg(); 1424 } 1425 1426 if (x > element.width - lens.offsetWidth) {x = element.width - lens.offsetWidth;} 1427 if (x < 0) {x = 0;} 1428 1429 if (y > element.height - lens.offsetHeight) {y = element.height - lens.offsetHeight;} 1430 if (y < 0) {y = 0;} 1431 lens.style.left = x + "px"; 1432 lens.style.top = y + "px"; 1433 1434 const bgPosX = x * (defaults.width / lens.offsetWidth), 1435 bgPosY = y * (defaults.height / lens.offsetHeight); 1436 1437 result.style.backgroundPosition = `-${bgPosX}px -${bgPosY}px`; 1438 } 1439 1440 function getCursorPos(e) { 1441 let a, x = 0, y = 0; 1442 e = e || window.event; 1443 a = element.getBoundingClientRect(); 1444 x = e.pageX - a.left; 1445 y = e.pageY - a.top; 1446 x = x - window.pageXOffset; 1447 y = y - window.pageYOffset; 1448 return { x: x, y: y }; 1449 } 1450 1451 function destroy() { 1452 T('.t-zoom-image').removeClass('t-zoom-image'); 1453 element.parentElement.style.height = ''; 1454 if(lens) element.parentNode.removeChild(lens); 1455 if (control == 1) { 1456 document.body.removeChild(result); 1457 } 1458 control = 0; 1459 } 1460 1461 tInitFn(function() { 1462 if (element.zoomImage == 1) return; 1463 1464 element.parentNode.addEventListener('mouseenter', e => { 1465 if (element.active != 1) { 1466 image = new Image(); 1467 image.src = element.dataset.image; 1468 maxSize = element.width + (element.width * .2); 1469 1470 image.onload = function() { 1471 if (image.width > maxSize) { 1472 element.active = 1; 1473 createZoom(); 1474 } 1475 } 1476 } else { 1477 createZoom(); 1478 } 1479 }); 1480 element.parentNode.addEventListener("mouseleave", destroy); 1481 1482 self.element = element; 1483 element.zoomImage = 1; 1484 }); 1485 }, 1486 modal: function(element, options) { 1487 T.modal.instance = T.modal.instance || {}; 1488 T.modal.counter = T.modal.counter || 0; 1489 T.modal.close = T.modal.close || null; 1490 1491 const defaults = T.extend({ 1492 id: '', 1493 class: '', 1494 width: '', 1495 height: '', 1496 title: '', 1497 html: '', 1498 close: false, 1499 autoClose: 0, 1500 disableClose: false, 1501 openCallback: () => {}, 1502 closeCallback: () => {}, 1503 buttons: [ 1504 /* {text: '', href: '', class: '', event: function() {}, }, */ 1505 ], 1506 }, (element.nodeName == undefined ? arguments[0] : options)); 1507 1508 function createModal() { 1509 const modal = document.createElement('div'); 1510 const modalBackdrop = document.createElement('div'); 1511 const modalContent = document.createElement('div'); 1512 1513 T.modal.counter++; 1514 if (defaults.id.trim() == '') { 1515 defaults.id = 'popup' + T.modal.counter; 1516 } 1517 modal.id = defaults.id; 1518 1519 if (T('.t-modal-wrapper').length > 0) { 1520 modal.className = `t-modal-wrapper fade-in modal-level-${T.modal.counter} ${defaults.class}`; 1521 } else { 1522 modal.className = 't-modal-wrapper fade-in ' + defaults.class; 1523 } 1524 1525 modal.classList.add(THEME_FOLDER); 1526 1527 const modalContainer = document.createElement('div'); 1528 modalContainer.classList.add('t-modal-container'); 1529 1530 if (defaults.width.trim() != '') { 1531 modalContent.style.width = defaults.width; 1532 } 1533 1534 if (defaults.height.trim() != '') { 1535 modalContent.style.height = defaults.height; 1536 } 1537 1538 modalBackdrop.className = 't-modal-backdrop'; 1539 modalBackdrop.addEventListener('click', (event) => { 1540 closeModal(modal); 1541 }); 1542 modalContainer.appendChild(modalBackdrop); 1543 1544 modalContent.className = 't-modal-content'; 1545 modalContent.innerHTML = defaults.title + defaults.html; 1546 1547 if (defaults.buttons.length > 0) { 1548 const modalButtons = document.createElement('div'); 1549 modalButtons.className = 'd-flex justify-content-end gap-1 mt-1 t-modal-buttons'; 1550 defaults.buttons.forEach(btn => { 1551 const button = document.createElement('a'); 1552 button.className = btn.class || ''; 1553 button.innerHTML = btn.text || ''; 1554 button.href = btn.href || 'javascript:void(0)'; 1555 if (btn.event) { 1556 button.addEventListener('click', () => { 1557 try { 1558 btn.event(); 1559 } catch (error) { 1560 console.error('Button event error:', error); 1561 } 1562 }); 1563 } 1564 modalButtons.append(button); 1565 }); 1566 modalContent.append(modalButtons); 1567 } 1568 1569 if(defaults.close === true) { 1570 const closeEl = document.createElement('span'); 1571 closeEl.className = 't-modal-close'; 1572 closeEl.id = 't-modal-close-' + T.modal.counter; 1573 closeEl.innerHTML = '<i class="ti-close"></i>'; 1574 closeEl.addEventListener('click', () => { 1575 closeModal(modal); 1576 }); 1577 modalContainer.appendChild(closeEl); 1578 } 1579 1580 if (defaults.autoClose > 0) { 1581 setTimeout(() => { 1582 closeModal(modal); 1583 }, defaults.autoClose); 1584 } 1585 1586 T.modal.close = () => { 1587 closeModal(modal); 1588 }; 1589 1590 modal.appendChild(modalContainer); 1591 modalContainer.appendChild(modalContent); 1592 1593 setTimeout(() => { 1594 Array.from(modal.querySelectorAll('[data-action="destroy"]')).forEac
1594h(destroyEl => { 1595 destroyEl.addEventListener('click', e => { 1596 e.preventDefault(); 1597 e.stopPropagation(); 1598 closeModal(modal); 1599 }); 1600 }); 1601 }, 150); 1602 1603 defaults.openCallback?.(); 1604 return modal; 1605 } 1606 1607 function closeModal(modal) { 1608 if (defaults.disableClose == true) return; 1609 if (document.getElementById(modal.id) == null) return; 1610 document.body.removeChild(modal); 1611 T.modal.counter--; 1612 1613 defaults.closeCallback?.(); 1614 1615 if(T.modal.counter == 0) { 1616 T('html').removeClass('is-active-modal'); 1617 } 1618 } 1619 1620 tInitFn(function() { 1621 T('html').addClass('is-active-modal'); 1622 document.body.appendChild(createModal()); 1623 evalScripts(document.querySelector('.t-modal-wrapper:last-child').innerHTML); 1624 }); 1625 }, 1626 popupWin: function(element) { 1627 const self = this; 1628 1629 const openPopup = function() { 1630 const width = element.dataset.width ? element.dataset.width : 570; 1631 const elId = element.dataset.id ? element.dataset.id : `popupwin-${T.popupWin.counter}`; 1632 const url = element.dataset.url || element.getAttribute('href'); 1633 1634 if(url == 'undefined' || url == '') { 1635 return; 1636 } 1637 1638 axios.get(url).then(response => { 1639 const result = response.data; 1640 T.modal({ 1641 id: elId, 1642 width: width > 0 ? `${width}px` : 'auto', 1643 html: (typeof result == 'object' && element.dataset.property && result[element.dataset.property]) ? result[element.dataset.property] : result, 1644 close: true 1645 }); 1646 T.buttonLock.unlock(); 1647 }).catch(error => console.warn(`Popupwin error => ${error}`)); 1648 } 1649 1650 tInitFn(function() { 1651 if(element.Popupwin == 1) return; 1652 1653 T.popupWin.counter = T.popupWin.counter || 0; 1654 T.popupWin.counter++; 1655 1656 T(element).on('click', function(e) { 1657 e.preventDefault(); 1658 T.buttonLock.dom = element; 1659 T.buttonLock.lock(); 1660 openPopup(); 1661 }); 1662 1663 self.element = element; 1664 element.Popupwin = 1; 1665 }); 1666 }, 1667 tooltip: function(element, options = {}) { 1668 const self = this, 1669 dataset = element.dataset, 1670 titleString = element.getAttribute('title') || dataset.title; 1671 1672 let tooltip = null; 1673 1674 const defaults = { 1675 placement: options.placement ? options.placement : (dataset.placement ? dataset.placement : 'top'), 1676 container: element.closest('.t-modal-wrapper') ? element.closest('.t-modal-wrapper') : document.body, 1677 /* delay: options.delay ? options.delay : 200, */ 1678 }; 1679 1680 function createTooltip(){ 1681 tooltip = document.createElement('div'); 1682 let arrow = document.createElement('div'), 1683 tooltipInner = document.createElement('div'); 1684 1685 T(tooltip).addClass('t-tooltip fade-in'); 1686 T(arrow).addClass('arrow'); 1687 T(tooltipInner).addClass('tooltip-inner'); 1688 tooltipInner.innerHTML = titleString; 1689 tooltip.appendChild(arrow); 1690 tooltip.appendChild(tooltipInner); 1691 defaults.container.appendChild(tooltip); 1692 } 1693 1694 function destroyTooltip(){ 1695 tooltip.remove(); 1696 delete element.Tooltip; 1697 } 1698 1699 function stylePos(){ 1700 if (!element) return; 1701 if (!tooltip) return; 1702 1703 const rect = element.getBoundingClientRect(), 1704 leftPosition = rect.left + (element.offsetWidth/2), 1705 topPosition = rect.top + (defaults.container === document.body ? window.pageYOffset : defaults.container.offsetTop + defaults.container.scrollTop) - tooltip.offsetHeight; 1706 1707 tooltip.style.top = topPosition + 'px'; 1708 tooltip.style.left = leftPosition + 'px'; 1709 tooltip.style.right = 'auto'; 1710 } 1711 1712 function toggleEvents() { 1713 T(element).on(mouseHoverEvents[0], self.show); 1714 T(element).on(mouseHoverEvents[1], self.hide); 1715 T(element).on('click', self.hide); 1716 } 1717 1718 self.show = function () { 1719 createTooltip(); 1720 stylePos(); 1721 } 1722 1723 self.hide = function () { 1724 destroyTooltip(); 1725 } 1726 1727 tInitFn(function() { 1728 if (element.Tooltip == 1) return; 1729 if (!titleString) return; 1730 1731 if (!element.Tooltip) { 1732 toggleEvents(); 1733 } 1734 1735 self.element = element; 1736 element.Tooltip = 1; 1737 }); 1738 }, 1739 popConfirm: function(element) { 1740 let popWrapper = null; 1741 1742 const eventBtn = (btn, callback = null) => { 1743 const opt = element.dataset; 1744 1745 if (typeof callback === 'string' && typeof window[callback] === 'function') { 1746 T.buttonLock.dom = T(btn)[0]; 1747 T.buttonLock.lock(); 1748 if (opt.loading) T(btn).addClass('is-loading'); 1749 else T(popWrapper)[0].remove(); 1750 1751 window[callback](element, btn); 1752 setTimeout(() => { 1753 if (opt.loading) T(btn).removeClass('is-loading'); 1754 T(popWrapper)[0].remove(); 1755 window.onresize = ''; 1756 T.buttonLock.unlock(); 1757 }, 500); 1758 } else { 1759 T(popWrapper)[0].remove(); 1760 } 1761 } 1762 1763 function show() { 1764 if (T(popWrapper).length > 0) T(popWrapper)[0].remove(); 1765 createPopConfirm(element); 1766 element.open = true; 1767 toggleDismiss(); 1768 } 1769 1770 function toggleDismiss() { 1771 if (element.open == true) { 1772 T(document).on('click', dismissHandler); 1773 window.onresize = windowSize; 1774 } else { 1775 T(document).off('click', dismissHandler); 1776 } 1777 } 1778 1779 function dismissHandler(e) { 1780 if (T('.t-popconfirm').length > 0) { 1781 let eventTarget = e.target; 1782 1783 const tagNames = document.querySelector('.t-popconfirm').getElementsByTagName("*"); 1784 const tag = Array.from(tagNames).find(el => el == eventTarget); 1785 1786 if (tag || e.target.closest('[data-toggle="popconfirm"]') == element) { 1787 return; 1788 } else { 1789 T(popWrapper)[0].remove(); 1790 window.onresize = ''; 1791 } 1792 } else { 1793 element.open = false;
1794 toggleDismiss(); 1795 } 1796 } 1797 1798 function createPopConfirm(element) { 1799 const opt = element.dataset; 1800 1801 popWrapper = document.createElement('div'); 1802 T(popWrapper).addClass('t-popconfirm fade-in'); 1803 1804 const popInner = document.createElement('div'); 1805 T(popInner).addClass('t-popconfirm-inner'); 1806 1807 if (opt.title) { 1808 const title = document.createElement('div'); 1809 T(title).addClass('t-popconfirm-message'); 1810 T(title).html(`<div class="t-confirm-title">${opt.title}</div>`); 1811 1812 if (opt.icon) { 1813 const icon = document.createElement('div'); 1814 T(icon).addClass('t-popconfirm-icon'); 1815 T(icon).html(`<i class="${opt.icon}"></i>`); 1816 title.prepend(icon); 1817 } 1818 1819 popInner.prepend(title); 1820 } 1821 1822 if (opt.confirm || opt.cancel) { 1823 const buttons = document.createElement('div'); 1824 T(buttons).addClass('t-popconfirm-buttons'); 1825 1826 if (opt.confirm) { 1827 const confirm = document.createElement('button'); 1828 T(confirm).addClass('btn btn-primary t-popconfirm-confirm-btn'); 1829 T(confirm).text(opt.confirm); 1830 buttons.append(confirm); 1831 1832 T(confirm).on('click', () => { 1833 eventBtn(confirm, element.dataset.callback); 1834 }); 1835 } 1836 1837 if (opt.cancel) { 1838 const cancel = document.createElement('button'); 1839 T(cancel).addClass('btn btn-light t-popconfirm-cancel-btn'); 1840 T(cancel).text(opt.cancel); 1841 buttons.prepend(cancel); 1842 1843 T(cancel).on('click', () => { 1844 eventBtn(cancel, element.dataset.cancelcallback) 1845 }); 1846 } 1847 popInner.append(buttons); 1848 } 1849 1850 popWrapper.append(popInner); 1851 document.body.appendChild(popWrapper); 1852 stylePos(element, popWrapper); 1853 } 1854 1855 function stylePos(element, popWrapper){ 1856 if (!element || !popWrapper) return; 1857 1858 const rect = element.getBoundingClientRect(); 1859 let posY, posX; 1860 1861 if (rect.left + popWrapper.offsetWidth > window.innerWidth || (window.innerWidth - rect.right + popWrapper.offsetWidth) > window.innerWidth) { 1862 if (rect.left > (window.innerWidth - rect.right)) { 1863 posY = rect.top + window.pageYOffset - popWrapper.offsetHeight + (element.offsetHeight/2); 1864 posX = rect.right - popWrapper.offsetWidth - element.offsetWidth; 1865 1866 T(popWrapper).removeClass('popconfirm-left'); 1867 T(popWrapper).addClass('popconfirm-right'); 1868 } else { 1869 posY = rect.top + window.pageYOffset - popWrapper.offsetHeight + (element.offsetHeight/2); 1870 posX = rect.left + element.offsetWidth; 1871 T(popWrapper).removeClass('popconfirm-right'); 1872 T(popWrapper).addClass('popconfirm-left'); 1873 } 1874 } else { 1875 posY = rect.top + window.pageYOffset - popWrapper.offsetHeight; 1876 posX = rect.left + (element.offsetWidth/2); 1877 T(popWrapper).removeClass('popconfirm-right popconfirm-right'); 1878 } 1879 1880 if (posX < 1) { 1881 popWrapper.style.width = `${rect.left}px`; 1882 popWrapper.style.left = 0; 1883 posY = rect.top + window.pageYOffset - popWrapper.offsetHeight + (element.offsetHeight/2); 1884 } else { 1885 popWrapper.style.left = `${posX}px`; 1886 } 1887 1888 popWrapper.style.top = `${posY}px`; 1889 } 1890 1891 function windowSize() { 1892 stylePos(element, popWrapper); 1893 } 1894 1895 tInitFn(function() { 1896 if (element.popConfirm == 1) return; 1897 1898 if (!element.open) { 1899 T(element).on('click', show); 1900 } 1901 1902 element.open = false;
1903 self.element = element; 1904 element.popConfirm = 1; 1905 }); 1906 1907 }, 1908 drawer: function(element) { 1909 const self = this; 1910 const drawer = T(element.getAttribute('href')); 1911 if(drawer.length < 1) { 1912 T(element).addClass('d-none'); 1913 return; 1914 } 1915 1916 const overlay = T(`.drawer-overlay[data-rel="${element.getAttribute('href').replace('#', '')}"]`); 1917 const subCloseEl = T(element.getAttribute('href') + ` .sub-drawer-close[data-rel="${element.getAttribute('href').replace('#', '')}"]`); 1918 const closeEl = T(element.getAttribute('href') + ' .drawer-close'); 1919 const settings = drawer[0].dataset || {}; 1920 1921 self.show = function () { 1922 T(element).addClass('active'); 1923 drawer.addClass('animated active'); 1924 overlay.addClass('active'); 1925 document.body.classList.add(`body-${element.getAttribute('href').replace('#', '')}`); 1926 document.body.style.overflow = 'hidden'; 1927 if (settings.display == 'push') { 1928 document.body.classList.add(`drawer-${settings.position}-active`, 'drawer-animated'); 1929 } 1930 transitionCtrl(drawer[0], function() { 1931 drawer.removeClass('animated'); 1932 if (typeof settings.callback === 'string' && typeof window[settings.callback] === 'function') { 1933 window[settings.callback](); 1934 } 1935 }); 1936 } 1937 1938 self.hide = function () { 1939 T(element).removeClass('active'); 1940 drawer.addClass('animated'); 1941 drawer.removeClass('active'); 1942 if (settings.display == 'push') { 1943 document.body.classList.remove(`drawer-${settings.position}-active`); 1944 } 1945 transitionCtrl(T(drawer)[0], function() { 1946 drawer.removeClass('animated'); 1947 overlay.removeClass('active'); 1948 if (T('.drawer-overlay.active').length == 0) document.body.style.overflow = null; 1949 document.body.classList.remove(`body-${element.getAttribute('href').replace('#', '')}`); 1950 if (settings.display == 'push') { 1951 document.body.classList.remove('drawer-animated'); 1952 } 1953 }); 1954 } 1955 1956 tInitFn(function() { 1957 if(element.Drawer == 1 1958 || (element.tagName != 'A' && !element.href && drawer.length < 1) 1959 || (settings.platform == 'mobile' && !T.isMobile())) { 1960 return; 1961 } 1962 1963 if (closeEl != null) { 1964 drawer.addClass('closable-active'); 1965 } 1966 1967 T(element).on('click', function(e) { 1968 e.preventDefault(); 1969 if (T(element).hasClass('active')) { 1970 self.hide(); 1971 } else { 1972 self.show(); 1973 } 1974 }); 1975 1976 overlay.on('click', function(e) { 1977 e.preventDefault(); 1978 self.hide(); 1979 if (drawer[0].querySelectorAll('.sub-drawer-close').length > 0) T(drawer[0].querySelectorAll('.sub-drawer-close')).trigger('click'); 1980 }); 1981 1982 closeEl.on('click', function(e) { 1983 e.preventDefault(); 1984 self.hide(); 1985 if (drawer[0].querySelectorAll('.sub-drawer-close').length > 0) T(drawer[0].querySelectorAll('.sub-drawer-close')).trigger('click'); 1986 }); 1987 1988 subCloseEl.on('click', function(e) { 1989 e.preventDefault(); 1990 self.hide(); 1991 }); 1992 1993 self.element = element; 1994 element.Drawer = 1; 1995 }); 1996 }, 1997 checkValidity: function(form) { 1998 if(!form) { return; } 1999 2000 let self = this; 2001 let success = 1; 2002 const classNames = { 2003 'input': 'error-input', 2004 'errorEl': 'error-input-msg' 2005 }; 2006 const validateTool = [ 2007 'required', 2008 'email', 2009 'phone' 2010 ]; 2011 2012 self.trim = (s) => { 2013 return s.replace(/^\s+|\s+$/, ''); 2014 } 2015 2016 self.validateRequired = (input) => { 2017 if (self.trim(input.value) == '') { 2018 insertError(input, TLANG.form_required || "Bu alan boÅ bırakılamaz"); 2019 } 2020 } 2021 2022 self.validatePhone = (phone) => { 2023 if (phone.value.replaceAll(/\D/g, '').length < Number(phone.dataset.pattern || 12)) { 2024 insertError(phone, TLANG.form_required || "Bu alan boÅ bırakılamaz"); 2025 } 2026 } 2027 2028 self.validateEmail = (email) => { 2029 const 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,}))$/; 2030 2031 if (email.value == '') { 2032 return; 2033 } 2034 2035 if (!re.test(String(email.value).toLowerCase())) { 2036 insertError(email, TLANG.not_email_format || "Email formatına uygun deÄil"); 2037 } 2038 } 2039 2040 const insertError = (el, msg) => { 2041 const errorEl = document.createElement('div'); 2042 errorEl.className = classNames.errorEl; 2043 errorEl.innerHTML = msg; 2044 2045 if (el.closest('.input-group') && el.closest('.input-group').querySelector('.input-group-append')) { 2046 errorEl.style.right = (el.closest('.input-group').querySelector('.input-group-append').clientWidth + 6) + 'px'; 2047 } 2048 2049 let otherItem = null; 2050 if (el.closest('.city-input-container')) { 2051 otherItem = el.closest('.city-input-container').parentNode.querySelector('.city-select-container select'); 2052 } else if (el.closest('.town-input-container')) { 2053 otherItem = el.closest('.town-input-container').parentNode.querySelector('.town-select-container select'); 2054 } else if (el.closest('.district-input-container')) { 2055 otherItem = el.closest('.district-input-container').parentNode.querySelector('.district-select-container select'); 2056 } 2057 2058 T(el).addClass(classNames.input); 2059 T(el.parentNode).addClass('position-relative'); 2060 el.parentNode.insertBefore(errorEl, el.parentNode.lastElementChild.nextSibling); 2061 2062 if (otherItem != null && otherItem.parentNode) { 2063 let otherErrorEl = errorEl.cloneNode(true); 2064 T(otherItem).addClass(classNames.input); 2065 T(otherItem.parentNode).addClass(classNames.input); 2066 otherItem.parentNode.insertBefore(otherErrorEl, otherItem.parentNode.lastElementChild.nextSibling); 2067 T(otherItem).on('focus', () => { 2068 T(otherItem).removeClass(classNames.input); 2069 otherErrorEl.remove(); 2070 }); 2071 } 2072 2073 T(el).on('focus', () => { 2074 T(el).removeClass(classNames.input); 2075 errorEl.remove(); 2076 }); 2077 success = 0; 2078 } 2079 2080 const clearInputs = () => { 2081 const inputs = Array.from(form.querySelectorAll(`.${classNames.input}`)); 2082 if (inputs.length == 0) return;
2083 inputs.forEach(el => { 2084 el.classList.remove(classNames.input); 2085 if (el.parentNode.querySelector(`.${classNames.errorEl}`)) el.parentNode.querySelector(`.${classNames.errorEl}`).remove(); 2086 }); 2087 } 2088 2089 clearInputs(); 2090 Array.from(form.elements).forEach(el => { 2091 let validate = el.getAttribute('data-validate'); 2092 if(validate != null) { 2093 validate = validate.split(','); 2094 for (let i = 0; i < validate.length; i++) { 2095 const element = validate[i]; 2096 if(validateTool.find(x => x == element)) { 2097 const nameCapitalized = element.charAt(0).toUpperCase() + element.slice(1); 2098 const fonk = `validate${nameCapitalized}`; 2099 if(!T(el).hasClass(classNames.input)) { 2100 self[fonk](el); 2101 } 2102 } 2103 } 2104 } 2105 }); 2106 2107 return success; 2108 }, 2109 qty: function(qty) { 2110 const self = this; 2111 2112 const input = qty.querySelector('input[type="number"]'); 2113 const decreaseBtn = qty.querySelector('span.ti-minus'); 2114 const increaseBtn = qty.querySelector('span.ti-plus'); 2115 const multiItem = T('.product-multiple-item'); 2116 let inputOldCount; 2117 2118 self.calculate = function(inc, decimal) { 2119 let oldCount = Number.parseFloat(input.value); 2120 let count = oldCount; 2121 2122 if (inc != 'INPUT') { 2123 let minCount = input.min || 1; 2124 let maxCount = input.max; 2125 count += inc; 2126 if (minCount > count || (maxCount != '' && count > maxCount)) { 2127 return; 2128 } 2129 } else { 2130 oldCount = inputOldCount; 2131 } 2132 2133 if (!Number.isInteger(count)) count = Number.parseFloat(count.toFixed(decimal)); 2134 input.value = count; 2135 2136 if (qty.dataset.multiple && multiItem.length > 0) { 2137 self.multiple(count); 2138 } 2139 2140 const cb = qty.dataset.callback; 2141 if (typeof cb !== 'undefined' && typeof window[cb] === 'function' && (count != oldCount)) { 2142 window[cb](count, oldCount, qty, inc); 2143 } 2144 } 2145 2146 self.multiple = function(qtyCount) { 2147 for (let i = 0; i < multiItem.length; i++) { 2148 if (T('#multiple-price').length > 0) T('#multiple-price')[0].remove(); 2149 T(multiItem).removeClass('active'); 2150 const item = multiItem[i]; 2151 2152 if (item.dataset.min <= qtyCount && item.dataset.max >= qtyCount) { 2153 T(item).addClass('active'); 2154 if (document.querySelector('.product-multiple-scroll')) document.querySelector('.product-multiple-scroll').scrollTo(item.offsetLeft, 0); 2155 2156 if (item.closest('#product-multiple-discount').querySelector('.product-multiple-title')) { 2157 const selector = item.closest('#product-right'); 2158 if (selector == null) return; 2159 2160 let product = null; 2161 if (selector.querySelectorAll('.product-price').length) product = T(selector.querySelectorAll('.product-price')); 2162 if (selector.querySelectorAll('.product-price-not-vat').length) product = T(selector.querySelectorAll('.product-price-not-vat')); 2163 2164 const price = T(product).attr('data-price') || T(product).text() || 0, 2165 parse = T.priceToFloat(price); 2166 2167 const productCurrency = PRODUCT_DATA ? PRODUCT_DATA[0].currency_target : CURRENCY; 2168 const unitPrice = parse - (parse * item.dataset.percent / 100); 2169 const multiPrice = T.format((unitPrice) * input.value) + ' ' + productCurrency; 2170 const element = document.createElement('span'); 2171 element.id = 'multiple-price'; 2172 element.innerHTML = `<div>${multiPrice}</div><div class="multiple-unit-price">${input.value} x ${T.format(unitPrice)} ${productCurrency}</div>` 2173 2174 item.closest('#product-multiple-discount').querySelector('.product-multiple-title').append(element); 2175 } 2176 return; 2177 } 2178 } 2179 } 2180 2181 if (qty.dataset.multiple && multiItem.length > 0) { 2182 multiItem.on('click', (e) => { 2183 let item = e.target.classList['contains']('product-multiple-item') ? e.target : e.target.closest('.product-multiple-item'); 2184 input.value = item.dataset.min <= 0 ? 1 : item.dataset.min; 2185 self.calculate('INPUT'); 2186 }); 2187 } 2188 2189 tInitFn(function() { 2190 if (qty.Qty == 1) return; 2191 2192 const increment = qty.dataset.increment ? qty.dataset.increment : input.step || '1'; 2193 const decimal = increment.indexOf('.') > -1 ? increment.replaceAll(/^.*?\./g, '').trim().length : 0; 2194 2195 T(decreaseBtn).on('click', () => self.calculate(increment ? Number.parseFloat(`-${increment}`) : -1, decimal)); 2196 T(increaseBtn).on('click', () => self.calculate(increment ? Number.parseFloat(increment) : 1, decimal)); 2197 2198 input.addEventListener('focus', () => inputOldCount = Number.parseFloat(input.value)); 2199 input.addEventListener('blur', () => self.calculate('INPUT', decimal)); 2200 2201 self.qty = qty; 2202 qty.Qty = 1; 2203 }); 2204 2205 }, 2206 loginForm: function (element) { 2207 const self = this; 2208 2209 self.submit = function(form, submitButton) { 2210 if(!T.checkValidity(form)) { 2211 T.buttonLock.unlock(); 2212 return; 2213 } 2214 2215 let loginType = 'email'; 2216 const prefix = form.dataset.prefix || ''; 2217 const vendor = form.dataset.vendor || 0; 2218 const cb = form.dataset.callback || 'rastgelebirfonksionadi'; 2219 const selectedLoginType = (prefix != '') ? (document.getElementById(prefix + 'login-type') != null ? document.getElementById(prefix + 'login-type') : document.getElementById('login-type')) : null; 2220 2221 if (selectedLoginType != null) { 2222 loginType = selectedLoginType.querySelector('li.active').dataset.type; 2223 } 2224 2225 if (form.dataset.vendorcode == "1") { 2226 loginType = 'vendor-code'; 2227 } 2228 2229 memberLogin({ 2230 type: loginType, 2231 prefix: prefix, 2232 vendor: vendor, 2233 callback: typeof window[cb] === 'function' ? window[cb] : function(){}, 2234 submitter: submitButton, 2235 form: form 2236 }); 2237 }; 2238 2239 tInitFn(function() { 2240 if (1 == element.loginForm) 2241 return; 2242 2243 const prefix = element.dataset.prefix || ''; 2244 const email = element.querySelector(`#${prefix}email`); 2245 const phone = element.querySelector(`#${prefix}phone`); 2246 const rememberMe = element.querySelector(`#${prefix}remember`); 2247 2248 if (email) { 2249 const emailVal = T.getCookie('email'); 2250 if (emailVal) email.value = emailVal; 2251 } 2252 if (phone) { 2253 const phoneVal = T.getCookie('phone'); 2254 if (phoneVal) phone.value = phoneVal; 2255 } 2256 if (rememberMe) { 2257 const rememberVal = T.getCookie('rememberMe'); 2258 if (rememberVal) rememberMe.checked = true; 2259 } 2260 2261 T(element).on('submit', e => { 2262 e.preventDefault(); 2263 e.stopPropagation(); 2264 T.buttonLock.dom = e.submitter; 2265 T.buttonLock.lock(); 2266 self.submit(e.target, e.submitter); 2267 }); 2268 2269 self.loginForm = element; 2270 element.loginForm = 1; 2271 }); 2272 }, 2273 otpLogin: function (element) { 2274 const self = this; 2275 2276 const modalOtp = function(receiver, ttl) { 2277 loadSubFolder({ 2278 pageId: 5, 2279 blockParentId: 1006, 2280 subFolder: 'otp', 2281 params: { 2282 receiver: receiver, 2283 ttl: ttl 2284 }, 2285 success: function(loadRes){ 2286 T.modal({ 2287 id: 'otp-login-popup', 2288 html: loadRes, 2289 close: true, 2290 width: '480px' 2291 }); 2292 } 2293 }); 2294 } 2295 2296 self.submit = async function(form) { 2297 if(!T.checkValidity(form)) { 2298 T.buttonLock.unlock(); 2299 return; 2300 } 2301 2302 const formData = new FormData(form); 2303 const channel = form.dataset.otpChannel || ''; 2304 let otp = formData.get('otp').trim(); 2305 if (channel === 'sms') otp = otp.replaceAll(/\D/g, ''); 2306 2307 try { 2308 const response = await axios.post(getEndpoint('OTP_REQUEST', encodeURIComponent(otp))
2308); 2309 const result = response.data; 2310 if(result.status == 1) { 2311 modalOtp(otp, result.ttl || 60); 2312 } else if (result.ttl) { 2313 modalOtp(otp, result.ttl || 60); 2314 return; 2315 } 2316 2317 const message = result.statusText; 2318 const field = form.querySelector(`input[name="${result.field}"]`); 2319 if (message) { 2320 if (field) { 2321 popoverAlert.show( 2322 field, 2323 message, 2324 3000, 2325 `btn ${(result.status === true) ? 'btn-success' : 'btn-danger'} text-left`, 2326 false 2327 ); 2328 } else { 2329 T.notify({ 2330 text: message, 2331 className: result.status == 1 ? 'success' : 'danger', 2332 duration: 1800, 2333 }); 2334 } 2335 } 2336 } catch (error) { 2337 console.error(error); 2338 } finally { 2339 T.buttonLock.unlock(); 2340 } 2341 } 2342 2343 tInitFn(function() { 2344 if(element.otpLogin == 1) return; 2345 2346 T(element).on('submit', e => { 2347 e.preventDefault(); 2348 e.stopPropagation(); 2349 T.buttonLock.dom = e.submitter; 2350 T.buttonLock.lock(); 2351 self.submit(e.target); 2352 }); 2353 2354 self.otpLogin = element; 2355 element.otpLogin = 1; 2356 }); 2357 }, 2358 setLanguage: { 2359 set: function(element) { 2360 let language = (element.nodeName == 'SELECT' ? element.value : element.dataset.language) || ''; 2361 if(language == '') return; 2362 2363 const link_type = T('#link_type')[0], 2364 link_table_id = T('#link_table_id')[0]; 2365 2366 let link = link_type ? `/${link_type.value}` : ''; 2367 link += link_table_id ? `/${link_table_id.value}` : ''; 2368 2369 axios.get(`/srv/service/language/change/${language}${link}`).then(response => { 2370 const result = response.data; 2371 if(result.success == 1) { 2372 if (result.link == '') { 2373 (link_table_id && link_table_id.value == 1) ? window.location.href = '/' : window.location.reload(); 2374 } else { 2375 window.location.href = '/' + result.link; 2376 } 2377 } 2378 }).catch(error => console.warn(`Set language error => ${error}`)); 2379 }, 2380 init: function(element) { 2381 const self = this; 2382 let event = 'click'; 2383 2384 if(element.Language == 1) return; 2385 if (element.nodeName == 'SELECT') event = 'change'; 2386 2387 T(element).on(event, () => { 2388 T.setLanguage.set(element) 2389 }); 2390 2391 self.element = element; 2392 element.Language = 1; 2393 } 2394 }, 2395 setCurrency: { 2396 set: function(element, reload = true) { 2397 let currency = (element.nodeName == 'SELECT' ? element.value : element.dataset.currency) || ''; 2398 if(currency == '') return; 2399 2400 axios.get(`/srv/shopping/shopping/set-currency/${currency}`).then(response => { 2401 if(response.data == 1) { 2402 if (reload == true) window.location.reload(); 2403 } 2404 }).catch(error => console.warn(`Set currency error => ${error}`)); 2405 }, 2406 init: function(element) { 2407 const self = this; 2408 let event = 'click'; 2409 2410 if(element.Currency == 1) return; 2411 if (element.nodeName == 'SELECT') event = 'change'; 2412 2413 T(element).on(event, () => { 2414 T.setCurrency.set(element) 2415 }); 2416 2417 self.element = element; 2418 element.Currency = 1; 2419 } 2420 }, 2421 vat: function(p, vat) { 2422 if (p > 0 && p <= 0.0000001) { 2423 return 0; 2424 } 2425 let priceParam = Number.isNaN(Number(p)) ? 0.0 : Number.parseFloat(p); 2426 let vatParam = Number.isNaN(Number(vat)) > 0 ? 0 : Number.parseInt(vat); 2427 priceParam = priceParam * (100 + vatParam) / 100; 2428 return T.format(priceParam); 2429 }, 2430 format: function(p, d) { 2431 let decimals = typeof d != 'undefined' ? d : typeof DECIMAL_LENGTH !== 'undefined' ? DECIMAL_LENGTH : 2; 2432 let n = !Number.isFinite(Number(+p)) ? 0 : +p, 2433 prec = !Number.isFinite(Number(+decimals)) ? 2 : Math.abs(decimals), 2434 sep = (typeof SEP_THO === 'undefined') ? '.' : SEP_THO, 2435 dec = (typeof SEP_DEC === 'undefined') ? ',' : SEP_DEC, 2436 toFixedFix = function(n, prec) {
2437 const k = Math.pow(10, prec); 2438 return '' + Math.round(n * k) / k; 2439 }; 2440 let s = ''; 2441 2442 s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.'); 2443 if (s[0].length > 3) { 2444 s[0] = s[0].replaceAll(/\B(?=(?:\d{3})+(?!\d))/g, sep); 2445 } 2446 if ((s[1] || '').length < prec) { 2447 s[1] = s[1] || ''; 2448 s[1] += new Array(prec - s[1].length + 1).join('0'); 2449 } 2450 return s.join(dec); 2451 }, 2452 priceToFloat: function(p) { 2453 if (!p) return false; 2454 p = String(p); 2455 let price = ''; 2456 if (SEP_THO === ',') { 2457 price = Number.parseFloat(p.replaceAll(',', '')); 2458 } else if (SEP_DEC == ",") { 2459 price = Number.parseFloat(p.replaceAll('.', '').replace(',', '.')); 2460 } else { 2461 price = Number.parseFloat(p); 2462 } 2463 return price; 2464 }, 2465 timeConverter: function(UNIX_timestamp = 0, format = 'd.m.y') { 2466 let time = Number.parseInt(UNIX_timestamp); 2467 if(Number.isNaN(time) || time < 1000000000) { 2468 time = 1000000000; 2469 } else if (time < 9000000000) { 2470 time = time * 1000; 2471 } 2472 2473 const pad = s => (s < 10) ? '0' + s : s; 2474 const date = new Date(time); 2475 2476 format = format.replaceAll(/y+/ig, date.getFullYear()); 2477 format = format.replaceAll(/d+/ig, pad(date.getDate())); 2478 format = format.replaceAll(/m+/ig, pad(date.getMonth() + 1)); 2479 format = format.replaceAll(/h+/ig, pad(date.getHours())); 2480 format = format.replaceAll(/i+/ig, pad(date.getMinutes())); 2481 format = format.replaceAll(/s+/ig, pad(date.getSeconds())); 2482 2483 return format; 2484 }, 2485 affix: function(element) { 2486 if(T.isMobile()) return; 2487 let self = this, 2488 detectDirect = 0, 2489 tempMarginTop = 0, 2490 topDistance = element.dataset.top || Number(Number(T(`header [data-toggle="sticky"]:not([data-mobile="true"])`).height()) + 10) || 0, 2491 bottomDistance = element.dataset.bottom || 0, 2492 parentElement = document.querySelector(element.dataset.parent) || element.parentElement || null, 2493 marginElement = T(parentElement.querySelector(`.affix-margin`))[0]; 2494 elementHeight = T(element).height(), 2495 windowHeight = window.innerHeight, 2496 diff = windowHeight - elementHeight, 2497 2498 tInitFn(function() { 2499 if (element == null || element.Sticky == 1 || parentElement == null ) return; 2500 2501 T(element).addClass('position-sticky'); 2502 T(parentElement).addClass('position-relative'); 2503 2504 if(diff > 0){ 2505 element.setAttribute("style", `top:${topDistance}px`); 2506 return; 2507 } 2508 2509 if(!marginElement){ 2510 marginElement = document.createElement("div"); 2511 marginElement.classList.add("affix-margin"); 2512 element.parentNode.insertBefore(marginElement,element); 2513 } 2514 2515 document.addEventListener("scroll", (e) => { 2516 topDistance = element.dataset.top || Number(Number(T(`header [data-toggle="sticky"]:not([data-mobile="true"])`).height()) + 10) || 0, 2517 elementOffsetTop = element.offsetTop; 2518 if (detectDirect < window.pageYOffset) { 2519 if (elementOffsetTop <= tempMarginTop) { tempMarginTop = elementOffsetTop;} 2520 element.setAttribute("style", `top:${diff-bottomDistance}px; bottom:auto`); 2521 } else { 2522 if (elementOffsetTop >= tempMarginTop) { tempMarginTop = elementOffsetTop;} 2523 element.setAttribute("style", `bottom:${diff-topDistance}px; top:auto`); 2524 } 2525 marginElement.style = `margin-top:${tempMarginTop}px`; 2526 detectDirect = window.pageYOffset; 2527 }); 2528 2529 self.affix = element; 2530 element.affix = 1; 2531 }); 2532 }, 2533 sticky: function(element) { 2534 const self = this, 2535 elementHeight = element.offsetHeight, 2536 parentElement = document.querySelector(element.dataset.parent) || null, 2537 elementTop = Number(parentElement.offsetTop), 2538 className = element.dataset.class || 'sticky', 2539 topScroll = Number(element.dataset.scroll || 0), 2540 elementDirect = element.dataset.direction || false, 2541 mobile = element.dataset.mobile || false; 2542 2543 let detectDirect = 0 2544 const direction = () => { 2545 if (elementDirect == false) return; 2546 2547 if (detectDirect < window.pageYOffset) { 2548 T(element).removeClass(`${className}-direction`); 2549 } else if (detectDirect > window.pageYOffset) { 2550 T(element).addClass(`${className}-direction`); 2551 } 2552 detectDirect = window.pageYOffset; 2553 }; 2554 2555 tInitFn(function() {
2556 if (element == null || element.Sticky == 1 || parentElement == null) return; 2557 2558 if (mobile == 'true') { 2559 if (!T.isMobile()) return; 2560 } 2561 2562 window.addEventListener('scroll', () => { 2563 if (window.pageYOffset > (topScroll + elementTop)) { 2564 parentElement.style.paddingTop = `${elementHeight}px`; 2565 T(parentElement).addClass(`${className}-wrapper`); 2566 T(element).addClass(className); 2567 window[String(element.dataset.callback)]?.('active'); 2568 direction(); 2569 } else { 2570 parentElement.style.paddingTop = null; 2571 T(parentElement).removeClass(`${className}-wrapper`); 2572 T(element).removeClass(className); 2573 window[String(element.dataset.callback)]?.('passive'); 2574 } 2575 }); 2576 2577 self.sticky = element; 2578 element.Sticky = 1; 2579 }); 2580 }, 2581 buttonLock: { 2582 dom: null, 2583 text: '', 2584 tmp: '', 2585 lock: function() { 2586 const self = this; 2587 if (self.dom == null) 2588 return; 2589 2590 self.dom.setAttribute('disabled', true); 2591 2592 if (self.dom.nodeName == 'INPUT') { 2593 self.tmp = self.dom.value; 2594 self.text.trim() ? self.dom.value = self.text : ''; 2595 } 2596 else { 2597 self.tmp = self.dom.innerHTML; 2598 self.text.trim() ? self.dom.innerHTML = self.text : ''; 2599 } 2600 }, 2601 unlock: function() { 2602 const self = this; 2603 if (self.dom == null) 2604 return; 2605 2606 self.dom.removeAttribute('disabled'); 2607 2608 if (self.dom.nodeName == 'INPUT') { self.dom.value = self.tmp; } 2609 else { self.dom.innerHTML = self.tmp; } 2610 } 2611 }, 2612 inputFile: function(element) { 2613 const self = this; 2614 const label = element.id ? T(`label[for="${element.id}"]`)[0] : element.nextElementSibling; 2615 const defaultVal = label.querySelector('span').innerHTML || element.placeholder || TLANG.choose_file || 'Dosya Seçiniz'; 2616 const changeFile = e => { 2617 const input = e.target; 2618 const fileName = (input.files && input.files.length > 1) ? `${input.files.length} ${TLANG.file || 'Dosya'}` : input.value.split('\\').pop(); 2619 label.querySelector('span').innerHTML = fileName || defaultVal; 2620 } 2621 tInitFn(function() { 2622 if(element == null || element.inputFile == 1) 2623 return; 2624 2625 element.addEventListener('change', changeFile); 2626 element.style.display = 'none'; 2627 2628 self.inputFile = element; 2629 element.inputFile = 1; 2630 }); 2631 }, 2632 equalHeight: function(element) { 2633 const self = this; 2634 const wrapper = typeof element != 'string' ? T(element)[0] : null; 2635 const dom = wrapper == null ? T(element) : T(element.querySelectorAll(`${element.dataset.selector}`)); 2636 const selectors = dom.length ? dom : null; 2637 2638 const equalHeightFn = function() { 2639 setTimeout(function() { 2640 selectors.height('auto'); 2641 const maxHeight = Math.max(...selectors.height()); 2642 selectors.height(maxHeight); 2643 selectors.addClass('height-equalized'); 2644 }, 100); 2645 }; 2646 2647 tInitFn(function() { 2648 if(selectors == null || element == null) return; 2649 equalHeightFn(); 2650 self.equalHeight = element; 2651 element.equalHeight = 1; 2652 }); 2653 }, 2654 signInGoogleAuth: function(element) { 2655 tInitFn(function() { 2656 if(element.SocialGoogle == 1) return; 2657 2658 T(element).on('click', () => { 2659 googleTokenClientFn(); 2660 }); 2661 2662 element.SocialGoogle = 1; 2663 }); 2664 }, 2665 productListLayout: function(element) { 2666 const self = this; 2667 let layout = ''; 2668 let event = 'click'; 2669 const changeLayout = () => { 2670 layout = (element.nodeName == 'SELECT' ? element.value : element.dataset.layout) || ''; 2671 if(layout == '') return; 2672 2673 T.setCookie('selected_layout', layout, 365); 2674 location.reload(); 2675 } 2676 2677 tInitFn(function() { 2678 if(element.Layout == 1) return; 2679 2680 if (element.nodeName == 'SELECT') { 2681 event = 'change'; 2682 } 2683 2684 T(element).on(event, changeLayout); 2685 2686 self.element = element; 2687 element.Layout = 1; 2688 }); 2689 }, 2690 shareButton: function(element) { 2691 tInitFn(function() { 2692 if(element.ShareButton == 1) return; 2693 2694 T(element).on('click', () => { 2695 const platform = element.dataset.platform; 2696 const image = element.dataset.image ? (element.dataset.image.startsWith('http') ? element.dataset.image : window.location.origin + element.dataset.image) : ''; 2697 const title = element.dataset.title; 2698 const url = window.location.origin + window.location.pathname; 2699 2700 switch(platform) { 2701 case 'facebook': 2702 window.open(`https://www.facebook.com/sharer/sharer.php?u=${url}`, '_blank', 'width=600,height=400'); 2703 break; 2704 case 'twitter': 2705 window.open(`https://x.com/share?url=${url}&text=${title}`, '_blank', 'width=600,height=400'); 2706 break; 2707 case 'pinterest': 2708 window.open(`http://pinterest.com/pin/create/button/?url=${url}&media=${image}&description=${title}`, '_blank', 'width=600,height=400'); 2709 break; 2710 case 'whatsapp': 2711 window.open(`https://wa.me/?text=${url} - ${title}`, '_blank', 'width=600,height=400'); 2712 break; 2713 case 'linkedin': 2714 window.open(`https://www.linkedin.com/sharing/share-offsite?url=${url}&title=${title}`, '_blank', 'width=600,height=400'); 2715 break; 2716 default: 2717 break; 2718 } 2719 }); 2720 2721 element.ShareButton = 1; 2722 }); 2723 }, 2724}); 2725 2726const formLoader = options => { 2727 const opt = { 2728 selector: 'form:last', 2729 url: '', 2730 data: null, 2731 callback: function() {} 2732 }; 2733 2734 for (let i in options) { 2735 opt[i] = options[i]; 2736 } 2737 2738 const fillFormFields = (result) => { 2739 const form = document.querySelector(opt.selector); 2740 for (const key in result) { 2741 const value = result[key]; 2742 2743 if (value == null) continue; 2744 if (form == null) return; 2745 2746 const input = form.querySelector(`[name="${key}"]`); 2747 2748 if(input != null) { 2749 if (input.type === 'radio' || input.type === 'checkbox') { 2750 const inputsRadio = form.querySelectorAll(`[name="${key}"]`);
2751 Array.from(inputsRadio).forEach(item => { 2752 (value == item.value || Number.parseInt(value) === 1) ? item.checked = value : ''; 2753 2754 }); 2755 } else if(input.value === '' || typeof input.value === "undefined") { 2756 input.value = value; 2757 } 2758 } 2759 } 2760 2761 opt.callback(result); 2762 return; 2763 }; 2764 2765 if (String(opt.url).trim() == '' && opt.data !== null) { 2766 fillFormFields(opt.data); 2767 return; 2768 } 2769 2770 if (String(opt.url).trim() == '') return; 2771 2772 axios.get(opt.url).then(response => { 2773 const result = typeof response.data == 'object' && response.data != '' ? response.data : response; 2774 fillFormFields(result); 2775 }).catch(error => { 2776 console.warn(`FormLoader Error => ${error}`); 2777 }); 2778} 2779 2780const taxLoader = options => { 2781 const self = this; 2782 if (LANGUAGE != 'tr') return; 2783 const opt = { 2784 selector: '', 2785 limit: 15, 2786 start: 0, 2787 }; 2788 2789 for (let i in options) { 2790 opt[i] = options[i]; 2791 } 2792 2793 const element = T(opt.selector)[0]; 2794 if (!element) return; 2795 2796 const loadTax = (taxData, taxUl, limit) => { 2797 for (let i=opt.start; i<limit; i++) { 2798 const taxItem = document.createElement('li'); 2799 taxItem.className = 't-tax-list-item'; 2800 taxItem.dataset.value = taxData[i]; 2801 taxItem.innerText = taxData[i]; 2802 2803 T(taxItem).on('click', item => { 2804 element.value = item.target.dataset.value; 2805 if (element.parentNode.querySelector('.input-placeholder')) { 2806 element.parentNode.querySelector('.input-placeholder').classList.add('focused'); 2807 } 2808 }); 2809 taxUl.append(taxItem); 2810 } 2811 opt.start = limit; 2812 }; 2813 2814 axios.get(getEndpoint('TAX_OFFICE_LIST')).then(response => { 2815 const data = response.data; 2816 if ((data !== null || typeof data !== 'undefined')) { 2817 const taxData = data.toString().split("\n"), 2818 collator = new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' }); 2819 taxData.sort(collator.compare); 2820 2821 element.setAttribute('readonly', 'readonly'); 2822 element.classList.add('t-tax-form'); 2823 element.parentNode.classList.add('t-tax-office'); 2824 2825 const taxHtml = document.createElement('div'); 2826 taxHtml.className = 't-tax-list p-1'; 2827 taxHtml.style.display = 'none'; 2828 2829 const taxUl = document.createElement('ul'); 2830 taxUl.className = 'w-100 list-style-none t-tax-list-ul'; 2831 2832 const taxSearch = document.createElement('input'); 2833 taxSearch.type = 'search'; 2834 taxSearch.className = 'w-100 form-control form-control-sm no-cancel mb-1 t-tax-search'; 2835 taxSearch.placeholder = TLANG.search || 'Ara'; 2836 2837 taxSearch.addEventListener('keyup', event => { 2838 const value = event.target.value, 2839 searchString = String(value).toLocaleUpperCase('tr-TR'), 2840 items = taxUl.querySelectorAll('.t-tax-list-item'); 2841 2842 if (searchString != '' && searchString.length >= 2) { 2843 opt.limit = taxData.length; 2844 loadTax(taxData, taxUl, opt.limit); 2845 Array.from(items).forEach(li => { 2846 if(String(li.dataset.value).toLocaleUpperCase('tr-TR').indexOf(searchString) > -1) { 2847 li.classList.remove('d-none'); 2848 } else { 2849 li.classList.add('d-none'); 2850 } 2851 }); 2852 } else { 2853 Array.from(items).forEach(li => { 2854 li.classList.remove('d-none'); 2855 }); 2856 } 2857 }); 2858 2859 let count = 1; 2860 taxUl.addEventListener('scroll', () => { 2861 if (taxUl.scrollTop + taxUl.clientHeight >= taxUl.scrollHeight - 1) { 2862 count ++; 2863 if (count * opt.limit >= taxData.length) { 2864 opt.limit = taxData.length; 2865 loadTax(taxData, taxUl, opt.limit); 2866 return; 2867 } else { 2868 loadTax(taxData, taxUl, (count * opt.limit)); 2869 } 2870 } 2871 }); 2872 loadTax(taxData, taxUl, opt.limit); 2873 2874 const taxItem = document.createElement('li'); 2875 taxItem.classList.add('t-tax-list-item'); 2876 2877 taxHtml.append(taxSearch); 2878 taxHtml.append(taxUl); 2879 element.parentNode.insertBefore(taxHtml, element); 2880 2881 element.addEventListener('click', () => { 2882 taxHtml.classList.add('show'); 2883 taxHtml.style.display = 'block'; 2884 }); 2885 2886 element.addEventListener('focus', () => { 2887 taxHtml.classList.add('show'); 2888 taxHtml.style.display = 'block'; 2889 }); 2890 } 2891 }); 2892 2893 document.addEventListener('click', e => {
2894 let taxDom = e.target.nodeName == 'I' ? e.target.parentElement : e.target; 2895 if (!taxDom.classList.contains('t-tax-form') && !e.target.classList.contains('t-tax-search') && document.querySelectorAll('.t-tax-list.show').length) { 2896 document.querySelector('.t-tax-list').style.display = 'none'; 2897 document.querySelector('.t-tax-list.show').classList.remove('show'); 2898 } 2899 }); 2900} 2901 2902const regionLoader = options => { 2903 const self = this; 2904 2905 const opt = { 2906 country: { selector: '.country:last', value: '' }, 2907 city: { selector: '', value: '' }, 2908 town: { selector: '', value: '' }, 2909 district: { selector: '', value: '' }, 2910 countryLimit: true 2911 }; 2912 2913 for (let i in options) { 2914 opt[i] = options[i]; 2915 } 2916 2917 opt.country.value = opt.country.value || ''; 2918 opt.city.value = opt.city.value || ''; 2919 opt.town.value = opt.town.value || ''; 2920 opt.district.value = opt.district.value || ''; 2921 2922 let lastTownParent = null; 2923 let lastDistrictParent = null; 2924 2925 const getInput = input => T(`input[name="${input}"]`).length > 0 ? T(`input[name="${input}"]`)[0] : null; 2926 const hasSelect = selector => selector && T(selector).length > 0; 2927 const getSelect = selector => hasSelect(selector) ? T(selector)[0] : null; 2928 2929 const clearSelectOptions = selector => { 2930 if (!hasSelect(selector)) return; 2931 Array.prototype.forEach.call(T(`${selector} > option:not(:first-child)`), node => { 2932 node.parentNode.removeChild(node); 2933 }); 2934 } 2935 2936 const showInput = input => { 2937 const el = getInput(input); 2938 if (el) el.parentNode.classList.remove('d-none'); 2939 } 2940 2941 const hideSelect = selector => { 2942 const el = getSelect(selector); 2943 if (!el) return; 2944 el.parentNode.classList.add('d-none'); 2945 if (el.dataset.validate) el.dataset.validate = ''; 2946 } 2947 2948 const showSelect = selector => { 2949 const el = getSelect(selector); 2950 if (!el) return; 2951 el.parentNode.classList.remove('d-none'); 2952 } 2953 2954 const isValueEqual = (left, right) => `${left}`.trim() === `${right}`.trim(); 2955 2956 const setInputDisabled = (input, disabled) => { 2957 const el = getInput(input); 2958 if (!el) return; 2959 if (disabled) { 2960 el.setAttribute('disabled', 'disabled'); 2961 } else { 2962 el.removeAttribute('disabled'); 2963 } 2964 } 2965 2966 const setSelectDisabled = (selector, disabled) => { 2967 const el = getSelect(selector); 2968 if (!el) return; 2969 if (disabled) { 2970 el.setAttribute('disabled', 'disabled'); 2971 } else { 2972 el.removeAttribute('disabled'); 2973 } 2974 } 2975 2976 const setSelectValue = (selector, value) => { 2977 const selectEl = getSelect(selector); 2978 if (!selectEl) return false; 2979 if (value === undefined || value === null || value === '') return false; 2980 const targetValue = `${value}`.trim(); 2981 for (let i = 0; i < selectEl.options.length; i++) { 2982 if (`${selectEl.options[i].value}`.trim() === targetValue) { 2983 selectEl.value = selectEl.options[i].value; 2984 return true; 2985 } 2986 } 2987 return false; 2988 } 2989 2990 const matchSelectValueByText = (selector, text) => { 2991 const selectEl = getSelect(selector); 2992 if (!selectEl || !text) return ''; 2993 const targetText = `${text}`.trim(); 2994 for (let i = 0; i < selectEl.options.length; i++) { 2995 if (`${selectEl.options[i].text}`.trim() === targetText) { 2996 selectEl.value = selectEl.options[i].value; 2997 return selectEl.options[i].value; 2998 } 2999 } 3000 return ''; 3001 } 3002 3003 const resolveSelectedValue = (selector, rawValue) => { 3004 if (setSelectValue(selector, rawValue)) return rawValue; 3005 const asText = matchSelectValueByText(selector, rawValue); 3006 if (asText) return asText; 3007 return ''; 3008 } 3009 3010 const useInputFallback = (input, selector, { disableInput = false } = {}) => { 3011 showInput(input); 3012 setInputDisabled(input, disableInput); 3013 if (!hasSelect(selector)) return; 3014 clearSelectOptions(selector); 3015 const selectEl = getSelect(selector); 3016 if (selectEl) selectEl.value = ''; 3017 setSelectDisabled(selector, true); 3018 hideSelect(selector); 3019 } 3020 3021 const clearTownInputs = () => { 3022 opt.town.value = ''; 3023 opt.district.value = ''; 3024 const townInput = getInput('town'); 3025 const districtInput = getInput('district'); 3026 if (townInput) townInput.value = ''; 3027 if (districtInput) districtInput.value = ''; 3028 } 3029 3030 const clearDistrictInputs = () => { 3031 opt.district.value = ''; 3032 const districtInput = getInput('district'); 3033 if (districtInput) districtInput.value = ''; 3034 } 3035 3036 const loadCountries = () => { 3037 axios.get(getEndpoint('REGION_COUNTRIES')).then(response => { 3038 const data = response.data; 3039 data.countries = data.countries.map((country) => { 3040 return { 3041 code: country.code, 3042 name: country.title, 3043 pattern : country.pattern 3044 } 3045 }); 3046 if (data.countries.length == 1) {
3047 opt.country.value = data.countries[0].code; 3048 } 3049 3050 if (T(opt.country.selector).length < 1) { 3051 if (opt.country.selector == '') { 3052 loadCities(data.selected || MEMBER_INFO.COUNTRY || 'TR'); 3053 } 3054 return false; 3055 } 3056 3057 if (opt.country.value === '') { 3058 opt.country.value = data.selected || MEMBER_INFO.COUNTRY || 'TR'; 3059 } 3060 3061 Array.prototype.forEach.call(T(`${opt.country.selector} > option:not(:first-child)`), node => { 3062 node.parentNode.removeChild(node); 3063 }); 3064 3065 data.countries.forEach(country => { 3066 let option = document.createElement('option'); 3067 option.value = country.code; 3068 option.innerHTML = country.name; 3069 if(country.code == opt.country.value) { 3070 option.selected = true; 3071 } 3072 document.querySelector(opt.country.selector).appendChild(option); 3073 }); 3074 3075 T(opt.country.selector).trigger('change'); 3076 }).catch(error => { 3077 console.warn(`Country Loaded Error => ${error}`); 3078 return; 3079 }); 3080 } 3081 3082 const loadCities = (parentCode = 'TR') => { 3083 const flagInputs = document.querySelectorAll('[data-flag-masked]'); 3084 Array.from(flagInputs).forEach(item => { 3085 if (item.value != '') return; 3086 3087 if (item.dataset.key != parentCode) { 3088 try { 3089 tFlag.changePhoneMask(null, item, parentCode); 3090 } catch (error) { 3091 } 3092 } 3093 3094 }); 3095 3096 if (T(opt.city.selector).length < 1) { 3097 useInputFallback('city', opt.city.selector); 3098 useInputFallback('town', opt.town.selector); 3099 useInputFallback('district', opt.district.selector); 3100 return false; 3101 } 3102 3103 axios.get(getEndpoint('REGION_CITIES', parentCode)).then(response => { 3104 const data = response.data.cities; 3105 3106 if (data.length < 1) { 3107 useInputFallback('city', opt.city.selector); 3108 useInputFallback('town', opt.town.selector); 3109 useInputFallback('district', opt.district.selector); 3110 return; 3111 } 3112 3113 setInputDisabled('town', true); 3114 setInputDisabled('district', true); 3115 setSelectDisabled(opt.city.selector, false); 3116 3117 const cityInput = getInput('city'); 3118 if (cityInput) cityInput.parentNode.classList.add('d-none'); 3119 showSelect(opt.city.selector); 3120 3121 if(T('[name="province"]').length > 0) { 3122 const smallCode = parentCode.toLowerCase(); 3123 if (['us', 'cn', 'de', 'ru', 'gb', 'in', 'es'].includes(smallCode)) { 3124 T('[name="province"]')[0].closest('.popover-wrapper:first').classList.add('d-none'); 3125 } else { 3126 T('[name="province"]')[0].closest('.popover-wrapper:first').classList.remove('d-none'); 3127 } 3128 } 3129 3130 clearSelectOptions(opt.city.selector); 3131 3132 data.forEach(city => { 3133 let option = document.createElement('option'); 3134 option.value = city.code; 3135 option.innerHTML = city.title; 3136 option.selected = isValueEqual(opt.city.value, city.code); 3137 document.querySelector(opt.city.selector).appendChild(option); 3138 }); 3139 3140 opt.city.value = resolveSelectedValue(opt.city.selector, opt.city.value); 3141 T(opt.city.selector).trigger('change'); 3142 }).catch(() => { 3143 useInputFallback('city', opt.city.selector); 3144 useInputFallback('town', opt.town.selector); 3145 useInputFallback('district', opt.district.selector); 3146 }); 3147 } 3148 3149 const loadTowns = parentCode => { 3150 if (!parentCode) { 3151 clearTownInputs(); 3152 const hasCityOptions = hasSelect(opt.city.selector) && T(`${opt.city.selector} > option:not(:first-child)`).length > 0; 3153 useInputFallback('town', opt.town.selector, { disableInput: hasCityOptions }); 3154 useInputFallback('district', opt.district.selector, { disableInput: hasCityOptions }); 3155 return false;
3156 } else { 3157 setInputDisabled('town', false); 3158 setSelectDisabled(opt.town.selector, false); 3159 } 3160 3161 if (lastTownParent !== null && parentCode !== lastTownParent) { 3162 clearTownInputs(); 3163 } 3164 lastTownParent = parentCode; 3165 lastDistrictParent = null; 3166 3167 if (T(opt.town.selector).length < 1) { 3168 useInputFallback('town', opt.town.selector); 3169 useInputFallback('district', opt.district.selector); 3170 return false; 3171 } 3172 3173 axios.get(getEndpoint('REGION_TOWN', parentCode)).then(response => { 3174 let data = response.data.towns; 3175 3176 if (data.length < 1) { 3177 useInputFallback('town', opt.town.selector); 3178 useInputFallback('district', opt.district.selector); 3179 return; 3180 } 3181 3182 data = data.sort((a, b) => a.title.localeCompare(b.title)); 3183 3184 const townInput = getInput('town'); 3185 if (townInput) townInput.parentNode.classList.add('d-none'); 3186 showSelect(opt.town.selector); 3187 3188 clearSelectOptions(opt.town.selector); 3189 3190 data.forEach(town => { 3191 let option = document.createElement('option'); 3192 option.value = town.code; 3193 option.innerHTML = town.title; 3194 option.selected = isValueEqual(opt.town.value, town.code); 3195 document.querySelector(opt.town.selector).appendChild(option); 3196 }); 3197 3198 opt.town.value = resolveSelectedValue(opt.town.selector, opt.town.value); 3199 if (!opt.town.value) { 3200 setInputDisabled('district', true); 3201 } 3202 T(opt.town.selector).trigger('change'); 3203 }).catch(() => { 3204 useInputFallback('town', opt.town.selector); 3205 useInputFallback('district', opt.district.selector); 3206 }); 3207 } 3208 3209 const loadDistricts = parentCode => { 3210 if (!parentCode) { 3211 clearDistrictInputs(); 3212 const hasTownOptions = hasSelect(opt.town.selector) && T(`${opt.town.selector} > option:not(:first-child)`).length > 0; 3213 useInputFallback('district', opt.district.selector, { disableInput: hasTownOptions }); 3214 return false; 3215 } else { 3216 setInputDisabled('district', false); 3217 setSelectDisabled(opt.district.selector, false); 3218 } 3219 3220 if (lastDistrictParent !== null && parentCode !== lastDistrictParent) { 3221 clearDistrictInputs(); 3222 } 3223 lastDistrictParent = parentCode; 3224 3225 if (T(opt.district.selector).length < 1) { 3226 useInputFallback('district', opt.district.selector); 3227 return false; 3228 } 3229 3230 axios.get(getEndpoint('REGION_DISTRICTS', parentCode)).then(response => { 3231 let data = response.data.districts; 3232 3233 if (data.length < 1) { 3234 useInputFallback('district', opt.district.selector); 3235 return; 3236 } 3237 3238 data = data.sort((a, b) => a.title.localeCompare(b.title)); 3239 3240 clearSelectOptions(opt.district.selector); 3241 3242 data.forEach(district => { 3243 let option = document.createElement('option'); 3244 option.value = district.code; 3245 option.dataset.postacode = district.postalcode || ''; 3246 option.innerHTML = district.title; 3247 option.selected = opt.district.value == district.code; 3248 document.querySelector(opt.district.selector).appendChild(option); 3249 }); 3250 3251 if (T(`${opt.district.selector} > option[value="${opt.district.value}"]`).length > 0) { 3252 T(opt.district.selector)[0].value = opt.district.value; 3253 T(opt.district.selector).trigger('change'); 3254 } 3255 const districtInput = getInput('district'); 3256 if (districtInput) districtInput.parentNode.classList.add('d-none'); 3257 showSelect(opt.district.selector); 3258 }).catch(() => { 3259 useInputFallback('district', opt.district.selector); 3260 }); 3261 } 3262 3263 T(opt.country.selector).on('change', e => { 3264 loadCities(e.target.value); 3265 }); 3266 3267 T(opt.city.selector).on('change', e => { 3268 loadTowns(e.target.value); 3269 if (T('[name="city"]').length > 0 && T(opt.city.selector)[0].name != 'city' && T(opt.city.selector)[0].value != '') { 3270 T('[name="city"]')[0].value = T(opt.city.selector)[0].options[T(opt.city.selector)[0].options.selectedIndex].text; 3271 } 3272 }); 3273 3274 T(opt.town.selector).on('change', e => { 3275 loadDistricts(e.target.value); 3276 if (T('[name="town"]').length > 0 && T(opt.town.selector)[0].name != 'town' && T(opt.city.selector)[0].value != '') { 3277 T('[name="town"]')[0].value = T(opt.town.selector)[0].options[T(opt.town.selector)[0].options.selectedIndex].text; 3278 } 3279 }); 3280 3281 T(opt.district.selector).on('change', e => { 3282 if (T('[name="district"]').length > 0 && T(opt.district.selector)[0].name != 'district' && T(opt.city.selector)[0].value != '') { 3283 T('[name="district"]')[0].value = T(opt.district.selector)[0].options[T(opt.district.selector)[0].options.selectedIndex].text;
3284 const postacode = T(opt.district.selector)[0].options[T(opt.district.selector)[0].options.selectedIndex].dataset.postacode || ''; 3285 if (T('[name="post_code"]').length > 0) T('[name="post_code"]')[0].value = postacode; 3286 } 3287 }); 3288 3289 loadCountries(); 3290} 3291 3292const tsRegion = options => { 3293 const self = this; 3294 3295 const opt = { 3296 container: '.regions', 3297 countryLimit: 1, 3298 storeLimit: 0, 3299 regionLimit: null, 3300 country: { 3301 container: '.country-container', 3302 select: '.country-select', 3303 value: '', 3304 caption: '' 3305 }, 3306 state: { 3307 container: '.state-container', 3308 select: '.state-select', 3309 selectContainer: '.state-select-container', 3310 input: '.state-input', 3311 inputContainer: '.state-input-container', 3312 value: '', 3313 caption: '' 3314 }, 3315 city: { 3316 container: '.city-container', 3317 select: '.city-select', 3318 selectContainer: '.city-select-container', 3319 input: '.city-input', 3320 inputContainer: '.city-input-container', 3321 value: '', 3322 caption: '' 3323 }, 3324 town: { 3325 container: '.town-container', 3326 select: '.town-select', 3327 selectContainer: '.town-select-container', 3328 input: '.town-input', 3329 inputContainer: '.town-input-container', 3330 value: '', 3331 caption: '' 3332 }, 3333 district: { 3334 container: '.district-container', 3335 select: '.district-select', 3336 selectContainer: '.district-select-container', 3337 input: '.district-input', 3338 inputContainer: '.district-input-container', 3339 value: '', 3340 caption: '' 3341 } 3342 }; 3343 3344 if (typeof options == "object") { 3345 for (let i in options) { 3346 if (typeof options[i] == "object") { 3347 for (let j in options[i]) { 3348 opt[i][j] = options[i][j]; 3349 } 3350 } else { 3351 opt[i] = options[i]; 3352 } 3353 } 3354 } 3355 3356 const c = opt; 3357 const l = { 3358 country: [], 3359 state: [], 3360 city: [], 3361 town: [], 3362 district: [] 3363 }; 3364 3365 const v = { 3366 country: opt.country.value || "", 3367 state: opt.state.value || "", 3368 city: opt.city.value || "", 3369 town: opt.town.value || "", 3370 district: opt.district.value || "" 3371 }; 3372 3373 const vc = { 3374 country: opt.country.caption || "", 3375 state: opt.state.caption || "", 3376 city: opt.city.caption || "", 3377 town: opt.town.caption || "", 3378 district: opt.district.caption || "" 3379 }; 3380 const mapSTypes = { 3381 country: 'U', 3382 state: 'E', 3383 city: 'S', 3384 town: 'I', 3385 district: 'M' 3386 }; 3387 3388 const getInputEl = what => T(`${c.container} ${c[what].input}`).length ? T(`${c.container} ${c[what].input}`)[0] : null; 3389 const getSelectEl = what => T(`${c.container} ${c[what].select}`).length ? T(`${c.container} ${c[what].select}`)[0] : null; 3390 const setInputDisabled = (what, disabled) => { 3391 const el = getInputEl(what); 3392 if (!el) return; 3393 el.disabled = !!disabled; 3394 if (disabled) { 3395 el.setAttribute('disabled', 'disabled'); 3396 } else { 3397 el.removeAttribute('disabled'); 3398 } 3399 }; 3400 const setSelectDisabled = (what, disabled) => { 3401 const el = getSelectEl(what); 3402 if (!el) return; 3403 el.disabled = !!disabled; 3404 if (disabled) { 3405 el.setAttribute('disabled', 'disabled'); 3406 } else { 3407 el.removeAttribute('disabled'); 3408 } 3409 }; 3410 const getInputDisabledState = what => { 3411 const country = getCountry(v.country) || {}; 3412 const needsState = !!country.has_state && l.state.length > 0; 3413 const cityDisabled = needsState && !v.state; 3414 const townDisabled = (l.city.length > 0 && !v.city) || cityDisabled; 3415 3416 switch (what) { 3417 case 'city': 3418 return cityDisabled; 3419 case 'town': 3420 return townDisabled; 3421 case 'district': 3422 return (l.town.length > 0 && !v.town) || townDisabled; 3423 default: 3424 return false;
3425 } 3426 }; 3427 const applyDisabledRules = () => { 3428 if (l.city.length === 0) setInputDisabled('city', getInputDisabledState('city')); 3429 if (l.town.length === 0) setInputDisabled('town', getInputDisabledState('town')); 3430 if (l.district.length === 0) setInputDisabled('district', getInputDisabledState('district')); 3431 }; 3432 3433 const getCountry = (code) => { 3434 for (let i in l.country) { 3435 if (l.country[i].code == code) { 3436 const item = l.country[i]; 3437 item.has_state = item.has_state == 1; 3438 return item; 3439 } 3440 } 3441 }; 3442 3443 const loadCountries = function() { 3444 const rf = (result) => { 3445 if (result.countries) { 3446 if(opt.countryLimit){ 3447 result.countries = result.countries.filter(function(item){ 3448 return !MEMBER_INFO.E_COUNTRY || item.code == MEMBER_INFO.E_COUNTRY 3449 }); 3450 } 3451 l.country = result.countries; 3452 let ob = T(`${c.container} ${c.country.select}`), 3453 cExists = false; 3454 3455 if (ob.length) { 3456 result.countries.forEach(item => { 3457 let option = document.createElement('option'); 3458 option.value = item.code; 3459 option.innerHTML = item.title; 3460 ob[0].appendChild(option); 3461 if (item.code == v.country) { cExists = true; } 3462 }); 3463 } 3464 3465 if (v.country == "" || !cExists) { 3466 if (result.countries && result.countries.length && result.countries.length == 1) { 3467 v.country = result.countries[0].code; 3468 } else if (result.selected && getCountry(result.selected)) { 3469 v.country = result.selected; 3470 } else if (getCountry("TR")) { 3471 v.country = "TR"; 3472 } else if (result.countries.length > 0) { 3473 v.country = result.countries[0].code; 3474 } 3475 } 3476 if (ob.length) { 3477 ob[0].value = v.country; 3478 T.placeholder.reset(ob[0]); 3479 } 3480 loadStates(); 3481 } else { 3482 3483 } 3484 }; 3485 axios.get(getEndpoint('COUNTRY', '1?lang='+LANGUAGE+'&country='+(MEMBER_INFO.COUNTRY || 'TR'))).then(res => { 3486 const data = res.data; 3487 rf(data); 3488 }); 3489 }; 3490 3491 const _loadRegion = (what, parent) => { 3492 _reset(what); 3493 const rf = (result) => { 3494 const items = result && result.data ? result.data : []; 3495 l[what] = items; 3496 _render(what, items); 3497 }; 3498 if (!parent) { 3499 rf(); 3500 } else { 3501 const data = { storeLimit: opt.storeLimit }; 3502 switch (what) { 3503 case 'country': 3504 break; 3505 case 'state': 3506 data.U = v.country; 3507 break; 3508 case 'city': 3509 data.U = v.country; 3510 data.E = v.state; 3511 break; 3512 case 'town': 3513 data.U = v.country; 3514 data.E = v.state; 3515 data.S = v.city; 3516 break; 3517 case 'district': 3518 data.U = v.country; 3519 data.E = v.state; 3520 data.S = v.city; 3521 data.I = v.town; 3522 break; 3523 } 3524 3525 let formData = new FormData(); 3526 for (let key in data) { 3527 formData.append(key, data[key]); 3528 } 3529 3530 let lmt = opt.regionLimit != null ? opt.regionLimit : (opt.countryLimit ? "1" : "0"); 3531 axios.post(getEndpoint('REGION', `${mapSTypes[what]}/${parent}/${lmt}`), formData).then(res => { 3532 const data = res.data; 3533 rf(data); 3534 }); 3535 } 3536 return; 3537 }; 3538 3539 const loadStates = () => { 3540 const flagInputs = document.querySelectorAll('[data-flag-masked]');
3541 Array.from(flagInputs).forEach(item => { 3542 if (item.value != '') return; 3543 3544 if (item.dataset.key != v.country) { 3545 try { 3546 tFlag.changePhoneMask(null, item, v.country); 3547 } catch (error) { 3548 } 3549 } 3550 3551 }); 3552 3553 T(`${c.container} ${c.state.container}`).hide(); 3554 _reset("state"); 3555 let item = getCountry(v.country) || {}; 3556 if (!item.has_state) { 3557 loadCities(); 3558 return; 3559 } 3560 T(`${c.container} ${c.state.container}`).show(); 3561 _loadRegion("state", v.country); 3562 }; 3563 3564 const loadCities = () => { 3565 let item = getCountry(v.country) || {}; 3566 let pc = item.has_state ? v.state : v.country; 3567 _loadRegion("city", pc); 3568 }; 3569 3570 const loadTowns = () => { 3571 _loadRegion("town", v.city); 3572 }; 3573 3574 const loadDistricts = () => { 3575 _loadRegion("district", v.town); 3576 }; 3577 3578 const _render = (what, data) => { 3579 if (data.length == 0) { 3580 T(`${c.container} ${c[what].selectContainer}`).hide(); 3581 T(`${c.container} ${c[what].inputContainer}`).show(); 3582 if (T(`${c.container} ${c[what].input}`).length) { 3583 T(`${c.container} ${c[what].input}`)[0].value = vc[what]; 3584 T.placeholder.reset(T(`${c.container} ${c[what].input}`)[0]); 3585 } 3586 setInputDisabled(what, getInputDisabledState(what)); 3587 setSelectDisabled(what, true); 3588 applyDisabledRules(); 3589 } else { 3590 T(`${c.container} ${c[what].selectContainer}`).show(); 3591 T(`${c.container} ${c[what].inputContainer}`).hide(); 3592 if (T(`${c.container} ${c[what].input}`).length) { 3593 T(`${c.container} ${c[what].input}`)[0].value = ''; 3594 } 3595 setInputDisabled(what, true); 3596 setSelectDisabled(what, false); 3597 3598 const ob = T(`${c.container} ${c[what].select}`); 3599 3600 if (!ob.length) return; 3601 3602 const rCodes = []; 3603 3604 ob.html("<option value=''>" + ob[0].getAttribute('placeholder') + "</option>"); 3605 3606 data.forEach(item => { 3607 let option = document.createElement('option'); 3608 option.value = item.code; 3609 if (what == 'district') option.dataset.postacode = item.postalcode || ''; 3610 option.innerHTML = item.title; 3611 ob[0].appendChild(option); 3612 rCodes.push(item.code); 3613 }); 3614 3615 if (rCodes.indexOf(v[what]) == -1) { 3616 v[what] = ''; 3617 switch (what) { 3618 case 'state': 3619 v.city = ''; 3620 v.town = ''; 3621 v.district = ''; 3622 break; 3623 case 'city': 3624 v.town = ''; 3625 v.district = ''; 3626 break; 3627 case 'town': 3628 v.district = ''; 3629 break; 3630 } 3631 if (rCodes.length == 1) { 3632 ob[0].value = rCodes[0]; 3633 T(ob).trigger('change'); 3634 return; 3635 } 3636 } else { 3637 ob[0].value = v[what]; 3638 } 3639 T.placeholder.reset(ob[0]); 3640 } 3641 /* after render */ 3642 switch (what) { 3643 case 'state': 3644 loadCities(); 3645 break; 3646 case 'city': 3647 loadTowns(); 3648 break; 3649 case 'town': 3650 loadDistricts(); 3651 break; 3652 } 3653 applyDisabledRules(); 3654 }; 3655 3656 const _reset = (type) => { 3657 let obs = {}, 3658 $typeIdx = 0, 3659 $totalIdx = 4; 3660 obs[1] = c.state; 3661 obs[2] = c.city; 3662 obs[3] = c.town; 3663 obs[4] = c.district; 3664 3665 switch (type) { 3666 case 'state': 3667 $typeIdx = 1; 3668 break; 3669 case 'city': 3670 $typeIdx = 2; 3671 break; 3672 case 'town': 3673 $typeIdx = 3; 3674 break; 3675 case 'district': 3676 $typeIdx = 4; 3677 break; 3678 } 3679 3680 for (let i = $typeIdx; i <= $totalIdx; i++) { 3681 T(`${c.container} ${obs[i].select}`).html(''); 3682 if (T(`${c.container} ${obs[i].input}`).length) T(`${c.container} ${obs[i].input}`)[0].value = ''; 3683 T(`${c.container} ${obs[i].selectContainer}`).hide(); 3684 T(`${c.container} ${obs[i].inputContainer}`).show(); 3685 if (i === 1) l.state = []; 3686 if (i === 2) l.city = []; 3687 if (i === 3) l.town = []; 3688 if (i === 4) l.district = []; 3689 } 3690 applyDisabledRules(); 3691 }; 3692 3693 const _listener = () => { 3694 const rs = ["state", "city", "town", "district"]; 3695 T(`${c.container} ${c.country.select}`).on('change', el => { 3696 const _this = el.target; 3697 if (_this.dataset.value == _this.value) { 3698 return; 3699 } 3700 _this.dataset.value = _this.value; 3701 3702 v.country = el.target.value; 3703 for (i = 0; i < rs.length; i++) { 3704 vc[rs[i]] = ''; 3705 v[rs[i]] = ''; 3706 } 3707 loadStates(); 3708 }); 3709 T(`${c.container} ${c.state.select}`).on('change', el => { 3710 const _this = el.target; 3711 if (_this.dataset.value == _this.value) { 3712 return; 3713 } 3714 _this.dataset.value = _this.value; 3715 3716 v.state = el.target.value; 3717 for (i = 1; i < rs.length; i++) { 3718 vc[rs[i]] = ''; 3719 v[rs[i]] = ''; 3720 } 3721 loadCities(); 3722 }); 3723 T(`${c.container} ${c.city.select}`).on('change', el => { 3724 const _this = el.target; 3725 if (_this.dataset.value == _this.value) { 3726 return; 3727 } 3728 _this.dataset.value = _this.value; 3729 3730 v.city = el.target.value; 3731 for (i = 2; i < rs.length; i++) { 3732 vc[rs[i]] = ''; 3733 v[rs[i]] = ''; 3734 } 3735 loadTowns(); 3736 }); 3737 T(`${c.container} ${c.town.select}`).on('change', el => { 3738 const _this = el.target; 3739 if (_this.dataset.value == _this.value) { 3740 return; 3741 } 3742 _this.dataset.value = _this.value; 3743 3744 v.town = el.target.value; 3745 for (i = 3; i < rs.length; i++) { 3746 vc[rs[i]] = ''; 3747 v[rs[i]] = ''; 3748 } 3749 loadDistricts(); 3750 }); 3751 T(`${c.container} ${c.district.select}`).on('change', el => { 3752 const _this = el.target; 3753 if (_this.dataset.value == _this.value) { 3754 return; 3755 } 3756 _this.dataset.value = _this.value; 3757 3758 v.district = el.target.value; 3759
3760 const postacode = T(`${c.container} ${c.district.select}`)[0].options[T(`${c.container} ${c.district.select}`)[0].options.selectedIndex].dataset.postacode || ''; 3761 if (T('[name="post_code"]').length > 0) T('[name="post_code"]')[0].value = postacode; 3762 }); 3763 3764 T(`${c.container} ${c.state.input}`).on('keyup', el => { 3765 vc.state = el.target.value; 3766 }); 3767 T(`${c.container} ${c.city.input}`).on('keyup', el => { 3768 vc.city = el.target.value; 3769 }); 3770 T(`${c.container} ${c.town.input}`).on('keyup', el => { 3771 vc.town = el.target.value; 3772 }); 3773 T(`${c.container} ${c.district.input}`).on('keyup', el => { 3774 vc.district = el.target.value; 3775 }); 3776 }; 3777 3778 _listener(); 3779 loadCountries(); 3780} 3781 3782const loadSubFolder = function(options){ 3783 if(!options.pageId && !blockParentId && !subFolder) { 3784 return; 3785 } 3786 3787 const defOptions = { 3788 pageId : options.pageId || 0, 3789 blockParentId: options.blockParentId || 0, 3790 subFolder: options.subFolder || "", 3791 params: options.params || {}, 3792 success : options.success || function(){} 3793 } 3794 3795 const params = {}; 3796 for(let key in defOptions.params){ 3797 params[key] = defOptions.params[key]; 3798 } 3799 3800 const url = `/srv/service/content-v5/sub-folder/${defOptions.pageId}/${defOptions.blockParentId}/${defOptions.subFolder}`; 3801 axios.get(url, {params: params}).then(response => { 3802 defOptions.success(response.data); 3803 }).catch(error => { 3804 console.error(`Sub folder load error => ${error}`); 3805 }); 3806} 3807 3808const Cart = { 3809 callback: { 3810 update: null, 3811 updateAll: null, 3812 delete: null, 3813 deleteAll: null, 3814 load: [], 3815 add: [], 3816 }, 3817 storageKey : 'Cart', 3818 update: function(sessIndex, count, callback) { 3819 axios.get(`/srv/service/cart/update-item/${sessIndex}/${count}`).then(response => { 3820 const res = response.data; 3821 if (typeof mobileApp !== 'undefined') { 3822 try { 3823 mobileApp.changedCartCount(res.totalQuantity); 3824 } catch (err) {} 3825 } 3826 if (typeof webkit !== 'undefined') { 3827 try { 3828 webkit.messageHandlers.callbackHandler.postMessage(res.totalQuantity); 3829 } catch (err) {} 3830 } 3831 Cart.setStorage('update',res,sessIndex); 3832 3833 for(let i=0; i < callbacks.cart.update.length; i++){ 3834 if(typeof callbacks.cart.update[i] === 'function'){ 3835 try { 3836 callbacks.cart.update[i]?.(res); 3837 } catch (error) { console.log(`Cart Update Callback Error => ${error}`); } 3838 } 3839 } 3840 3841 if (typeof callback === 'function') { 3842 callback(res); 3843 if (typeof Cart.callback.update === 'function') { 3844 Cart.callback.update(res); 3845 } 3846 } else { 3847 T.modal({ 3848 width: '400px', 3849 html: res.statusText 3850 }); 3851 setTimeout(function() { 3852 window.location.reload(); 3853 }, 2500); 3854 } 3855 }).catch(error => console.warn(`Error cart update => ${error}`)); 3856 }, 3857 updateAll: function(countList, callback) { 3858 const param = typeof countList === 'object' ? countList.join('-') : countList; 3859 axios.get(`/srv/service/cart/update/${param}`).then(response => { 3860 const res = response.data; 3861 if (typeof mobileApp !== 'undefined') { 3862 try { 3863 mobileApp.changedCartCount(res.totalQuantity); 3864 } catch (err) {} 3865 } 3866 if (typeof webkit !== 'undefined') { 3867 try { 3868 webkit.messageHandlers.callbackHandler.postMessage(res.totalQuantity); 3869 } catch (err) {} 3870 } 3871 3872 for(let i=0; i < callbacks.cart.updateAll.length; i++){ 3873 if(typeof callbacks.cart.updateAll[i] === 'function'){ 3874 try { 3875 callbacks.cart.updateAll[i]?.(res); 3876 } catch (error) { console.log(`Cart UpdateAll Callback Error => ${error}`); } 3877 } 3878 } 3879 3880 if (typeof callback === 'function') { 3881 callback(res); 3882 if (typeof Cart.callback.updateAll === 'function') { 3883 Cart.callback.updateAll(res); 3884 } 3885 } else { 3886 window.location.reload(); 3887 } 3888 }).catch(error => console.warn(`Error cart updateAll => ${error}`)); 3889 }, 3890 delete: function(sessIndex, callback) { 3891 axios.get(`/srv/service/cart/delete/${sessIndex}`).then(response => { 3892 const res = response.data;
3893 if (typeof mobileApp !== 'undefined') { 3894 try { 3895 mobileApp.changedCartCount(res.totalQuantity); 3896 } catch (err) {} 3897 } 3898 if (typeof webkit !== 'undefined') { 3899 try { 3900 webkit.messageHandlers.callbackHandler.postMessage(res.totalQuantity); 3901 } catch (err) {} 3902 } 3903 3904 Cart.setStorage('delete',response,sessIndex); 3905 3906 for(let i=0; i < callbacks.cart.delete.length; i++){ 3907 if(typeof callbacks.cart.delete[i] === 'function'){ 3908 try { 3909 callbacks.cart.delete[i]?.(res); 3910 } catch (error) { console.log(`Cart Delete Callback Error => ${error}`); } 3911 } 3912 } 3913 3914 if (typeof callback === 'function') { 3915 callback(res); 3916 if (typeof Cart.callback.delete === 'function') { 3917 Cart.callback.delete(res); 3918 } 3919 } else if (typeof window[callback] === 'function') { 3920 window[callback](res); 3921 if (typeof Cart.callback.delete === 'function') { 3922 Cart.callback.delete(res); 3923 } 3924 } else { 3925 window.location.reload(); 3926 } 3927 }).catch(error => console.warn(`Error cart delete => ${error}`)); 3928 }, 3929 deleteAll: function(callback) { 3930 axios.get(`/srv/service/cart/delete-all`).then(response => { 3931 const res = response.data; 3932 if (typeof mobileApp !== 'undefined') { 3933 try { 3934 mobileApp.changedCartCount(0); 3935 } catch (err) {} 3936 } 3937 if (typeof webkit !== 'undefined') { 3938 try { 3939 webkit.messageHandlers.callbackHandler.postMessage(0); 3940 } catch (err) {} 3941 } 3942 3943 Cart.setStorage('deleteAll'); 3944 3945 for(let i=0; i < callbacks.cart.deleteAll.length; i++){ 3946 if(typeof callbacks.cart.deleteAll[i] === 'function'){ 3947 try { 3948 callbacks.cart.deleteAll[i]?.(res); 3949 } catch (error) { console.log(`Cart DeleteAll Callback Error => ${error}`); } 3950 } 3951 } 3952 3953 if (typeof Cart.callback.deleteAll === 'function') { 3954 Cart.callback.deleteAll(res); 3955 } 3956 if (typeof callback === 'function') { 3957 callback(res); 3958 } else { 3959 setTimeout(function() { 3960 window.location.reload(); 3961 }, 750); 3962 } 3963 }).catch(error => console.warn(`Error cart deleteAll => ${error}`)); 3964 }, 3965 setStorage : function(action,response,index){ 3966 if(typeof window.localStorage === 'undefined'){ 3967 return false; 3968 } 3969 let storage = window.localStorage.getItem(Cart.storageKey); 3970 if(storage === null){ 3971 storage = { summary : { }, items : [] }; 3972 }else{ 3973 storage = JSON.parse(storage); 3974 } 3975 3976 switch(action) { 3977 case 'update': 3978 case 'add': 3979 if(response.cartProducts === null){ 3980 return false; 3981 } 3982 storage.items = response.cartProducts; 3983 storage.summary = { total : response.totalPrice}; 3984 break; 3985 3986 case 'delete': 3987 if (storage && storage.items) { 3988 if(storage.items.length === 0){ 3989 return false; 3990 } 3991 storage.items.splice(index,1); 3992 storage.summary.total = response.priceCart; 3993 break; 3994 } 3995 3996 case 'deleteAll': 3997 storage.items = []; 3998 storage.summary = { total : 0}; 3999 break; 4000 } 4001 4002 window.localStorage.setItem(Cart.storageKey,JSON.stringify(storage)); 4003 return true; 4004 }, 4005 getStorage : function(){ 4006 let storage = window.localStorage.getItem(Cart.storageKey); 4007 if(storage === null){ 4008 storage = []; 4009 }else{ 4010 storage = JSON.parse(storage); 4011 } 4012 return storage; 4013 } 4014} 4015 4016const OrderCallback = { 4017 address: [], 4018 payment: [], 4019 paymentChange: [], 4020 approve: [], 4021} 4022 4023const addToSelectionProducts = function() { 4024 const inputs = T('input.multiple-ids-cart:checked'); 4025 4026 if(inputs.length < 1) { 4027 T.notify({ 4028 text: TLANG.no_products_selected || 'Seçili ürün bulunmamaktadır', 4029 className: 'danger', 4030 duration: 1800, 4031 }); 4032 return; 4033 } 4034 4035 const pids = [], 4036 variants = [], 4037 counts = []; 4038
4039 Array.from(inputs).forEach(input => { 4040 const id = input.value; 4041 const variant = T(`#subPro${input.dataset.target}`); 4042 const p_count = T(`#ProductCount${input.dataset.target}`); 4043 pids.push(id); 4044 variants.push(variant.length > 0 ? variant[0].value : 0); 4045 counts.push(p_count.length > 0 ? p_count[0].value : 1); 4046 }); 4047 4048 if (pids.length < 1) return; 4049 multiCart = true; 4050 addToCart(pids, variants, counts); 4051}; 4052 4053const destroySelectionProducts = function() { 4054 const inputs = T('input.multiple-ids-cart:checked') || []; 4055 Array.from(inputs).forEach(input => { 4056 input.checked = false; 4057 }); 4058}; 4059 4060const addToCart = function(options) { 4061 const personalizationPid = []; 4062 let opt = { 4063 productId: 0, 4064 variantId: 0, 4065 quantity: 0, 4066 buyNow: 0, 4067 redirect: PAGE_LINK.CART, 4068 relatedProductId: '', 4069 relatedProductIds: [], 4070 multi: 0, 4071 beforeHtml: '', 4072 afterHtml: '', 4073 callbackFn: null, 4074 openModal: true 4075 }; 4076 if (opt.redirect == 'order') opt.redirect = PAGE_LINK.ORDER; 4077 4078 if (typeof options === 'object' && typeof options.productId !== 'undefined') { 4079 for (let i in options) { 4080 opt[i] = options[i]; 4081 } 4082 } else if (arguments.length > 1) { 4083 let i = 0; 4084 for (let key in opt) { 4085 if (i >= arguments.length) { 4086 break; 4087 } 4088 opt[key] = arguments[i]; 4089 i++; 4090 } 4091 } 4092 4093 const post = new FormData(); 4094 /** 4095 * Product id(s) append 4096 */ 4097 if(Array.isArray(opt.productId) && opt.productId.length > 0) { 4098 opt.productId.forEach(item => { 4099 post.append('productId[]', item); 4100 personalizationPid.push(item); 4101 }); 4102 } else { 4103 post.append('productId', opt.productId); 4104 personalizationPid.push(opt.productId); 4105 } 4106 /** 4107 * Variant id(s) append 4108 */ 4109 if(Array.isArray(opt.variantId) && opt.variantId.length > 0) { 4110 opt.variantId.forEach(item => { 4111 post.append('variantId[]', item); 4112 }); 4113 } else { 4114 post.append('variantId', opt.variantId); 4115 } 4116 /** 4117 * Quantity value(s) append 4118 */ 4119 if(Array.isArray(opt.quantity) && opt.quantity.length > 0) { 4120 opt.quantity.forEach(item => { 4121 post.append('quantity[]', item); 4122 }); 4123 } else { 4124 post.append('quantity', opt.quantity); 4125 } 4126 /** 4127 * Related Product id(s) append 4128 */ 4129 const paramRelatedProductId = getUrlParam('relatedProductId'); 4130 if (paramRelatedProductId) { 4131 const paramRelatedProductIdArray = paramRelatedProductId.split('-'); 4132 const paramRelatedId = paramRelatedProductIdArray[0]; 4133 const paramProductId = paramRelatedProductIdArray[1]; 4134 if(paramRelatedId && paramProductId && (paramProductId == opt.productId)) { 4135 opt.relatedProductId = paramRelatedId; 4136 } 4137 } 4138 4139 if(Array.isArray(opt.relatedProductId) && opt.relatedProductId.length > 0) { 4140 opt.relatedProductId.forEach(item => { 4141 post.append('relatedProductId[]', item); 4142 }); 4143 } else { 4144 post.append('relatedProductId', opt.relatedProductId); 4145 } 4146 /** 4147 * subscribe id append 4148 */ 4149 4150 if (typeof opt.productId != 'object' && T(`input#product-subscribe-${opt.productId}:checked`).length > 0) { 4151 const subscribe = T(`input#product-subscribe-${opt.productId}:checked`).length == 1 ? 1 : 0; 4152 const subscribeFrequency = subscribe == 1 ? T(`#product-subscribe-frequency-${opt.productId}`)[0].value : ''; 4153 post.append('subscribe', subscribe); 4154 post.append('subscribeFrequency', subscribeFrequency); 4155 } 4156 /** 4157 * product note 4158 */ 4159 if(T(`#order-note-${opt.productId}`).length > 0 && T(`#order-note-${opt.productId}`)[0].value != '') { 4160 post.append('orderNotes', T(`#order-note-${opt.productId}`)[0].value); 4161 } 4162 /* 4163 multi: opt.multi 4164 */ 4165 4166 /** 4167 * personalization 4168 */ 4169 4170 let validateStatus = true; 4171 if (typeof PERSONALIZATION != 'undefined') { 4172 if (opt.productId == PERSONALIZATION.product) {
4173 PERSONALIZATION.validate(); 4174 if (PERSONALIZATION.validateStatus == false) { 4175 return false; 4176 } 4177 const data = PERSONALIZATION.formData; 4178 for (let key in data) { 4179 post.append(key, data[key]); 4180 } 4181 } else { 4182 personalizationPid.forEach(pid => { 4183 if (PERSONALIZATION[pid]) { 4184 PERSONALIZATION[pid].validate(); 4185 validateStatus = PERSONALIZATION[pid].validateStatus; 4186 4187 let data = {}; 4188 for (let key in PERSONALIZATION[pid].formData) { 4189 data[key] = PERSONALIZATION[pid].formData[key]; 4190 } 4191 post.append(`formData[${pid}]`, JSON.stringify(data)); 4192 } 4193 4194 }); 4195 } 4196 } 4197 if (validateStatus == false) return; 4198 4199 /** 4200 * CSRF_TOKEN 4201 */ 4202 post.append('csrfToken', CART_CSRF_TOKEN); 4203 4204 axios.post('/srv/service/cart/add-to-cart', post).then(result => { 4205 const res = result.data; 4206 if (res.status > 0 || (Array.isArray(res) && res[0].status > 0)) { 4207 window['CART_COUNT'] = Array.isArray(res) ? res[res.length - 1].totalQuantity : res.totalQuantity; 4208 T('.cart-soft-count').text(CART_COUNT); 4209 4210 window['CART_TOTAL'] = Array.isArray(res) ? res[res.length - 1].totalPrice : res.totalPrice; 4211 T('.cart-soft-price').text(CART_TOTAL); 4212 4213 Cart.setStorage('add',res); 4214 4215 for(let i=0; i < callbacks.cart.add.length; i++){ 4216 if(typeof callbacks.cart.add[i] === 'function'){ 4217 try { 4218 callbacks.cart.add[i]?.(res); 4219 } catch (error) { console.log(`Cart Add Callback Error => ${error}`); } 4220 } 4221 } 4222 4223 for (let i = 0; i < Cart.callback.add.length; i++) { 4224 if (typeof Cart.callback.add[i] === 'function') { 4225 try { 4226 Cart.callback.add[i]?.(res); 4227 } catch (error) { console.warn(`Shopping basket adding Callback error => ${error}`) } 4228 } 4229 } 4230 4231 /* callback just running */ 4232 if (typeof opt.callbackFn === 'string' && typeof window[opt.callbackFn] === 'function') { 4233 try { 4234 return window[opt.callbackFn]?.(res); 4235 } catch (error) { console.warn(`Shopping basket adding Callback error => ${error}`) } 4236 } 4237 } 4238 4239 if(multiCart) { 4240 const errorMessage = []; 4241 for(let i=0; i<res.length; i++) { 4242 const that = res[i]; 4243 if(that.status < 1) { 4244 errorMessage.push(that); 4245 } 4246 else { 4247 multiCartItem = that; 4248 } 4249 } 4250 4251 if (multiCartItem != null) { 4252 switch (multiCartItem.status) { 4253 case 1: 4254 autoCart = false; 4255 multiCart = false; 4256 if (opt.buyNow == 0) { 4257 openModal(); 4258 } else { 4259 window.location.href = '/' + opt.redirect; 4260 } 4261 destroySelectionProducts(); 4262 break; 4263 case 2: 4264 autoCart = false; 4265 window.location.href = multiCartItem.url; 4266 break; 4267 case 3: 4268 autoCart = false; 4269 multiCart = false; 4270 if (opt.buyNow == 0) { 4271 openModal(); 4272 } else { 4273 window.location.href = '/' + opt.redirect; 4274 } 4275 destroySelectionProducts(); 4276 break; 4277 } 4278 multiCartItem = null; 4279 } 4280 if (errorMessage.length > 0) { 4281 let errorHtml = ''; 4282 errorMessage.forEach(msg => { 4283 if (msg.url && msg.title) { 4284 errorHtml += `<p class="text-body">${msg.statusText} : <a href="/${msg.url}" class="text-danger text-underline" target="_blank">${msg.title}</a></p>`; 4285 } else { 4286 errorHtml += `<p class="text-body">${msg.statusText}</p>`; 4287 } 4288 }); 4289 setTimeout(() => { 4290 T.notify({ 4291 text: errorHtml, 4292 className: 'danger', 4293 stopOnFocus : true, 4294 duration: 2400, 4295 }); 4296 }, 500); 4297 } 4298 } else { 4299 switch (res.status) { 4300 case -1: /* varyant selection error */ 4301 for(let i=0; i < callbacks.cart.error.length; i++){ 4302 if(typeof callbacks.cart.error[i] === 'function'){ 4303 try { 4304 callbacks.cart.error[i]?.(res); 4305 } catch (error) { console.log(`Cart Error Callback Error => ${error}`); } 4306 } 4307 } 4308 4309 if (res.url != '') { 4310 if (PAGE_TYPE === 'product') { 4311 if (document.getElementById('link_table_id').value == opt.productId) { 4312 T.notify({ 4313 text: res.statusText, 4314 className: 'danger', 4315 stopOnFocus : true, 4316 duration: 2400, 4317 }); 4318 return false;
4319 } else { 4320 window.location.href = '/' + res.url; 4321 return false; 4322 } 4323 } else { 4324 window.location.href = '/' + res.url; 4325 return false; 4326 } 4327 } else { 4328 let errorHtml = ''; 4329 if (res.url || res.title) { 4330 errorHtml += `<p class="text-body">${res.statusText} : <a href="/${res.url}" class="text-danger text-underline" target="_blank">${res.title}</a></p>`; 4331 } else { 4332 errorHtml += `<p class="text-body">${res.statusText}</p>`; 4333 } 4334 T.notify({ 4335 text: errorHtml, 4336 className: 'danger', 4337 stopOnFocus : true, 4338 duration: 2400, 4339 }); 4340 } 4341 break; 4342 case 0: 4343 if (res.personalization_error && PAGE_TYPE !== 'product' && res.url) { 4344 window.location.href = '/' + res.url; 4345 return false; 4346 } 4347 T.notify({ 4348 text: res.statusText || TLANG.no_product_add || 'Ãrün sepetinize eklenemedi', 4349 className: 'danger', 4350 stopOnFocus : true, 4351 duration: 2400, 4352 }); 4353 break; 4354 case -2: 4355 T.notify({ 4356 text: res.statusText, 4357 className: 'danger', 4358 stopOnFocus : true, 4359 duration: 2400, 4360 }); 4361 loadSubFolder({ 4362 pageId: 85, 4363 blockParentId: 1110, 4364 subFolder: 'set-store', 4365 params : opt, 4366 success: function(loadRes){ 4367 T.modal({ 4368 html: loadRes, 4369 width: '580px', 4370 close: true 4371 }); 4372 } 4373 }); 4374 break; 4375 case 1: 4376 if (opt.buyNow == 0) { 4377 } else { 4378 window.location.href = '/' + opt.redirect; 4379 } 4380 break; 4381 case 2: 4382 window.location.href = res.url; 4383 break; 4384 case 3: 4385 if (opt.buyNow == 0) { 4386 openModal(); 4387 } else { 4388 window.location.href = '/' + opt.redirect; 4389 } 4390 break; 4391 case 4: 4392 if (opt.buyNow == 0) { 4393 T.notify({ 4394 text: `<div>${res.statusText}</div><a href="/${PAGE_LINK.CART}" class="fw-semibold underline">${TLANG.go_to_cart || 'Sepete git'}</a>`, 4395 className: 'success', 4396 duration: 5000, 4397 }); 4398 } else { 4399 window.location.href = '/' + opt.redirect; 4400 } 4401 default: 4402 break; 4403 } 4404 } 4405 }).catch(error => { console.warn(`Shopping basket adding error => ${error}`) }); 4406 4407 const openModal = () => { 4408 if (!opt.openModal) return; 4409 let cartRelatedProductId = opt.relatedProductId; 4410 if (opt.relatedProductIds && opt.relatedProductIds.length > 0) { 4411 cartRelatedProductId = opt.relatedProductIds.join(','); 4412 } 4413 loadSubFolder({ 4414 pageId: 30, 4415 blockParentId: 1054, 4416 subFolder: 'popup-cart', 4417 params: { 4418 product: (Array.isArray(opt.productId) && opt.productId.length > 0) ? opt.productId.join('-') : opt.productId, 4419 variantId: (Array.isArray(opt.variantId) && opt.variantId.length > 0) ? opt.variantId.join('-') : opt.variantId || 0, 4420 multi : (Array.isArray(opt.productId) && opt.productId.length > 0) ? true : false, 4421 relatedProductId : cartRelatedProductId 4422 }, 4423 success: function(loadRes){ 4424 if(document.getElementById('modal-popup-cart') != null) { 4425 let popupContent = document.getElementById('modal-popup-cart').querySelector('.t-modal-content'); 4426 popupContent.innerHTML = loadRes; 4427 evalScripts(popupContent.innerHTML); 4428 } else { 4429 T.modal({
4430 id: 'modal-popup-cart', 4431 width: '570px', 4432 html: loadRes, 4433 close: true 4434 }); 4435 } 4436 if (PAGE_ID == 30 && cartVue && typeof cartVue.load == 'function') cartVue.load(); 4437 } 4438 }); 4439 } 4440}; 4441 4442const popoverAlert = { 4443 show: function(item, message, duration = 3000, classes = '', scrollable = true, type = 'inline', hideAll = true) { 4444 if (item == null) return; 4445 4446 if (hideAll) popoverAlert.hideAll(); 4447 4448 const popoverWrapper = item.closest('.popover-wrapper'); 4449 if(popoverWrapper == null) return; 4450 if(popoverWrapper.querySelector('.popover-item') != null) return; 4451 4452 const inlineWarning = classes !== '' && classes !== 'undefined' && type == 'inline' && message.trim().length < 51; 4453 const pop = document.createElement('span'); 4454 pop.className = `popover-item fade-in ${classes.indexOf('success') > -1 ? 'success' : ''} ${inlineWarning ? type : ''}`; 4455 pop.innerHTML = message; 4456 4457 let explodeClass = inlineWarning ? classes.replaceAll('btn-danger', 'btn-outline-danger').replaceAll('btn-success', 'btn-outline-success').replace('no-radius', '') : classes; 4458 explodeClass = explodeClass.split(' ').filter(e => e.trim() != ''); 4459 4460 if(inlineWarning) { 4461 item.classList.add(...explodeClass); 4462 if (popoverWrapper.classList.contains('input-group') && popoverWrapper.querySelector('.input-group-append')) { 4463 pop.style.right = (popoverWrapper.querySelector('.input-group-append').clientWidth + 6) + 'px'; 4464 } 4465 } else { 4466 pop.classList.add(...explodeClass); 4467 } 4468 4469 popoverWrapper.appendChild(pop); 4470 if(scrollable === true) { 4471 if (T('html').hasClass('is-active-modal')) { 4472 const position = popoverWrapper.offsetTop - popoverWrapper.closest('.t-modal-content').offsetTop + popoverWrapper.closest('.t-modal-content').scrollTop; 4473 popoverWrapper.closest('.t-modal-container').scrollTo({ 4474 top: position - 140, 4475 behavior: 'smooth' 4476 }); 4477 } else { 4478 scroll({ 4479 top: popoverWrapper.offsetTop - 200, 4480 behavior: "smooth" 4481 }); 4482 } 4483 } 4484 4485 if(duration !== false) { 4486 setTimeout(function () { 4487 popoverAlert.hide(pop, explodeClass); 4488 item.classList.remove(...explodeClass); 4489 }, duration + 250); 4490 } 4491 4492 T(item).on('focus', () => { 4493 popoverAlert.hide(pop, explodeClass); 4494 item.classList.remove(...explodeClass); 4495 }); 4496 4497 }, 4498 hide: function(item, removeClass) { 4499 if (!item.closest('.popover-wrapper')) return; 4500 const input = item.closest('.popover-wrapper').querySelector('input:not(.t-search-input)'); 4501 if (input != null && removeClass) { 4502 input.classList.remove(...removeClass); 4503 } 4504 item.closest('.popover-wrapper').removeChild(item); 4505 }, 4506 hideAll: function() { 4507 Array.from(document.querySelectorAll('.popover-item')).forEac
4507h(item => { 4508 popoverAlert.hide(item); 4509 }); 4510 } 4511}; 4512 4513const memberLogin = function (options) { 4514 const self = this; 4515 let opt = { 4516 type: 'email', 4517 prefix: '', 4518 vendor: 0, 4519 callback: function() { 4520 }, 4521 submitter: null, 4522 form: null 4523 }; 4524 4525 for (let i in options) { 4526 opt[i] = options[i]; 4527 } 4528 4529 opt.email = opt.prefix + 'email'; 4530 opt.phone = opt.prefix + 'phone'; 4531 opt.password = opt.prefix + 'password'; 4532 opt.remember = opt.prefix + 'remember'; 4533 opt.redirect = opt.prefix + 'redirect'; 4534 opt.security_code = opt.prefix + 'security_code'; 4535 opt.prefix = opt.prefix === '' ? 'deneme' : opt.prefix; 4536 4537 const data = new FormData(); 4538 if (opt.type == 'phone') { 4539 data.append('username', document.getElementById(opt.phone).value.replaceAll(/\D/g, '')); 4540 data.append('type', opt.type); 4541 } else { 4542 data.append('username', document.getElementById(opt.email).value); 4543 } 4544 4545 if (opt.vendor == '1') data.append('vendor', 1); 4546 4547 data.append('password', document.getElementById(opt.password).value); 4548 data.append('rememberMe', document.getElementById(opt.remember) != null && document.getElementById(opt.remember).checked ? 1 : 0); 4549 if (document.getElementById(opt.redirect) != null) data.append('redirect', document.getElementById(opt.redirect).value); 4550 if (document.getElementById(opt.security_code) != null) { 4551 const seccode = document.getElementById(opt.security_code); 4552 let limit = seccode.dataset.limit = Number.parseInt(seccode.dataset.limit) || 0; 4553 4554 if (limit < 1) data.append('security_code', seccode.value); 4555 4556 limit = Math.max(0, limit - 1); 4557 seccode.dataset.limit = limit; 4558 4559 if (limit < 1) seccode.parentNode.classList.remove('d-none'); 4560 if (document.querySelectorAll('[name="g-recaptcha-response"]')[0] && typeof document.querySelectorAll('[name="g-recaptcha-response"]')[0].value !== 'undefined') data.set('security_code', document.querySelectorAll('[name="g-recaptcha-response"]')[0].value); 4561 } 4562 4563 let httpsUri = '//' + window.location.host; 4564 let postUrl = httpsUri + getEndpoint('LOGIN'); 4565 4566 const changePassword = async function() { 4567 loadSubFolder({ 4568 pageId: 6, 4569 blockParentId: 1008, 4570 subFolder: 'change-password', 4571 success: async function(loadRes){ 4572 await T.modal({ 4573 id: 'modal-change-password', 4574 width: '480px', 4575 html: loadRes, 4576 close: true, 4577 }); 4578 4579 const changePasswordForm = document.querySelector('[data-toggle="change-password"]'); 4580 if (changePasswordForm) { 4581 changePasswordForm.addEventListener('submit', async e => { 4582 e.preventDefault(); 4583 e.stopPropagation(); 4584 4585 const form = e.target; 4586 const formData = new FormData(form); 4587 4588 if (!T.checkValidity(form)) return; 4589 4590 formData.append('type', opt.type); 4591 formData.append('username', data.get('username')); 4592 formData.append('password_old', data.get('password')); 4593 formData.append('redirect', data.get('redirect')); 4594 4595 const recaptchaResponse = formData.get('g-recaptcha-response'); 4596 if (recaptchaResponse != null && typeof grecaptcha !== 'undefined') formData.set('security_code', recaptchaResponse); 4597 4598 T.buttonLock.dom = form.submitter; 4599 T.buttonLock.lock(); 4600 4601 await axios.post(getEndpoint('CUSTOMER_CHANGE_PASSWORD'), formData).then(response => { 4602 const res = response.data; 4603 if (res.status) { 4604 const element = form.querySelector(`[name="password_new"]`); 4605 if (element) { 4606 popoverAlert.show( 4607 element, 4608 res.message, 4609 5000, 4610 `btn btn-success text-left`, 4611 true, 4612 '', 4613 ); 4614 } 4615 4616 setTimeout(() => { 4617 window.location.href = res.page?.url || '/'; 4618 }, 1500); 4619 } 4620 }).catch(error => { 4621 const grecaptchaEl = form.querySelector('.g-recaptcha'); 4622 if (grecaptchaEl && recaptchaResponse != null) grecaptchaReset(grecaptchaEl); 4623 4624 const captchaImg = form.querySelector('.captcha-img'); 4625 if (captchaImg) { 4626 const captcha = form.querySelector('[name="security_code"]'); 4627 if (captcha) captcha.value = ''; 4628 captchaImg.src = `/SecCode.php?${new Date().getTime()}`; 4629 } 4630 4631 let msg; 4632 if (error.response) { 4633 msg = error.response.data.data[0]; 4634 } else if (error.request) { 4635 msg = JSON.parse(error.request.response).data[0]; 4636 } 4637 if (!msg) return; 4638 4639 const element = form.querySelector(`[name="${msg.key}"]`); 4640 if (!element) return; 4641 4642 popoverAlert.show( 4643 element, 4644 msg.statusText, 4645 10000, 4646 `btn btn-danger no-radius text-left`, 4647 true, 4648 msg.key == '', 4649 ); 4650 }); 4651 4652 T.buttonLock.unlock(); 4653 }); 4654 } 4655 } 4656 }); 4657 } 4658 4659 axios.post(postUrl, data).then((response) => { 4660 const result = response.data; 4661 4662 opt.callback(result, options); 4663 4664 let obj = { value: result.data[0].bearer, timeout: result.data[0].exp_at }; 4665 localStorage.setItem('v5token', JSON.stringify(obj)); 4666 4667 if (result.status) { 4668 for(let i=0; i < callbacks.customer.login.length; i++){ 4669 if(typeof callbacks.customer.login[i] === 'function'){ 4670 try { 4671 callbacks.customer.login[i]?.(result); 4672 } catch (error) { console.log(`Customer Login Callback Error => ${error}`); } 4673 } 4674 } 4675 4676 if (typeof LoginPageTracking !== 'undefined') { 4677 if(typeof LoginPageTracking.Callback === 'function'){ 4678 try { 4679 LoginPageTracking.Callback(result); 4680 } catch (error) { console.log(error); } 4681 } 4682 for(let i = 0; i < LoginPageTracking.callbackArray.length; i++){ 4683 if(typeof LoginPageTracking.callbackArray[i] === 'function'){ 4684 try { 4685 LoginPageTracking.callbackArray[i]?.(result); 4686 } catch (error) { console.log(error); } 4687 } 4688 } 4689 } 4690 } 4691 4692 T.buttonLock.unlock(); 4693 }).catch(error => { 4694 if (error.response) { 4695 opt.callback(error.response.data, options); 4696 } else if (error.request) { 4697 const response = JSON.parse(error.request.response); 4698 if (response?.data[0]?.captcha_active) { 4699 const securityCode = document.getElementById(opt.security_code); 4700 if (securityCode) { 4701 securityCode.parentNode.classList.remove('d-none'); 4702 securityCode.focus(); 4703 } else { 4704 loadSubFolder({ 4705 pageId: 5, 4706 blockParentId: 1006, 4707 subFolder: 'captcha', 4708 params: { 4709 type: response?.data[0]?.captcha_type, 4710 prefix: opt.prefix 4711 }, 4712 success: function(loadRes){ 4713 const password = document.getElementById(opt.password); 4714 if (password) { 4715 const passowordWrapper = password.closest('.input-group'); 4716 if (passowordWrapper) { 4717 passowordWrapper.insertAdjacentHTML('afterend', loadRes); 4718 } else { 4719 password.parentNode.insertAdjacentHTML('afterend', loadRes); 4720 } 4721 evalScripts(loadRes); 4722 const securityCode = document.getElementById(opt.security_code); 4723 if (securityCode) securityCode.focus(); 4724 } 4725 } 4726 }); 4727 } 4728 } 4729 if (response?.data[0]?.password_change) { 4730 changePassword(); 4731 T.buttonLock.unlock(); 4732 return; 4733 } 4734 opt.callback(response, options); 4735 if (typeof loginCaptcha !== 'undefined') { 4736 try {
4737 loginCaptcha.forEach(item => item.refreshCode()); 4738 } catch (error) { 4739 console.error(`Login Captcha Refresh Code Error => ${error}`); 4740 } 4741 } 4742 } 4743 T.buttonLock.unlock(); 4744 }); 4745} 4746 4747const subscribe = { 4748 change: function(el) { 4749 const selector = el.closest('#product-right'); 4750 if (selector == null) return; 4751 4752 let productPrice = null, 4753 productNotDiscounted = null; 4754 4755 if (selector.querySelectorAll('.product-price').length) productPrice = T(selector.querySelectorAll('.product-price')); 4756 if (selector.querySelectorAll('.product-price-not-vat').length) productPrice = T(selector.querySelectorAll('.product-price-not-vat')); 4757 4758 if (selector.querySelectorAll('.product-price-not-discounted').length) productNotDiscounted = T(selector.querySelectorAll('.product-price-not-discounted')); 4759 if (selector.querySelectorAll('.product-price-not-discounted-not-vat').length) productNotDiscounted = T(selector.querySelectorAll('.product-price-not-discounted-not-vat')); 4760 4761 if (productPrice == null) return; 4762 4763 const price = T(productPrice).attr('data-price') || T(productPrice).text() || 0; 4764 const parsePrice = T.priceToFloat(price); 4765 T(productPrice).attr('data-price', price); 4766 4767 const notDiscounted = productNotDiscounted != null ? T(productNotDiscounted).attr('data-price') || T(productNotDiscounted).text() || 0 : null; 4768 let parseNotDiscounted = notDiscounted != null ? T.priceToFloat(notDiscounted) : null; 4769 if (productNotDiscounted != null) T(productNotDiscounted).attr('data-price', notDiscounted); 4770 4771 const subsDiscount = el.checked == true ? el.dataset.discount || 0 : 0; 4772 4773 T(productPrice).text(T.format(parsePrice - (parsePrice * subsDiscount / 100))); 4774 if (productNotDiscounted != null) T(productNotDiscounted).text(T.format(parseNotDiscounted - (parseNotDiscounted * subsDiscount / 100))); 4775 }, 4776 init: function(el = null) { 4777 if (el == null || el.Subscribe == 1) return; 4778 4779 el.addEventListener('change', () => { 4780 subscribe.change(el); 4781 }); 4782 4783 self.sticky = el; 4784 el.Subscribe = 1; 4785 }, 4786}; 4787 4788const selectVaryant = { 4789 set: { 4790 price: function(self, data, element) { 4791 const selector = self.closest(self.dataset.wrapper) || self.closest('.product-item') || self.closest('#product-right'); 4792 if (selector != null && data) { 4793 if (self.closest('#product-detail')) { 4794 PRODUCT_DATA[0].subproduct_code = data.WS_CODE; 4795 PRODUCT_DATA[0].subproduct_id = data.ID; 4796 } 4797 4798 const vPrice = Number.parseFloat(data.PRICE); 4799 const vNotDiscounted = Number.parseFloat(data.PRICE_NOT_DISCOUNTED); 4800 let vDiscountPercent = (((vPrice - vNotDiscounted) / vNotDiscounted) * 100); 4801 const mop = (1 + data.MONEY_ORDER_PERCENT / 100) * vPrice; 4802 4803 T(selector.querySelectorAll('.money-order-price')).text(T.vat(mop, data.VAT)); 4804 T(selector.querySelectorAll('.money-order-price-not-vat')).text(T.format(mop)); 4805 4806 T(selector.querySelectorAll('.product-price')).text(T.vat(vPrice, data.VAT)); 4807 T(selector.querySelectorAll('.product-price-not-vat')).text(T.format(vPrice)); 4808 4809 T(selector.querySelectorAll('.product-price-not-discounted')).text(T.vat(vNotDiscounted, data.VAT)); 4810 T(selector.querySelectorAll('.product-price-not-discounted-not-vat')).text(T.format(vNotDiscounted)); 4811 4812 if (selector.querySelectorAll('.product-price').length) { 4813 T(selector.querySelectorAll('.product-price')).attr('data-price', T.vat(vPrice, data.VAT)); 4814 T(selector.querySelectorAll('.product-price')).attr('data-default-price', data.PRICE); 4815 } 4816 if (selector.querySelectorAll('.product-price-not-vat').length) { 4817 T(selector.querySelectorAll('.product-price-not-vat')).attr('data-price', T.format(vPrice)); 4818 T(selector.querySelectorAll('.product-price-not-vat')).attr('data-default-price', data.PRICE); 4819 } 4820 if (selector.querySelectorAll('.product-price-not-discounted').length) { 4821 T(selector.querySelectorAll('.product-price-not-discounted')).attr('data-price', T.vat(vNotDiscounted, data.VAT)); 4822 T(selector.querySelectorAll('.product-price-not-discounted')).attr('data-default-price', data.PRICE); 4823 } 4824 if (selector.querySelectorAll('.product-price-not-discounted-not-vat').length) { 4825 T(selector.querySelectorAll('.product-price-not-discounted-not-vat')).attr('data-price', T.format(vNotDiscounted)); 4826 T(selector.querySelectorAll('.product-price-not-discounted-not-vat')).attr('data-default-price', data.PRICE); 4827 } 4828 4829 if (vDiscountPercent < 0) vDiscountPercent = vDiscountPercent * -1; 4830 4831 if (vDiscountPercent <= 0) { 4832 T(selector.querySelectorAll('.discounted-badge')).addClass('d-none'); 4833 T(selector.querySelectorAll('.product-discounted-price')).addClass('d-none'); 4834 } else { 4835 T(selector.querySelectorAll('.product-discounted-price')).removeClass('d-none'); 4836 T(selector.querySelectorAll('.discounted-badge')).removeClass('d-none'); 4837 T(selector.querySelectorAll('.product-discount')).text(vDiscountPercent.toFixed()); 4838 } 4839 4840 if (typeof PERSONALIZATION != 'undefined') { 4841 if (PERSONALIZATION[self.dataset.pid]) { 4842 PERSONALIZATION[self.dataset.pid].price(); 4843 } else if (PERSONALIZATION.price) { 4844 PERSONALIZATION.price(); 4845 } 4846 } 4847 4848 const changeSubs = selector.querySelector('[data-toggle="subscribe"]'); 4849 if (changeSubs) subscribe.change(changeSubs); 4850 4851 if (data.CODE == '') {
4852 const supplier_code = T('#product-supplier-code'); 4853 if (supplier_code.length > 0) { 4854 T(selector.querySelector('#product-code')).show(); 4855 T(selector.querySelector('#product-code #supplier-product-code')).text(supplier_code[0].value); 4856 } else { 4857 T(selector.querySelector('#product-code')).hide(); 4858 } 4859 } else { 4860 T(selector.querySelector('#product-code')).show(); 4861 T(selector.querySelector('#product-code #supplier-product-code')).text(data.CODE ? data.CODE : ''); 4862 } 4863 4864 if (data.BARCODE == '') { 4865 const barcode = T('#barcode-product-code'); 4866 if (barcode.length > 0) { 4867 T(selector.querySelector('#product-barcode')).show(); 4868 T(selector.querySelector('#product-barcode #barcode-product-code')).text(barcode[0].value); 4869 } else { 4870 T(selector.querySelector('#product-barcode')).hide(); 4871 } 4872 } else { 4873 T(selector.querySelector('#product-barcode')).show(); 4874 T(selector.querySelector('#product-barcode #barcode-product-code')).text(data.BARCODE ? data.BARCODE : ''); 4875 } 4876 4877 if (data.CASH_POINT_AMOUNT) { 4878 T(selector.querySelector('#product-cash-amount')).text(T.format(data.CASH_POINT_AMOUNT)); 4879 T(selector.querySelector('#product-cash-amount')).attr('data-price', data.CASH_POINT_AMOUNT); 4880 } 4881 if (data.CASH_POINT) { 4882 T(selector.querySelector('#product-cash-point')).text(data.CASH_POINT); 4883 T(selector.querySelector('#product-cash-point')).attr('data-point', data.CASH_POINT); 4884 } 4885 } 4886 4887 window[element.dataset.callback]?.(element, self, data); 4888 }, 4889 stock: function(el, status) { 4890 const selector = el.closest('.product-item') || el.closest('#product-right') || el.closest(el.dataset.wrapper); 4891 if (selector == null) return; 4892 4893 if (typeof cnf_negative_stock !== 'undefined' && cnf_negative_stock == 1) status = true; 4894 4895 if (status) { 4896 T(selector.querySelectorAll('.out-of-stock')).addClass('d-none'); 4897 T(selector.querySelectorAll('.in-stock-available')).show(); 4898 T(selector.querySelectorAll('.out-stock-available')).addClass('d-none'); 4899 } else { 4900 T(selector.querySelectorAll('.out-of-stock')).removeClass('d-none'); 4901 T(selector.querySelectorAll('.in-stock-available')).hide(); 4902 T(selector.querySelectorAll('.out-stock-available')).removeClass('d-none'); 4903 } 4904 }, 4905 buttonLink: function(self, proId, data) { 4906 const selector = self.closest(self.dataset.wrapper) || self.closest('.product-item') || self.closest('#product-detail') || self.closest('#product-right'); 4907 if (selector == null) return; 4908 4909 Array.from(T(selector.querySelectorAll('[data-type="price"], [data-type="shoplist"], [data-type="stock"], [data-type="installment"], [data-type="store"]'))).forEach(item => { 4910 let dataType; 4911 if (item.dataset.url) { 4912 dataType = item.dataset.url; 4913 } else if (item.dataset.href) { 4914 dataType = item.dataset.href; 4915 } else { 4916 dataType = item.href; 4917 } 4918 let link = dataType.split('?'); 4919 link[1] = link[1] || ""; 4920 4921 let params = new URLSearchParams(link[1]); 4922 4923 params.set('product', proId); 4924 params.set('variant', data.ID); 4925 4926 if (dataType.includes('isHtml')) { 4927 params.set('isHtml', '1'); 4928 } 4929 4930 link[1] = params.toString(); 4931 4932 let joinedLink = link.join('?').replaceAll(/\/\?\&/ig,'&'); 4933 if (item.dataset.url) { 4934 item.dataset.url = joinedLink; 4935 } else if (item.dataset.href) { 4936 item.dataset.href = joinedLink; 4937 } else { 4938 item.href = joinedLink; 4939 } 4940 4941 if (item.dataset.type == 'installment') { 4942 if (T(item.parentNode).hasClass('loaded')) { 4943 T(item.parentNode).removeClass('loaded'); 4944 T(item.parentNode).addClass('load'); 4945 } 4946 if (T(item.parentNode).hasClass('active')) { 4947 T(item).trigger('click'); 4948 } 4949 } 4950 }); 4951 }, 4952 }, 4953 init: function(element = null) { 4954 if(element == null || element.Variant) return; 4955 4956 let event = 'click'; 4957 if(element.nodeName == 'SELECT') event = 'change'; 4958 4959 const variantWrapper = element.closest('.variant-wrapper'); 4960 const subOne = variantWrapper?.querySelector('.sub-one'); 4961 const subTwo = variantWrapper?.querySelector('.sub-two'); 4962 const variantSub = element.closest('.sub-one') ? subOne : subTwo; 4963 const variantOtherSub = variantSub == subOne ? subTwo : subOne; 4964 const variantItem = (element.nodeName === 'SELECT') ? element.options[element.selectedIndex] : element; 4965 4966 element.addEventListener(event, async function(e) { 4967 let self = this; 4968 if(element.nodeName == 'A') 4969 e.preventDefault(); 4970 4971 if(element.nodeName == 'SELECT') 4972 self = element.options[self.options.selectedIndex]; 4973 4974 const subId = self.dataset.id; 4975 const subProId = self.dataset.target; 4976 const proId = self.dataset.pid; 4977 4978 if ((self.value === '' || self.value === '0') && element.subpro && element.nodeName == 'SELECT') { 4979 T(element.subpro)[0].value = '0'; 4980 element.querySelectorAll('option').forEach(option => { 4981 option.classList.remove('selected'); 4982 }); 4983 T(self).addClass('selected'); 4984 selectVaryant.set.stock(self, true); 4985 return; 4986 } 4987 4988 if (!subId || !subProId || !proId) return; 4989 element.subpro = '#subPro' + subProId; 4990 4991 const variantWrapper = self.closest('.variant-wrapper'); 4992 const subEl = self.closest('.sub-one') == null ? self.closest('.sub-two') : self.closest('.sub-one'); 4993 if (!subEl) return; 4994 const otherSubEl = T(subEl).hasClass('sub-one') == true ? '.sub-two' : '.sub-one'; 4995 4996 let variantData = []; 4997 4998 const defaultSelect = function() { 4999 if (subOne && subTwo && variantSub == subOne && variantSub.oneClick != 1 && self.classList.contains('selected')) { 5000 variantSub.oneClick = 1; 5001 5002 const activeElement = variantOtherSub.querySelector('.selected'); 5003 if (!activeElement) return; 5004 5005 const isElementPassive = activeElement.classList.contains('passive') || activeElement.classList.contains('not-sub'); 5006 const otherElements = variantOtherSub.querySelectorAll('[data-toggle="variant"]:not(select), select[data-toggle="variant"] option[data-id]'); 5007 const otherNotActive = variantOtherSub.querySelectorAll('.passive, .not-sub'); 5008 5009 if (isElementPassive && otherNotActive.length != otherElements.length) { 5010 let stats = 0;
5011 Array.from(otherElements).forEach(item => { 5012 item.classList.remove('selected'); 5013 if (stats) return; 5014 5015 if (!(item.classList.contains('passive') || item.classList.contains('not-sub')) && item.dataset.type) { 5016 stats = 1; 5017 item.classList.add('selected'); 5018 5019 const select = variantOtherSub.querySelector('select[data-toggle="variant"]'); 5020 if (select && item.value !== '0') { 5021 select.value = item.value; 5022 T(select).trigger('change'); 5023 } else { 5024 T(item).trigger('click'); 5025 } 5026 } 5027 }); 5028 } else { 5029 setTimeout(() => { 5030 const select = variantOtherSub.querySelector('select[data-toggle="variant"]'); 5031 if (select && activeElement.value !== '0') { 5032 select.value = activeElement.value; 5033 T(select).trigger('change'); 5034 } else { 5035 T(activeElement).trigger('click'); 5036 } 5037 }, 1); 5038 } 5039 } 5040 } 5041 5042 const notAjax = async () => { 5043 const data = { 5044 'ADDITIONAL_INFO': self.dataset.additional || '', 5045 'ID': self.dataset.subproductId, 5046 'TYPE_ID': self.dataset.id, 5047 'TYPE': self.dataset.type, 5048 'CODE': self.dataset.code, 5049 'TYPE_COLOR_CODE': self.dataset.colorCode, 5050 'PRICE': self.dataset.price, 5051 'STOCK': self.dataset.stock, 5052 'IN_STOCK': self.dataset.instock, 5053 'BARCODE': self.dataset.barcode, 5054 'MONEY_ORDER_PERCENT': self.dataset.mop, 5055 'VAT': self.dataset.vat, 5056 'PRICE_NOT_DISCOUNTED': self.dataset.notDiscounted, 5057 'WS_CODE': self.dataset.wscode, 5058 'WEIGHT': self.dataset.weight, 5059 'CASH_POINT': self.dataset.cashPoint, 5060 'CASH_POINT_AMOUNT': self.dataset.cashPointAmount, 5061 }; 5062 5063 selectVaryant.set.price(self, data, element); 5064 selectVaryant.set.stock(self, data.STOCK > 0); 5065 selectVaryant.set.buttonLink(self, proId, data); 5066 T('#subPro' + subProId)[0].value = data.ID; 5067 defaultSelect(); 5068 } 5069 5070 if (variantWrapper.querySelector(otherSubEl)) { 5071 const subOneLenght = variantWrapper.querySelector('.sub-one').querySelectorAll('[data-toggle="variant"]:not(select), select[data-toggle="variant"] option[data-id]'); 5072 if (subOneLenght.length == 1) { 5073 if (T(subEl).hasClass('sub-two')) { 5074 notAjax(); 5075 } else { 5076 setTimeout(() => { 5077 defaultSelect(); 5078 }, 1); 5079 } 5080 } else { 5081 const getList = T(subEl).hasClass('sub-one') ? 'get-variant2-list' : 'get-variant1-list'; 5082 axios.get(getEndpoint('VARIANT', `${getList}/${proId}/${subId}`)).then(res => { 5083 const data = res.data.VARIANT2_LIST ?? res.data.VARIANT1_LIST; 5084 const variantArray = variantWrapper.querySelector(otherSubEl).querySelectorAll('[data-toggle="variant"]:not(select), select[data-toggle="variant"] option'); 5085
5086 Array.from(variantArray).forEach(el => { 5087 if(el.value == '0' || el.value == '') return; 5088 5089 if (T(subEl).hasClass('sub-one')) { 5090 T(el).addClass('d-none'); 5091 T(el).addClass('passive not-sub'); 5092 } 5093 5094 if (el['name'] == null) el['name'] = T(el).text(); 5095 const subData = Array.from(data).find(x => x.TYPE_ID == el.dataset.id); 5096 if (subData) { 5097 if (subData.STOCK > 0) { 5098 T(el).removeClass('passive'); 5099 if (el.nodeName == 'OPTION') { 5100 T(el).text(el.name); 5101 el.removeAttribute('disabled'); 5102 } 5103 } else { 5104 if (el.nodeName == 'OPTION') { 5105 T(el).text(`${el.name} (${TLANG.out_of_stock || 'Tükendi'})`); 5106 if (el.closest('.product-item')) { 5107 if (el.closest('.sub-two')) el.setAttribute('disabled', 'disabled'); 5108 } 5109 } 5110 } 5111 T(el).removeClass('d-none not-sub'); 5112 } 5113 }); 5114 5115 const otherSelected = variantWrapper.querySelector(otherSubEl).querySelector('.selected'); 5116 if (otherSelected != null && (otherSelected.value === '0' || otherSelected.value === '')) return; 5117 5118 if (otherSelected != null) { 5119 if (T(otherSelected).hasClass('d-none')) T(otherSelected).removeClass('selected'); 5120 const subId = otherSelected.dataset.id; 5121 variantData = Array.from(data).find(x => x.TYPE_ID == subId); 5122 const variantId = variantData ? variantData.ID : '0'; 5123 selectVaryant.set.price(self, variantData, element); 5124 selectVaryant.set.buttonLink(self, proId, variantData); 5125 if (T(self).hasClass('not-sub')) { 5126 selectVaryant.set.stock(self, true); 5127 } else { 5128 selectVaryant.set.stock(self, !T(self).hasClass('passive')); 5129 } 5130 T('#subPro' + subProId)[0].value = variantId; 5131 } else { 5132 window[element.dataset.callback]?.(element, self, data); 5133 } 5134 5135 defaultSelect(); 5136 }); 5137 } 5138 } else { 5139 notAjax(); 5140 } 5141 5142 T(subEl.querySelectorAll('[data-toggle="variant"]:not(select)')).removeClass('selected'); 5143 T(subEl.querySelectorAll('select[data-toggle="variant"] option')).removeClass('selected'); 5144 if (!T(self).hasClass('d-none')) T(self).addClass('selected'); 5145 }); 5146 5147 if (typeof selectVariantCallback === 'function' && PAGE_TYPE === 'product' && typeof PRODUCT_DATA === 'object' && PRODUCT_DATA[0]?.id && !selectVariantCallback.ready) { 5148 selectVariantCallback.ready = 1; 5149 const getVariantId = getUrlParam('variant'); 5150 try { 5151 const subOne = document.querySelector('.sub-one'); 5152 const subTwo = document.querySelector('.sub-two'); 5153 selectVariantCallback(PRODUCT_DATA, getVariantId, subOne, subTwo); 5154 } catch (error) { } 5155 } 5156 5157 const isOnylSub = (variantOtherSub && variantSub === subOne) || (subOne && !subTwo || subTwo && !subOne); 5158 const isElementActive = variantItem.classList.contains('selected'); 5159 const isElementPassive = variantItem.classList.contains('passive') || variantItem.classList.contains('not-sub'); 5160 const otherElements = variantSub.querySelectorAll('[data-toggle="variant"]:not(select), select[data-toggle="variant"] option[data-id]'); 5161 const otherNotActive = variantSub.querySelectorAll('.passive, .not-sub'); 5162 const subOneLenght = subOne?.querySelectorAll('[data-toggle="variant"]:not(select), select[data-toggle="variant"] option[data-id]'); 5163 5164 if (isOnylSub && isElementActive) { 5165 if (!variantOtherSub && isElementActive && isElementPassive && otherNotActive.length != otherElements.length) { 5166 let stats = 0;
5167 Array.from(otherElements).forEach(item => { 5168 item.classList.remove('selected'); 5169 if (stats) return; 5170 5171 if (!(item.classList.contains('passive') || item.classList.contains('not-sub')) && item.dataset.type) { 5172 stats = 1; 5173 item.classList.add('selected'); 5174 const select = variantSub.querySelector('select[data-toggle="variant"]'); 5175 setTimeout(() => { 5176 if (select && item.value !== '0') { 5177 select.value = item.value; 5178 T(select).trigger('change'); 5179 } else { 5180 T(item).trigger('click'); 5181 } 5182 }, 1); 5183 } 5184 }); 5185 } else { 5186 T(element).trigger(event); 5187 } 5188 } else if (variantSub === subOne && subOneLenght?.length == 1) { 5189 T(element).trigger(event); 5190 } 5191 5192 if (!variantOtherSub || (variantOtherSub && subOneLenght?.length == 1 && variantSub == subTwo)) { 5193 if (element.nodeName == 'SELECT') { 5194 Array.from(element.options).forEach(option => { 5195 const stock = Number(option.dataset.stock); 5196 if (option['name'] == null) option['name'] = T(option).text(); 5197 if (stock <= 0) { 5198 T(option).text(`${option.name} (${TLANG.out_of_stock || 'Tükendi'})`); 5199 if (option.closest('.product-item')) option.setAttribute('disabled', 'disabled'); 5200 } else { 5201 T(option).text(option.name); 5202 option.removeAttribute('disabled'); 5203 } 5204 }); 5205 } 5206 } 5207 5208 element.Variant = element; 5209 } 5210}; 5211 5212const snapScroll = { 5213 init: function(element = null) { 5214 if(element == null || element.Snap) return; 5215 element.style.opacity = 0; 5216 let count = 0; 5217 const snapItem = element.querySelectorAll('.snap-item'); 5218 snapItem[0].classList.add('snap-item-active'); 5219 5220 const scroll = element.querySelector('.snap-scroll'); 5221 const btnPrev = element.querySelector('.snap-prev'); 5222 const btnNext = element.querySelector('.snap-next'); 5223 5224 T(btnPrev).on('click', () => { 5225 count--; 5226 if (count <= 0) count = 0; 5227 5228 element.querySelector('.snap-item-active').classList.remove('snap-item-active'); 5229 snapItem[count].classList.add('snap-item-active'); 5230 scroll.scrollBy(-element.querySelector('.snap-item-active').offsetWidth, 0); 5231 }); 5232 5233 T(btnNext).on('click', () => { 5234 count++; 5235 if (count >= snapItem.length) count = snapItem.length - 1; 5236 5237 element.querySelector('.snap-item-active').classList.remove('snap-item-active'); 5238 snapItem[count].classList.add('snap-item-active'); 5239 scroll.scrollBy(element.querySelector('.snap-item-active').offsetWidth, 0); 5240 }); 5241 5242 setTimeout(() => { 5243 if (scroll.clientWidth < element.clientWidth) { 5244 T(btnPrev).addClass('d-none'); 5245 T(btnNext).addClass('d-none'); 5246 } else { 5247 T(scroll).addClass('overflow-x-auto overflow-y-hidden'); 5248 } 5249 scroll.scrollTo(0, 0); 5250 element.style.opacity = null; 5251 }, 250); 5252 5253 element.Snap = element; 5254 } 5255}; 5256 5257const favouriteProducts = { 5258 STORAGE_KEY: "favorite_products", 5259 SESSION_KEY: "favorites_fetched", 5260 SESSION_SERVER: "server_favorites", 5261 LIST_API_URL: "/srv/service/profile/get-shopping-list", 5262 ADD_API_URL: "/srv/service/profile/add-to-fav-list", 5263 REMOVE_API_URL: "/srv/service/profile/delete-shopping-products-by-product-id", 5264 updateTimeout: null, 5265 debounceTimeout: null, 5266 maxChanges: 10, 5267 syncFavorites: false, 5268 ids: [], 5269 async add(ids = null) { 5270 if (MEMBER_INFO.ID <= 0) { 5271 favouriteProducts.login(); 5272 return; 5273 } 5274 5275 let isSingle = false;
5276 5277 if (ids == null) ids = []; 5278 if (!Array.isArray(ids)) { 5279 ids = [ids]; 5280 isSingle = true; 5281 } 5282 if (ids.length === 0) return; 5283 5284 let favorites = this.getFavorites(); 5285 let changed = false; 5286 const callback = this.callback; 5287 5288 ids.forEach(productId => { 5289 if (isSingle) { 5290 if (favorites.includes(productId)) { 5291 favorites.splice(favorites.indexOf(productId), 1); 5292 callback(productId, 'remove'); 5293 changed = true; 5294 } else { 5295 favorites.push(productId); 5296 callback(productId, 'add'); 5297 changed = true; 5298 } 5299 } else { 5300 if (!favorites.includes(productId)) { 5301 favorites.push(productId); 5302 callback(productId, 'add'); 5303 changed = true; 5304 } 5305 } 5306 }); 5307 5308 if (changed) { 5309 await this.setFavorites(favorites); 5310 await this.sendUpdates(true); 5311 this.set(); 5312 } 5313 }, 5314 remove(ids = null) { 5315 if (ids == null) return; 5316 if (!Array.isArray(ids)) { 5317 ids = [ids]; 5318 } 5319 let favorites = this.getFavorites(); 5320 const callback = this.callback; 5321 ids.forEach(productId => { 5322 if (favorites.includes(productId)) { 5323 favorites.splice(favorites.indexOf(productId), 1); 5324 callback(productId, 'remove'); 5325 } 5326 }); 5327 this.setFavorites(favorites); 5328 this.sendUpdates(); 5329 this.set(); 5330 }, 5331 counter() { 5332 sessionStorage.removeItem(this.SESSION_KEY); 5333 this.fetchFavorites(); 5334 }, 5335 getFavorites() { 5336 return JSON.parse(localStorage.getItem(this.STORAGE_KEY)) || []; 5337 }, 5338 async setFavorites(favorites) { 5339 localStorage.setItem(this.STORAGE_KEY, JSON.stringify(favorites)); 5340 T('.customer-favorites-count, .tsoft-favourite-count').text(favorites.length || 0); 5341 }, 5342 fetchFavorites() { 5343 if (MEMBER_INFO.ID <= 0) { 5344 localStorage.removeItem(this.STORAGE_KEY); 5345 sessionStorage.removeItem(this.SESSION_KEY); 5346 sessionStorage.removeItem(this.SESSION_SERVER); 5347 return; 5348 } 5349 5350 if (sessionStorage.getItem(this.SESSION_KEY) && localStorage.getItem(this.STORAGE_KEY)) { 5351 this.sendUpdates(); 5352 return; 5353 }; 5354 5355 axios.get(this.LIST_API_URL) 5356 .then(response => { 5357 let data = response.data; 5358 let apiFavorites = data?.CATEGORIES?.[0]?.PRODUCTS?.map(p => p.ID) || []; 5359 5360 this.setFavorites(apiFavorites); 5361 sessionStorage.setItem(this.SESSION_SERVER, JSON.stringify(apiFavorites)); 5362 sessionStorage.setItem(this.SESSION_KEY, "true"); 5363 5364 this.sendUpdates(false, apiFavorites); 5365 this.set(); 5366 }) 5367 .catch(error => { 5368 console.error("API hatası:", error); 5369 }); 5370 }, 5371 async set() { 5372 const favorites = this.getFavorites(); 5373 T('.customer-favorites-count, .tsoft-favourite-count').text(favorites.length || 0); 5374 const allFavButtons = document.querySelectorAll('.add-favourite-btn[data-id]'); 5375 5376 allFavButtons.forEach(btn => { 5377 btn.classList.remove('fav-added'); 5378 }); 5379 5380 favorites.forEach(productId => { 5381 const favButtons = document.querySelectorAll(`.add-favourite-btn[data-id="${productId}"]`); 5382 favButtons.forEach(btn => { 5383 btn.classList.add('fav-added'); 5384 }); 5385 }); 5386 }, 5387 toggleFavorite(productId) { 5388 let favorites = this.getFavorites(); 5389 const index = favorites.indexOf(productId); 5390 5391 const favButtons = document.querySelectorAll(`[data-id="${productId}"]`); 5392 5393 if (index === -1) { 5394 favorites.push(productId); 5395 favButtons.forEach(btn => { 5396 btn.classList.add('fav-added'); 5397 }); 5398 this.callback(productId, 'add'); 5399 } else { 5400 favorites.splice(index, 1); 5401 favButtons.forEach(btn => { 5402 btn.classList.remove('fav-added'); 5403 }); 5404 this.callback(productId, 'remove'); 5405 } 5406 5407 this.setFavorites(favorites); 5408 this.scheduleUpdate(); 5409 }, 5410 debounceToggleFavorite(productId) { 5411 clearTimeout(this.debounceTimeout); 5412 this.debounceTimeout = setTimeout(() => { 5413 if (MEMBER_INFO.ID <= 0) { 5414 favouriteProducts.login(); 5415 return; 5416 } 5417 5418 if (!localStorage.getItem(this.STORAGE_KEY)) { 5419 this.fetchFavorites().then(() => { 5420 this.toggleFavorite(productId); 5421 }); 5422 return; 5423 } 5424 5425 this.toggleFavorite(productId); 5426 }, 500); 5427 }, 5428 async scheduleUpdate() { 5429 if (this.updateTimeout) clearTimeout(this.updateTimeout); 5430 5431 let storedFavorites = this.getFavorites(); 5432 let serverFavorites = JSON.parse(sessionStorage.getItem(this.SESSION_SERVER)
5432) || []; 5433 5434 let toAdd = storedFavorites.filter(id => !serverFavorites.includes(id)); 5435 let toRemove = serverFavorites.filter(id => !storedFavorites.includes(id)); 5436 5437 if (toAdd.length + toRemove.length > this.maxChanges) { 5438 this.sendUpdates(); 5439 return; 5440 } 5441 5442 this.updateTimeout = setTimeout(() => { 5443 this.sendUpdates(); 5444 }, 60000); 5445 }, 5446 sendUpdates(message = false, localFavorites = []) { 5447 if (this.syncFavorites) return; 5448 this.syncFavorites = true; 5449 5450 let storedFavorites = localFavorites.length > 0 ? localFavorites : this.getFavorites(); 5451 let serverFavorites = JSON.parse(sessionStorage.getItem(this.SESSION_SERVER)) || []; 5452 5453 let toAdd = storedFavorites.filter(id => !serverFavorites.includes(id)); 5454 let toRemove = serverFavorites.filter(id => !storedFavorites.includes(id)); 5455 5456 let sent = true; 5457 5458 const sendSync = async (url, data, isAdd = true) => { 5459 try { 5460 if (message) { 5461 try { 5462 let response = await axios.post(url, data); 5463 const result = response.data; 5464 5465 if (result?.status) { 5466 if (result?.data?.length > 1) { 5467 let message = ''; 5468 const not_added_product = []; 5469 5470 result.data.map(item => { 5471 if (item.status) { 5472 message += `<div class="d-flex align-items-center mb-1"><i class="ti-check text-primary mr-1"></i> ${item.product.name}</div>`; 5473 } else { 5474 if (not_added_product.indexOf(item.statusText) === -1) not_added_product.push(item.statusText); 5475 } 5476 }); 5477 5478 if (not_added_product.length > 0) message += `<div class="text-gray mt-1 py-1 border-top border-light">${not_added_product.join('<br>')}</div>`; 5479 5480 T.modal({ 5481 html: `<div class="block-title mb-1">${TLANG.favorited_products || 'Favoriye Eklenen Ãrünler'}</div>${message}`, 5482 width: '480px' 5483 }); 5484 } else { 5485 T.notify({ 5486 text: isAdd ? TLANG.added_to_favorites || 'Ãrün favorilerinize eklendi' : TLANG.removed_from_favorites || 'Ãrün favorilerinizden çıkarıldı', 5487 className: isAdd ? 'success add-favourite-added-notify' : 'danger add-favourite-removed-notify', 5488 duration: 2500, 5489 iconClass : isAdd ? 'ti-thumbs-up' : 'ti-trash', 5490 }); 5491 } 5492 } else { 5493 const not_added_product = []; 5494 result.data.map(item => { 5495 if (not_added_product.indexOf(item.statusText) === -1) not_added_product.push(item.statusText); 5496 }); 5497 5498 if (not_added_product.length > 0) { 5499 T.modal({ 5500 html: `<div class="text-gray py-1">${not_added_product.join('<br>')}</div>`, 5501 width: '480px' 5502 }); 5503 } 5504 } 5505 5506 return result.status; 5507 } catch (error) { 5508 console.error("Veri gönderme hatası:", error); 5509 return false; 5510 } 5511 } else if (navigator.sendBeacon) { 5512 return navigator.sendBeacon(url, data); 5513 } else { 5514 const xhr = new XMLHttpRequest(); 5515 xhr.open('POST', url, false); 5516 try { 5517 xhr.send(data); 5518 return xhr.status === 200; 5519 } catch (error) { 5520 console.error("Veri gönderme hatası:", error); 5521 return false;
5522 } 5523 } 5524 } catch (error) { 5525 console.error("sendSync iÅlemi sırasında hata:", error); 5526 return false; 5527 } 5528 }; 5529 5530 const processUpdates = async () => { 5531 try { 5532 if (toAdd.length > 0) { 5533 const body = new FormData(); 5534 toAdd.forEach(id => { 5535 body.append('ids[]', id + '-0'); 5536 }); 5537 body.append('fetch', true); 5538 body.append('cat_id', 1); 5539 const addResult = await sendSync(this.ADD_API_URL, body, true); 5540 sent = sent && addResult; 5541 } 5542 5543 if (toRemove.length > 0) { 5544 const body = new FormData(); 5545 toRemove.forEach(id => { 5546 body.append('products[]', id); 5547 }); 5548 const removeResult = await sendSync(this.REMOVE_API_URL, body, false); 5549 sent = sent && removeResult; 5550 } 5551 5552 if (sent) { 5553 sessionStorage.setItem(this.SESSION_SERVER, JSON.stringify(storedFavorites)); 5554 if (localFavorites.length > 0) { 5555 this.setFavorites(localFavorites); 5556 this.set(); 5557 } 5558 } 5559 } catch (error) { 5560 console.error("Favori güncellemesi sırasında hata:", error); 5561 } finally { 5562 // İÅlem baÅarılı veya baÅarısız olsa da kilidi kaldır 5563 this.syncFavorites = false; 5564 } 5565 }; 5566 5567 processUpdates(); 5568 }, 5569 handleOnline() { 5570 this.sendUpdates(); 5571 }, 5572 handlePageLeave() { 5573 this.sendUpdates(); 5574 }, 5575 click: function(element) { 5576 if (element.clickFavBtn == 1) return; 5577 element.addEventListener('click', () => { 5578 let productId = element.getAttribute("data-id"); 5579 if (productId) favouriteProducts.debounceToggleFavorite(productId); 5580 }); 5581 element.clickFavBtn = 1; 5582 }, 5583 login: function() { 5584 loadSubFolder({ 5585 pageId: 5, 5586 blockParentId: 1006, 5587 subFolder: 'popup-login', 5588 success: function(loadRes){ 5589 T.modal({ 5590 id: 'popup-login', 5591 html: loadRes, 5592 close: true 5593 }); 5594 } 5595 }); 5596 }, 5597 callback: function(id, type) { 5598 const product = Array.from(PRODUCT_DATA).find(p => p.id == id); 5599 if (product) { 5600 const returnData = [{ 5601 data: { 5602 code: product.code, 5603 id: product.id, 5604 name: product.name, 5605 currency: product.currency, 5606 category_id: product.category_id, 5607 category_name: product.category, 5608 category_path: product.category_path, 5609 brand: product.brand, 5610 price: product.total_sale_price 5611 }, 5612 status: 1 5613 }]; 5614 5615 if (type == 'add') { 5616 for(let i=0; i < callbacks.product.wishList.add.length; i++){ 5617 if(typeof callbacks.product.wishList.add[i] === 'function'){ 5618 try { 5619 callbacks.product.wishList.add[i]?.(returnData); 5620 } catch (error) { console.log(`Product Wishlist Add Callback Error => ${error}`); } 5621 } 5622 } 5623 5624 for(let i=0; i < callbacks.product.favourite.add.length; i++){ 5625 if(typeof callbacks.product.favourite.add[i] === 'function'){ 5626 try { 5627 callbacks.product.favourite.add[i]?.(id); 5628 } catch (error) { console.log(`Products Favourite Add Callback Error => ${error}`); } 5629 } 5630 } 5631 } else { 5632 for(let i=0; i < callbacks.product.wishList.remove.length; i++){ 5633 if(typeof callbacks.product.wishList.remove[i] === 'function'){ 5634 try { 5635 callbacks.product.wishList.remove[i]?.(returnData); 5636 } catch (error) { console.log(`Product Wishlist Remove Callback Error => ${error}`); } 5637 } 5638 } 5639 5640 for(let i=0; i < callbacks.product.favourite.remove.length; i++){ 5641 if(typeof callbacks.product.favourite.remove[i] === 'function'){ 5642 try { 5643 callbacks.product.favourite.remove[i]?.(id); 5644 } catch (error) { console.log(`Products Favourite Remove Callback Error => ${error}`); } 5645 } 5646 } 5647 } 5648 } 5649 }, 5650 init() { 5651 this.fetchFavorites(); 5652 this.set(); 5653 5654 if (MEMBER_INFO.ID > 0) { 5655 window.addEventListener("online", () => this.handleOnline()); 5656 5657 const boundHandlePageLeave = this.handlePageLeave.bind(this); 5658 5659 window.addEventListener("beforeunload", boundHandlePageLeave); 5660 window.addEventListener("unload", boundHandlePageLeave); 5661 window.addEventListener("pagehide", boundHandlePageLeave); 5662 window.addEventListener("visibilitychange", () => { 5663 if (document.visibilityState === 'hidden') { 5664 boundHandlePageLeave(); 5665 } 5666 }); 5667 } 5668 } 5669}; 5670 5671const countDown = { 5672 init: function(count = null) { 5673 let timer = count.dataset.timer; 5674 timer = timer.split(','); 5675 timer = new Date(timer[0], timer[1]-1, timer[2], timer[3], timer[4], timer[5]); 5676 countDown.get(count, timer); 5677 }, 5678 get: function(element, timer) { 5679 const x = setInterval(function() { 5680 const now = new Date(); 5681 const countDate = new Date(timer); 5682 const amount = Date.parse(countDate) - Date.parse(now); 5683 delete now; 5684 if (amount < 0) { 5685 clearInterval(x); 5686 return; 5687 } 5688 const days = Math.floor(amount / (1000 * 60 * 60 * 24)), 5689 hours = Math.floor((amount % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)), 5690 minutes = Math.floor((amount % (1000 * 60 * 60)) / (1000 * 60)), 5691 seconds = Math.floor((amount % (1000 * 60)) / 1000); 5692 5693 const formattedHours = hours < 10 ? '0' + hours : hours, 5694 formattedMinutes = minutes < 10 ? '0' + minutes : minutes, 5695 formattedSeconds = seconds < 10 ? '0' + seconds : seconds; 5696 5697 if (element.querySelector('.day .timer-text')) element.querySelector('.day .timer-text').innerHTML = days; 5698 if (element.querySelector('.hour .timer-text')) element.querySelector('.hour .timer-text').innerHTML = formattedHours; 5699 if (element.querySelector('.minute .timer-text')) element.querySelector('.minute .timer-text').innerHTML = formattedMinutes; 5700 if (element.querySelector('.second .timer-text')) element.querySelector('.second .timer-text').innerHTML = formattedSeconds; 5701 }, 1000); 5702 } 5703}; 5704 5705const passwordStrengthControl = function() { 5706 if (Number(MEMBER_INFO.ID) < 1) return; 5707 if(typeof MEMBER_INFO.PASSWORD_STRENGTH == 'undefined') return; 5708 if (Number(MEMBER_INFO.PASSWORD_STRENGTH) > 6) return; 5709 5710 loadSubFolder({ 5711 pageId: 6, 5712 blockParentId: 1008, 5713 subFolder: 'update-password', 5714 params: {}, 5715 success: function(loadRes){ 5716 T.modal({
5717 id: 'modal-update-password', 5718 width: '570px', 5719 html: loadRes, 5720 close: false 5721 }); 5722 } 5723 }); 5724}; 5725 5726const mobileAppFn = function() { 5727 const element = document.querySelector('[data-toggle="mobile-app"]'); 5728 if (element && T.isMobile() && PAGE_ID == 1) { 5729 5730 if (T.getCookie('mobileApp') == 1) { 5731 element.remove(); 5732 return; 5733 } else { 5734 element.classList.remove('d-none'); 5735 } 5736 5737 const downloadBtn = element.querySelector('[data-toggle="mobile-app-download"]'); 5738 const closeBtn = element.querySelector('[data-toggle="mobile-app-close"]'); 5739 5740 const MobileAppRedirect = element.querySelector('[name="MobileAppRedirect"]')?.value || '', 5741 AppMarketLink = element.querySelector('[name="AppMarketLink"]')?.value || '', 5742 OpenAppLink = element.querySelector('[name="OpenAppLink"]')?.value || ''; 5743 5744 let storeUrl; 5745 if (MobileAppRedirect == 'ios') { 5746 storeUrl = `https://itunes.apple.com/app/id${AppMarketLink}`; 5747 } else if (MobileAppRedirect == 'android') { 5748 storeUrl = `market://details?id=${AppMarketLink}`; 5749 } 5750 if (!storeUrl) return; 5751 5752 const meta = document.createElement('meta'); 5753 meta.name = 'apple-itunes-app'; 5754 meta.content = `app-id=${AppMarketLink}, affiliate-data=myAffiliateData, app-argument=${OpenAppLink}://`; 5755 document.head.append(meta); 5756 5757 if (downloadBtn) { 5758 downloadBtn.addEventListener('click', e => { 5759 setTimeout(() => { 5760 document.location.href = storeUrl; 5761 }, 2000); 5762 document.location.href = `${OpenAppLink}://`; 5763 }); 5764 } 5765 5766 if (closeBtn) { 5767 closeBtn.addEventListener('click', e => { 5768 element.remove(); 5769 T.setCookie('mobileApp', 1); 5770 }); 5771 } 5772 } 5773} 5774 5775const catalog = function(element) { 5776 if (T.isMobile()) return; 5777 5778 if(element == null || element.catalog) return; 5779 5780 const productItem = element.closest('.product-item'); 5781 if (!productItem) { 5782 console.warn('catalog warn: productItem undefined'); 5783 return; 5784 }; 5785 5786 const productId = element.dataset.product; 5787 if (!productId) { 5788 console.warn('getCatalog warn: productId (catalog.dataset.product) undefined'); 5789 return; 5790 }; 5791 5792 const modelId = element.dataset.model; 5793 if (!modelId) { 5794 console.warn('getCatalog warn: modelId (catalog.dataset.model) undefined'); 5795 return; 5796 }; 5797 5798 const isCatalogActive = element.querySelector('[data-toggle="is-catalog-active"]'); 5799 if (!isCatalogActive?.value) return; 5800 5801 let hoverTimeout; 5802 element.addEventListener('mouseenter', () => { 5803 if (element.classList.contains('catalog-loaded') || element.catalogApp) return; 5804 5805 hoverTimeout = setTimeout(async () => { 5806 productItem.classList.add('catalog-opacity'); 5807 element.classList.add('pointer-events-none'); 5808 5809 element['catalogApp'] = Vue.createApp({ 5810 data() { 5811 return { 5812 ATTRIBUTES: [], 5813 } 5814 }, 5815 methods: { 5816 async getAttribute(product_id = null, product = true) { 5817 if (product_id == null) return; 5818 const self = this; 5819 5820 if (element[`PRODUCT_ATTRIBUTES_${product_id}`]) { 5821 self.ATTRIBUTES = JSON.parse(JSON.stringify(element[`PRODUCT_ATTRIBUTES_${product_id}`])); 5822 Array.from(self.ATTRIBUTES).forEach(item => { 5823 const selectedOption = item.OPTIONS.find(opt => opt.SELECTED === true); 5824 if (selectedOption) { 5825 item['SELECT_ID'] = selectedOption.ID; 5826 item['SELECT_NAME'] = selectedOption.NAME; 5827 if (self.ATTRIBUTES.CATALOG_VIEW == 'select') item['SELECT_SEARCH'] = item['SELECT_NAME']; 5828 } 5829 }); 5830 } else { 5831 const formData = new FormData(); 5832 formData.append('product_id', product_id); 5833 formData.append('with_image', '1'); 5834 5835 try { 5836 await axios.post(getEndpoint('CATALOG_ATTRIBUTES'), formData).then(response => { 5837 if (!response.data?.length) { 5838 console.warn('productCardCatalog warn: CATALOG_ATTRIBUTES length'); 5839 return; 5840 }; 5841 self.ATTRIBUTES = response.data; 5842 5843 Array.from(self.ATTRIBUTES).forEac
5843h(item => { 5844 item.OPTIONS = item.OPTIONS.filter(opt => opt.PRODUCT_ID != null); 5845 const selectedOption = item.OPTIONS.find(opt => opt.SELECTED === true); 5846 if (selectedOption) { 5847 item['SELECT_ID'] = selectedOption.ID; 5848 item['SELECT_NAME'] = selectedOption.NAME; 5849 if (item.CATALOG_VIEW == 'select') item['SELECT_SEARCH'] = item['SELECT_NAME']; 5850 } 5851 }); 5852 element[`PRODUCT_ATTRIBUTES_${product_id}`] = JSON.parse(JSON.stringify(self.ATTRIBUTES)); 5853 return; 5854 }); 5855 } catch (error) { 5856 console.warn(`CATALOG_ATTRIBUTES error => ${error}`); 5857 } 5858 } 5859 5860 if (product == null) { 5861 element.ATTRIBUTES = JSON.parse(JSON.stringify(self.ATTRIBUTES)); 5862 self.getProductProperties(); 5863 } 5864 5865 setTimeout(() => { 5866 self.slideAttribute(); 5867 }, 50); 5868 5869 productItem.classList.remove('catalog-opacity'); 5870 element.classList.remove('pointer-events-none'); 5871 element.classList.add('catalog-loaded'); 5872 }, 5873 setAttribute(attribute = null, option = null) { 5874 const self = this; 5875 5876 if (option.target?.value) option = Array.from(attribute.OPTIONS).find(x => x.ID == option.target.value); 5877 if (attribute == null || option == null) return; 5878 if (attribute['SELECT_ID'] == option.ID) return; 5879 5880 Array.from(attribute.OPTIONS).map(x => x.SELECTED = x.ID == option.ID ? true : false); 5881 attribute['SELECT_ID'] = option.ID; 5882 attribute['SELECT_NAME'] = option.NAME; 5883 if (attribute.CATALOG_VIEW == 'select') { 5884 attribute['SELECT_SEARCH'] = attribute['SELECT_NAME']; 5885 attribute.IS_OPEN = false; 5886 Array.from(attribute.OPTIONS).forEach(item => { 5887 item['HIDDEN'] = false; 5888 }); 5889 } 5890 5891 element.ATTRIBUTES = JSON.parse(JSON.stringify(self.ATTRIBUTES)); 5892 5893 self.getProductProperties(option); 5894 return; 5895 }, 5896 async getProductProperties(option = null) { 5897 const self = this; 5898 let catalogProductId = ''; 5899 5900 const formData = new FormData(); 5901 formData.append('model_id', modelId); 5902 Array.from(self.ATTRIBUTES).forEach((item, index) => { 5903 if (item.SELECT_ID) { 5904 catalogProductId += `${item.GROUP_ID}_${item.SELECT_ID}`; 5905 formData.append(`attribute[${index}][id]`, item.GROUP_ID); 5906 formData.append(`attribute[${index}][option_id]`, item.SELECT_ID); 5907 } 5908 }); 5909 5910 if (element[`PRODUCT_DATA_${catalogProductId}`]) { 5911 const PRODUCT = element[`PRODUCT_DATA_${catalogProductId}`]; 5912 await self.setProductData(PRODUCT); 5913 await self.getAttribute(PRODUCT.ID); 5914 return; 5915 } 5916 5917 try { 5918 productItem.classList.add('catalog-opacity'); 5919 element.classList.add('pointer-events-none'); 5920 5921 await axios.post(getEndpoint('CATALOG_GET_PRODUCT'), formData).then(async response => { 5922 if (response?.data?.length) { 5923 const PRODUCT = response.data[0]; 5924 if (PRODUCT?.ID) { 5925 element[`PRODUCT_DATA_${catalogProductId}`] = PRODUCT; 5926 await self.setProductData(PRODUCT); 5927 await self.getAttribute(PRODUCT.ID); 5928 } else { 5929 await self.getAttribute(option.PRODUCT_ID, null); 5930 } 5931 } 5932 }); 5933 } catch (error) { 5934 console.warn(`CATALOG_GET_PRODUCT error => ${error}`); 5935 } finally { 5936 productItem.classList.remove('catalog-opacity'); 5937 element.classList.remove('pointer-events-none'); 5938 } 5939 }, 5940 async setProductData(P = null) { 5941 if (P == null) return; 5942 5943 productItem.dataset.id = P.ID; 5944 const productItemData = productItem.querySelectorAll(` 5945 [data-toggle="product-title"], 5946 [data-toggle="product-url"], 5947 [data-toggle="product-id"], 5948 .product-price, .product-price-not-vat, 5949 .product-price-not-discounted, .product-price-not-discounted-not-vat, 5950 .product-discount` 5951 ); 5952
5953 Array.from(productItemData).forEach(item => { 5954 if (item.dataset.toggle == 'product-title') item.innerText = P.TITLE; 5955 if (item.dataset.toggle == 'product-url') item.href = P.URL; 5956 if (item.dataset.toggle == 'product-id') item.value = P.ID; 5957 5958 if (item.classList.contains('product-price')) item.innerText = T.vat(P.PRICE_SELL, P.VAT); 5959 if (item.classList.contains('product-price-not-vat')) item.innerText = T.format(P.PRICE_SELL); 5960 if (item.classList.contains('product-price-not-discounte')) item.innerText = T.vat(P.PRICE_NOT_DISCOUNTED, P.VAT); 5961 if (item.classList.contains('product-price-not-discounted-not-vat')) item.innerText = T.format(P.PRICE_NOT_DISCOUNTED); 5962 if (item.classList.contains('product-discount')) item.innerText = P.DISCOUNT_PERCENT; 5963 }); 5964 5965 const discountItems = productItem.querySelectorAll('.discounted-badge, .product-discounted-price'); 5966 Array.from(discountItems).forEach(item => { 5967 if (P.IS_DISPLAY_DISCOUNTED_ACTIVE && P.DISCOUNT_PERCENT > 0) { 5968 item.classList.remove('d-none'); 5969 } else { 5970 item.classList.add('d-none'); 5971 } 5972 }); 5973 5974 const productItemImages = productItem.querySelectorAll('[data-toggle="product-image"]'); 5975 if (productItemImages?.length) { 5976 for (let i = 0; i < productItemImages.length; i++ ) { 5977 if (productItemImages[i].nodeName == 'SOURCE') { 5978 productItemImages[i].srcset = P.IMAGE_LIST[i]?.MEDIUM || P.IMAGE_LIST[0]?.MEDIUM || ''; 5979 } else { 5980 productItemImages[i].src = P.IMAGE_LIST[i]?.MEDIUM || P.IMAGE_LIST[0]?.MEDIUM || ''; 5981 } 5982 } 5983 } 5984 return; 5985 }, 5986 async slideAttribute() { 5987 const catalogSliders = element.querySelectorAll('.swiper-container'); 5988 Array.from(catalogSliders).forEach(item => { 5989 if (item.slider == 1) { 5990 item['swiperData'] .update() 5991 return; 5992 } 5993 5994 const nextEl = item.querySelector('.swiper-button-next'); 5995 const prevEl = item.querySelector('.swiper-button-prev'); 5996 5997 item['swiperData'] = new Swiper(item, { 5998 slidesPerView: 'auto', 5999 spaceBetween: 5, 6000 watchOverflow: true, 6001 navigation: { 6002 nextEl: nextEl, 6003 prevEl: prevEl 6004 }, 6005 }); 6006 6007 item.slider = 1; 6008 }); 6009 }, 6010 open(attribute) { 6011 attribute['SELECT_SEARCH'] = ''; 6012 attribute.IS_OPEN = true; 6013 }, 6014 search(attribute) { 6015 Array.from(attribute.OPTIONS).forEach(item => { 6016 if (item.NAME.toLowerCase().includes(attribute.SELECT_SEARCH.toLowerCase())) { 6017 item['HIDDEN'] = false; 6018 } else { 6019 item['HIDDEN'] = true; 6020 } 6021 }); 6022 }, 6023 async close(attribute) { 6024 attribute['SELECT_SEARCH'] = attribute['SELECT_NAME']; 6025 setTimeout(() => { 6026 Array.from(attribute.OPTIONS).forEac
6026h(item => { 6027 item['HIDDEN'] = false; 6028 }); 6029 6030 attribute.IS_OPEN = false; 6031 }, 500); 6032 }, 6033 parentClass(el) { 6034 let currentElement = el; 6035 6036 while (currentElement && currentElement?.dataset?.toggle != 'product') { 6037 currentElement.classList.add('catalog-parent-element'); 6038 currentElement = currentElement.parentElement; 6039 } 6040 } 6041 }, 6042 async mounted() { 6043 const self = this; 6044 self.parentClass(element); 6045 6046 await self.getAttribute(productId); 6047 element.classList.add('catalog-first-loaded'); 6048 6049 setTimeout(() => { 6050 element.classList.remove('catalog-first-loaded'); 6051 }, 1500); 6052 } 6053 }).mount(element); 6054 }, 250); 6055 6056 return; 6057 }); 6058 6059 element.addEventListener('mouseleave', () => { 6060 if (element.classList.contains('catalog-loaded')) return; 6061 clearTimeout(hoverTimeout); 6062 }); 6063 6064 element.catalog = element; 6065}; 6066 6067const catalogApp = { 6068 ATTRIBUTES: [], 6069 items: {}, 6070 data: {}, 6071 requestManager: { 6072 currentRequests: new Map(), 6073 async makeRequest(key, requestFn) { 6074 if (this.currentRequests.has(key)) { 6075 this.currentRequests.get(key).abort(); 6076 } 6077 const controller = new AbortController(); 6078 this.currentRequests.set(key, controller); 6079 6080 try { 6081 const result = await requestFn(controller.signal); 6082 this.currentRequests.delete(key); 6083 return result; 6084 } catch (error) { 6085 if (error.name === 'AbortError') { 6086 console.log('Request cancelled'); 6087 return null; 6088 } 6089 throw error; 6090 } 6091 } 6092 }, 6093 cacheManager: { 6094 maxItems: 100, 6095 cache: new Map(), 6096 set(key, value) { 6097 if (this.cache.size >= this.maxItems) { 6098 const firstKey = this.cache.keys().next().value; 6099 this.cache.delete(firstKey); 6100 } 6101 this.cache.set(key, value); 6102 }, 6103 get(key) { 6104 return this.cache.get(key); 6105 }, 6106 clear() { 6107 this.cache.clear(); 6108 } 6109 }, 6110 errorHandler: { 6111 handle(error, context) { 6112 console.error(`${context}: ${error.message}`); 6113 const userMessages = { 6114 'CATALOG_ATTRIBUTES': 'Ãrün özellikleri yüklenirken bir hata oluÅtu', 6115 'CATALOG_GET_PRODUCT': 'Ãrün bilgileri alınırken bir hata oluÅtu', 6116 'PAGE_LOAD': 'Sayfa yüklenirken bir hata oluÅtu' 6117 }; 6118 6119 const message = userMessages[context] || 'Bir hata oluÅtu'; 6120 this.showError(message); 6121 }, 6122 showError(message) { 6123 const event = new CustomEvent('show-error', { detail: message }); 6124 window.dispatchEvent(event); 6125 } 6126 }, 6127 deepClone: (obj) => { 6128 try { 6129 return window.structuredClone ? structuredClone(obj) : JSON.parse(JSON.stringify(obj)); 6130 } catch (error) { 6131 return JSON.parse(JSON.stringify(obj)); 6132 } 6133 }, 6134 init: async function() { 6135 const productCatalogs = document.querySelectorAll('[data-toggle="product-catalog"]'); 6136 [...productCatalogs].forEach(productCatalog => { 6137 if (productCatalog.component) return; 6138 6139 const { product: productId, model: modelId } = productCatalog.dataset; 6140 6141 if (!productId || !modelId) { 6142 catalogApp.errorHandler.handle(new Error('Missing required data'), 'INIT'); 6143 return; 6144 } 6145 6146 catalogApp.items[productId] = Vue.createApp({ 6147 data() { 6148 return { 6149 ATTRIBUTES: [], 6150 loading: false 6151 } 6152 }, 6153 methods: { 6154 async getAttribute(product_id = null, product = true) { 6155 if (!product_id) return; 6156 const self = this; 6157 6158 const cachedData = catalogApp.cacheManager.get(`PRODUCT_ATTRIBUTES_${product_id}`); 6159 if (cachedData) { 6160 this.processAttributes(cachedData); 6161 } else { 6162 await this.fetchAttributes(product_id); 6163 } 6164 6165 if (product == null) { 6166 catalogApp.ATTRIBUTES = catalogApp.deepClone(self.ATTRIBUTES); 6167 self.getProductProperties(); 6168 } 6169 this.updateLoadingState(false); 6170 }, 6171 6172 async fetchAttributes(product_id) { 6173 const formData = new FormData(); 6174 formData.append('product_id', product_id); 6175 formData.append('with_image', '1'); 6176 6177 try { 6178 const response = await catalogApp.requestManager.makeRequest
6178( 6179 'attributes', 6180 async (signal) => { 6181 return await axios.post(getEndpoint('CATALOG_ATTRIBUTES'), formData, { signal }); 6182 } 6183 ); 6184 6185 if (!response?.data?.length) { 6186 catalogApp.errorHandler.handle(new Error('No data received'), 'CATALOG_ATTRIBUTES'); 6187 return; 6188 } 6189 6190 this.processAttributes(response.data); 6191 catalogApp.cacheManager.set(`PRODUCT_ATTRIBUTES_${product_id}`, catalogApp.deepClone(this.ATTRIBUTES)); 6192 } catch (error) { 6193 catalogApp.errorHandler.handle(error, 'CATALOG_ATTRIBUTES'); 6194 } 6195 }, 6196 6197 processAttributes(attributes) { 6198 this.ATTRIBUTES = catalogApp.deepClone(attributes); 6199 this.ATTRIBUTES.forEach(item => { 6200 item.OPTIONS = item.OPTIONS.filter(opt => opt.PRODUCT_ID != null); 6201 const selectedOption = item.OPTIONS.find(opt => opt.SELECTED === true); 6202 if (selectedOption) { 6203 item.SELECT_ID = selectedOption.ID; 6204 item.SELECT_NAME = selectedOption.NAME; 6205 if (item.CATALOG_VIEW === 'select') { 6206 item.SELECT_SEARCH = item.SELECT_NAME; 6207 } 6208 } 6209 }); 6210 }, 6211 6212 async setAttribute(attribute = null, option = null) { 6213 if (!attribute || !option) return; 6214 6215 if (this.setAttributeTimeout) { 6216 clearTimeout(this.setAttributeTimeout); 6217 } 6218 6219 this.setAttributeTimeout = setTimeout(async () => { 6220 if (option.target?.value) { 6221 option = attribute.OPTIONS.find(x => x.ID == option.target.value); 6222 } 6223 if (attribute.SELECT_ID === option.ID) return; 6224 6225 attribute.OPTIONS.forEach(x => x.SELECTED = x.ID === option.ID); 6226 attribute.SELECT_ID = option.ID; 6227 attribute.SELECT_NAME = option.NAME; 6228 6229 if (attribute.CATALOG_VIEW === 'select') { 6230 attribute.SELECT_SEARCH = attribute.SELECT_NAME; 6231 attribute.IS_OPEN = false; 6232 attribute.OPTIONS.forEach(item => item.HIDDEN = false); 6233 } 6234 6235 catalogApp.ATTRIBUTES = catalogApp.deepClone(this.ATTRIBUTES); 6236 await this.getProductProperties(option); 6237 }, 300); 6238 }, 6239 6240 async getProductProperties(option = null) { 6241 let catalogProductId = ''; 6242 const formData = new FormData(); 6243 formData.append('model_id', modelId); 6244 6245 this.ATTRIBUTES.forEach((item, index) => { 6246 if (item.SELECT_ID) { 6247 catalogProductId += `${item.GROUP_ID}_${item.SELECT_ID}`; 6248 formData.append(`attribute[${index}][id]`, item.GROUP_ID); 6249 formData.append(`attribute[${index}][option_id]`, item.SELECT_ID); 6250 } 6251 }); 6252 6253 if (catalogApp.cacheManager.get(`PRODUCT_DATA_${catalogProductId}`)) { 6254 const PRODUCT = catalogApp.cacheManager.get(`PRODUCT_DATA_${catalogProductId}`); 6255 await this.setProductData(PRODUCT); 6256 return; 6257 } 6258 6259 try { 6260 this.setLoadingState(); 6261 const response = await catalogApp.requestManager.makeRequest
6261( 6262 'product', 6263 async (signal) => { 6264 return await axios.post(getEndpoint('CATALOG_GET_PRODUCT'), formData, { signal }); 6265 } 6266 ); 6267 6268 if (response?.data?.length) { 6269 const PRODUCT = response.data[0]; 6270 if (PRODUCT?.ID) { 6271 catalogApp.cacheManager.set(`PRODUCT_DATA_${catalogProductId}`, PRODUCT); 6272 await this.getAttribute(PRODUCT.ID); 6273 await this.setProductData(PRODUCT); 6274 } else { 6275 await this.getAttribute(option.PRODUCT_ID, null); 6276 } 6277 } 6278 } catch (error) { 6279 catalogApp.errorHandler.handle(error, 'CATALOG_GET_PRODUCT'); 6280 } finally { 6281 this.removeLoadingState(); 6282 } 6283 }, 6284 6285 updateLoadingState(isLoading) { 6286 const element = document.querySelector('.folder-product-detail'); 6287 if (!element) return; 6288 6289 if (isLoading) { 6290 element.classList.add('catalog-opacity', 'pointer-events-none'); 6291 } else { 6292 element.classList.remove('catalog-opacity', 'pointer-events-none'); 6293 } 6294 this.loading = isLoading; 6295 }, 6296 6297 setLoadingState() { 6298 this.updateLoadingState(true); 6299 }, 6300 6301 removeLoadingState() { 6302 this.updateLoadingState(false); 6303 }, 6304 6305 validateUrl(url) { 6306 try { 6307 new URL(url, window.location.origin); 6308 return true; 6309 } catch { 6310 return false; 6311 } 6312 }, 6313 6314 async setProductData(PRODUCT = null) { 6315 if (!PRODUCT) return; 6316 6317 const url = '/' + PRODUCT.URL; 6318 if (!this.validateUrl(url)) { 6319 catalogApp.errorHandler.handle(new Error('Invalid URL'), 'PAGE_LOAD'); 6320 return; 6321 } 6322 6323 if (!catalogApp.cacheManager.get(`PAGE_DATA_${PRODUCT.ID}`)) { 6324 this.setLoadingState(); 6325 window.pushstateloaded = true; 6326 6327 if (window.history && window.history.pushState) { 6328 try { 6329 const response = await axios.get(url); 6330 catalogApp.cacheManager.set(`PAGE_DATA_${PRODUCT.ID}`, response.data); 6331 } catch (error) { 6332 catalogApp.errorHandler.handle(error, 'PAGE_LOAD'); 6333 window.location.href = url; 6334 return; 6335 } 6336 } else { 6337 window.location.href = url; 6338 return; 6339 } 6340 } 6341 6342 const PAGE_DATA = catalogApp.cacheManager.get(`PAGE_DATA_${PRODUCT.ID}`); 6343 if (!PAGE_DATA) return; 6344 6345 const parser = new DOMParser(); 6346 const htmlDoc = parser.parseFromString(PAGE_DATA, 'text/html'); 6347 const newProductDetail = htmlDoc?.querySelector('.folder-product-detail'); 6348 const productDetail = document.querySelector('.folder-product-detail'); 6349 6350 if (productDetail && newProductDetail) { 6351 productDetail.innerHTML = newProductDetail.innerHTML; 6352 await window.history.replaceState('catalog', null, url); 6353 6354 initComponents(); 6355 const blockId = productDetail.dataset.id; 6356 if (typeof BLOCKS == 'object') { 6357 const BLOCK = Array.from(BLOCKS).find(x => x.ID == blockId); 6358 BLOCK_FN[BLOCK.ID](BLOCK, BLOCK.SETTING); 6359 } 6360 6361 const callback = productCatalog.dataset.callback; 6362 window[callback]?.(productCatalog, PAGE_DATA); 6363 6364 this.removeLoadingState(); 6365 } else { 6366 window.location.href = url; 6367 } 6368 }, 6369 6370 open(attribute) { 6371 attribute.SELECT_SEARCH = ''; 6372 attribute.IS_OPEN = true; 6373 }, 6374 6375 search(attribute) { 6376 const searchTerm = attribute.SELECT_SEARCH.toLowerCase(); 6377 attribute.OPTIONS.forEach(item => { 6378 item.HIDDEN = !item.NAME.toLowerCase().includes(searchTerm); 6379 }); 6380 }, 6381 6382 async close(attribute) { 6383 attribute.SELECT_SEARCH = attribute.SELECT_NAME; 6384 setTimeout(() => { 6385 attribute.OPTIONS.forEach(item => item.HIDDEN = false); 6386 attribute.IS_OPEN = false;
6387 }, 500); 6388 }, 6389 6390 parentClass(element) { 6391 while (element && !element.classList.contains('folder-product-detail')) { 6392 element.classList.add('catalog-parent-element'); 6393 element = element.parentElement; 6394 } 6395 } 6396 }, 6397 async mounted() { 6398 try { 6399 document.body.classList.add('is-loading'); 6400 const cachedAttributes = catalogApp.cacheManager.get(`PRODUCT_ATTRIBUTES_${productId}`); 6401 6402 if (cachedAttributes) { 6403 this.ATTRIBUTES = catalogApp.deepClone(cachedAttributes); 6404 } else if (catalogApp.ATTRIBUTES.length) { 6405 this.ATTRIBUTES = catalogApp.deepClone(catalogApp.ATTRIBUTES); 6406 } else { 6407 await this.getAttribute(productId); 6408 } 6409 6410 this.parentClass(productCatalog); 6411 } catch (error) { 6412 catalogApp.errorHandler.handle(error, 'MOUNT'); 6413 } finally { 6414 document.body.classList.remove('is-loading'); 6415 } 6416 } 6417 }).mount(productCatalog); 6418 6419 productCatalog.component = 1; 6420 }); 6421 } 6422}; 6423catalogApp.init(); 6424 6425const setupImageTracking = { 6426 SETUP_IMAGE_TIMEOUT: 7000, 6427 isSvg(src) { 6428 if (!src) return true; 6429 return ( 6430 src.endsWith('.svg') || 6431 src.includes('.svg?') || 6432 src.startsWith('data:image/svg') 6433 ); 6434 }, 6435 triggerFallback(img, src) { 6436 if (img.dataset.fallbackProcessed) return; 6437 img.dataset.fallbackProcessed = 'true'; 6438 6439 const fallbackSrc = src.replace(/(?:https?:)?\/\/[^/]+/i, `${location.protocol}//${location.hostname}`); 6440 6441 if (img.dataset.src) { 6442 img.dataset.src = fallbackSrc; 6443 setTimeout(() => { 6444 if (img.src != fallbackSrc) img.src = fallbackSrc; 6445 }, 100); 6446 } else { 6447 img.src = fallbackSrc; 6448 } 6449 6450 const imgPicture = img.closest('picture'); 6451 if (imgPicture) { 6452 const imgSource = imgPicture.querySelector('source'); 6453 if (imgSource) { 6454 const srcset = imgSource.srcset; 6455 const fallbackSrcset = srcset.replace(/(?:https?:)?\/\/[^/]+/i, `${location.protocol}//${location.hostname}`); 6456 imgSource.srcset = fallbackSrcset; 6457 } 6458 } 6459 }, 6460 trackImage(img, src) { 6461 if (window.location.hostname === 'local.tsoft.biz') return; 6462 if (!src || !src.includes('witcdn.') || setupImageTracking.isSvg(src)) return; 6463 6464 const timer = setTimeout(() => { 6465 if (!img.complete || img.naturalWidth === 0) { 6466 setupImageTracking.triggerFallback(img, src); 6467 } 6468 }, setupImageTracking.SETUP_IMAGE_TIMEOUT); 6469 6470 img.addEventListener('load', () => { 6471 if (img.naturalWidth === 0) { 6472 setupImageTracking.triggerFallback(img, src); 6473 } 6474 clearTimeout(timer); 6475 }, { once: true }); 6476 6477 img.addEventListener('error', () => { 6478 setupImageTracking.triggerFallback(img, src); 6479 clearTimeout(timer); 6480 }, { once: true }); 6481 6482 if (img.complete && img.naturalWidth === 0) { 6483 clearTimeout(timer); 6484 setupImageTracking.triggerFallback(img, src); 6485 } 6486 }, 6487 init() { 6488 document.querySelectorAll('img').forEach(img => { 6489 const src = img.src; 6490 const dataSrc = img.dataset.src; 6491 6492 if (dataSrc || img.classList.contains('lazyload')) return; 6493 setupImageTracking.trackImage(img, src); 6494 }); 6495 } 6496}; 6497 6498const imageTrackingObserver = new MutationObserver(mutations => { 6499 mutations.forEach(mutation => { 6500 mutation.addedNodes.forEach(node => { 6501 if (node.nodeType === 1) { 6502 if (node.tagName === 'IMG') { 6503 const src = node.src; 6504 const dataSrc = node.dataset.src; 6505 if (!dataSrc && !node.classList.contains('lazyload')) { 6506 setupImageTracking.trackImage(node, src); 6507 } 6508 } 6509 const imgs = node.querySelectorAll && node.querySelectorAll('img'); 6510 if (imgs) {
6511 imgs.forEach(img => { 6512 const src = img.src; 6513 const dataSrc = img.dataset.src; 6514 if (!dataSrc && !img.classList.contains('lazyload')) { 6515 setupImageTracking.trackImage(img, src); 6516 } 6517 }); 6518 } 6519 } 6520 }); 6521 }); 6522}); 6523 6524imageTrackingObserver.observe(document.body, { 6525 childList: true, 6526 subtree: true 6527}); 6528 6529document.addEventListener('lazyloaded', e => { 6530 const img = e.target; 6531 if (!img || img.tagName !== 'IMG') return; 6532 6533 const src = img.dataset.src; 6534 setTimeout(() => { 6535 setupImageTracking.trackImage(img, src); 6536 }, 100); 6537}); 6538 6539const initComponents = () => { 6540 catalogApp.init(); 6541 setupImageTracking.init(); 6542 6543 let tsoftComponents = { 6544 Dropdown: [T.dropdown, '[data-toggle*="dropdown"]'], 6545 Tab: [T.tab, '[data-toggle*="tab"]'], 6546 Accordion: [T.accordion, '[data-toggle*="accordion"]'], 6547 Placeholder: [T.placeholder.init, '[data-toggle*="placeholder"]'], 6548 Mask: [T.mask, '[data-toggle*="mask"]'], 6549 Zoom: [T.zoomImage, '[data-toggle*="zoom-image"]'], 6550 Modal: [T.modal, '[data-toggle*="modal"]'], 6551 Tooltip: [T.tooltip, '[data-toggle*="tooltip"]'], 6552 Drawer: [T.drawer, '[data-toggle*="drawer"]'], 6553 Qty: [T.qty, '[data-toggle*="qty"]'], 6554 Login: [T.loginForm, '[data-toggle*="login-form"]'], 6555 OtpLogin: [T.otpLogin, '[data-toggle*="otp-login"]'], 6556 PhoneMask: [tFlag.init, '[data-flag-masked]'], 6557 Language: [T.setLanguage.init, '[data-toggle*="language"]'], 6558 Currency: [T.setCurrency.init, '[data-toggle*="currency"]'], 6559 Variant: [selectVaryant.init, '[data-toggle*="variant"]'], 6560 Catalog: [catalog, '[data-toggle*="product-item-catalog"]'], 6561 Popupwin: [T.popupWin, '.popupwin'], 6562 Affix: [T.affix, '[data-toggle*="affix"]'], 6563 Sticky: [T.sticky, '[data-toggle*="sticky"]'], 6564 InputFile: [T.inputFile, '[data-toggle*="input-file"]'], 6565 EqualHeight: [T.equalHeight, '[data-toggle*="equalHeight"]'], 6566 Subscribe: [subscribe.init, '[data-toggle*="subscribe"]'], 6567 AddFavBtn: [favouriteProducts.click, '.add-favourite-btn'], 6568 PopConfirm: [T.popConfirm, '[data-toggle*="popconfirm"]'], 6569 CountDown: [countDown.init, '[data-toggle*="count-down"]'], 6570 SnapScroll: [snapScroll.init, '[data-toggle*="snap-scroll"]'], 6571 SocialGoogle:[T.signInGoogleAuth, '[data-toggle*="signin-google"]'], 6572 ProductListLayout: [T.productListLayout, '[data-toogle="layaout"]'], 6573 ShareButton: [T.shareButton, '[data-toggle*="share"]'], 6574 }; 6575 6576 let initializeDataAPI = function(Constructor, collection) { 6577 Array.from(collection).map(function(x) { return new Constructor(x); }); 6578 }; 6579 6580 for (let component in tsoftComponents) { 6581 let selectors = tsoftComponents[component][1].split(/\s+/); 6582 let elements = []; 6583 6584 selectors.forEach(selector => { 6585 let selectedElements = document.querySelectorAll(selector.trim()); 6586 elements = elements.concat(Array.from(selectedElements)); 6587 }); 6588 6589 initializeDataAPI(tsoftComponents[component][0], elements); 6590 } 6591 6592 T.mask('input[type="password"]', 'password'); 6593 T.mask('input[type="email"]', 'email'); 6594 T.mask('input[name="name"], input[name="surname"], input[name="fullname"], input[name="firstname"], input[name="lastname"]', 'string'); 6595 6596 T('a[href*="authentication/social-login"]').on('click', (e) => { 6597 e.preventDefault(); 6598 6599 if(getUrlParam('type', e.target.href) == 'apple') { 6600 axios.get(e.target.href).then(response => { 6601 window.location.href = response.data.data[0]; 6602 }); 6603 } 6604 }); 6605 6606}; 6607 6608const lazyControl = (wrapper) => { 6609 if (!wrapper || typeof wrapper !== 'object') return; 6610 6611 const observer = new IntersectionObserver((entries) => { 6612 entries.forEach(entry => { 6613 if (entry.isIntersecting) { 6614 const swiper = entry.target.querySelector('.swiper-wrapper'); 6615 if (swiper && !swiper.lazyItem) { 6616 loadImagesProgressively(swiper); 6617 swiper.lazyItem = 1; 6618 } 6619 observer.unobserve(entry.target); 6620 } 6621 }); 6622 }, {
6623 threshold: 0.1 6624 }); 6625 6626 observer.observe(wrapper); 6627}; 6628 6629const loadImagesProgressively = (container, batchSize = 3) => { 6630 const lazyImages = container.querySelectorAll('[loading="lazy"]:not(.lazyloaded)'); 6631 if (!lazyImages.length) return; 6632 6633 const loadBatch = (startIndex) => { 6634 const batch = Array.from(lazyImages).slice(startIndex, startIndex + batchSize); 6635 if (!batch.length) return; 6636 6637 batch.forEach(img => { 6638 img.classList.add('lazyloaded'); 6639 img.dataset.priority = 'true'; 6640 img.setAttribute('loading', 'eager'); 6641 lazySizes.loader.unveil(img); 6642 }); 6643 6644 setTimeout(() => { 6645 loadBatch(startIndex + batchSize); 6646 }, 100); 6647 }; 6648 6649 loadBatch(0); 6650 lazySizes.autoSizer.checkElems(); 6651}; 6652 6653const kvkkCallback = []; 6654const memberKvkkControl = () => { 6655 if (typeof ADMIN_USER_FULLNAME != 'undefined' && ADMIN_USER_FULLNAME.trim() != '') return; 6656 6657 if (MEMBER_INFO.ID > 0 && MEMBER_INFO.KVKK != 1 && SETTINGS.KVKK_REQUIRED == 1) { 6658 axios.get('/srv/service/content-v5/sub-folder/6/1008/notifications').then(response => { 6659 const data = response.data; 6660 T.modal({ 6661 id: 'notifications-popup', 6662 html: data, 6663 width: '480px', 6664 close : true, 6665 closeCallback() { 6666 if (PAGE_TYPE == 'order' || PAGE_TYPE == 'address' || PAGE_TYPE == 'payment') window.location.reload(); 6667 } 6668 }); 6669 }); 6670 } 6671}; 6672 6673const activationControl = () => { 6674 const activationType = getUrlParam('activation'); 6675 if (activationType) { 6676 switch (activationType) { 6677 case 'newsletter': 6678 const token = getUrlParam('token'); 6679 axios.post('/srv/service/guest/activateSubscription/' + token).then(response => { 6680 const data = response.data; 6681 if (data.status === 1) { 6682 T.modal({ 6683 id: 'activation-newsletter', 6684 html: data.statusText, 6685 width: '580px', 6686 close : true, 6687 }); 6688 6689 setTimeout(function (){ 6690 for(let i=0; i < callbacks.customer.subscribe.length; i++){ 6691 if(typeof callbacks.customer.subscribe[i] === 'function'){ 6692 try { 6693 callbacks.customer.subscribe[i]?.(data); 6694 } catch (error) { console.log(`Customer Other Callback Error => ${error}`); } 6695 } 6696 } 6697 }, 500); 6698 6699 } 6700 }); 6701 break; 6702 case 'membership': 6703 const memberId = getUrlParam('id'), 6704 memberToken = getUrlParam('token'); 6705 axios.post('/srv/service/customer/activateMembership/' + memberId + '/' + memberToken).then(response => { 6706 const data = response.data; 6707 if (data.status) { 6708 T.modal({ 6709 id: 'activation-membership', 6710 html: `<a href="/srv/service/content-v5/sub-folder/5/1006/popup-login" class="popupwin">${TLANG.activation_membership_success || 'ÃyeliÄiniz baÅarıyla aktifleÅtirilmiÅtir, giriÅ yapmak için <b>tıklayınız</b>'}</a>`, 6711 width: 'auto', 6712 close : true, 6713 }); 6714 initComponents(); 6715 history.pushState('', '', '/'); 6716 } 6717 }); 6718 break; 6719 case 'facebook': 6720 axios.get('/srv/service/content-v5/sub-folder/6/1008/facebook-email').then(response => { 6721 const data = response.data; 6722 T.modal({ 6723 id: 'activation-facebook-email', 6724 html: data, 6725 width: '400px', 6726 close : true, 6727 }); 6728 }); 6729 break; 6730 case 'facebookphone': 6731 axios.get('/srv/service/content-v5/sub-folder/6/1008/facebook-phone').then(response => { 6732 const data = response.data; 6733 T.modal({ 6734 id: 'activation-facebook-phone', 6735 html: data, 6736 width: '400px', 6737 close : true, 6738 }); 6739 }); 6740 break; 6741 case 'twitter': 6742 axios.get('/srv/service/content-v5/sub-folder/6/1008/twitter-email').then(response => { 6743 const data = response.data; 6744 T.modal({ 6745 id: 'activation-twitter-email', 6746 html: data, 6747 width: '400px', 6748 close : true, 6749 }); 6750 }); 6751 break;
6752 case 'googlephone': 6753 axios.get('/srv/service/content-v5/sub-folder/6/1008/google-phone').then(response => { 6754 const data = response.data; 6755 T.modal({ 6756 id: 'activation-google-phone', 6757 html: data, 6758 width: '400px', 6759 close : true, 6760 }); 6761 }); 6762 break; 6763 case 'social': 6764 axios.get('/srv/service/content-v5/sub-folder/6/1008/social').then(response => { 6765 const data = response.data; 6766 T.modal({ 6767 id: 'activation-social', 6768 html: data, 6769 width: '400px', 6770 close : true, 6771 }); 6772 }); 6773 break; 6774 } 6775 } 6776 6777 const activationTypeError = getUrlParam('error'); 6778 if (activationTypeError && PAGE_ID == '5' && MEMBER_INFO.ID < 1) { 6779 switch (activationTypeError) { 6780 case 'mail_already_registered': 6781 T.modal({ 6782 html: `<div class="p-1" style="font-size: 14px">${TLANG.login_mail_error || 'Bu e-posta adresiyle kayıt yapılmıÅtır. Lütfen giriÅ yapınız.'}</div>`, 6783 width: '435px', 6784 close: true 6785 }); 6786 const mailUrl = new URL(window.location.href); 6787 mailUrl.searchParams.delete('error'); 6788 window.history.replaceState({}, '', mailUrl); 6789 break; 6790 case 'phone_already_registered': 6791 T.modal({ 6792 html: `<div class="p-1" style="font-size: 14px">${TLANG.login_phone_error || 'Bu telefon numarasıyla kayıt yapılmıÅtır. Lütfen giriÅ yapınız.'}</div>`, 6793 width: '435px', 6794 close: true 6795 }); 6796 const phoneUrl = new URL(window.location.href); 6797 phoneUrl.searchParams.delete('error'); 6798 window.history.replaceState({}, '', phoneUrl); 6799 break; 6800 } 6801 } 6802 6803 const multiShoppingToken = getUrlParam('TmultiShoppingCart'); 6804 if (multiShoppingToken) { 6805 const parts = multiShoppingToken.split('.'); 6806 if (parts.length === 3) { 6807 const base64 = parts[1].replace(/-/g, '+').replace(/_/g, '/'); 6808 const padded = base64 + '='.repeat((4 - base64.length % 4) % 4); 6809 const payload = JSON.parse(atob(padded)); 6810 6811 if (payload.length == 0) return; 6812 6813 const cartOpt = { 6814 productId: [], 6815 variantId: [], 6816 quantity: [], 6817 buyNow: 1, 6818 redirect: 'order' 6819 }; 6820 6821 const formData = new FormData(); 6822 Array.from(payload).forEach(product => { 6823 formData.append('ws_codes[]', product.supplierProductCode); 6824 }); 6825 6826 document.body.classList.add('is-loading'); 6827 axios.post(getEndpoint('GET_PRODUCT_BY_WS_CODES'), formData).then(response => { 6828 const data = response.data.data; 6829 if (!data?.length) return; 6830 6831 Array.from(data).forEach(item => { 6832 cartOpt.productId.push(item.id); 6833 6834 const product = payload.find(i => i.supplierProductCode == item.ws_code); 6835 if (product) { 6836 cartOpt.quantity.push(product.quantity || 1); 6837 cartOpt.variantId.push(item.variant_id || 0); 6838 } 6839 }); 6840 6841 if (cartOpt.productId.length) { 6842 multiCart = true; 6843 addToCart(cartOpt); 6844 } 6845 }).catch(error => { 6846 console.warn(`GET_PRODUCT_BY_WS_CODES error => ${error}`); 6847 }).finally(() => { 6848 document.body.classList.remove('is-loading'); 6849 }); 6850 } 6851 } 6852}; 6853 6854const referererStorage = { 6855 api: '', 6856 hasLocal: 'localStorage' in window && window['localStorage'] !== null, 6857 hasQueryString: function() { 6858 let ref = document.referrer || ""; 6859 if (ref == '') { 6860 return false;
6861 } 6862 let a = document.createElement('a'); 6863 a.href = ref; 6864 let q = ''; 6865 let queryString = a.search; 6866 let pairs = (queryString[0] === '?' ? queryString.substr(1) : queryString).split('&'); 6867 for (let i = 0; i < pairs.length; i++) { 6868 let pair = pairs[i].split('='); 6869 if (pair[0] == 'q') { 6870 q = pair[1]; 6871 } 6872 } 6873 return q != ''; 6874 }, 6875 addItemStorage: async function() { 6876 let cReferrer = localStorage.getItem('cReferrer'); 6877 let items = []; 6878 if (cReferrer !== null) { 6879 let obj = {}; 6880 try { 6881 obj = JSON.parse(cReferrer); 6882 } catch (err) { 6883 obj = {}; 6884 } 6885 if (typeof obj.schedule != "undefined" && Date.now() < obj.schedule && !this.hasQueryString()) { 6886 return; 6887 } 6888 items = obj.items || []; 6889 } 6890 6891 try { 6892 if (!this.api) { 6893 const response = await axios.get('/srv/service/guest/ip'); 6894 this.api = response.data; 6895 } 6896 } catch (error) { 6897 console.warn(`GET_IP error => ${error}`); 6898 } 6899 items.push({ time: Number.parseInt(Date.now() / 1000), uri: document.referrer, page: window.location.href, ip: this.api }); 6900 this.setItems(items); 6901 }, 6902 getObj: function() { 6903 let cReferrer = null; 6904 let cReferrerObj = {}; 6905 if (this.hasLocal) { 6906 cReferrer = localStorage.getItem('cReferrer'); 6907 } else { 6908 try { 6909 cReferrer = T.getCookie('cReferrer'); 6910 } catch (err) {} 6911 } 6912 try { 6913 cReferrerObj = JSON.parse(cReferrer); 6914 } catch (err) {} 6915 return cReferrerObj; 6916 }, 6917 getItems: function() { 6918 return this.getObj().items || []; 6919 }, 6920 setItems: function(items) { 6921 let obj = { 6922 schedule: Date.now() + (24 * 60 * 60 * 1000), 6923 items: items || [] 6924 }; 6925 this.save(obj); 6926 }, 6927 save: function(sObj) { 6928 if (this.hasLocal) { 6929 this.saveStorage(sObj); 6930 } else { 6931 this.saveCookie(sObj); 6932 } 6933 }, 6934 saveStorage: function(sObj) { 6935 localStorage.setItem('cReferrer', JSON.stringify(sObj)); 6936 }, 6937 saveCookie: function(sObj) { 6938 try { 6939 T.setCookie('cReferrer', JSON.stringify(sObj), { path: '/', expires: 30 }); 6940 } catch (err) {} 6941 } 6942}; 6943 6944const grecaptchaReset = function(element = null) { 6945 if (typeof grecaptcha == 'undefined') return; 6946 const recaptchas = document.querySelectorAll('.g-recaptcha'); 6947 6948 if (element) { 6949 const elementIndex = Array.from(recaptchas).indexOf(element); 6950 if (elementIndex > -1) grecaptcha.reset(elementIndex); 6951 } else { 6952 Array.from(recaptchas).forEach((_, index) => { 6953 grecaptcha.reset(index); 6954 6955 }); 6956 } 6957} 6958 6959const googleTokenClientFn = () => { 6960 if (typeof googleTokenClient != 'undefined') { 6961 googleTokenClient.requestAccessToken(); 6962 return; 6963 } 6964 6965 if (typeof google !== 'undefined') { 6966 try { 6967 googleTokenClient = google.accounts.oauth2.initTokenClient({ 6968 client_id: GOOGLE_CLIENT_ID, 6969 scope: 'openid email profile', 6970 callback: (response) => { 6971 if (response.access_token) { 6972 location.href = location.origin + `/srv/service/social/google/login?code=${response.access_token}`; 6973 } else { 6974 console.warn('Google Sign-In error:', response); 6975 } 6976 }, 6977 }); 6978 googleTokenClient.requestAccessToken(); 6979 } catch (error) { 6980 googleTokenClient = undefined; 6981 console.warn('Google Sign-In error:', error); 6982 } 6983 } 6984} 6985 6986T.ready(() => { 6987 const productPoint = document.querySelector('#product-point'); 6988 if (productPoint?.value) T('.product-cash-amount').html(T.format(productPoint.value, 2)); 6989 6990 T('.product-item').on('click', e => { 6991 const element = e.target; 6992 const productItem = element.closest('.product-item'); 6993 const productLink = element.closest('a'); 6994 if (!productLink) return; 6995 6996 let hrefValue = productLink.getAttribute('href'); 6997 if (!hrefValue || hrefValue == '#') return; 6998 6999 if (!hrefValue.startsWith('http://') && !hrefValue.startsWith('https://')) { 7000 hrefValue = `${window.location.origin}${hrefValue}`; 7001 } 7002 7003 try { 7004 const url = new URL(hrefValue); 7005 const productIndex = Array.from(document.querySelectorAll('.product-item')).indexOf(productItem); 7006 for (let i = 0; i < callbacks.product.click.length; i++) { 7007 if (typeof callbacks.product.click[i] === 'function') { 7008 try { 7009 callbacks.product.click[i]?.(productIndex, productItem); 7010 } catch (error) { 7011 console.warn(`Product Click Callback Error => ${error}`); 7012 } 7013 } 7014 } 7015 } catch (error) { 7016 console.warn('Invalid URL:', hrefValue); 7017 } 7018 }); 7019 7020 T('.logout').on('click', e => { 7021 e.preventDefault(); 7022 axios.get('/srv/service/customer/logout').then(() => { 7023 LocalApi.remove('v5token'); 7024 window.location.href = '/'; 7025 }); 7026 }); 7027 7028 T('.cart-soft-count').text(CART_COUNT); 7029 T('.cart-soft-price').text(CART_TOTAL); 7030 7031 favouriteProducts.init(); 7032 compareSet();
7033 mobileAppFn(); 7034 7035 passwordStrengthControl(); 7036 memberKvkkControl(); 7037 activationControl(); 7038 referererStorage.addItemStorage(); 7039 /* Pwa(); */ 7040}); 7041 7042document.body ? initComponents() : T(document).one('DOMContentLoaded', initComponents);
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.