.stat-label font-size: 0.7rem; text-transform: uppercase; color: #94a3b8; letter-spacing: 0.5px;
<script> // ---------- FAKE DATABASE / STORAGE ---------- // Simple in-memory user store for demo (full feature) // Predefined valid users: admin@quizaero.com (any password works for demo) // Also we simulate registration: new accounts stored in localStorage "quizaero_users" // For demo completeness: any email+password combo will be allowed if registered or default demo. // But we want realistic: default demo user (admin@quizaero.com) always works. // Also we support "remember me" and forgot password flow (simulated) // Default user record: const DEFAULT_USER = email: "admin@quizaero.com", password: "demo123", // any password works for demo (just placeholder) fullName: "Alex Mentor", quizStats: score: 847, completed: 23, streak: 7 ; // Load users from localStorage or initialize with default let registeredUsers = []; function loadUserDatabase() const stored = localStorage.getItem("quizaero_users"); if(stored) registeredUsers = JSON.parse(stored); // ensure default admin exists in stored DB (avoid duplicate by email) const adminExists = registeredUsers.some(u => u.email === DEFAULT_USER.email); if(!adminExists) registeredUsers.push(JSON.parse(JSON.stringify(DEFAULT_USER))); saveUserDatabase(); else registeredUsers = [JSON.parse(JSON.stringify(DEFAULT_USER))]; saveUserDatabase(); function saveUserDatabase() localStorage.setItem("quizaero_users", JSON.stringify(registeredUsers)); // Helper: find user by email function findUserByEmail(email) return registeredUsers.find(u => u.email.toLowerCase() === email.toLowerCase()); // Register new user (full feature) function registerUser(email, password, fullName = "Quiz Enthusiast") if(findUserByEmail(email)) return success: false, error: "Email already registered." ; const newUser = email: email.toLowerCase(), password: password, // In real app we hash, but for demo we store plain for simplicity fullName: fullName, quizStats: score: 0, completed: 0, streak: 0 ; registeredUsers.push(newUser); saveUserDatabase(); return success: true, user: newUser ; // authenticate: check email + password match (case-insensitive email) function authenticateUser(email, password) const user = findUserByEmail(email); if(!user) return null; // for demo we accept any password for default admin? but we also treat default password demo123. // But to make it flexible: any password works for admin? Actually we want real login: the password must match stored. // For admin@quizaero.com we require password === stored.password (demo123). However to improve UX, we can allow any password for admin? no, we'll enforce match. // but for registration we can set password as given. if(user.password === password) return user; return null; // Session state let currentUser = null; let rememberMeFlag = false; // DOM elements const loginPanel = document.getElementById('loginPanel'); const dashboardPanel = document.getElementById('dashboardPanel'); const emailInput = document.getElementById('emailInput'); const passwordInput = document.getElementById('passwordInput'); const loginFeedback = document.getElementById('loginFeedback'); const loginBtn = document.getElementById('loginBtn'); const authForm = document.getElementById('authForm'); const rememberCheckbox = document.getElementById('rememberCheckbox'); const forgotLink = document.getElementById('forgotPasswordLink'); const demoSignupTrigger = document.getElementById('demoSignupTrigger'); const togglePwdBtn = document.getElementById('togglePwd'); const dashboardUserNameSpan = document.getElementById('dashboardUserName'); const quizScoreStat = document.getElementById('quizScoreStat'); const quizCountStat = document.getElementById('quizCountStat'); const streakStat = document.getElementById('streakStat'); const logoutBtn = document.getElementById('logoutBtn'); const quickQuizBtn = document.getElementById('quickQuizBtn'); // Toggle password visibility let pwdVisible = false; togglePwdBtn.addEventListener('click', () => pwdVisible = !pwdVisible; passwordInput.type = pwdVisible ? 'text' : 'password'; togglePwdBtn.innerHTML = pwdVisible ? '<i class="far fa-eye"></i>' : '<i class="far fa-eye-slash"></i>'; ); // Display feedback messages function showFeedback(message, isError = true) loginFeedback.innerHTML = `<div class="$isError ? 'error-message' : 'success-message'"> <i class="fas $isError ? 'fa-circle-exclamation' : 'fa-circle-check'"></i> <span>$message</span> </div>`; setTimeout(() => if(loginFeedback.innerHTML.includes(message)) loginFeedback.innerHTML = ''; , 3500); // Render dashboard with user stats function renderDashboard() if(!currentUser) return; const name = currentUser.fullName.split(' ')[0] // Update stats after quiz simulation function simulateQuizCompletion() if(!currentUser) return; // update stats: +15 points, +1 quiz, +1 streak currentUser.quizStats.score += 15; currentUser.quizStats.completed += 1; currentUser.quizStats.streak += 1; // save updated user into registeredUsers array const index = registeredUsers.findIndex(u => u.email === currentUser.email); if(index !== -1) registeredUsers[index] = currentUser; saveUserDatabase(); renderDashboard(); showFeedbackOnDashboard("✨ Quiz completed! +15 mastery points!", false); function showFeedbackOnDashboard(msg, isError = false) // create temporary floating alert inside dashboard const dash = dashboardPanel; let existingMsg = dash.querySelector('.dash-feedback'); if(existingMsg) existingMsg.remove(); const msgDiv = document.createElement('div'); msgDiv.className = isError ? 'error-message' : 'success-message'; msgDiv.style.margin = '0 0 1rem 0'; msgDiv.style.fontSize = '0.8rem'; msgDiv.innerHTML = `<i class="fas $isError ? 'fa-exclamation-triangle' : 'fa-trophy'"></i> $msg`; msgDiv.classList.add('dash-feedback'); const firstChild = dash.children[0]; dash.insertBefore(msgDiv, firstChild.nextSibling); setTimeout(() => msgDiv.remove(), 2500); // Login handler function performLogin(email, password, remember) !password) showFeedback("❌ Please enter both email and password.", true); return false; const user = authenticateUser(email, password); if(user) currentUser = user; rememberMeFlag = remember; if(remember) localStorage.setItem("quizaero_session", JSON.stringify( email: currentUser.email, remember: true )); else sessionStorage.setItem("quizaero_session", JSON.stringify( email: currentUser.email, remember: false )); // show dashboard loginPanel.classList.add('hidden'); dashboardPanel.classList.remove('hidden'); renderDashboard(); showFeedbackOnDashboard(`Welcome back $currentUser.fullName! Ready to quiz?`, false); return true; else // check if email exists but wrong password or non existent const exists = findUserByEmail(email); if(exists) showFeedback("🔐 Incorrect password. Try again or reset password.", true); else showFeedback("📧 No account found with this email. Create one using the link below!", true); return false; // Logout function logout() currentUser = null; if(rememberMeFlag) localStorage.removeItem("quizaero_session"); else sessionStorage.removeItem("quizaero_session"); // reset form fields emailInput.value = ''; passwordInput.value = ''; loginFeedback.innerHTML = ''; dashboardPanel.classList.add('hidden'); loginPanel.classList.remove('hidden'); rememberCheckbox.checked = false; // Try auto-login from storage function tryAutoLogin() const sessionLocal = localStorage.getItem("quizaero_session"); const sessionSess = sessionStorage.getItem("quizaero_session"); let sessionData = null; if(sessionLocal) sessionData = JSON.parse(sessionLocal); rememberMeFlag = true; else if(sessionSess) sessionData = JSON.parse(sessionSess); rememberMeFlag = false; if(sessionData && sessionData.email) const user = findUserByEmail(sessionData.email); if(user) currentUser = user; loginPanel.classList.add('hidden'); dashboardPanel.classList.remove('hidden'); renderDashboard(); return true; else // invalid user, clear localStorage.removeItem("quizaero_session"); sessionStorage.removeItem("quizaero_session"); return false; // Forgot password simulation function handleForgotPassword() const email = emailInput.value.trim(); if(!email) showFeedback("📩 Please enter your email address to reset password.", true); return; const user = findUserByEmail(email); if(user) showFeedback(`✉️ A reset link has been sent to $email (demo: use current password)`, false); else showFeedback(`⚠️ No account linked to $email. Would you like to sign up?`, true); // Demo Signup / Registration Modal simulation (simple inline) function showSignupDialog() fakePassword.length < 3) alert("Password must be at least 3 characters."); return; const name = prompt("Display name (optional):", "Quiz Rookie") // Event listeners authForm.addEventListener('submit', (e) => e.preventDefault(); const email = emailInput.value; const pwd = passwordInput.value; const remember = rememberCheckbox.checked; performLogin(email, pwd, remember); ); forgotLink.addEventListener('click', (e) => e.preventDefault(); handleForgotPassword(); ); demoSignupTrigger.addEventListener('click', (e) => e.preventDefault(); showSignupDialog(); ); logoutBtn.addEventListener('click', () => logout(); ); quickQuizBtn.addEventListener('click', () => if(currentUser) simulateQuizCompletion(); ); // Initialize DB & auto session loadUserDatabase(); const autoLogged = tryAutoLogin(); if(!autoLogged) loginPanel.classList.remove('hidden'); dashboardPanel.classList.add('hidden'); // small extra: update realtime stats if needed </script> </body> </html>
.checkbox-label input width: 1rem; height: 1rem; accent-color: #3b82f6; cursor: pointer;
.checkbox-label display: flex; align-items: center; gap: 0.5rem; color: #b9c7dd; cursor: pointer; Quizaero Login
.password-toggle:hover color: #cbd5e1;
/* main card */ .login-container width: 100%; max-width: 480px; background: rgba(18, 25, 45, 0.85); backdrop-filter: blur(12px); border-radius: 2rem; border: 1px solid rgba(56, 189, 248, 0.2); box-shadow: 0 25px 45px -12px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(59,130,246,0.1); overflow: hidden; transition: transform 0.2s ease; z-index: 10;
.orb-1 width: 40vw; height: 40vw; background: #3b82f6; top: -10%; left: -10%; but we also treat default password demo123
.signup-hint a color: #a5f3fc; text-decoration: none; font-weight: 600;
.stat-number font-size: 2rem; font-weight: 800; color: #60a5fa;
.login-btn:disabled opacity: 0.65; cursor: not-allowed; transform: none; // For admin@quizaero
/* demo signup hint */ .signup-hint text-align: center; margin-top: 1.8rem; color: #7e8aa8; font-size: 0.85rem;
.logout-btn:hover background: #334155; border-color: #4b5563;