<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Skyonn Admin Portal</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" integrity="sha512-z3gLpd7yknf1YoNbCzqRKc4qyor8gaKU1qmn+CShxbuBusANI9QpRohGBreCFkKxLhei6S9CQXFEbbKuqLg0DA==" crossorigin="anonymous" referrerpolicy="no-referrer" /> <style> body { font-family: Arial; } .container { width: 20rem; margin: auto; border: 1px solid black; padding: 20px; border-radius: 10px; margin-top: 50px; position: relative; } .input-group { margin-bottom: 10px; } .input-group input[type="text"], .input-group input[type="password"], .input-group input[type="email"], .input-group select { width: calc(100% - 22px); border-radius: 5px; padding: 10px; box-sizing: border-box; display: block; margin-bottom: 5px; font-weight: bold; } button { background-color: white; color: black; padding: 5px; border-radius: 5px; margin: 3px 0; width: 100%; font-size: 15px; background-color:#66D3FA; } h2 { color: black; text-align: center; margin-top: -5px; margin-bottom: 20px; } .toggle-form { text-align: center; margin-top: 20px; } .toggle-form a { color: #3C99DC; text-decoration: none; } .footer-text { position: absolute; bottom: 0; width: 100%; text-align: center; color: #3C99DC; margin-bottom: 10px; } </style> </head> <body> <div class="container"> <h2>Skyonn Admin Portal</h2> <div id="login-form"> <form id="loginForm" action="{% url 'admin_login' %}" method="post" enctype="multipart/form-data"> {% csrf_token %} <div class="input-group"> <input type="text" id="PhoneField" placeholder="Phone" name="phone" > </div> <div class="input-group"> <input type="password" id="passwordField" placeholder="Password" name="password" > </div> <button type="button" id="submitButton" onclick="adminLogin()">Login</button> </form> <div class="toggle-form"> <p>New user? <a href="#" onclick="toggleForms('signup-form')">Sign Up</a></p> </div> </div> <div id="signup-form" style="display: none;"> <form id="signupForm" method="post" action="{% url 'create_admin' %}" enctype="multipart/form-data"> {% csrf_token %} <div class="input-group"> <label for="first_name">First Name*:</label> <input type="text" id="first_name" name="first_name" required> </div> <div class="input-group"> <label for="last_name">Last Name*:</label> <input type="text" id="last_name" name="last_name" required> </div> <div class="input-group"> <label for="phone">Phone no.*:</label> <input type="text" id="phone" name="phone" required> </div> <div class="input-group"> <label for="phone_2">Phone no. 2:</label> <input type="text" id="phone_2" name="phone_2"> </div> <div class="input-group"> <label for="company_email">Company Email*:</label> <input type="email" id="company_email" name="company_email" required> </div> <div class="input-group"> <label for="personal_email">Personal Email*:</label> <input type="email" id="personal_email" name="personal_email" required> </div> <div class="input-group"> <label for="address">Address*:</label> <input type="text" id="address" name="address" required> </div> <div class="input-group"> <label for="work_location">Work Location*:</label> <input type="text" id="work_location" name="work_location" required> </div> <div class="input-group"> <label for="password">Password*:</label> <input type="password" id="password" name="password" required> </div> <div class="input-group"> <label for="picture">Upload Picture *</label> <input type="file" id="picture" name="picture" accept=".svg, .jpg, .jpeg, .png"> </div> <input type="button" value="Create Account" onclick="saveAdmin()"> </form> <div class="toggle-form"> <p>Already have an account? <a href="#" onclick="toggleForms('login-form')">Login</a></p> </div> </div> </div> <script> function toggleForms(formId) { var signupForm = document.getElementById('signup-form'); var loginForm = document.getElementById('login-form'); if (formId === 'signup-form') { signupForm.style.display = 'block'; loginForm.style.display = 'none'; } else { signupForm.style.display = 'none'; loginForm.style.display = 'block'; } } document.addEventListener('DOMContentLoaded', function () { const form = document.getElementById('loginForm'); const phoneField = document.getElementById('PhoneField'); const passwordField = document.getElementById('passwordField'); const clearValidation = (field) => { field.setCustomValidity(''); field.style.borderColor = ''; }; phoneField.addEventListener('input', () => { clearValidation(phoneField); }); passwordField.addEventListener('input', () => { clearValidation(passwordField); }); // Function to perform AJAX validation const validateField = (field, fieldName) => { const formData = new FormData(); formData.append(fieldName, field.value.trim()); fetch(form.action, { // Replace with your actual login URL method: 'POST', body: formData, headers: { 'X-CSRFToken': '{{csrf_token}}' } }) .then(response => response.json()) .then(data => { clearValidation(field); // Clear previous validation if (data.error) { field.setCustomValidity(data.error); field.reportValidity(); } else { field.style.borderColor = 'green'; // Show success feedback field.setCustomValidity(''); // Clear any errors } }) .catch(error => { console.error('Error:', error); }); }; // Trigger validation on blur for phone number phoneField.addEventListener('blur', () => { if (phoneField.value.trim()) { validateField(phoneField, 'phone'); } }); // Trigger validation on blur for password (only if phone is valid) passwordField.addEventListener('blur', () => { if (phoneField.value.trim() && passwordField.value.trim()) { const formData = new FormData(); formData.append('phone', phoneField.value.trim()); formData.append('password', passwordField.value.trim()); fetch(form.action, { // Replace with your actual login URL method: 'POST', body: formData, headers: { 'X-CSRFToken': '{{csrf_token}}' } }) .then(response => response.json()) .then(data => { clearValidation(passwordField); // Clear previous validation if (data.error) { passwordField.setCustomValidity(data.error); passwordField.reportValidity(); } else { passwordField.setCustomValidity(''); } }) .catch(error => { console.error('Error:', error); }); } }); // Handle form submission (already implemented in your code) window.adminLogin = function() { const form = document.getElementById('loginForm'); const formData = new FormData(form); fetch(form.action, { method: 'POST', body: formData, headers: { 'X-CSRFToken': '{{csrf_token}}' } }) .then(response => response.json()) .then(data => { if (data.error) { if (data.error.includes('phone number')) { phoneField.setCustomValidity(data.error); phoneField.reportValidity(); } else if (data.error.includes('password')) { passwordField.setCustomValidity(data.error); passwordField.reportValidity(); } } else if (data.success) { window.location.href = data.redirect_url; } }) .catch(error => { console.error('Error:', error); }); } }); document.addEventListener('DOMContentLoaded', function () { document.addEventListener('change', function () { const form = document.getElementById('signupForm'); const phoneNumberInput1 = document.getElementById('phone'); const emailInput1 = document.getElementById('company_email'); const phoneNumberInput2 = document.getElementById('phone_2'); const emailInput2 = document.getElementById('personal_email'); if(!phoneNumberInput1 || !emailInput1 || !phoneNumberInput2 || !emailInput2) { return;} const phonePattern = /^[6-9]\d{9}$/; const emailPattern = /^[^\s@]+@[^\s@]+\.[a-zA-Z]{2,}$/; const emailPattern2 = /^[^\s@]{1,64}@([^\s@_]+\.)+[a-zA-Z]{2,}$/; const validateField = (field) => { if (!field.value.trim()) { field.style.borderColor = ''; field.setCustomValidity('Please fill out this field.'); field.reportValidity(); return false; } else { field.style.borderColor = 'black'; field.setCustomValidity(''); return true; } }; const clearValidation = (field) => { field.setCustomValidity(''); field.style.borderColor = ''; }; emailInput1.addEventListener('input', () => { clearValidation(emailInput1); }); phoneNumberInput1.addEventListener('input', () => { clearValidation(phoneNumberInput1); }); emailInput2.addEventListener('input', () => { clearValidation(emailInput2); }); phoneNumberInput2.addEventListener('input', () => { clearValidation(phoneNumberInput2); }); emailInput1.addEventListener('blur', () => { if (emailInput1.value.trim() && (!emailInput1.value.match(/^[^\s@]+@[^\s@]+\.[a-zA-Z]{2,}$/) || emailInput1.value.includes('..') || !emailInput1.value.match(/^[^\s@]{1,64}@([^\s@_]+\.)+[a-zA-Z]{2,}$/))) { emailInput1.style.borderColor = ''; emailInput1.setCustomValidity('Please enter a valid Email address'); emailInput1.reportValidity(); return; } else { clearValidation(emailInput1); if (emailInput1.value.trim()) { checkFieldExists('company_email', emailInput1); } } }); phoneNumberInput1.addEventListener('blur', () => { if (phoneNumberInput1.value.trim() && !phoneNumberInput1.value.match(/^[6-9]\d{9}$/)) { phoneNumberInput1.style.borderColor = ''; phoneNumberInput1.setCustomValidity('Please enter a valid Phonenumber.'); phoneNumberInput1.reportValidity(); return; } else { clearValidation(phoneNumberInput1); if (phoneNumberInput1.value.trim()) { checkFieldExists('phone', phoneNumberInput1); } } }); emailInput2.addEventListener('blur', () => { if (emailInput2.value.trim() && (!emailInput2.value.match(/^[^\s@]+@[^\s@]+\.[a-zA-Z]{2,}$/) || emailInput2.value.includes('..') || !emailInput2.value.match(/^[^\s@]{1,64}@([^\s@_]+\.)+[a-zA-Z]{2,}$/))) { emailInput2.style.borderColor = ''; emailInput2.setCustomValidity('Please enter a valid Email address'); emailInput2.reportValidity(); return; } else { clearValidation(emailInput2); if (emailInput2.value.trim()) { checkFieldExists('personal_email', emailInput2); } } }); phoneNumberInput2.addEventListener('blur', () => { if (phoneNumberInput2.value.trim() && !phoneNumberInput2.value.match(/^[6-9]\d{9}$/)) { phoneNumberInput2.style.borderColor = ''; phoneNumberInput2.setCustomValidity('Please enter a valid Phonenumber.'); phoneNumberInput2.reportValidity(); return; } else { clearValidation(phoneNumberInput2); if (phoneNumberInput2.value.trim()) { checkFieldExists('phone_2', phoneNumberInput2); } } }); function checkFieldExists(fieldName, field) { const value = field.value.trim(); fetch(`/skyonnadmin/validate_admin/?${fieldName}=${value}`) .then(response => response.json()) .then(data => { if (data.exists) { if(fieldName == 'phone' || fieldName == 'phone_2') { field.setCustomValidity('Phone number already exists.'); } else { field.setCustomValidity('Email already exists.'); } field.style.borderColor = 'red'; field.reportValidity(); field.focus(); } else { clearValidation(field); } }) .catch(error => console.error('Error:', error)); }; }); }); window.saveAdmin = async function() { const form = document.getElementById('signupForm'); const requiredFields = [ 'first_name', 'last_name', 'phone', 'phone_2', 'company_email', 'personal_email', 'address', 'work_location', 'picture','password']; const phoneNumberInput1 = document.getElementById('phone'); const emailInput1 = document.getElementById('company_email'); const phoneNumberInput2 = document.getElementById('phone_2'); const emailInput2 = document.getElementById('personal_email'); let isValid = true; requiredFields.forEach(id => { const field = document.getElementById(id); if (field) { field.setCustomValidity(''); // Clear previous validation message field.style.borderColor = ''; // Reset border color } }); for (let id of requiredFields) { const field = document.getElementById(id); if (id !== 'picture' && field.value.trim() === '') { isValid = false; field.setCustomValidity('Please fill out this field.'); field.reportValidity(); } if(id === 'picture' && field.files.length === 0) { isValid = false; field.setCustomValidity('Please upload a image'); field.reportValidity(); } } const validateEmail = (emailInput) => { if (emailInput.value.trim() && (!emailInput.value.match(/^[^\s@]+@[^\s@]+\.[a-zA-Z]{2,}$/) || emailInput.value.includes('..') || !emailInput.value.match(/^[^\s@]{1,64}@([^\s@_]+\.)+[a-zA-Z]{2,}$/))) { isValid = false; emailInput.style.borderColor = ''; emailInput.setCustomValidity('Please enter a valid Email address'); emailInput.reportValidity(); } else { emailInput.setCustomValidity(''); emailInput.style.borderColor = ''; } } const checkValidity = (field,pattern,errorMsg) =>{ if (field.value.trim() && !field.value.match(pattern)) { field.setCustomValidity(errorMsg); field.reportValidity(); isValid=false; } else { field.setCustomValidity(''); field.style.borderColor = ''; } }; checkValidity(phoneNumberInput1, /^[6-9]\d{9}$/, 'Please enter a valid Phonenumber.'); validateEmail(emailInput1); if (phoneNumberInput2.value.trim()) { checkValidity(phoneNumberInput2, /^[6-9]\d{9}$/, 'Please enter a valid Phonenumber.'); } if (emailInput2.value.trim()) { validateEmail(emailInput2); } const checkFieldExists = (fieldName, field) => { return new Promise((resolve, reject) => { const value = field.value.trim(); fetch(`/skyonnadmin/validate_admin/?${fieldName}=${value}`) .then(response => response.json()) .then(data => { if (data.exists) { if (fieldName === 'phone' || fieldName === 'phone_2') { field.setCustomValidity('Phone number already exists.'); } else { field.setCustomValidity('Email already exists.'); } field.style.borderColor = 'red'; field.reportValidity(); resolve(false); //Invalid } else { field.setCustomValidity(''); field.style.borderColor = ''; resolve(true); // Valid } }) .catch(error => { console.error('Error:', error); reject(error); }); }); } if (isValid) { const phoneNo1Valid = await checkFieldExists('phone', phoneNumberInput1); const phoneNo2Valid = await checkFieldExists('phone_2', phoneNumberInput2); const email1Valid = await checkFieldExists('company_email', emailInput1); const email2Valid = await checkFieldExists('personal_email', emailInput2); isValid = phoneNo1Valid && email1Valid && phoneNo2Valid && email2Valid; console.log(phoneNo1Valid, email1Valid, phoneNo2Valid, email2Valid, isValid); } if (!isValid) { console.log("Validation failed. Please fill out the required fields."); return; } // Proceed with saving data if all fields are valid const formData = new FormData(form); const url = form.getAttribute('action'); console.log("Submitting form to:", url); console.log("Form data:", [...formData.entries()]); // Log the form data fetch(url, { method: 'POST', body: formData, headers: { 'X-CSRFToken': '{{ csrf_token }}', // Assuming you have CSRF token available }, }) .then(response => response.json()) .then(data => { console.log('Success:', data); form.reset(); window.location.href = data.redirect_url; }) .catch(error => { console.error('Error:', error); alert('Error: ' + error.message); }) } </script> </body> </html>