Build
Smart
لوحة المالك
البريد الإلكتروني
كلمة المرور
< truncated lines 122-666 > const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!email || !emailRegex.test(email)) { showFieldError('err-newEmail', 'أدخل بريداً إلكترونياً صحيحاً'); hasError = true; } if (!password || password.length < 8) { showFieldError('err-newPassword', 'كلمة المرور 8 أحرف على الأقل'); hasError = true; } if (hasError) return; const users = await getAllData('users'); if (users.find(function(u) { return u.email.toLowerCase() === email; })) { showFieldError('err-newEmail', 'هذا البريد مستخدم مسبقاً'); return; } const salt = generateSalt(); const passwordHash = await hashPassword(password, salt); const newUser = { id: Date.now(), name: name, email: email, passwordHash: passwordHash, salt: salt, role: role, active: active, createdAt: new Date().toISOString() }; await addData('users', newUser); closeModal(); renderDashboard(); }; } function showFieldError(id, text) { const el = document.getElementById(id); el.textContent = text; el.style.display = 'block'; } async function toggleUser(id) { if (currentUser && id === currentUser.id) return; const user = await getDataById('users', id); if (!user) return; user.active = !user.active; await putData('users', user); renderDashboard(); } async function deleteUser(id) { if (currentUser && id === currentUser.id) return; if (!confirm('حذف المستخدم نهائياً؟')) return; await deleteData('users', id); renderDashboard(); } function closeModal() { document.getElementById('modalOverlay').classList.remove('show'); modalCallback = null; } function modalSave() { if (modalCallback) modalCallback(); } // ================================================================ // INIT // ================================================================ async function initApp() { try { await openDB(); await seedDatabase(); const saved = sessionStorage.getItem('admin_session'); if (saved) { try { const session = JSON.parse(saved); const user = session && session.id ? await getDataById('users', session.id) : null; // نتحقق من قاعدة البيانات الحقيقية، وليس فقط من الجلسة المخزّنة if (user && user.active && user.role === 'admin') { currentUser = user; enterApp(user); return; } sessionStorage.removeItem('admin_session'); } catch (e) { sessionStorage.removeItem('admin_session'); } } document.getElementById('loginPage').style.display = 'flex'; document.getElementById('app').style.display = 'none'; } catch (error) { console.error('خطأ في التهيئة:', error); document.getElementById('loginPage').style.display = 'flex'; document.getElementById('loginMsg').className = 'msg error'; document.getElementById('loginMsg').textContent = 'خطأ في التهيئة: ' + error.message; document.getElementById('loginMsg').style.display = 'block'; } } document.addEventListener('DOMContentLoaded', function() { const form = document.getElementById('loginForm'); if (form) form.addEventListener('submit', handleLogin); }); // EXPOSE GLOBALS (used by inline onclick handlers) window.logout = logout; window.confirmResetDatabase = confirmResetDatabase; window.openAddUserModal = openAddUserModal; window.toggleUser = toggleUser; window.deleteUser = deleteUser; window.closeModal = closeModal; window.modalSave = modalSave; initApp();