/** * Client-side form validation and authentication handling */ // Token management functions function getToken() { return localStorage.getItem('auth_token'); } function setToken(token) { localStorage.setItem('auth_token', token); } function removeToken() { localStorage.removeItem('auth_token'); } // Check authentication state and update UI accordingly async function checkAuthState() { try { const token = getToken(); const headers = token ? { 'Authorization': `Bearer ${token}` } : {}; const response = await fetch('/api/user/current', { headers }); if (!response.ok) { throw new Error('Auth check failed'); } const user = await response.json(); const loggedIn = document.querySelector('.auth-logged-in'); const loggedOut = document.querySelector('.auth-logged-out'); const userProfile = document.querySelector('.user-profile'); if (user && user.username) { loggedIn.style.display = 'block'; loggedOut.style.display = 'none'; userProfile.textContent = user.username; } else { loggedIn.style.display = 'none'; loggedOut.style.display = 'block'; } } catch (error) { console.error('Auth check failed:', error); document.querySelector('.auth-logged-in').style.display = 'none'; document.querySelector('.auth-logged-out').style.display = 'block'; removeToken(); } } document.addEventListener('DOMContentLoaded', function() { // Check auth state when page loads checkAuthState(); // Set up form validation listeners const loginForm = document.getElementById('login-form'); if (loginForm) { loginForm.addEventListener('submit', handleLoginSubmit); } const signupForm = document.getElementById('signup-form'); if (signupForm) { signupForm.addEventListener('submit', handleSignupSubmit); } // Handle logout const logoutLink = document.querySelector('a[href="/logout"]'); if (logoutLink) { logoutLink.addEventListener('click', function(e) { e.preventDefault(); removeToken(); window.location.href = '/'; }); } }); async function handleLoginSubmit(e) { e.preventDefault(); const email = document.getElementById('email').value; const password = document.getElementById('password').value; if (!validateLoginForm(email, password)) { return; } try { const response = await fetch('/token', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: `username=${encodeURIComponent(email)}&password=${encodeURIComponent(password)}` }); if (!response.ok) { throw new Error('Login failed'); } const data = await response.json(); setToken(data.access_token); window.location.href = '/dashboard'; } catch (error) { console.error('Login error:', error); showError('Login failed. Please check your credentials and try again.'); } } async function handleSignupSubmit(e) { e.preventDefault(); const email = document.getElementById('email').value; const password = document.getElementById('password').value; const confirmPassword = document.getElementById('confirm_password').value; if (!validateSignupForm(email, password, confirmPassword)) { return; } try { const response = await fetch('/signup', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ email: email, password: password }) }); if (!response.ok) { throw new Error('Signup failed'); } const data = await response.json(); setToken(data.access_token); window.location.href = '/dashboard'; } catch (error) { console.error('Signup error:', error); showError('Signup failed. Please try again.'); } } function validateLoginForm(email, password) { if (!email || !email.match(/^[^\s@]+@[^\s@]+\.[^\s@]+$/)) { showError('Please enter a valid email address'); return false; } if (!password || password.length < 8) { showError('Password must be at least 8 characters long'); return false; } return true; } function validateSignupForm(email, password, confirmPassword) { if (!email || !email.match(/^[^\s@]+@[^\s@]+\.[^\s@]+$/)) { showError('Please enter a valid email address'); return false; } if (!password || password.length < 8) { showError('Password must be at least 8 characters long'); return false; } if (password !== confirmPassword) { showError('Passwords do not match'); return false; } return true; } function showError(message) { // Remove any existing error alerts const existingAlert = document.querySelector('.alert-danger'); if (existingAlert) { existingAlert.remove(); } // Create and show new error alert const alert = document.createElement('div'); alert.className = 'alert alert-danger alert-dismissible fade show'; alert.role = 'alert'; alert.innerHTML = ` ${message} `; const form = document.querySelector('form'); form.parentNode.insertBefore(alert, form); }