1(function ($) { 2 $(function () { 3 console.log('Header V2 script loaded'); 4 5 $('.menu-arrow').on('click', function () { 6 $(this).toggleClass('rotate-180'); 7 $(this).closest('li').find('ul').toggleClass('level-three-menu'); 8 }); 9 10 $('.mobile-menu-icon').on('click', function () { 11 $('.menu-open-box').toggleClass('left-0'); 12 $('.overlaySection').removeClass('hidden'); 13 }); 14 15 $('.back-to-main-menu').on('click', function () { 16 $('.menu-open-box').removeClass('left-0'); 17 $('.mobile-level-two-menu').removeClass('left-0'); 18 $('.overlaySection').addClass('hidden'); 19 }); 20 21 // Mobile: toggle menu 22 $('.open-sub-menu-mobile').on('click', function (e) { 23 e.preventDefault(); 24 $(this) 25 .parents('.has-mobile-menu') 26 .find('.mobile-level-two-menu') 27 .addClass('left-0'); 28 let getMenuText = $(this) 29 .parents('.has-mobile-menu') 30 .find('.level-one-menu') 31 .text(); 32 $(this) 33 .parents('.has-mobile-menu') 34 .find('.submenu-title') 35 .text(getMenuText); 36 }); 37 38 $('.back-level-one-menu').on('click', function () { 39 $('.mobile-level-two-menu').removeClass('left-0'); 40 }); 41 42 $('.desktop-menu .has-submenu').on('hover', function () { 43 $('.overlaySection').removeClass('hidden'); 44 }); 45 46 $('.desktop-menu .has-submenu').hover( 47 function () { 48 $('.overlaySection').removeClass('hidden'); // Add 'active' when hovered 49 $('.react-popover').fadeOut(); 50 }, 51 function () { 52 $('.overlaySection').addClass('hidden'); // Remove 'active' when not hovered 53 } 54 ); 55 56 $('.m1-id-field').hide(); 57 $('.m1-id-field-response').hide(); 58 $('.otp-field').hide(); 59 $('.login-success').hide(); 60 $('.limit-exceed-error').hide(); 61 $('.m1-id-not-found').hide(); 62 $('.m1loader').hide(); 63 $('.logged-in-banner').hide(); 64 let otpDisabled = $('#react-tiny-popover-container').data('otp-disable'); //false; 65 let javaBaseURL = $('#react-tiny-popover-container').data('javabase'); //"https://apimuat.m1.com.sg/web2.0"; 66 let javaApimKey = $('#react-tiny-popover-container').data('java-apim'); //"dfdc2098a2cc49e59f790b97170829fb"; 67 68 let getB2CURL = $('#react-tiny-popover-container').data('b2curl'); //"https://loginuat.m1.com.sg/M1UAT.onmicrosoft.com/oauth2/v2.0/"; 69 let getClientID = $('#react-tiny-popover-container').data('client-id'); //"2a681942-f2e0-45f6-905c-c86b91d09a9b"; 70 let getclientSecretId = $('#react-tiny-popover-container').data( 71 'client-secret-id' 72 ); //"aQC8Q~C-DHSiJY5pU.JkVrofph6WpML2Pfh7Yclj"; 73 let getReturnUrl = $('#react-tiny-popover-container').data('callback'); //"https://uatneww.m1.com.sg/content/M1/us/web/shop/sign-up/step.html"; 74 75 $('.login-action-reset').on('click', function () { 76 $('.email-error').text(''); 77 $('#emailid').val('').removeClass('error-border'); 78 $('#nricid').val('').removeClass('error-border'); 79 $('.login-with-email').show(); 80 $('.otp-field').hide(); 81 $('.m1-id-field').hide(); 82 $('.m1-id-field-response').hide(); 83 $('.m1-id-not-found').hide(); 84 $('.limit-exceed-error').hide(); 85 $('.login-success').hide(); 86 $('.m1loader').hide(); 87 $('.resend-otp') 88 .addClass('pointer-events-none text-neutral-gray') 89 .removeClass('text-primary-orange cursor-pointer'); 90 $('.otp-error').text(''); 91 $('.pincode-input-text').val(''); 92 $('.resend-otp').removeClass('resend-done'); 93 }); 94 95 let getLoginInfo = sessionStorage.getItem('customerInfo') ? true : false; 96 97 if (getLoginInfo) { 98 $('.after-login').show(); 99 $('.before-login').hide(); 100 $('.guest-banner').hide(); 101 $('.logged-in-banner').show(); 102 } else { 103 $('.after-login').hide(); 104 $('.before-login').show(); 105 $('.guest-banner').show(); 106 $('.logged-in-banner').hide(); 107 } 108 109 let getVoucherCount = sessionStorage.getItem('voucherCount'); 110 let getOfferDesc = $('.after-login .offers-popover-content').text(); 111 if (getVoucherCount) { 112 $('.after-login .offers-popover-content').html( 113 getOfferDesc.replaceAll('{{totalVoucher}}', `<span class="set-voucher-count">${getVoucherCount}</span>`) 114 ); 115 $('.set-voucher-count').text(getVoucherCount); 116 } else { 117 $('.after-login .offers-popover-content').html( 118 getOfferDesc.replaceAll('{{totalVoucher}}', `<span class="set-voucher-count">${$('.promo-voucher-list').length}</span>`) 119 ); 120 $('.set-voucher-count').text($('.promo-voucher-list').length); 121 } 122 123 function loginAction(width) { 124 let getLoginInfo = sessionStorage.getItem('customerInfo') ? true : false;
125 if (getLoginInfo) { 126 $('.after-login').show(); 127 $('.before-login').hide(); 128 } else { 129 $('.after-login').hide(); 130 $('.before-login').show(); 131 } 132 if (width > 1023) { 133 $('.react-popover').fadeIn(); 134 } else { 135 $('.react-popover').fadeToggle(); 136 } 137 } 138 139 $('.login-action').on('mouseover', function (e) { 140 if ($(window).width() > 1023) { 141 loginAction($(window).width()); 142 } 143 }); 144 145 $('.login-action').on('click', function () { 146 if ($(window).width() < 1024) { 147 loginAction($(window).width()); 148 } 149 }); 150 151 // $(document).on('mousedown', function (e) { 152 // if (!$(e.target).closest('.react-popover').length) { 153 // $('.react-popover').hide(); 154 // } 155 // }); 156 157 $(document).on('.modal-overlay', 'click', function () { 158 $('.login-action-reset').click(); 159 }); 160 161 $(document).on('click', function (e) { 162 if ( 163 $(window).width() > 1023 && 164 $(e.target).closest('.react-popover').length === 0 165 ) { 166 $('.react-popover').fadeOut(); 167 } 168 }); 169 170 $('.login-action-open').on('click', function () { 171 console.log('login-action-open clicked'); 172 $('.react-popover').fadeOut(); 173 new bootstrap.Modal($('#login')).show(); 174 }); 175 176 $('.back-to-login').on('click', function () { 177 $('.m1-id-field-response').hide(); 178 $('#emailid').val(''); 179 $('.login-with-email').show(); 180 }); 181 182 $('.forgot-m1-id').on('click', function () { 183 $('.login-with-email').hide(); 184 $('#nricid').val(''); 185 $('.m1-id-field').show(); 186 }); 187 188 $('#nricid').on('blur', function (e) { 189 e.preventDefault(); 190 const nric = $(this).val(); 191 if (nric === '') { 192 $('.email-error-nric').text('NRIC/FIN Number required'); 193 $('#nricid').addClass('error-border'); 194 return false; 195 } else if (IsNRIC(nric) === false) { 196 $('.email-error-nric').text( 197 'Invalid NRIC/FIN format. Please check again' 198 ); 199 $('#nricid').addClass('error-border'); 200 return false; 201 } else { 202 $('.email-error-nric').text(''); 203 $('#nricid').removeClass('error-border'); 204 return true; 205 } 206 return false; 207 }); 208 209 $('.pincode-input-text').on('paste', function (e) { 210 e.preventDefault(); 211 var pastedData = (e.originalEvent || e).clipboardData.getData('text'); 212 pastedData = pastedData.trim(); 213 if (!/^\d{6}$/.test(pastedData)) { 214 $('.otp-error').text('Invalid OTP. Please enter a valid 6-digit OTP.'); 215 return; 216 } 217 $('.pincode-input-text').each(function (index) { 218 $(this).val(pastedData[index]); 219 }); 220 }); 221 222 $('.pincode-input-text').keyup(function (e) { 223 var index = $(this).index('input'); 224 var inputs = $('.pincode-input-text'); 225 if (e.keyCode == 8) { 226 var index = inputs.index(this); 227 if (index != 0) 228 inputs 229 .eq(index - 1) 230 .val('') 231 .focus(); 232 } else { 233 $('input') 234 .eq(index + 1) 235 .focus(); 236 } 237 }); 238 239 $('#nricid').on('blur', function (e) { 240 e.preventDefault(); 241 const nric = $(this).val(); 242 if (nric === '') { 243 $('.email-error-nric').text('NRIC/FIN Number required'); 244 $('#nricid').addClass('error-border'); 245 return false; 246 } else if (IsNRIC(nric) === false) { 247 $('.email-error-nric').text( 248 'Invalid NRIC/FIN format. Please check again' 249 ); 250 $('#nricid').addClass('error-border'); 251 return false; 252 } else { 253 $('.email-error-nric').text(''); 254 $('#nricid').removeClass('error-border'); 255 return true; 256 } 257 return false; 258 }); 259 260 $('#emailid').on('blur', function (e) { 261 e.preventDefault(); 262 const email = $(this).val(); 263 if (email === '') { 264 $('.email-error').text('Email ID required'); 265 $('#emailid').addClass('error-border'); 266 return false; 267 } else if (IsEmail(email) === false) { 268 $('.email-error').text('Enter Valid EmailID'); 269 $('#emailid').addClass('error-border'); 270 return false;
271 } else { 272 $('.email-error').text(''); 273 $('#emailid').removeClass('error-border'); 274 return true; 275 } 276 return false; 277 }); 278 279 function IsNRIC(nric) { 280 const regex = /^[a-zA-Z][0-9]{7}[a-zA-Z]+$/; 281 if (!regex.test(nric)) { 282 return false; 283 } else { 284 return true; 285 } 286 } 287 288 function IsEmail(email) { 289 const regex = 290 /^([a-zA-Z0-9_\.\-\+])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/; 291 if (!regex.test(email)) { 292 return false; 293 } else { 294 return true; 295 } 296 } 297 298 function showLoader(show) { 299 if (show) { 300 $('.m1loader').css('display', 'flex'); 301 } else { 302 $('.m1loader').hide(); 303 } 304 } 305 306 function ajaxCall(url, data, method) { 307 let getCustomerInfo = JSON.parse(sessionStorage.getItem('customerInfo')); 308 return $.ajax({ 309 url: url.includes('onmicrosoft') ? url : javaBaseURL + url, 310 headers: { 311 'apim-subscription-key': javaApimKey, 312 'content-type': 'application/json', 313 Token: getCustomerInfo?.access_token 314 ? getCustomerInfo.access_token 315 : '', 316 }, 317 method: method, 318 dataType: 'json', 319 data: method.toUpperCase() === 'GET' ? data : JSON.stringify(data), 320 processData: method.toUpperCase() === 'GET', 321 contentType: 322 method.toUpperCase() === 'GET' ? false : 'application/json', 323 }); 324 } 325 326 let timerLimit = 1; // for example, 2 minutes 327 let intervalHandle = null; 328 329 function startCountdown(timerLimit) { 330 let secondsRemaining = timerLimit * 60; 331 332 // Clear any previous interval 333 if (intervalHandle) clearInterval(intervalHandle); 334 335 intervalHandle = setInterval(function () { 336 // clear OTP message on every tick 337 $('.otp-error').text(''); 338 339 let min = Math.floor(secondsRemaining / 60); 340 let sec = secondsRemaining - min * 60; 341 if (sec < 10) sec = '0' + sec; 342 let message = '0' + min.toString() + ':' + sec; 343 344 $('#countdown').text(message); 345 346 if (secondsRemaining === 0) { 347 $('.otp-error').text( 348 'OTP has expired. Please request for a new one.' 349 ); 350 clearInterval(intervalHandle); 351 $('.resend-otp') 352 .removeClass('pointer-events-none text-neutral-gray') 353 .addClass('text-primary-orange cursor-pointer'); 354 } 355 secondsRemaining--; 356 }, 1000); 357 } 358 359 $('.resend-otp').on('click', function () { 360 // Reset the countdown timer 361 $('.email-login').click(); // Trigger the email login click event to resend OTP 362 $(this) 363 .addClass('pointer-events-none text-neutral-gray resend-done') 364 .removeClass('text-primary-orange cursor-pointer'); 365 // clearInterval(intervalHandle); 366 // startCountdown(timerLimit); 367 368 // Clear OTP input fields 369 $('.pincode-input-text').val(''); 370 371 // Optionally, you can also show a message or perform an AJAX call to resend the OTP 372 $('.otp-error').text(''); 373 }); 374 375 var emailResponse = null; 376 $('.email-login').on('click', function (e) { 377 e.preventDefault(); 378 const email = $('#emailid').val().trim(); 379 if (!email) { 380 $('.email-error').text('Email ID required'); 381 return; 382 } 383 if (!IsEmail(email)) { 384 $('.email-error').text('Enter Valid EmailID'); 385 return; 386 } 387 $('.email-error').text(''); 388 $('#emailid').removeClass('error-border'); 389 // Proceed with AJAX call or further processing 390 showLoader(true); 391 let data = { 392 emailID: email, 393 planType: 'NEWLINE', 394 onlyEmailRequired: 'true', 395 }; 396 397 ajaxCall('/login/sendOTP', data, 'POST') 398 .done(function (response) { 399 // Handle success 400 console.log('Success:', response); 401 console.log('Success 111:', response?.verificationKey); 402 showLoader(false); 403 if (response?.verificationKey) { 404 emailResponse = response; 405 sessionStorage.setItem('customerLogin', JSON.stringify(response)); 406 if (otpDisabled) {
407 idHintTokenCall(emailResponse); 408 } else { 409 if ($('.resend-otp').hasClass('resend-done')) { 410 startCountdown(timerLimit); 411 } else { 412 $('.login-with-email').hide(); 413 $('.otp-email').text(email); 414 $('.otp-field').show(); 415 startCountdown(timerLimit); 416 } 417 } 418 } else if ( 419 response?.message === 'UPPER_LIMIT_EXCEEDED' || 420 response?.message === 'LOWER_LIMIT_EXCEEDED' 421 ) { 422 $('.limit-exceed-error').show(); 423 $('.login-with-email').hide(); 424 $('.otp-field').hide(); 425 } else { 426 if (response?.error?.errorCode === '400') { 427 $('.email-error').text('Somthing went wrong. Please try again.'); 428 } else if (response?.statusCode === 429) { 429 $('.email-error').text( 430 'Oops! Looks like you have requested for the OTP too many times. Please try again later.' 431 ); 432 } else { 433 if ( 434 response?.error && 435 response?.error?.errorMessage === 'PROSPECT_CUSTOMER' 436 ) { 437 $('.email-error').text( 438 'Check that you have entered the correct email or sign up as a New customer.' 439 ); 440 } else { 441 $('.email-error').text( 442 response?.error 443 ? response?.error?.errorDescription 444 : response?.message 445 ); 446 } 447 } 448 } 449 }) 450 .fail(function (error) { 451 // Handle error 452 showLoader(false); 453 console.error('Error:', error); 454 $('.email-error').text( 455 error?.response?.errorCode ? 'M1 ID is incorrect' : error?.message 456 ); 457 $('#emailid').addClass('error-border'); 458 }); 459 }); 460 461 $('.m1-id-login').on('click', function (e) { 462 e.preventDefault(); 463 const nric = $('#nricid').val().trim(); 464 if (!nric) { 465 $('.email-error-nric').text('NRIC/FIN Number required'); 466 $('#nricid').addClass('error-border'); 467 return; 468 } 469 if (!IsNRIC(nric)) { 470 $('.email-error-nric').text('Enter Valid NRIC/FIN Number'); 471 $('#nricid').addClass('error-border'); 472 return; 473 } 474 $('.email-error-nric').text(''); 475 $('#nricid').removeClass('error-border'); 476 477 // Proceed with AJAX call or further processing 478 showLoader(true); 479 let data = { 480 customerIdValue: nric, 481 isForgotM1Id: 'true', 482 }; 483 ajaxCall('/login/sendOTP', data, 'POST') 484 .done(function (response) { 485 // Handle success 486 console.log('Success:', response); 487 if (response) { 488 showLoader(false); 489 nricResponse = response; 490 if ( 491 response?.emailID && 492 response?.emailID?.indexOf('@dummy') > -1 493 ) { 494 $('.email-id-not-found').show(); 495 $('.login-with-email').hide(); 496 } else { 497 if (response?.emailID) { 498 $('.m1-id-field').hide(); 499 $('.masked-m1-id').text(response?.emailID); 500 $('.m1-id-field-response').show(); 501 } else { 502 $('.email-error-nric').text( 503 response?.error ? 'M1 ID is incorrect' : response?.message 504 ); 505 } 506 } 507 } 508 }) 509 .fail(function (error) { 510 // Handle error 511 showLoader(false); 512 console.error('Error:', error); 513 }); 514 }); 515 516 $('.submit-otp').on('click', function (e) { 517 e.preventDefault(); 518 $('.otp-error').text(''); 519 let getLoginInfo = JSON.parse(sessionStorage.getItem('customerLogin')); 520 console.log('getLoginInfo', getLoginInfo); 521 const otp = $('.pincode-input-text') 522 .map(function () { 523 return $(this).val(); 524 }) 525 .get() 526 .join(''); 527 if (otp.length < 6) { 528 $('.otp-error').text('Please enter a valid 6-digit OTP'); 529 return; 530 } 531 532 showLoader(true); 533 let data = { 534 emailID: $('#emailid').val(), 535 verificationKey: getLoginInfo.verificationKey, 536 otp: otp, 537 }; 538 ajaxCall('/login/verifyOTP', data, 'POST') 539 .done(function (response) { 540 // Handle success 541 console.log('Success:', response); 542 showLoader(false); 543 if (response) { 544 if (response?.error) { 545 $('.otp-error').text( 546 response?.error 547 ? 'M1 ID is incorrect' 548 : response?.errorDescription 549 ); 550 } else if (response?.result === false) { 551 $('.otp-error').text( 552 response?.error 553 ? response?.error?.errorDescription 554 : response?.message 555 ); 556 } else { 557 showLoader(true); 558 authorizeB2CLogin(response?.token); 559 } 560 } 561 }) 562 .fail(function (error) { 563 // Handle error 564 console.error('Error:', error); 565 showLoader(false); 566 $('.otp-error').text( 567 error?.response?.errorCode ? 'M1 ID is incorrect' : error?.message 568 ); 569 }); 570 }); 571 572 async function authorizeB2CLogin(resToken) { 573 showLoader(true); 574 const res = await fetch( 575 `${getB2CURL}authorize?client_id=${getClientID}&scope=${getClientID}+offline_access+openid&response_type=code&redirect_uri=${getReturnUrl}&state=12345678&nonce=DefaultNonce&resource=${getClientID}&p=B2C_1A_M1_BlueSky_CBP&id_token_hint=${resToken}` 576 ); 577 // Code fails before you ever get here and check res.status 578 console.log('res', res); 579 const newLocation = res.url; 580 console.log('newLocation', newLocation); 581 let url = new URL(newLocation); 582 let AuthCode = url.searchParams.get('code'); 583 if (AuthCode) { 584 B2CLoginTokenCall(AuthCode); 585 } 586 } 587 588 function B2CLoginTokenCall(AuthCode) { 589 showLoader(true); 590 ajaxCall( 591 `${getB2CURL}token`, 592 { 593 client_secret: getclientSecretId, 594 grant_type: 'authorization_code', 595 redirect_uri: getReturnUrl, 596 code: AuthCode, 597 client_id: getClientID, 598 p: 'B2C_1A_M1_BlueSky_CBP', 599 scope: getClientID, 600 offline_access: 'openid', 601 }, 602 'GET' 603 ) 604 .done(function (response) { 605 // Handle successful token response 606 console.log('Token Response:', response); 607 showLoader(false); 608 const decoded = parseJwt(response.access_token); 609 let data = { 610 emailID: $('#emailid').val(), 611 access_token: response.access_token, 612 customerId: decoded?.sub, 613 customerData: JSON.parse(JSON.stringify(decoded)), 614 }; 615 sessionStorage.setItem('customerInfo', JSON.stringify(data)); 616 console.log('decoded JWT', decoded); 617 console.log('data', data); 618 $('.login-with-email').hide(); 619 $('.otp-field').hide(); 620 $('.login-success').show(); 621 $('.before-login').hide(); 622 $('.after-login').show(); 623 $('.guest-banner').hide(); 624 $('.logged-in-banner').show();
625 let getDesc = $('.after-login .offers-popover-content').text(); 626 if (getDesc && getDesc.includes('{{totalVoucher}}')) { 627 $('.after-login .offers-popover-content').html( 628 getDesc.replaceAll('{{totalVoucher}}', `<span class="set-voucher-count">${$('.promo-voucher-list').length}</span>`) 629 ); 630 $('.set-voucher-count').text($('.promo-voucher-list').length); 631 } 632 }) 633 .fail(function (error) { 634 // Handle token error 635 console.error('Token Error:', error); 636 showLoader(false); 637 }); 638 } 639 640 $('.log-out').on('click', function () { 641 sessionStorage.removeItem('customerInfo'); 642 sessionStorage.removeItem('customerLogin'); 643 sessionStorage.removeItem('voucherCount'); 644 $('.after-login').hide(); 645 $('.guest-banner').show(); 646 $('.logged-in-banner').hide(); 647 $('#emailid').val(''); 648 $('#nricid').val(''); 649 $('.email-error').text(''); 650 $('.email-error-nric').text(''); 651 }); 652 653 function parseJwt(token) { 654 var base64Url = token.split('.')[1]; 655 var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/'); 656 var jsonPayload = decodeURIComponent( 657 atob(base64) 658 .split('') 659 .map(function (c) { 660 return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); 661 }) 662 .join('') 663 ); 664 665 return JSON.parse(jsonPayload); 666 } 667 668 function idHintTokenCall(emailResponse) { 669 console.log('emailResponse', emailResponse); 670 showLoader(true); 671 let data = { 672 emailID: $('#emailid').val(), 673 isSingPass: false, 674 }; 675 ajaxCall('/login/id-hint-token', data, 'POST') 676 .done(function (response) { 677 // Handle successful token response 678 console.log('Token Response:', response); 679 if (response) { 680 showLoader(false); 681 if (response && response?.error) { 682 if ( 683 response?.error?.errorCode === '400' || 684 response?.error?.errorCode === '404' 685 ) { 686 $('.email-error').text( 687 'Somthing went wrong. Please try again.' 688 ); 689 } 690 } 691 if (response?.token) { 692 // GET B2C call to get AuthCode 693 authorizeB2CLogin(response?.token); 694 } else { 695 $('.m1-id-not-found').show(); 696 $('.login-with-email').hide(); 697 } 698 } 699 }) 700 .fail(function (error) { 701 // Handle token error 702 console.error('Token Error:', error); 703 showLoader(false); 704 }); 705 } 706 707 // Fetch offer popup 708 $('.offers-button').on('click', function () { 709 $('.offersDropdown .dropdown-content').toggle(); 710 $('.offersDropdown .dropdown-icon').toggleClass('rotate-180'); 711 }); 712 713 $(document).on('click', '.offersDropdown .dropdown-content .item', function () { 714 $('.offersDropdown .dropdown-content').hide(); 715 $('.offersDropdown .dropdown-icon').removeClass('rotate-180'); 716 $('.offersDropdown .dropdown-customRadio').removeClass('dropdownActive'); 717 $('.offersDropdown .dropdown-customRadioInner').removeClass('dropdownActiveInner'); 718 $(this).find('.dropdown-customRadio').addClass('dropdownActive'); 719 $(this) 720 .find('.dropdown-customRadioInner') 721 .addClass('dropdownActiveInner'); 722 $('.selected-line').text($(this).find('.line-no').text()); 723 let getSACID = $(this).data('sac'); 724 retrieveUserOffers(getSACID); 725 }); 726 727 function retrieveAllLines() { 728 showLoader(true); 729 console.log('sessionStorage', sessionStorage.getItem('customerInfo')); 730 let getCustomerInfo = JSON.parse(sessionStorage.getItem('customerInfo')); 731 console.log('getCustomerInfo', getCustomerInfo); 732 $('.no-offer-found').hide(); 733 $('.selected-line').text('New Line'); 734 $('.dynamic-lines').empty(); 735 $('.offers-list .offers-list-data').empty(); 736 ajaxCall( 737 '/shoppingcart/offers/retrieve-all-lines?emailID=' + 738 getCustomerInfo?.emailID + 739 '&B2C_GUID=' + 740 getCustomerInfo?.customerId, 741 '', 742 'GET' 743 ) 744 .done(function (response) { 745 // Handle successful token response 746 console.log('retrieve-all-lines Response:', response); 747 showLoader(false); 748 if (response?.error) { 749 } else { 750 // Populate dropdown with lines 751 $('.custom-dropdown').data('id-number', response?.idNumber); 752 $('.custom-dropdown').data('id-type', response?.idType); 753 let linesHtml = ''; 754 let retrieveAllLinesApi = response; 755 let finalLines = []; 756 if ( 757 retrieveAllLinesApi && 758 retrieveAllLinesApi?.BANs && 759 retrieveAllLinesApi?.BANs.length > 0 && 760 retrieveAllLinesApi?.BANs[0]?.Lines && 761 retrieveAllLinesApi?.BANs[0]?.Lines.length > 0 762 ) { 763 retrieveAllLinesApi?.BANs.map((obj) => { 764 if (obj?.Lines && obj?.Lines.length > 0) {
765 obj.Lines.forEach(function (objjj) { 766 if ( 767 objjj.assetStatus === 'Active' && 768 objjj.provisioningStatus === 'Active' 769 ) { 770 finalLines.push(objjj); 771 } 772 }); 773 } 774 }); 775 } 776 if (finalLines?.length > 0) { 777 finalLines.forEach(function (line) { 778 let formattedLine = line.MSISDN.replace( 779 /(\d{4})(\d{4})/, 780 '$1 $2' 781 ); 782 linesHtml += `<div class="item flex flex-row items-center" data-sac="${line.SACId}" data-line="${line.MSISDN}"> 783 <div class="dropdown-customRadio"> 784 <div class="dropdown-customRadioInner"></div> 785 </div> 786 <span class="line-no">${formattedLine}</span> 787 </div>`; 788 }); 789 $('.dynamic-lines').html(linesHtml); 790 $('.selected-line').text( 791 finalLines[0]?.MSISDN?.replace(/(\d{4})(\d{4})/, '$1 $2') 792 ); 793 $( 794 '.dropdown-content .dynamic-lines .item:first .dropdown-customRadio' 795 ).addClass('dropdownActive'); 796 $( 797 '.dropdown-content .dynamic-lines .item:first .dropdown-customRadioInner' 798 ).addClass('dropdownActiveInner'); 799 retrieveUserOffers(finalLines[0]?.SACId); 800 } else { 801 $('.dropdown-content .new-line .dropdown-customRadio').addClass( 802 'dropdownActive' 803 ); 804 $( 805 '.dropdown-content .new-line .dropdown-customRadioInner' 806 ).addClass('dropdownActiveInner'); 807 $('.selected-line').text('New Line'); 808 retrieveUserOffers(); 809 } 810 } 811 }) 812 .fail(function (error) { 813 // Handle token error 814 console.error('Token Error:', error); 815 showLoader(false); 816 }); 817 } 818 819 function setSGTDateZone(date) { 820 const dateNew = new Date(date); 821 822 // Convert to UTC 823 const options = { timeZone: 'UTC' };
824 const utcDate = new Date(dateNew.toLocaleString('en-US', options)); 825 826 // Format date as "dd MMM yyyy" 827 const day = String(utcDate.getDate()).padStart(2, '0'); 828 const monthNames = [ 829 'Jan', 830 'Feb', 831 'Mar', 832 'Apr', 833 'May', 834 'Jun', 835 'Jul', 836 'Aug', 837 'Sep', 838 'Oct', 839 'Nov', 840 'Dec', 841 ]; 842 const month = monthNames[utcDate.getMonth()]; 843 const year = utcDate.getFullYear(); 844 845 const formattedDate = `${day} ${month} ${year}`; 846 847 console.log('datee==', formattedDate); 848 return formattedDate; 849 } 850 851 function retrieveUserOffers(sacId) { 852 showLoader(true); 853 let getCustomerInfo = JSON.parse(sessionStorage.getItem('customerInfo')); 854 console.log('getCustomerInfo', getCustomerInfo); 855 let getLoginInfo = JSON.parse(sessionStorage.getItem('customerLogin')); 856 console.log('getLoginInfo', getLoginInfo); 857 let data = { 858 userIds: [ 859 { 860 user_id: getLoginInfo.cac, 861 }, 862 { 863 user_id: sacId, 864 }, 865 ], 866 customerInfo: { 867 customerPriIdNo: $('.custom-dropdown').data('id-number'), 868 customerPriIdType: $('.custom-dropdown').data('id-type'), 869 customerId: getCustomerInfo?.customerId, 870 activeOffer: true, 871 planType: '', 872 orderType: '-', 873 }, 874 }; 875 if (!sacId) { 876 data.userIds.pop(); // Remove the second user_id if sacId is not provided 877 } 878 console.log('data', data); 879 ajaxCall('/customer/offers/retrieve-user-offers', data, 'POST') 880 .done(function (response) { 881 // Handle success 882 console.log('Success:', response); 883 if (response) { 884 if (response?.error?.errorCode) { 885 } else { 886 const voucherArr = response; 887 let voucherCount = 0; 888 let offersHtml = ''; 889 if ( 890 voucherArr && 891 voucherArr.offerResponse && 892 voucherArr.offerResponse.length > 0 893 ) { 894 voucherArr.offerResponse.forEach(function (offer) { 895 console.log('offerResponse offer', offer); 896 let offerDate = setSGTDateZone(offer.redemption_end_date); 897 offersHtml += `<div class="py-24 promo-voucher-list list-none relative w-full border-b border-neutral-gray" data-offer-title="${offer.title}" data-offer-date="${offerDate}" data-offer-description="${offer.description}"> 898 <div class="w-6 h-6"> 899 <svg class="fill-current w-6 h-6 text-primary-orange" fill="" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> 900 <path 901 fill-rule="evenodd" 902 clip-rule="evenodd" 903 d="M17.016 8.085c.478.28.807.609 1.004 1.004v.008c.675 1.201.222 2.748-1.004 3.43-.395.23-.584.708-.436 1.11l.033.149a2.245 2.245 0 0 1 0 1.538 2.487 2.487 0 0 1-3.151 1.604l-.132-.033a.908.908 0 0 0-1.12.428c-.279.477-.608.806-1.003 1.004-.378.214-.79.312-1.201.312-.889 0-1.761-.477-2.23-1.316-.23-.395-.708-.584-1.11-.436l-.149.033a2.248 2.248 0 0 1-1.539 0 2.48 2.48 0 0 1-1.604-3.15l.033-.132a.907.907 0 0 0-.428-1.119c-.477-.28-.807-.609-1.004-1.003a2.505 2.505 0 0 1-.206-1.917c.19-.65.617-1.185 1.21-1.514.395-.23.584-.707.436-1.11l-.033-.148a2.247 2.247 0 0 1 0-1.539 2.48 2.48 0 0 1 3.151-1.604l.132.033a.908.908 0 0 0 1.12-.427c.279-.478.608-.807 1.003-1.004 1.21-.675 2.748-.222 3.431.995.23.395.708.584 1.111.436l.148-.033a2.248 2.248 0 0 1 1.539 0 2.48 2.48 0 0 1 1.604 3.15l-.033.14a.9.9 0 0 0 .428 1.111Zm-.749 3.052c.198-.098.305-.214.363-.386h-.017a.937.937 0 0 0 .09-.724.909.909 0 0 0-.452-.56 2.53 2.53 0 0 1-1.185-2.97l.041-.082a.748.748 0 0 0 0-.534.939.939 0 0 0-1.176-.625l-.14.032a2.515 2.515 0 0 1-2.962-1.217 1.063 1.063 0 0 0-.37-.37.898.898 0 0 0-.7-.082.91.91 0 0 0-.56.452 2.532 2.532 0 0 1-2.97 1.185l-.132-.033a.818.818 0 0 0-.56 0 .942.942 0 0 0-.617 1.176l.034.14A2.534 2.534 0 0 1 3.769 9.5c-.148.099-.28.222-.37.379a.922.922 0 0 0 .37 1.266 2.53 2.53 0 0 1 1.185 2.97l-.033.107a.794.794 0 0 0 0 .551.942.942 0 0 0 1.177.617l.14-.033c.246-.074.501-.107.748-.107.946 0 1.794.51 2.222 1.325.09.148.214.28.37.37.206.123.46.148.7.082a.909.909 0 0 0 .559-.452 2.532 2.532 0 0 1 2.97-1.185l.132.033c.19.066.37.066.56 0a.94.94 0 0 0 .617-1.176l-.033-.14a2.46 2.46 0 0 1 1.184-2.97ZM11.322 8.03c.3-.299.76-.299 1.06 0l-.014.008c.3.299.3.758
9030 1.057l-3.635 3.626a.256.256 0 0 1-.08.08l-.015.015a.76.76 0 0 1-1.053-.08.743.743 0 0 1-.176-.54.768.768 0 0 1 .256-.518l3.657-3.648Zm.9 2.739c-.636 0-1.111.475-1.111 1.111s.475 1.111 1.111 1.111 1.111-.49 1.111-1.11c0-.622-.49-1.112-1.11-1.112ZM7.778 7.806c.62 0 1.11.49 1.11 1.111 0 .62-.474 1.111-1.11 1.111a1.084 1.084 0 0 1-1.111-1.11c0-.637.49-1.112 1.11-1.112Z" 904 fill="" 905 ></path> 906 </svg> 907 </div> 908 <div class="promo-voucher-action w-full"> 909 <div class="flex flex-col"> 910 <div class="inline-block items-center"><span class="text-16 font-dinBold">${offer.title}</span></div> 911 <div class="text-12 flex items-center align-middle gap-x-2 text-primary-black"><span class="py-16 leading-none">Valid till: ${offerDate}</span></div> 912 </div> 913 <div class="show-offer-detail"> 914 <svg class="fill-current mt-1 w-5 h-5 fill-current cursor-pointer text-primary-orange" fill="" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> 915 <g id="chevron"> 916 <path 917 id="glyph" 918 fill-rule="evenodd" 919 clip-rule="evenodd" 920 d="M8.12001 2.33L16.88 11.19C17.32 11.63 17.32 12.35 16.88 12.8L8.12001 21.67C7.68001 22.11 6.97001 22.11 6.53001 21.67C6.09001 21.23 6.09001 20.51 6.53001 20.06L14.49 12L6.53001 3.94C6.09001 3.5 6.09001 2.78 6.53001 2.33C6.97001 1.89 7.68001 1.89 8.12001 2.33Z" 921 fill="" 922 stroke="" 923 stroke-width="0" 924 ></path> 925 </g> 926 </svg> 927 </div> 928 </div> 929 </div>`; 930 }); 931 } 932 if ( 933 voucherArr && 934 voucherArr.voucherResponse && 935 voucherArr.voucherResponse.length > 0 936 ) { 937 voucherArr.voucherResponse.forEach(function (offer) { 938 console.log('voucherResponse offer', offer); 939 let getDesc = 'Applicable on Early Re-contract Fee &/or upfront device payment for Bespoke Contract. Unused voucher value will be forfeited.'; 940 if (offer.offerName.toLowerCase().includes('early')) { 941 getDesc = 'Get $250 Early Re-contract Fee waiver with $59.95 Bespoke Contract Plan. Or up to $350 Early Re-contract Fee waiver with $75.95 & above Bespoke Contract Plan.' 942 } 943 offersHtml += `<div class="py-24 promo-voucher-list list-none relative w-full border-b border-neutral-gray" data-offer-title="${offer.offerName 944 }" data-offer-date="${offer.offerEndDate 945 }" data-offer-description="${getDesc}"> 946 <div class="w-6 h-6"> 947 <svg class="fill-current w-6 h-6 text-primary-orange" fill="" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> 948 <path 949 fill-rule="evenodd" 950 clip-rule="evenodd" 951 d="M22 10.04C21.89 10.01 21.76 10 21.64 10C20.54 10 19.64 10.9 19.64 12C19.64 13.1 20.54 14 21.64 14C21.76 14 21.88 13.98 22 13.96V19C22 20.1 21.1 21 20 21H4C2.9 21 2 20.1 2 19V13.96C2.11 13.99 2.24 14 2.36 14C3.46 14 4.36 13.1 4.36 12C4.36 10.9 3.46 10 2.36 10C2.24 10 2.12 10.02 2 10.04V5C2 3.9 2.9 3 4 3H20C21.1 3 22 3.9 22 5V10.04ZM17.64 12C17.64 10.38 18.61 8.98 20 8.35V5.5C20 5.22 19.78 5 19.5 5H4.5C4.22 5 4 5.22 4 5.5V8.35C5.39 8.98 6.36 10.38 6.36 12C6.36 13.62 5.39 15.02 4 15.65V18.5C4 18.78 4.22 19 4.5 19H19.5C19.78 19 20 18.78 20 18.5V15.65C18.61 15.02 17.64 13.62 17.64 12ZM15.6473 8.21541C1
9515.2568 7.82488 14.6236 7.82488 14.2331 8.21541L8.20485 14.2436C7.81432 14.6342 7.81432 15.2673 8.20485 15.6579L8.2968 15.7498C8.68732 16.1403 9.32049 16.1403 9.71101 15.7498L15.7392 9.72157C16.1298 9.33105 16.1298 8.69788 15.7392 8.30736L15.6473 8.21541ZM10.04 9.53003C10.04 10.3585 9.36847 11.03 8.54004 11.03C7.71161 11.03 7.04004 10.3585 7.04004 9.53003C7.04004 8.7016 7.71161 8.03003 8.54004 8.03003C9.36847 8.03003 10.04 8.7016 10.04 9.53003ZM15.46 15.97C16.2884 15.97 16.96 15.2984 16.96 14.47C16.96 13.6415 16.2884 12.97 15.46 12.97C14.6315 12.97 13.96 13.6415 13.96 14.47C13.96 15.2984 14.6315 15.97 15.46 15.97Z" 952 fill="" 953 ></path> 954 </svg> 955 </div> 956 <div class="promo-voucher-action w-full"> 957 <div class="flex flex-col"> 958 <div class="inline-block items-center"><span class="text-16 font-dinBold">${offer.offerName 959 }</span></div> 960 <div class="text-12 flex items-center align-middle gap-x-2 text-primary-black"><span class="py-16 leading-none">Valid till: ${offer.offerEndDate?.replaceAll( 961 '-', 962 ' ' 963 )}</span></div> 964 </div> 965 <div class="show-offer-detail"> 966 <svg class="fill-current mt-1 w-5 h-5 fill-current cursor-pointer text-primary-orange" fill="" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> 967 <g id="chevron"> 968 <path 969 id="glyph" 970 fill-rule="evenodd" 971 clip-rule="evenodd" 972 d="M8.12001 2.33L16.88 11.19C17.32 11.63 17.32 12.35 16.88 12.8L8.12001 21.67C7.68001 22.11 6.97001 22.11 6.53001 21.67C6.09001 21.23 6.09001 20.51 6.53001 20.06L14.49 12L6.53001 3.94C6.09001 3.5 6.09001 2.78 6.53001 2.33C6.97001 1.89 7.68001 1.89 8.12001 2.33Z" 973 fill="" 974 stroke="" 975 stroke-width="0" 976 ></path> 977 </g> 978 </svg> 979 </div> 980 </div> 981 </div>`; 982 }); 983 } 984 $('.offers-list .offers-list-data').html(offersHtml); 985 if ($('.promo-voucher-list').length > 0) { 986 voucherCount = $('.promo-voucher-list').length; 987 } 988 sessionStorage.setItem('voucherCount', voucherCount); 989 let getDesc = $('.after-login .offers-popover-content').text(); 990 if (getDesc && getDesc.includes('{{totalVoucher}}')) { 991 $('.after-login .offers-popover-content').html( 992 getDesc.replaceAll('{{totalVoucher}}', `<span class="set-voucher-count">${voucherCount}</span>`) 993 ); 994 } 995 $('.set-voucher-count').text($('.promo-voucher-list').length); 996 $('.offers-list .promo-voucher-list').each(function (element) { 997 let getDate = $(this).data('validate-date'); 998 if (getDate) { 999 let offerDate = setSGTDateZone(getDate); 1000 $(this) 1001 .find('.promo-voucher-action .offer-date') 1002 .text(`Valid till: ${offerDate}`); 1003 } 1004 }); 1005 } 1006 showLoader(false); 1007 } 1008 }) 1009 .fail(function (error) { 1010 // Handle error 1011 showLoader(false); 1012 $('.offers-list .offers-list-data').empty(); 1013 $('.no-offer-found').css('display', 'flex'); 1014 console.error('Error:', error); 1015 }); 1016 } 1017 1018 const urlMappings = window.OFFER_URL_MAPPINGS || []; 1019 1020 let matchedCTA = null; 1021 1022 const findMatchingCTA = (input, ctaData = []) => { 1023 if (!input || !Array.isArray(ctaData) || ctaData.length === 0) 1024 return null; 1025 1026 const normalizedInput = String(input).toLowerCase().replace(/\s+/g, ''); 1027 1028 return ( 1029 ctaData.find((item) => { 1030 if (!item?.keyword) return false;
1031 1032 const parts = item.keyword 1033 .split('&&') 1034 .map((k) => k.trim()) 1035 .filter(Boolean); 1036 1037 return parts.every((part) => { 1038 const normalizedKeyword = part.toLowerCase().replace(/\s+/g, ''); 1039 return normalizedInput.includes(normalizedKeyword); 1040 }); 1041 }) || null 1042 ); 1043 }; 1044 1045 $(document).on('click', '.show-offer-detail', function () { 1046 let getDesc = $(this) 1047 .closest('.promo-voucher-list') 1048 .data('offer-description'); 1049 matchedCTA = findMatchingCTA(getDesc, urlMappings || []); 1050 1051 if (!matchedCTA) { 1052 $('.offer-redirect').text('Close'); 1053 } else { 1054 $('.offer-redirect').text(matchedCTA.ctaLabel || 'Go there'); 1055 } 1056 1057 $('#offer-section').hide(); 1058 $('.offer-detail-title').text( 1059 $(this).closest('.promo-voucher-list').data('offer-title') 1060 ); 1061 $('.offer-detail-description li').text( 1062 $(this).closest('.promo-voucher-list').data('offer-description') 1063 ); 1064 $('.offer-detail-date').text( 1065 $(this).closest('.promo-voucher-list').data('offer-date') 1066 ); 1067 $('.offer-details-container').show(); 1068 }); 1069 1070 $('.offer-action-reset').on('click', function () { 1071 new bootstrap.Modal($('#fetch-offer-popup')).hide(); 1072 $('.offer-details-container').hide(); 1073 $('#offer-section').show(); 1074 $('.offers-list .offers-list-data').empty(); 1075 $('.offersDropdown .dropdown-content').hide(); 1076 }); 1077 1078 $('.close-offer-details').on('click', function () { 1079 $('.offer-details-container').hide(); 1080 $('#offer-section').show(); 1081 }); 1082 1083 $('.see-offers').on('click', function () { 1084 new bootstrap.Modal($('#fetch-offer-popup')).show(); 1085 $('.react-popover').fadeOut(); 1086 retrieveAllLines(); 1087 }); 1088 1089 $('.reload-offer').on('click', function () { 1090 retrieveAllLines(); 1091 }); 1092 1093 $('.offer-redirect').on('click', function () { 1094 console.log('matchedCTA', matchedCTA); 1095 if (!matchedCTA) { 1096 $('.offer-details-container').hide(); 1097 $('#offer-section').show(); 1098 return; 1099 } 1100 window.location.href = matchedCTA.ctaURL; 1101 }); 1102 1103 $('.login-success-action').on('click', function () { 1104 $('.login-action-reset').click(); 1105 new bootstrap.Modal($('#fetch-offer-popup')).show(); 1106 retrieveAllLines(); 1107 }); 1108 1109 // Man Icon Changes End -WEB-9619 1110 }); 1111})(jQuery);
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.