// NextSnap - Authentication logic 'use strict'; const Auth = { currentTab: 'tech', init() { // Tab switching document.querySelectorAll('.login-tab').forEach(tab => { tab.addEventListener('click', () => this.switchTab(tab.dataset.tab)); }); // Tech login form const techForm = document.getElementById('tech-login-form'); if (techForm) { techForm.addEventListener('submit', (e) => this.handleTechLogin(e)); } // Admin login form const adminForm = document.getElementById('admin-login-form'); if (adminForm) { adminForm.addEventListener('submit', (e) => this.handleAdminLogin(e)); } // Clear field errors on input document.querySelectorAll('.form-input').forEach(input => { input.addEventListener('input', () => { const errorEl = document.getElementById(input.id + '-error'); if (errorEl) errorEl.textContent = ''; input.classList.remove('error'); }); }); }, switchTab(tab) { this.currentTab = tab; // Update tab buttons document.querySelectorAll('.login-tab').forEach(t => { t.classList.toggle('active', t.dataset.tab === tab); }); // Show/hide forms const techForm = document.getElementById('tech-login-form'); const adminForm = document.getElementById('admin-login-form'); const helpText = document.getElementById('login-help'); if (tab === 'tech') { techForm.style.display = ''; adminForm.style.display = 'none'; helpText.innerHTML = 'Tip: Use your username and PIN to login'; const field = document.getElementById('tech-username'); if (field) field.focus(); } else { techForm.style.display = 'none'; adminForm.style.display = ''; helpText.innerHTML = 'Tip: Use your Nextcloud admin credentials'; const field = document.getElementById('admin-username'); if (field) field.focus(); } // Clear errors on tab switch document.querySelectorAll('.error-message').forEach(el => el.classList.add('hidden')); document.querySelectorAll('.field-error').forEach(el => el.textContent = ''); document.querySelectorAll('.form-input').forEach(el => el.classList.remove('error')); }, _setLoading(btn, loading) { const text = btn.querySelector('.btn-text'); const spinner = btn.querySelector('.btn-loading'); btn.disabled = loading; text.classList.toggle('hidden', loading); spinner.classList.toggle('hidden', !loading); }, async handleTechLogin(event) { event.preventDefault(); const username = document.getElementById('tech-username').value.trim(); const pin = document.getElementById('tech-pin').value; const errorMessage = document.getElementById('tech-error-message'); const btn = document.getElementById('tech-login-btn'); if (!username) { document.getElementById('tech-username-error').textContent = 'Username is required'; document.getElementById('tech-username').classList.add('error'); return; } if (!pin) { document.getElementById('tech-pin-error').textContent = 'PIN is required'; document.getElementById('tech-pin').classList.add('error'); return; } errorMessage.classList.add('hidden'); this._setLoading(btn, true); try { const response = await fetch('/api/auth/login/tech', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username, pin }) }); const data = await response.json(); if (response.ok && data.success) { window.location.href = '/capture'; } else { errorMessage.textContent = data.error || 'Login failed. Please check your credentials.'; errorMessage.classList.remove('hidden'); } } catch (error) { console.error('Login error:', error); errorMessage.textContent = 'Network error. Please check your connection and try again.'; errorMessage.classList.remove('hidden'); } finally { this._setLoading(btn, false); } }, async handleAdminLogin(event) { event.preventDefault(); const username = document.getElementById('admin-username').value.trim(); const password = document.getElementById('admin-password').value; const errorMessage = document.getElementById('admin-error-message'); const btn = document.getElementById('admin-login-btn'); if (!username) { document.getElementById('admin-username-error').textContent = 'Username is required'; document.getElementById('admin-username').classList.add('error'); return; } if (!password) { document.getElementById('admin-password-error').textContent = 'Password is required'; document.getElementById('admin-password').classList.add('error'); return; } errorMessage.classList.add('hidden'); this._setLoading(btn, true); 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) { window.location.href = '/capture'; } else { errorMessage.textContent = data.error || 'Login failed. Please check your credentials.'; errorMessage.classList.remove('hidden'); } } catch (error) { console.error('Login error:', error); errorMessage.textContent = 'Network error. Please check your connection and try again.'; errorMessage.classList.remove('hidden'); } finally { this._setLoading(btn, false); } }, 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); window.location.href = '/'; } } }; // Initialize when DOM is ready if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', () => Auth.init()); } else { Auth.init(); }