PageSourceSearch

https://www.americaneagle.ae/scripts/aura-utils/aura-utils.js

js americaneagle.ae collected 2026-10-02 13:26:07 UTC 9,278 bytes, 258 lines download raw bytes

1import { getConfigValue, getCountryIso } from '../configs.js';
2import { closeModal } from '../utils.js';
3import { fetchPlaceholdersForLocale } from '../scripts.js';
4import { loginMobile, sendOtpApiCall, getAuraLinkingDetails } from '../aura/api.js';
5import {
6  validateInput, setErrorMessageForField, showErrorMessage, validatePhone,
7  resetMessage,
8} from '../forms.js';
9import debounce from '../helpers/debounce.js';
10import { loadCSS } from '../aem.js';
11
12const placeholders = await fetchPlaceholdersForLocale();
13let timerInterval;
14
15export function addFormValidation(form) {
16  form.querySelectorAll('input').forEach((input) => {
17    setErrorMessageForField(input, placeholders);
18    const button = form.querySelector('button') || form.closest('.contact-method').querySelector('button');
19    input.addEventListener('input', () => {
20      if (!validateInput(input)) {
21        button.disabled = true;
22      } else {
23        button.disabled = false;
24      }
25    });
26  });
27}
28
29export function debouncedFormValidation(form) {
30  const button = form.querySelector('button') || form.closest('.contact-method').querySelector('button');
31  form.querySelectorAll('input').forEach((input) => {
32    setErrorMessageForField(input, placeholders);
33    input.addEventListener('input', () => {
34      debounce(() => {
35        resetMessage(input);
36        button.disabled = false;
37      }, 300)();
38    });
39
40    input.addEventListener('blur', () => {
41      if (!validateInput(input)) {
42        button.disabled = true;
43      }
44    });
45  });
46}
47
48export function nextStage(joinAura) {
49  const curr = joinAura.querySelector('.show');
50  curr.nextElementSibling.classList.add('show');
51  curr.classList.remove('show');
52}
53
54export function prevStage(joinAura) {
55  const curr = joinAura.querySelector('.show');
56  curr.previousElementSibling.classList.add('show');
57  curr.classList.remove('show');
58}
59
60export async function addResendListener(otpContainer, mobileForm) {
61  const resendLinkEvent = otpContainer.querySelector('.otp-info-text a');
62  const mobile = mobileForm.querySelector('#login-mobile').value;
63  const countrycode = await getConfigValue('country-code');
64  const countryPrefix = `${await getCountryIso(countrycode)}`;
65  resendLinkEvent.addEventListener('click', async (event) => {
66    let response;
67    event.preventDefault();
68    const auraLinkingDetails = getAuraLinkingDetails();
69    if (auraLinkingDetails) {
70      const { type, value, countryIsoAdded } = auraLinkingDetails;
71      if (type !== null && value !== null) {
72        response = await sendOtpApiCall('', type, value, countryIsoAdded);
73      } else {
74        response = await loginMobile(mobile, countryPrefix);
75      }
76      if (response === true) {
77        // eslint-disable-next-line no-use-before-define
78        startResendOtpTimer(otpContainer, mobileForm);
79      } else {
80        const inputFieldWrapper = otpContainer.querySelector('.input-field-wrapper');
81        otpContainer.querySelector('.otp-info-text a').classList.add('inactive');
82        const errorMessage = response.parameters?.length > 0 ? response?.parameters[0] : 'Maximum number of attempts reached. Please try after sometime.';
83        showErrorMessage(inputFieldWrapper, errorMessage);
84      }
85    }
86  });
87}
88
89function startResendOtpTimer(otpContainer, mobileForm) {
90  const successMessageDiv = otpContainer.querySelector('.otp-success-message');
91  const resendLink = otpContainer.querySelector('.otp-info-text p');
92  const originalText = resendLink.innerHTML;
93  let timeRemaining = 60;
94  resendLink.textContent = `${placeholders.resending}` || 'Resending';
95  successMessageDiv.classList.remove('hide-message');
96  setTimeout(() => {
97    successMessageDiv.classList.add('hide-message');
98  }, 5000);
99  timerInterval = setInterval(() => {
100    resendLink.classList.add('disabled');
101    if (timeRemaining > 0) {
102      timeRemaining -= 1;
103      const seconds = timeRemaining < 10 ? `0${timeRemaining}` : timeRemaining;
104      resendLink.textContent = `${placeholders.resendIn || 'Resend In'} 00:${seconds}s`;
105    } else {
106      clearInterval(timerInterval);
107      resendLink.classList.remove('disabled');
108      resendLink.innerHTML = originalText;
109      addResendListener(otpContainer, mobileForm);
110    }
111  }, 1000);
112}
113
114export function resetOtp(otpContainer, defaultOtpResendText, mobileForm) {
115  const resendText = otpContainer.querySelector('.otp-info-text p');
116  const otpInput = otpContainer.querySelector('.aura-otp-form input');
117  resendText.innerHTML = defaultOtpResendText;
118  if (otpInput) {
119    otpInput.value = '';
120  }
121  clearInterval(timerInterval);
122  addResendListener(otpContainer, mobileForm);
123}
124
125export async function phonenumberValidation(mobileForm) {
126  const phoneInput = mobileForm.querySelector('#login-mobile');
127  phoneInput.addEventListener('input', async (event) => {
128    event.target.value = event.target.value.replace(/[^0-9]/g, '');
129    const countryName = await getConfigValue('country-code');
130    const mobile = phoneInput.value;
131    if (mobile === '') {
132      const inputFieldWrapper = mobileForm.querySelector('.input-field-wrapper');
133      const errorMessage = placeholders.noMobileMessage || 'Please enter Mobile Number';
134      showErrorMessage(inputFieldWrapper, errorMessage);
135      return;
136    }
137    if (event.target.value.length >= phoneInput.maxLength) {
138      const isValidPhoneNumber = await validatePhone(
139        phoneInput.value,
140        countryName,
141      );
142      let phoneErrorMessage = placeholders.invalidMobileNumber || `The number provided ${phoneInput.value} is not a valid mobile number.`;
143      phoneErrorMessage = phoneErrorMessage.replace('{{mobile}}', phoneInput.value);
144
145      if (!isValidPhoneNumber) {
146        showErrorMessage(phoneInput, phoneErrorMessage);
147        mobileForm.querySelector('.aura-buttons button').disabled = true;
148      } else {
149        mobileForm.querySelector('.aura-buttons button').disabled = false;
150      }
151    }
152  });
153}
154
155export async function phonenumberBlurValidation(mobileForm) {
156  const phoneInput = mobileForm.querySelector('#login-mobile');
157  const button = mobileForm.querySelector('.aura-buttons button');
158  const countryName = await getConfigValue('country-code');
159  setErrorMessageForField(phoneInput, placeholders);
160
161  phoneInput.addEventListener('blur', async () => {
162    if (!validateInput(phoneInput)) {
163      button.disabled = true;
164    } else {
165      button.disabled = false;
166    }
167    if (phoneInput.value.length >= phoneInput.maxLength) {
168      const isValidPhoneNumber = await validatePhone(
169        phoneInput.value,
170        countryName,
171      );
172      let phoneErrorMessage = placeholders.invalidMobileNumber || `The number provided ${phoneInput.value} is not a valid mobile number.`;
173      phoneErrorMessage = phoneErrorMessage.replace('{{mobile}}', phoneInput.value);
174
175      if (!isValidPhoneNumber) {
176        showErrorMessage(phoneInput, phoneErrorMessage);
177        button.disabled = true;
178      } else {
179        button.disabled = false;
180      }
181    }
182  });
183
184  phoneInput.addEventListener('input', () => {
185    resetMessage(phoneInput);
186    button.disabled = false;
187  });
188
189  phoneInput.addEventListener('keydown', (e) => {
190    if (e.ctrlKey || e.metaKey) {
191      return;
192    }
193    if (e.key.length === 1 && !/[\d]/.test(e.key)) {
194      e.preventDefault();
195    }
196  });
197}
198
199export function submitOnEnter(forms) {
200  forms.forEach((form) => {
201    form.addEventListener('keydown', (event) => {
202      if (event.key === 'Enter') {
203        event.preventDefault();
204        const inputs = form.querySelectorAll('input');
205        inputs.forEach((input) => {
206          if (input.value) {
207            input.dispatchEvent(new Event('blur', { cancelable: true, bubbles: true }));
208          }
209        });
210        if (!form.querySelector('button').disabled) {
211          form.dispatchEvent(new Event('submit', { cancelable: true, bubbles: true }));
212        }
213      }
214    });
215  });
216}
217
218export function auraModalRedirection(congratsForm, dialogName, redirectName, reDecorate) {
219  congratsForm.addEventListener('click', async (event) => {
220    event.preventDefault();
221    const lang = document.documentElement.lang || 'en';
222    const redirectLink = await getConfigValue(redirectName);
223    closeModal(dialogName);
224    // For join-aura / link-aura remove the generic overlay once the modal is closed.
225    const genericOverlay = document.querySelector('.generic-overlay-background');
226    if (genericOverlay?.classList.contains('show')) {
227      genericOverlay?.classList.remove('show');
228    }
229    if (dialogName === 'link-your-aura-dialog') {
230      window.dispatchEvent(new CustomEvent('linkAuraSuccess'));
231    }
232
233    if (reDecorate) {
234      reDecorate();
235    }
236
237    if (redirectLink && redirectLink !== '') {
238      window.location.href = `/${lang}${redirectLink}`;
239    }
240  });
241}
242
243export async function loadAuraAutoEnrollmentCss() {
244  document.body.classList.add('aura-auto-enrollment');
245  const cssFiles = [
246    { base: '/styles/', file: 'aura-auto-enrollment.css' },
247  ];
248  const { getBrandPath } = await import('../scripts.js');
249  const brandPath = getBrandPath();
250  const excluded = ['ult'];
251  if (excluded.includes(brandPath)) {
252    return;
253  }
254  cssFiles.forEach(({ base, file }) => {
255    const brandSpecificPath = `${base}${brandPath}${file}`;
256    loadCSS(brandSpecificPath);
257  });
258}

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.