483 lines
16 KiB
JavaScript
483 lines
16 KiB
JavaScript
function validateEmailSendOTP() {
|
|
var emailInput = $('#email');
|
|
var btnSendOTP = $('#sendOTP');
|
|
var otpInput = $('#Otp');
|
|
var modal = $('#sendOTPModal');
|
|
|
|
const emailInputed = document.getElementById('email');
|
|
|
|
emailInputed.addEventListener('input', removeErrorClass);
|
|
|
|
function removeErrorClass() {
|
|
if (this.value.trim() !== '') {
|
|
this.classList.remove('error-input');
|
|
}
|
|
}
|
|
|
|
const email = emailInputed.value;
|
|
if (!email) {
|
|
showToast('warning', 'Please fill the required field!', 'failed!', 4000);
|
|
emailInputed.classList.add('error-input');
|
|
return;
|
|
} else if (!/^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/.test(email)) {
|
|
showToast('warning', 'Invalid email address, please double-check!', 'failed!', 4000);
|
|
return;
|
|
}
|
|
|
|
// Create the overlay div element
|
|
var overlay = $('<div id="overlay" class="overlay"></div>');
|
|
|
|
// Create the loader spinner element
|
|
var loader = $('<div id="loader" class="loader"></div>');
|
|
|
|
// Append the overlay and loader to the modal
|
|
modal.append(overlay);
|
|
modal.append(loader);
|
|
|
|
$.ajax({
|
|
url: endpoint.SendOTPByEmail,
|
|
type: 'POST',
|
|
data: { email },
|
|
beforeSend: function () {
|
|
overlay.show();
|
|
loader.show();
|
|
},
|
|
complete: function () {
|
|
overlay.hide();
|
|
loader.hide();
|
|
},
|
|
success: function (response) {
|
|
if (response.success) {
|
|
$('#btnSendOTP').prop('disabled', false);
|
|
|
|
emailInput.prop('readonly', true);
|
|
otpInput.prop('readonly', false);
|
|
$('#sendOTP').prop('disabled', true);
|
|
// Set the countdown duration in seconds (3 minutes = 180 seconds)
|
|
var countdownDuration = 180;
|
|
var countdownInterval = setInterval(function () {
|
|
btnSendOTP.text('Resend OTP (' + countdownDuration + 's)');
|
|
countdownDuration--;
|
|
if (countdownDuration < 0) {
|
|
$('#sendOTP').prop('disabled', false);
|
|
btnSendOTP.text('Resend OTP');
|
|
clearInterval(countdownInterval);
|
|
}
|
|
}, 1000);
|
|
showToast('success', "Success!: Please check your email to get the OTP code", 'success!', 4000);
|
|
} else {
|
|
showToast('warning', 'Email is not valid, please double-check!', 'failed!', 4000);
|
|
}
|
|
},
|
|
error: function (xhr, error, thrown) {
|
|
console.log('Error:', error);
|
|
console.log('Details:', thrown);
|
|
console.log('xhr Details:', xhr);
|
|
showToast('warning', 'Email is not valid, please double-check!', 'failed!', 4000);
|
|
// Hide the overlay and loader manually in case of an error
|
|
overlay.hide();
|
|
loader.hide();
|
|
}
|
|
});
|
|
}
|
|
function clearElements() {
|
|
document.getElementById("NewPassword").value = "";
|
|
document.getElementById("emailForgotPassword").value = "";
|
|
document.getElementById("ConfirmPassword").value = "";
|
|
document.getElementById("sendOTP").value = "";
|
|
document.getElementById("email").value = "";
|
|
}
|
|
function validateOTP() {
|
|
var loader = $('#overlay, #loader');
|
|
|
|
const email = document.getElementById('email').value;
|
|
var emailInput = document.getElementById("emailForgotPassword");
|
|
|
|
const otpInput = document.getElementById('Otp');
|
|
|
|
otpInput.addEventListener('input', function () {
|
|
if (otpInput.value.trim() !== '') {
|
|
otpInput.classList.remove('error-input');
|
|
}
|
|
});
|
|
|
|
const otp = otpInput.value;
|
|
|
|
if (!otp) {
|
|
showToast('warning', 'Please fill the required field!', 'failed!', 4000);
|
|
otpInput.classList.add('error-input');
|
|
return;
|
|
} else if (otp.length !== 8) {
|
|
showToast('warning', 'OTP is invalid, please double-check!', 'OTP failed!', 4000);
|
|
return;
|
|
}
|
|
$.ajax({
|
|
url: endpoint.ValidateOTP,
|
|
type: 'POST',
|
|
data: { email, otp },
|
|
beforeSend: function () {
|
|
loader.show();
|
|
},
|
|
complete: function () {
|
|
loader.hide();
|
|
},
|
|
success: function (response) {
|
|
if (response.success) {
|
|
$('#sendOTPModal').modal('hide');
|
|
$('#forgotPasswordModal').modal('show');
|
|
emailInput.value = email;
|
|
} else {
|
|
showToast('error', 'Email or OTP is invalid, please double-check!', 'OTP failed!', 4000);
|
|
}
|
|
},
|
|
error: function (xhr, error, thrown) {
|
|
console.log('Error:', error);
|
|
console.log('Details:', thrown);
|
|
console.log('xhr Details:', xhr);
|
|
showToast('error', 'Email or OTP is invalid, please double-check!', 'OTP failed!', 4000);
|
|
}
|
|
});
|
|
}
|
|
function refreshCaptcha() {
|
|
const captchaImage = document.getElementById('captchaImage');
|
|
captchaImage.src = `/Home/GetCaptcha?ts=${new Date().getTime()}`; // Cache-busting query
|
|
}
|
|
|
|
// Password visibility toggle
|
|
function togglePasswordVisibility() {
|
|
const input = document.getElementById('PasswordLogin');
|
|
const icon = document.getElementById('togglePassword');
|
|
const isHidden = input.type === 'password';
|
|
input.type = isHidden ? 'text' : 'password';
|
|
icon.classList.toggle('fa-eye', !isHidden);
|
|
icon.classList.toggle('fa-eye-slash', isHidden);
|
|
icon.style.color = isHidden ? '#00897b' : '#9ca3af';
|
|
}
|
|
|
|
// Call this at the START of your login() function
|
|
function setLoginLoading(loading) {
|
|
const btn = document.getElementById('BtnLogin');
|
|
const icon = document.getElementById('btnIcon');
|
|
const text = document.getElementById('btnText');
|
|
|
|
if (loading) {
|
|
btn.disabled = true;
|
|
icon.className = ''; // remove fa classes
|
|
icon.innerHTML = '<span class="lp-spinner"></span>';
|
|
text.textContent = 'Signing in...';
|
|
} else {
|
|
btn.disabled = false;
|
|
icon.innerHTML = '';
|
|
icon.className = 'fas fa-sign-in-alt';
|
|
icon.style.marginRight = '8px';
|
|
text.textContent = 'Sign In';
|
|
}
|
|
}
|
|
function validateCaptCha(captchaCode) {
|
|
return new Promise((resolve, reject) => {
|
|
var loader = $('#overlay, #loader');
|
|
$.ajax({
|
|
url: endpoint.ValidateCaptcha,
|
|
type: 'POST',
|
|
data: { captchaCode },
|
|
beforeSend: function () {
|
|
loader.show();
|
|
},
|
|
complete: function () {
|
|
loader.hide();
|
|
},
|
|
success: function (response) {
|
|
if (response.success) {
|
|
resolve(true);
|
|
} else {
|
|
showToast('error', 'Invalid CAPTCHA. Please try again!','Login failed!',4000);
|
|
reject(false);
|
|
setLoginLoading(false);
|
|
}
|
|
},
|
|
error: errorHandler
|
|
});
|
|
});
|
|
}
|
|
// Function to remove error styling
|
|
function removeErrClass(event) {
|
|
const input = event.target;
|
|
const wrapper = input.closest('.login-input-wrapper');
|
|
|
|
// Remove error class from input
|
|
input.classList.remove('error-input');
|
|
|
|
// Remove error class from wrapper (for icon styling)
|
|
if (wrapper) {
|
|
wrapper.classList.remove('error');
|
|
}
|
|
|
|
// Remove any error messages (optional)
|
|
const errorMessage = wrapper?.nextElementSibling;
|
|
if (errorMessage && errorMessage.classList.contains('login-error-message')) {
|
|
errorMessage.remove();
|
|
}
|
|
}
|
|
|
|
// Function to add error styling
|
|
function addErrorClass(input, message = '') {
|
|
const wrapper = input.closest('.login-input-wrapper');
|
|
|
|
// Add error class to input
|
|
input.classList.add('error-input');
|
|
|
|
// Add error class to wrapper (for icon styling)
|
|
if (wrapper) {
|
|
wrapper.classList.add('error');
|
|
}
|
|
|
|
// Optional: Add error message
|
|
if (message && wrapper) {
|
|
// Remove existing error message first
|
|
const existingError = wrapper.nextElementSibling;
|
|
if (existingError && existingError.classList.contains('login-error-message')) {
|
|
existingError.remove();
|
|
}
|
|
|
|
// Create and insert new error message
|
|
const errorDiv = document.createElement('div');
|
|
errorDiv.className = 'login-error-message';
|
|
errorDiv.innerHTML = `<i class="fas fa-exclamation-circle"></i> ${message}`;
|
|
wrapper.parentNode.insertBefore(errorDiv, wrapper.nextSibling);
|
|
}
|
|
}
|
|
|
|
function login() {
|
|
var loader = $('#overlay, #loader').css('z-index', 1090);
|
|
setLoginLoading(true);
|
|
|
|
const userNameInput = document.getElementById('UserNameLogin');
|
|
const passwordInput = document.getElementById('PasswordLogin');
|
|
const captchaCodeInput = document.getElementById('captchaCode');
|
|
|
|
// Clear any existing errors first
|
|
removeErrClass({ target: userNameInput });
|
|
removeErrClass({ target: passwordInput });
|
|
removeErrClass({ target: captchaCodeInput });
|
|
|
|
// Add event listeners for real-time error removal
|
|
userNameInput.addEventListener('input', removeErrClass);
|
|
passwordInput.addEventListener('input', removeErrClass);
|
|
captchaCodeInput.addEventListener('input', removeErrClass);
|
|
|
|
const captchaCode = captchaCodeInput.value.trim();
|
|
const UserName = userNameInput.value.trim();
|
|
const Password = passwordInput.value.trim();
|
|
|
|
let hasErrors = false;
|
|
|
|
// Validate each field and add appropriate error styling
|
|
if (!UserName) {
|
|
addErrorClass(userNameInput, 'Username is required');
|
|
hasErrors = true;
|
|
setLoginLoading(false);
|
|
}
|
|
|
|
if (!Password) {
|
|
addErrorClass(passwordInput, 'Password is required');
|
|
hasErrors = true;
|
|
setLoginLoading(false);
|
|
}
|
|
|
|
if (!captchaCode) {
|
|
addErrorClass(captchaCodeInput, 'Security verification is required');
|
|
hasErrors = true;
|
|
setLoginLoading(false);
|
|
}
|
|
|
|
// If there are validation errors, show toast and return
|
|
if (hasErrors) {
|
|
showToast('warning', 'Please fill all required fields!', 'Login failed!', 4000);
|
|
setLoginLoading(false);
|
|
// Focus on the first error field
|
|
if (!UserName) {
|
|
userNameInput.focus();
|
|
} else if (!Password) {
|
|
passwordInput.focus();
|
|
} else if (!captchaCode) {
|
|
captchaCodeInput.focus();
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Proceed with validation and login
|
|
validateCaptCha(captchaCode)
|
|
.then(() => {
|
|
$.ajax({
|
|
url: endpoint.Login,
|
|
type: 'POST',
|
|
data: { UserName, Password },
|
|
beforeSend: function () {
|
|
loader.show();
|
|
},
|
|
complete: function () {
|
|
loader.hide();
|
|
},
|
|
success: function (response) {
|
|
|
|
let parsedMessage = null;
|
|
|
|
if (response && response.responseMessage) {
|
|
try {
|
|
parsedMessage = JSON.parse(response.responseMessage);
|
|
} catch (e) {
|
|
console.error("Failed to parse responseMessage", e);
|
|
}
|
|
}
|
|
|
|
if (response && response.success === true) {
|
|
window.location.href = '/' + response.responseController + '/' + response.responseAction;
|
|
}
|
|
else if (response && response.success === false) {
|
|
|
|
const errorMessage = parsedMessage?.message || "Login failed.";
|
|
|
|
showToast('error', errorMessage, 'Login failed!', 4000);
|
|
|
|
// Highlight inputs if credential-related error
|
|
if (errorMessage.toLowerCase().includes('username') ||
|
|
errorMessage.toLowerCase().includes('credential')) {
|
|
|
|
addErrorClass(userNameInput);
|
|
addErrorClass(passwordInput);
|
|
}
|
|
}
|
|
setLoginLoading(false);
|
|
},
|
|
error: function (xhr, status, error) {
|
|
errorHandler(xhr, status, error);
|
|
addErrorClass(userNameInput);
|
|
addErrorClass(passwordInput);
|
|
setLoginLoading(false);
|
|
}
|
|
});
|
|
})
|
|
.catch(() => {
|
|
showToast('error', 'Login aborted due to invalid CAPTCHA.', 'Login failed!', 4000);
|
|
addErrorClass(captchaCodeInput, 'Invalid security code');
|
|
captchaCodeInput.focus();
|
|
});
|
|
}
|
|
document.addEventListener('keydown', function (event) {
|
|
if (event.key === 'Enter') {
|
|
event.preventDefault();
|
|
login();
|
|
}
|
|
});
|
|
function showForgotPasswordModal() {
|
|
$('#forgotPasswordModal').modal('show');
|
|
}
|
|
function changePassword() {
|
|
var loader = $('#overlay, #loader');
|
|
|
|
const email = document.getElementById('email').value;
|
|
const newPasswordInput = document.getElementById('NewPassword');
|
|
const confirmPasswordInput = document.getElementById("ConfirmPassword");
|
|
const oTP = document.getElementById("Otp").value;
|
|
|
|
// Add an event listener for the input event
|
|
newPasswordInput.addEventListener('input', removeErrorClass);
|
|
confirmPasswordInput.addEventListener('input', removeErrorClass);
|
|
|
|
// Function to remove the 'error-input' class when the input is not empty
|
|
function removeErrorClass() {
|
|
if (this.value.trim() !== '') {
|
|
this.classList.remove('error-input');
|
|
}
|
|
}
|
|
|
|
// Check if UserName or Password is empty or null
|
|
const newPassword = newPasswordInput.value;
|
|
const confirmPassword = confirmPasswordInput.value;
|
|
|
|
if (newPassword !== confirmPassword) {
|
|
alert('New password and Confirm password not match!');
|
|
|
|
// Make the input fields red by adding a CSS class
|
|
if (!newPassword) {
|
|
newPasswordInput.classList.add('error-input');
|
|
}
|
|
if (!confirmPassword) {
|
|
confirmPasswordInput.classList.add('error-input');
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Check if UserName or Password is empty or null
|
|
if (!newPassword || !confirmPassword) {
|
|
alert('Please fill the required fields!');
|
|
|
|
// Make the input fields red by adding a CSS class
|
|
if (!newPassword) {
|
|
newPasswordInput.classList.add('error-input');
|
|
}
|
|
if (!confirmPassword) {
|
|
confirmPasswordInput.classList.add('error-input');
|
|
}
|
|
return;
|
|
}
|
|
|
|
//console.log('OTP Value: ' + oTP);
|
|
$.ajax({
|
|
url: '/Account/ChangePassword',
|
|
type: 'PUT',
|
|
data: { email, newPassword, oTP },
|
|
beforeSend: function () {
|
|
loader.show();
|
|
},
|
|
complete: function () {
|
|
loader.hide();
|
|
},
|
|
success: function (response) {
|
|
// console.log('Response from api: ' + response.success)
|
|
if (response.success) {
|
|
alert("Your password reset successfully!");
|
|
$('#forgotPasswordModal').modal('hide');
|
|
loader.hide();
|
|
clearElements();
|
|
|
|
} else {
|
|
// console.log('response message: ' + response.responseMessage);
|
|
// If email is not valid, show an alert
|
|
alert("Error: " + response.responseMessage);
|
|
}
|
|
},
|
|
error: function (xhr, error, thrown) {
|
|
console.log('Error:', error);
|
|
console.log('Details:', thrown);
|
|
console.log('xhr Details:', xhr);
|
|
// If email is not valid, show an alert
|
|
alert("Email or OTP is invalid, please double-check!");
|
|
}
|
|
});
|
|
}
|
|
async function forGotPassword() {
|
|
const email = document.getElementById('email').value;
|
|
try {
|
|
const response = await fetch('https://lloydwebapi.lloydlab.com:2021/api/account/RequestResetPassword', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
email: email,
|
|
}),
|
|
});
|
|
|
|
if (response.ok) {
|
|
const result = await response.json();
|
|
alert(result.message); // Show a success message
|
|
// Optionally close the modal or do other actions
|
|
} else {
|
|
const errorResult = await response.json();
|
|
alert(`Error: ${errorResult.message}`);
|
|
}
|
|
} catch (error) {
|
|
console.error('Error:', error);
|
|
}
|
|
} |