// NextSnap - Authentication logic 'use strict'; const Auth = { init() { const loginForm = document.getElementById('login-form'); if (loginForm) { loginForm.addEventListener('submit', this.handleLogin.bind(this)); // Add input validation const usernameInput = document.getElementById('username'); const passwordInput = document.getElementById('password'); if (usernameInput) { usernameInput.addEventListener('blur', () => this.validateUsername()); usernameInput.addEventListener('input', () => this.clearFieldError('username')); } if (passwordInput) { passwordInput.addEventListener('input', () => this.clearFieldError('password')); } } }, validateUsername() { const username = document.getElementById('username').value.trim(); const usernameError = document.getElementById('username-error'); const usernameInput = document.getElementById('username'); if (!username) { usernameError.textContent = 'Username is required'; usernameInput.classList.add('error'); return false; } if (username.length < 2) { usernameError.textContent = 'Username must be at least 2 characters'; usernameInput.classList.add('error'); return false; } usernameError.textContent = ''; usernameInput.classList.remove('error'); return true; }, validatePassword() { const password = document.getElementById('password').value; const passwordError = document.getElementById('password-error'); const passwordInput = document.getElementById('password'); if (!password) { passwordError.textContent = 'Password is required'; passwordInput.classList.add('error'); return false; } passwordError.textContent = ''; passwordInput.classList.remove('error'); return true; }, clearFieldError(field) { const errorElement = document.getElementById(`${field}-error`); const inputElement = document.getElementById(field); if (errorElement) errorElement.textContent = ''; if (inputElement) inputElement.classList.remove('error'); }, async handleLogin(event) { event.preventDefault(); // Validate fields const usernameValid = this.validateUsername(); const passwordValid = this.validatePassword(); if (!usernameValid || !passwordValid) { return; } const username = document.getElementById('username').value.trim(); const password = document.getElementById('password').value; const errorMessage = document.getElementById('error-message'); const loginBtn = document.getElementById('login-btn'); const loginBtnText = document.getElementById('login-btn-text'); const loginBtnLoading = document.getElementById('login-btn-loading'); // Clear previous error errorMessage.classList.add('hidden'); errorMessage.textContent = ''; // Disable button and show loading state loginBtn.disabled = true; loginBtnText.classList.add('hidden'); loginBtnLoading.classList.remove('hidden'); try { const response = await fetch('/api/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username, password }) }); const data = await response.json(); if (response.ok && data.success) { // Login successful - redirect to capture page window.location.href = '/capture'; } else { // Login failed - show error const errorText = data.error || 'Login failed. Please check your credentials and try again.'; errorMessage.textContent = errorText; errorMessage.classList.remove('hidden'); // Focus back on username for retry document.getElementById('username').focus(); } } catch (error) { console.error('Login error:', error); errorMessage.textContent = 'Network error. Please check your connection and try again.'; errorMessage.classList.remove('hidden'); } finally { // Re-enable button and restore normal state loginBtn.disabled = false; loginBtnText.classList.remove('hidden'); loginBtnLoading.classList.add('hidden'); } }, async checkStatus() { try { const response = await fetch('/api/auth/status'); const data = await response.json(); return data.authenticated ? data : null; } catch (error) { console.error('Auth status check failed:', error); return null; } }, async logout() { try { await fetch('/api/auth/logout', { method: 'POST' }); window.location.href = '/'; } catch (error) { console.error('Logout error:', error); // Redirect anyway window.location.href = '/'; } } }; // Initialize when DOM is ready if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', () => Auth.init()); } else { Auth.init(); }