1/* global jQuery, WizApi, GlobalScripts */ 2/** 3 * Login widget: per-root behavior driven by `data-login-config` on 4 * [data-login-widget-id] (see Login_Widget in login-plugin.php). 5 */ 6function runWizLoginPlugin(root) { 7 if (!root || !root.getAttribute) { 8 return; 9 } 10 var cfg; 11 try { 12 cfg = JSON.parse(root.getAttribute('data-login-config') || '{}'); 13 } catch (e) { 14 return; 15 } 16 if (!cfg || !cfg.widgetId) { 17 return; 18 } 19 20 var widgetId = cfg.widgetId; 21 var showAddress = !!cfg.showAddress; 22 var addressTypeMain = cfg.addressTypeMain || 'billing'; 23 var addressTypeMenu = cfg.addressTypeMenu || 'billing'; 24 var addressFields = Array.isArray(cfg.addressFields) ? cfg.addressFields : ['city', 'state', 'country']; 25 var showAddressLabelsMain = cfg.showAddressLabelsMain !== false; 26 var showAddressLabelsMenu = cfg.showAddressLabelsMenu !== false; 27 var wizCachedAllowedCustomers = Array.isArray(cfg.wizCachedAllowedCustomers) ? cfg.wizCachedAllowedCustomers : []; 28 var parentChildEnabled = cfg.parentChildEnabled !== false 29 && window.wizParentChildEnabled !== false 30 && !(window.wizActiveBuyerBoot && window.wizActiveBuyerBoot.parentChildEnabled === false); 31 // true | null from PHP preload;
31 JS may still lazy-fetch when null. 32 var switchableChildState = cfg.wizHasSwitchableChildCustomers; 33 34 function canUseCustomerSwitcher() { 35 return parentChildEnabled; 36 } 37 var ALLOWED_CUSTOMERS_TTL_MS = 5 * 60 * 1000; 38 var ALLOWED_CUSTOMERS_LS_KEY = 'wiz_allowed_customers_cache'; 39 40 /** 41 * Parse allowed-customers API payload (all_customers or legacy allowed_customers). 42 * 43 * @param {object|null} payload WizApi result.data or inner data object 44 * @returns {Array} 45 */ 46 function extractCustomersFromAllowedCustomersPayload(payload) { 47 if (!payload) { 48 return []; 49 } 50 var inner = payload; 51 if (payload.data && typeof payload.data === 'object' && !Array.isArray(payload.data)) { 52 inner = payload.data; 53 } 54 if (Array.isArray(inner.all_customers)) { 55 return inner.all_customers; 56 } 57 if (Array.isArray(inner.allowed_customers)) { 58 return inner.allowed_customers; 59 } 60 if (Array.isArray(payload.all_customers)) { 61 return payload.all_customers; 62 } 63 if (Array.isArray(payload.allowed_customers)) { 64 return payload.allowed_customers; 65 } 66 if (Array.isArray(payload)) { 67 return payload; 68 } 69 return []; 70 } 71 72 /** 73 * Login switcher: parent always shown; children require is_access_enabled. 74 * 75 * @param {Array} customers 76 * @returns {Array} 77 */ 78 function filterAccessEnabledCustomers(customers) { 79 if (!Array.isArray(customers)) { 80 return []; 81 } 82 return customers.filter(function (customer) { 83 if (customer.is_parent === true) { 84 return true; 85 } 86 if (typeof customer.is_access_enabled === 'undefined') { 87 return true; 88 } 89 return customer.is_access_enabled === true; 90 }); 91 } 92 93 /** 94 * Single-line address: non-empty values for the given field keys, joined by ", ". 95 * Shared by dropdown items and main button (same shape as PHP wiz_join_address_field_values). 96 */ 97 function formatAddressFieldsLine(address, fields) { 98 if (!address || !fields || !fields.length) { 99 return ''; 100 } 101 var parts = []; 102 fields.forEach(function (field) { 103 var value = address[field]; 104 if (value && value.trim && value.trim()) { 105 parts.push(value.trim()); 106 } 107 }); 108 return parts.join(', '); 109 } 110 111 function shouldShowMainAddress() { 112 return showAddress && addressTypeMain !== 'none'; 113 } 114 115 function shouldShowMenuAddress() { 116 return showAddress && addressTypeMenu !== 'none'; 117 } 118 119 function buildMenuAddressLineHtml(label, value, showLabel) { 120 if (!value) { 121 return ''; 122 } 123 var labelHtml = showLabel 124 ? '<span class="wiz-customer-item-address-label">' + escapeHtml(label) + '</span>' 125 : ''; 126 var valuePrefix = showLabel ? ' ' : ''; 127 return '<span class="wiz-customer-item-address">' + 128 labelHtml + 129 '<span class="wiz-customer-item-address-value">' + valuePrefix + escapeHtml(value) + '</span>' + 130 '</span>'; 131 } 132 133 function buildMainAddressLinesHtml(customer) { 134 var lines = []; 135 136 if (addressTypeMain === 'billing' || addressTypeMain === 'both') { 137 var billingStr = formatAddressFieldsLine(customer.default_billing_address, addressFields); 138 if (billingStr) { 139 var billLabelHtml = showAddressLabelsMain 140 ? '<span class="login_active_customer_address-label">Bill:</span>' 141 : ''; 142 var billValuePrefix = showAddressLabelsMain ? ' ' : ''; 143 lines.push( 144 '<span class="login_active_customer_address-line">' + 145 billLabelHtml + 146 '<span class="login_active_customer_address-value">' + billValuePrefix + escapeHtml(billingStr) + '</span>' + 147 '</span>' 148 ); 149 } 150 } 151 152 if (addressTypeMain === 'shipping' || addressTypeMain === 'both') { 153 var shippingStr = formatAddressFieldsLine(customer.default_shipping_address, addressFields); 154 if (shippingStr) { 155 var shipLabelHtml = showAddressLabelsMain 156 ? '<span class="login_active_customer_address-label">Ship:</span>' 157 : ''; 158 var shipValuePrefix = showAddressLabelsMain ? ' ' : ''; 159 lines.push( 160 '<span class="login_active_customer_address-line">' + 161 shipLabelHtml + 162 '<span class="login_active_customer_address-value">' + shipValuePrefix + escapeHtml(shippingStr) + '</span>' + 163 '</span>' 164 ); 165 } 166 } 167 168 return lines.join(''); 169 } 170 171 // ââ Helpers ââ 172 173 function status_check_widget() { 174 var persistedUserString = localStorage.getItem('persist:root'); 175 if (persistedUserString) { 176 var persistedUser = JSON.parse(persistedUserString || '{}'); 177 if (persistedUser && persistedUser.persistedUserData) { 178 var userData = JSON.parse(persistedUser.persistedUserData || '{}'); 179 return userData.auth_access_token !== null; 180 } 181 } 182 return false;
183 } 184 185 function idsEqual(a, b) { 186 return !!(a && b && String(a).toLowerCase() === String(b).toLowerCase()); 187 } 188 189 function getCustomerRecordId(customer) { 190 return customer && (customer.id || customer.buyer_id) ? (customer.id || customer.buyer_id) : ''; 191 } 192 193 function readActiveBuyerIdFromUrl() { 194 try { 195 var id = new URLSearchParams(window.location.search).get('active-buyer'); 196 if (id && /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(id)) { 197 return id; 198 } 199 } catch (e) { /* ignore */ } 200 return null; 201 } 202 203 function getConfiguredParentBuyerId() { 204 if (cfg.parentBuyerId) { 205 return cfg.parentBuyerId; 206 } 207 if (window.WizActiveBuyerContext && typeof window.WizActiveBuyerContext.getParentBuyerId === 'function') { 208 return window.WizActiveBuyerContext.getParentBuyerId() || ''; 209 } 210 return ''; 211 } 212 213 function isParentBuyerId(buyerId, parentCustomer) { 214 if (!buyerId) { 215 return true; 216 } 217 var configuredParentId = getConfiguredParentBuyerId(); 218 if (configuredParentId && idsEqual(buyerId, configuredParentId)) { 219 return true; 220 } 221 if (parentCustomer) { 222 var recordId = getCustomerRecordId(parentCustomer); 223 if (recordId && idsEqual(buyerId, recordId)) { 224 return true; 225 } 226 } 227 return false; 228 } 229 230 /** 231 * True when URL has ?active-buyer={child} (parent context = param absent or parent id). 232 */ 233 function isInChildBuyerContext(parentCustomer) { 234 var fromUrl = readActiveBuyerIdFromUrl(); 235 if (!fromUrl) { 236 return false; 237 } 238 return !isParentBuyerId(fromUrl, parentCustomer); 239 } 240 241 function getActiveCustomerBuyerId(parentCustomer) { 242 var fromUrl = readActiveBuyerIdFromUrl(); 243 if (fromUrl && !isParentBuyerId(fromUrl, parentCustomer)) { 244 return fromUrl; 245 } 246 247 if (window.WizActiveBuyerContext && typeof window.WizActiveBuyerContext.getActiveBuyerId === 'function') { 248 var fromContext = window.WizActiveBuyerContext.getActiveBuyerId(); 249 if (fromContext && !isParentBuyerId(fromContext, parentCustomer)) { 250 return fromContext; 251 } 252 } 253 254 return null; 255 } 256 257 function escapeHtml(str) { 258 var div = document.createElement('div'); 259 div.appendChild(document.createTextNode(str || '')); 260 return div.innerHTML; 261 } 262 263 function showSwitchPopup(customer) { 264 if (window.GlobalScripts && typeof window.GlobalScripts.showPopUp === 'function') { 265 var message = 'Switched to: ' + (customer.company_name || 'selected account'); 266 267 if (customer.default_billing_address) { 268 var addr = customer.default_billing_address; 269 var addressParts = []; 270 if (addr.city) { addressParts.push(addr.city); } 271 if (addr.state) { addressParts.push(addr.state); } 272 if (addr.country) { addressParts.push(addr.country); } 273 274 if (addressParts.length > 0) { 275 message += ', ' + addressParts.join(', '); 276 } 277 } 278 279 window.GlobalScripts.showPopUp(message, 'success', 2000); 280 } 281 } 282 283 // ââ Customer context switch ââ 284 285 function getCartSummarySlugForSwitch() { 286 var boot = window.wizActiveBuyerBoot || {}; 287 if (boot.cartSummaryBasePath) { 288 return String(boot.cartSummaryBasePath).replace(/^\/+|\/+$/g, ''); 289 } 290 if (typeof cartSummaryHeaderConfig !== 'undefined' && cartSummaryHeaderConfig.cartSummaryBasePath) { 291 return String(cartSummaryHeaderConfig.cartSummaryBasePath).replace(/^\/+|\/+$/g, ''); 292 } 293 return 'cart-summary'; 294 } 295 296 function isCartSummaryPagePath(path) { 297 var slug = getCartSummarySlugForSwitch().replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); 298 return new RegExp( 299 '^/' + slug + '(?:/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})?/?$', 300 'i' 301 ).test(path || ''); 302 } 303 304 function getReloadUrlAfterCustomerSwitch() { 305 var path = window.location.pathname; 306 var isOrderOrQuotePage = /\/checkout\/(order|quote)\//i.test(path) 307 || /\/review\/(order|quote)\//i.test(path); 308 var isWishlistDetailPage = /^\/wishlist\/[0-9a-f-]+\/?$/i.test(path); 309 var isInvoiceDetailPage = /^\/invoice\/[0-9a-f-]+\/?$/i.test(path) 310 || /^\/account\/invoices\/[0-9a-f-]+\/?$/i.test(path); 311 if (isOrderOrQuotePage || isWishlistDetailPage || isInvoiceDetailPage) { 312 return '/all-products/'; 313 } 314 315 // Cart-summary cart ids are buyer-specific â reset to base path on switch. 316 if (isCartSummaryPagePath(path)) { 317 return '/' + getCartSummarySlugForSwitch() + '/'; 318 } 319 320 var isPlp = window.WizFilters && typeof window.WizFilters.isPlpPath === 'function' 321 ? window.WizFilters.isPlpPath(path) 322 : (/\/all-products(\/|$)/.test(path) 323 || /\/product-listing(\/|$)/.test(path) 324 || /\/search(\/|$)/.test(path) 325 || /\/category(\/products)?(\/|$)/.test(path) 326 || /\/collection(\/products)?(\/|$)/.test(path) 327 || /^\/[^/]+\/(category|collection)(\/products)?(\/|$)/.test(path)); 328 329 if (!isPlp) { 330 return null; 331 } 332 333 if (window.WizFilters && typeof window.WizFilters.buildUrlWithoutPlpFilters === 'function') { 334 return window.WizFilters.buildUrlWithoutPlpFilters(path, window.location.search); 335 } 336 337 var params = new URLSearchParams(window.location.search); 338 params.delete('filter'); 339 params.delete('range_filter'); 340 params.delete('sort'); 341 params.delete('pagination_data'); 342 params.delete('page'); 343 params.delete('paged'); 344 params.delete('search'); 345 params.delete('type'); 346 var keys = [];
347 params.forEach(function (_v, k) { keys.push(k); }); 348 keys.forEach(function (k) { 349 if (k.indexOf('filters*') === 0 || k.indexOf('range_filters*') === 0) { 350 params.delete(k); 351 } 352 }); 353 params.delete('categoryLevel2'); 354 params.delete('categoryLevel3'); 355 params.delete('active-buyer'); 356 var qs = params.toString(); 357 return path + (qs ? '?' + qs : ''); 358 } 359 360 /** 361 * Remove ?active-buyer from a URL. Does not depend on WizActiveBuyerContext 362 * (parent switch must work on every page type). 363 */ 364 function stripActiveBuyerParam(url) { 365 if (!url) { 366 return url; 367 } 368 if (window.WizActiveBuyerContext && typeof window.WizActiveBuyerContext.removeFromUrl === 'function') { 369 return window.WizActiveBuyerContext.removeFromUrl(url); 370 } 371 try { 372 var parsed = new URL(url, window.location.origin); 373 parsed.searchParams.delete('active-buyer'); 374 return parsed.pathname + parsed.search + parsed.hash; 375 } catch (e) { 376 return url; 377 } 378 } 379 380 /** 381 * Notify listeners to clear buyer-scoped client caches before a context switch. 382 * Global-scripts.js subscribes via wiz:buyer:reset. 383 */ 384 function dispatchBuyerContextReset() { 385 try { 386 window.dispatchEvent(new CustomEvent('wiz:buyer:reset')); 387 } catch (e) { 388 try { WizCartSync.remove('cartData'); } catch (e2) {} 389 try { localStorage.removeItem('buyer_data'); } catch (e3) {} 390 } 391 } 392 393 function isParentCustomer(customer) { 394 return !!(customer && (customer.is_parent === true || customer.is_parent === 'true' || customer.is_parent === 1)); 395 } 396 397 function buildUrlAfterCustomerSwitch(customer) { 398 var isParent = isParentCustomer(customer); 399 var baseUrl = getReloadUrlAfterCustomerSwitch(); 400 var targetUrl; 401 402 if (baseUrl) { 403 targetUrl = baseUrl; 404 } else { 405 targetUrl = window.location.pathname + window.location.search + window.location.hash; 406 } 407 408 if (window.WizActiveBuyerContext && typeof window.WizActiveBuyerContext.stripCartIdFromCartSummaryUrl === 'function') { 409 targetUrl = window.WizActiveBuyerContext.stripCartIdFromCartSummaryUrl(targetUrl); 410 } 411 412 if (isParent) { 413 return stripActiveBuyerParam(targetUrl); 414 } 415 416 var paramName = (window.WizActiveBuyerContext && window.WizActiveBuyerContext.PARAM) 417 ? window.WizActiveBuyerContext.PARAM 418 : 'active-buyer'; 419 var parsed = new URL(targetUrl, window.location.origin); 420 parsed.searchParams.set(paramName, getCustomerRecordId(customer)); 421 return parsed.pathname + parsed.search + parsed.hash; 422 } 423 424 function switchToCustomer(customer) { 425 dispatchBuyerContextReset(); 426 427 showSwitchPopup(customer); 428 setTimeout(function () { 429 var isParent = isParentCustomer(customer); 430 var nextUrl = buildUrlAfterCustomerSwitch(customer); 431 432 if (window.WizActiveBuyerContext && typeof window.WizActiveBuyerContext.navigate === 'function') { 433 if (isParent) { 434 window.WizActiveBuyerContext.navigate(nextUrl, { context: 'parent' }); 435 } else { 436 window.WizActiveBuyerContext.navigate(nextUrl, { 437 context: 'child', 438 buyerId: getCustomerRecordId(customer) 439 }); 440 } 441 } else { 442 window.location.href = nextUrl; 443 } 444 }, 800); 445 } 446 447 // ââ Render switcher list ââ 448 449 function renderCustomerSwitcher(root, customers) { 450 var switcher = root.querySelector('.wiz-customer-switcher'); 451 var list = root.querySelector('.wiz-customer-list'); 452 if (!switcher || !list) { return; } 453 454 if (!customers || customers.length === 0) { 455 switchableChildState = false; 456 switcher.style.display = 'none';
457 hideActiveCustomerTriggerDisplay(root); 458 return; 459 } 460 461 var isParentUser = customers.some(isParentCustomer); 462 463 var childCustomers = customers.filter(function (customer) { 464 return !isParentCustomer(customer); 465 }); 466 467 var hasChildCustomers = childCustomers.length > 0; 468 469 var parentCustomer = customers.filter(isParentCustomer)[0]; 470 if (!parentCustomer) { 471 parentCustomer = customers.filter(function (c) { return c.is_default; })[0] || customers[0]; 472 } 473 474 var activeBuyerId = getActiveCustomerBuyerId(parentCustomer); 475 476 var effectiveActiveBuyerId; 477 if (activeBuyerId) { 478 effectiveActiveBuyerId = activeBuyerId; 479 } else if (parentCustomer) { 480 effectiveActiveBuyerId = parentCustomer.id; 481 } else { 482 effectiveActiveBuyerId = ''; 483 } 484 485 var activeCustomerForHeader = customers.filter(function (c) { 486 return idsEqual(getCustomerRecordId(c), effectiveActiveBuyerId); 487 })[0] || parentCustomer; 488 489 if (!isParentUser) { 490 switchableChildState = false; 491 switcher.style.display = 'none'; 492 hideActiveCustomerTriggerDisplay(root); 493 return; 494 } 495 496 if (!hasChildCustomers) { 497 switchableChildState = false; 498 switcher.style.display = 'none'; 499 hideActiveCustomerTriggerDisplay(root); 500 return; 501 } 502 503 switchableChildState = true; 504 505 updateActiveCustomerDisplay(root, activeCustomerForHeader); 506 switcher.style.display = 'flex'; 507 508 var sortedChildren = childCustomers.slice().sort(function (a, b) { 509 var an = (a.company_name || '').toLowerCase(); 510 var bn = (b.company_name || '').toLowerCase(); 511 if (an < bn) { return -1; } 512 if (an > bn) { return 1; } 513 return 0; 514 }); 515 516 list.innerHTML = ''; 517 518 var inChildContext = isInChildBuyerContext(parentCustomer) || !!( 519 activeBuyerId && !isParentBuyerId(activeBuyerId, parentCustomer) 520 ); 521 522 var isParentActive = !inChildContext; 523 524 var backItem = document.createElement('div'); 525 backItem.className = 'wiz-customer-item wiz-customer-item-parent-return' + (isParentActive ? ' active' : ''); 526 var backAddressHTML = ''; 527 if (shouldShowMenuAddress()) { 528 var backLines = []; 529 if (addressTypeMenu === 'billing' || addressTypeMenu === 'both') { 530 var backBill = formatAddressFieldsLine(parentCustomer.default_billing_address, addressFields); 531 var backBillHtml = buildMenuAddressLineHtml('Bill:', backBill, showAddressLabelsMenu); 532 if (backBillHtml) { 533 backLines.push(backBillHtml); 534 } 535 } 536 if (addressTypeMenu === 'shipping' || addressTypeMenu === 'both') { 537 var backShip = formatAddressFieldsLine(parentCustomer.default_shipping_address, addressFields); 538 var backShipHtml = buildMenuAddressLineHtml('Ship:', backShip, showAddressLabelsMenu); 539 if (backShipHtml) { 540 backLines.push(backShipHtml); 541 } 542 } 543 if (backLines.length > 0) { 544 backAddressHTML = backLines.join(''); 545 } 546 } 547 backItem.innerHTML = 548 '<div class="wiz-customer-item-info">' + 549 '<span class="wiz-customer-item-name">' + 550 escapeHtml(parentCustomer.company_name || '') + 551 ' <span class="wiz-customer-parent-badge">Parent</span>' + 552 '</span>' + 553 backAddressHTML + 554 '</div>' + 555 (isParentActive ? '<span class="wiz-customer-checkmark">✓</span>' : ''); 556 if (!isParentActive || isInChildBuyerContext(parentCustomer)) { 557 backItem.addEventListener('click', function (e) { 558 e.stopPropagation(); 559 if (isParentActive && !isInChildBuyerContext(parentCustomer)) { 560 return; 561 } 562 switchToCustomer(parentCustomer); 563 }); 564 } 565 list.appendChild(backItem); 566
567 sortedChildren.forEach(function (customer) { 568 var isActive = idsEqual(getCustomerRecordId(customer), effectiveActiveBuyerId); 569 var item = document.createElement('div'); 570 item.className = 'wiz-customer-item' + (isActive ? ' active' : ''); 571 572 var addressHTML = ''; 573 if (shouldShowMenuAddress()) { 574 var addressLines = []; 575 576 if (addressTypeMenu === 'billing' || addressTypeMenu === 'both') { 577 var billingStr = formatAddressFieldsLine(customer.default_billing_address, addressFields); 578 var billingHtml = buildMenuAddressLineHtml('Bill:', billingStr, showAddressLabelsMenu); 579 if (billingHtml) { 580 addressLines.push(billingHtml); 581 } 582 } 583 584 if (addressTypeMenu === 'shipping' || addressTypeMenu === 'both') { 585 var shippingStr = formatAddressFieldsLine(customer.default_shipping_address, addressFields); 586 var shippingHtml = buildMenuAddressLineHtml('Ship:', shippingStr, showAddressLabelsMenu); 587 if (shippingHtml) { 588 addressLines.push(shippingHtml); 589 } 590 } 591 592 if (addressLines.length > 0) { 593 addressHTML = addressLines.join(''); 594 } 595 } 596 597 item.innerHTML = 598 '<div class="wiz-customer-item-info">' + 599 '<span class="wiz-customer-item-name">' + escapeHtml(customer.company_name) + '</span>' + 600 addressHTML + 601 '</div>' + 602 (isActive ? '<span class="wiz-customer-checkmark">✓</span>' : ''); 603 604 if (!isActive) { 605 item.addEventListener('click', function (e) { 606 e.stopPropagation(); 607 switchToCustomer(customer); 608 }); 609 } 610 list.appendChild(item); 611 }); 612 } 613 614 function hideActiveCustomerTriggerDisplay(root) { 615 var display = root.querySelector('.login_active_customer_display'); 616 if (display) { display.style.display = 'none'; } 617 } 618 619 function updateActiveCustomerDisplay(root, customer) { 620 if (!customer) { return; } 621 var display = root.querySelector('.login_active_customer_display'); 622 var nameEl = root.querySelector('.login_active_customer_name'); 623 624 if (display) { display.style.display = 'flex'; } 625 if (nameEl) { nameEl.textContent = customer.company_name || ''; } 626 627 var addressContainer = root.querySelector('.login_active_customer_address'); 628 629 if (shouldShowMainAddress()) { 630 var addressHtml = buildMainAddressLinesHtml(customer); 631 632 if (addressHtml) { 633 if (!addressContainer) { 634 addressContainer = document.createElement('div'); 635 addressContainer.className = 'login_active_customer_address'; 636 if (nameEl && nameEl.parentNode) { 637 nameEl.parentNode.appendChild(addressContainer); 638 } 639 } 640 if (addressContainer) { 641 addressContainer.innerHTML = addressHtml; 642 addressContainer.style.display = 'block'; 643 } 644 } else if (addressContainer) { 645 addressContainer.style.display = 'none'; 646 } 647 } else if (addressContainer) { 648 addressContainer.style.display = 'none'; 649 } 650 } 651 652 function getAllowedCustomersFromLocalStorage() { 653 try { 654 var ud = JSON.parse(localStorage.getItem('UserDetails') || 'null'); 655 return (ud && Array.isArray(ud.allowed_customers)) ? ud.allowed_customers : []; 656 } catch (e) { return []; } 657 } 658 659 function getAllowedCustomersFromTTLCache() { 660 try { 661 var raw = localStorage.getItem(ALLOWED_CUSTOMERS_LS_KEY); 662 if (!raw) { 663 return null; 664 } 665 var cached = JSON.parse(raw); 666 if (!cached || !Array.isArray(cached.customers) || !cached.fetchedAt) { 667 return null; 668 } 669 if (Date.now() - cached.fetchedAt > ALLOWED_CUSTOMERS_TTL_MS) { 670 return null; 671 } 672 return cached.customers; 673 } catch (e) { 674 return null; 675 } 676 } 677 678 function saveAllowedCustomersToTTLCache(customers) { 679 if (!Array.isArray(customers) || customers.length === 0) { 680 return; 681 } 682 try { 683 localStorage.setItem(ALLOWED_CUSTOMERS_LS_KEY, JSON.stringify({ 684 fetchedAt: Date.now(), 685 customers: customers 686 })); 687 } catch (e) { /* ignore */ } 688 } 689 690 function clearAllowedCustomersCaches() { 691 wizCachedAllowedCustomers.length = 0; 692 switchableChildState = null; 693 try { localStorage.removeItem(ALLOWED_CUSTOMERS_LS_KEY); } catch (e) { /* ignore */ } 694 window.__wizAllowedCustomersPromise = null; 695 } 696 697 function forceReloadCustomerSwitcher() { 698 clearAllowedCustomersCaches(); 699 root.__wizSwitcherLoaded = false;
700 fetchAllowedCustomersFromApi(root); 701 } 702 703 root.__wizForceReloadCustomerSwitcher = forceReloadCustomerSwitcher; 704 705 function hideCustomerSwitcher(root) { 706 var switcher = root.querySelector('.wiz-customer-switcher'); 707 if (switcher) { 708 switcher.style.display = 'none'; 709 } 710 hideActiveCustomerTriggerDisplay(root); 711 } 712 713 function resolveCustomersWithoutApi() { 714 if (wizCachedAllowedCustomers.length > 0) { 715 return filterAccessEnabledCustomers(wizCachedAllowedCustomers); 716 } 717 718 var ttlCustomers = getAllowedCustomersFromTTLCache(); 719 if (ttlCustomers && ttlCustomers.length > 0) { 720 return filterAccessEnabledCustomers(ttlCustomers); 721 } 722 723 var lsCustomers = filterAccessEnabledCustomers(getAllowedCustomersFromLocalStorage()); 724 if (lsCustomers.length > 0) { 725 return lsCustomers; 726 } 727 728 return null; 729 } 730 731 function wizWarnCustomerSwitcher(message, err) { 732 try { 733 var on = (typeof window !== 'undefined' && window.wizDebugCustomerSwitcher) || 734 (typeof localStorage !== 'undefined' && localStorage.getItem('wiz_debug_customer_switcher') === '1'); 735 if (on) { 736 console.warn('[WizShop login] ' + message, err || ''); 737 } 738 } catch (w) {} 739 } 740 741 function fetchCustomersFromUserApi(root) { 742 try { 743 var ud = JSON.parse(localStorage.getItem('UserDetails') || 'null'); 744 if (!ud || !ud.id || !window.WizApi) { 745 renderCustomerSwitcher(root, []); 746 return; 747 } 748 window.WizApi.call('get_wizshop_user', { user_id: ud.id }) 749 .done(function (result) { 750 var customers = []; 751 try { 752 var user = (result.data && result.data.data && result.data.data.user) 753 ? result.data.data.user 754 : null; 755 var raw = []; 756 if (user && Array.isArray(user.all_customers)) { 757 raw = user.all_customers; 758 } else if (user && Array.isArray(user.allowed_customers)) { 759 raw = user.allowed_customers; 760 } 761 customers = filterAccessEnabledCustomers(raw); 762 } catch (e) { 763 wizWarnCustomerSwitcher('get_wizshop_user: could not read user.all_customers (response shape drift?)', e); 764 } 765 syncInMemoryAllowedCustomers(customers); 766 saveAllowedCustomersToTTLCache(customers); 767 renderCustomerSwitcher(root, customers); 768 root.__wizSwitcherLoaded = true; 769 }) 770 .fail(function () { 771 renderCustomerSwitcher(root, []); 772 root.__wizSwitcherLoaded = true; 773 }); 774 } catch (e) { 775 wizWarnCustomerSwitcher('fetchCustomersFromUserApi outer failure', e); 776 renderCustomerSwitcher(root, []); 777 root.__wizSwitcherLoaded = true; 778 } 779 } 780 781 function fetchAllowedCustomersFromApi(root) { 782 if (!window.WizApi || typeof window.WizApi.call !== 'function') { 783 renderCustomerSwitcher(root, []); 784 root.__wizSwitcherLoaded = true; 785 return; 786 } 787 788 if (window.__wizAllowedCustomersPromise) { 789 window.__wizAllowedCustomersPromise 790 .done(function (result) { 791 handleAllowedCustomersResult(root, result); 792 }) 793 .fail(function () { 794 fetchCustomersFromUserApi(root); 795 }); 796 return; 797 } 798 799 window.__wizAllowedCustomersPromise = window.WizApi.call('allowed_customers'); 800 window.__wizAllowedCustomersPromise 801 .done(function (result) { 802 handleAllowedCustomersResult(root, result); 803 }) 804 .fail(function () { 805 fetchCustomersFromUserApi(root); 806 }) 807 .always(function () { 808 window.__wizAllowedCustomersPromise = null; 809 }); 810 } 811 812 /** 813 * @param {Element} root 814 * @param {{fetchIfMissing?: boolean}} options 815 */ 816 function loadCustomerSwitcher(root, options) { 817 options = options || {}; 818
819 var cached = resolveCustomersWithoutApi(); 820 if (cached && cached.length > 0) { 821 saveAllowedCustomersToTTLCache(cached); 822 renderCustomerSwitcher(root, cached); 823 root.__wizSwitcherLoaded = true; 824 return; 825 } 826 827 if (!options.fetchIfMissing) { 828 hideCustomerSwitcher(root); 829 return; 830 } 831 832 fetchAllowedCustomersFromApi(root); 833 } 834 835 function ensureCustomerSwitcherLoaded(root) { 836 if (root.__wizSwitcherLoaded) { 837 return; 838 } 839 loadCustomerSwitcher(root, { fetchIfMissing: true }); 840 } 841 842 function syncInMemoryAllowedCustomers(customers) { 843 wizCachedAllowedCustomers.length = 0; 844 if (!Array.isArray(customers) || customers.length === 0) { 845 return; 846 } 847 customers.forEach(function (customer) { 848 wizCachedAllowedCustomers.push(customer); 849 }); 850 } 851 852 function initCustomerSwitcherLazy(root) { 853 if (!canUseCustomerSwitcher()) { 854 hideCustomerSwitcher(root); 855 return; 856 } 857 var needsAddress = shouldShowMainAddress() || shouldShowMenuAddress(); 858 loadCustomerSwitcher(root, { fetchIfMissing: needsAddress }); 859 } 860 861 function handleAllowedCustomersResult(root, result) { 862 var customers = []; 863 try { 864 var payload = (result.data && result.data.data) ? result.data.data : (result.data || null); 865 customers = filterAccessEnabledCustomers( 866 extractCustomersFromAllowedCustomersPayload(payload) 867 ); 868 } catch (e) { 869 wizWarnCustomerSwitcher('allowed_customers endpoint: could not parse all_customers (response shape drift?)', e); 870 } 871 872 if (customers.length > 0) { 873 syncInMemoryAllowedCustomers(customers); 874 saveAllowedCustomersToTTLCache(customers); 875 renderCustomerSwitcher(root, customers); 876 root.__wizSwitcherLoaded = true; 877 return; 878 } 879 880 fetchCustomersFromUserApi(root); 881 } 882 883 if (!window.logout) { 884 window.logout = function () { 885 var isSecure = window.location.protocol === 'https:'; 886 var secureFlag = isSecure ? '; Secure' : ''; 887 888 try { 889 document.dispatchEvent(new CustomEvent('wiz:storefront:logout')); 890 } catch (e) { /* ignore */ } 891 892 localStorage.clear(); 893 sessionStorage.clear(); 894 localStorage.setItem('logout-event', 'logout' + Math.random()); 895 document.cookie.split(';').forEach(function (c) { 896 var cookie = c.trim(); 897 var eqPos = cookie.indexOf('='); 898 var name = eqPos > -1 ? cookie.substring(0, eqPos) : cookie; 899 document.cookie = name + '=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/' + secureFlag; 900 }); 901 document.querySelectorAll('.login_signup').forEach(function (el) { 902 el.style.setProperty('display', 'flex', 'important'); 903 }); 904 document.querySelectorAll('.login_user_menu_wrapper').forEach(function (el) { 905 el.style.setProperty('display', 'none', 'important'); 906 }); 907 window.location.href = '/?clear_session=1'; 908 }; 909 } 910 911 function updateUserInfo(root, userDetailsObj) { 912 if (!root || !userDetailsObj) { return; } 913 var email = root.querySelector('.login_menu_id'); 914 var name = root.querySelector('.login_menu_name'); 915 if (email) { email.textContent = userDetailsObj.email; } 916 if (name) { name.textContent = 'Hello ' + userDetailsObj.first_name + ' ' + userDetailsObj.last_name; } 917 } 918 919 function initWidget(root) { 920 if (!root) { return; } 921 var loginSignup = root.querySelector('.login_signup'); 922 var loginUserMenuWrapper = root.querySelector('.login_user_menu_wrapper'); 923 if (!loginSignup || !loginUserMenuWrapper) { return; } 924 925 var login_user = status_check_widget(); 926 927 if (login_user) { 928 loginSignup.style.setProperty('display', 'none', 'important'); 929 loginUserMenuWrapper.style.setProperty('display', 'flex', 'important'); 930 931 try { 932 var userDetailsObj = JSON.parse(localStorage.getItem('UserDetails') || 'null'); 933 updateUserInfo(root, userDetailsObj); 934 } catch (e) { 935 console.error('Error parsing user details', e); 936 } 937 938 document.addEventListener('click', function (event) { 939 var menu = root.querySelector('.login_icon_button'); 940 var toggleBtn = root.querySelector('.login_icon_menu'); 941 if (!menu) { return; } 942 if (toggleBtn && toggleBtn.contains(event.target)) { 943 var opening = menu.style.display === 'none' || menu.style.display === ''; 944 menu.style.display = opening ? 'flex' : 'none'; 945 if (opening && canUseCustomerSwitcher()) { 946 ensureCustomerSwitcherLoaded(root); 947 } 948 } else if (!menu.contains(event.target)) { 949 menu.style.display = 'none'; 950 } 951 }); 952 953 initCustomerSwitcherLazy(root); 954 } else { 955 loginUserMenuWrapper.style.setProperty('display', 'none', 'important'); 956 loginSignup.style.setProperty('display', 'flex', 'important'); 957 } 958 } 959 960 function onStorageChange(e) { 961 if (e.key !== 'logout-event' && e.key !== 'persist:root' && e.key !== 'UserDetails') { return; } 962 var r = document.querySelector('[data-login-widget-id="' + widgetId + '"]'); 963 if (!r) { return; } 964 var loginSignup = r.querySelector('.login_signup'); 965 var loginUserMenuWrapper = r.querySelector('.login_user_menu_wrapper'); 966 if (e.key === 'logout-event') { 967 if (loginSignup) { loginSignup.style.display = 'flex'; } 968 if (loginUserMenuWrapper) { loginUserMenuWrapper.style.display = 'none'; } 969 try { 970 document.dispatchEvent(new CustomEvent('wiz:storefront:logout')); 971 } catch (err) { /* ignore */ } 972 return; 973 } 974 var login_user = status_check_widget(); 975 if (login_user) { 976 if (loginSignup) { loginSignup.style.display = 'none'; } 977 if (loginUserMenuWrapper) { loginUserMenuWrapper.style.display = 'flex'; } 978 try { 979 updateUserInfo(r, JSON.parse(localStorage.getItem('UserDetails') || 'null')); 980 } catch (e) {} 981 } else { 982 if (loginUserMenuWrapper) { loginUserMenuWrapper.style.display = 'none'; } 983 if (loginSignup) { loginSignup.style.display = 'flex'; } 984 try { 985 document.dispatchEvent(new CustomEvent('wiz:storefront:logout')); 986 } catch (err) { /* ignore */ } 987 } 988 } 989 990 if (typeof window.elementor === 'undefined' || !window.elementor.frontend || !window.elementor.frontend.isEditMode()) { 991 if (document.readyState === 'loading') { 992 document.addEventListener('DOMContentLoaded', function () { 993 initWidget(root); 994 }); 995 } else { 996 initWidget(root); 997 } 998 window.addEventListener('storage', onStorageChange); 999 document.addEventListener('wizContentReady', function () { 1000 var r = document.querySelector('[data-login-widget-id="' + widgetId + '"]'); 1001 if (!r || !status_check_widget()) { return; } 1002 try { 1003 updateUserInfo(r, JSON.parse(localStorage.getItem('UserDetails') || 'null')); 1004 } catch (e) {} 1005 }); 1006 } 1007 1008 if (typeof window.elementor !== 'undefined') { 1009 window.elementor.hooks.addAction('panel/open_editor/widget/login_wiz_plugin_widget', function (panel, model) { 1010 var settings = model.get('settings'); 1011 if (!settings) { return; } 1012 settings.on('change:preview_state', function (changedModel, value) { 1013 var r = document.querySelector('[data-login-widget-id="' + widgetId + '"]'); 1014 if (!r) { return; } 1015 var s = r.querySelector('.login_signup'); 1016 var w = r.querySelector('.login_user_menu_wrapper'); 1017 if (value === 'logged_in') { 1018 if (s) { s.style.setProperty('display', 'none', 'important'); } 1019 if (w) { w.style.setProperty('display', 'block', 'important'); } 1020 } else { 1021 if (w) { w.style.setProperty('display', 'none', 'important'); } 1022 if (s) { s.style.setProperty('display', 'block', 'important'); } 1023 } 1024 }); 1025 }); 1026 } 1027} 1028 1029(function bootWizLoginPlugins() { 1030 if (!window.WizShopLogin) { 1031 window.WizShopLogin = {}; 1032 } 1033 1034 window.WizShopLogin.refreshCustomerSwitcher = function () { 1035 document.querySelectorAll('[data-login-widget-id][data-login-config]').forEach(function (root) { 1036 if (typeof root.__wizForceReloadCustomerSwitcher === 'function') { 1037 root.__wizForceReloadCustomerSwitcher(); 1038 } 1039 }); 1040 }; 1041 1042 if (!window.__wizAllowedCustomersChangedListener) { 1043 window.__wizAllowedCustomersChangedListener = true; 1044 window.addEventListener('wiz:allowed-customers:changed', function () { 1045 if (window.wizParentChildEnabled === false) { 1046 return; 1047 } 1048 window.WizShopLogin.refreshCustomerSwitcher(); 1049 }); 1050 } 1051 1052 function boot() { 1053 document.querySelectorAll('[data-login-widget-id][data-login-config]').forEach(function (root) { 1054 runWizLoginPlugin(root); 1055 }); 1056 } 1057 if (document.readyState === 'loading') { 1058 document.addEventListener('DOMContentLoaded', boot); 1059 } else { 1060 boot(); 1061 } 1062})();
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.