'use client' import { useEffect, useState } from 'react' import { useRouter } from 'next/navigation' import Link from 'next/link' import Topnav from '@/components/topnav' import Footer from '@/components/footer' import { safeNext } from '@/lib/next' import '../styles/login.css' export default function LoginPage() { const router = useRouter() const [showPassword, setShowPassword] = useState(false) const [status, setStatus] = useState('') const [busy, setBusy] = useState(false) const [nextPath, setNextPath] = useState(null) useEffect(() => { setNextPath(safeNext(new URLSearchParams(window.location.search).get('next'))) }, []) async function onSubmit(e: React.FormEvent) { e.preventDefault() const form = e.currentTarget if (!form.checkValidity()) { setStatus('تحقق من البريد الإلكتروني وكلمة المرور.') form.reportValidity() return } setBusy(true) setStatus('') const data = new FormData(form) try { const res = await fetch('/api/users/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email: data.get('email'), password: data.get('password') }), }) if (res.ok) { router.refresh() router.push(safeNext(new URLSearchParams(window.location.search).get('next')) ?? '/account-settings') return } const err = await res.json().catch(() => null) as { error?: string; errors?: { message?: string }[] } | null // Rate-limit / middleware shape first: { error: string } + optional Retry-After. if (typeof err?.error === 'string') { const retryAfterSec = Number(res.headers.get('Retry-After')) setStatus( res.headers.get('Retry-After') && Number.isFinite(retryAfterSec) ? `${err.error} حاول بعد ${Math.max(1, Math.ceil(retryAfterSec / 60))} دقيقة.` : err.error, ) return } const message = err?.errors?.[0]?.message if (message && /locked/i.test(message)) { // Payload lockout: maxLoginAttempts 5 / lockTime 15min (Users.ts). setStatus('تم تجاوز عدد المحاولات المسموح. حاول بعد ١٥ دقيقة.') return } setStatus('تعذّر تسجيل الدخول — تحقّق من البريد وكلمة المرور.') } catch { setStatus('تعذّر الاتصال. حاول تسجيل الدخول مرة أخرى.') } finally { setBusy(false) } } return (
{/* eslint-disable-next-line @next/next/no-img-element */}

أكمل من حيث توقفت.

سجّل الدخول لمتابعة قراءة الأدلة والمشاركة في النقاشات.

أهلاً بعودتك

تسجيل الدخول

استخدم بريدك وكلمة المرور للوصول إلى حسابك.

e.currentTarget.setCustomValidity('أدخل بريداً إلكترونياً صحيحاً.')} onInput={e => e.currentTarget.setCustomValidity('')} />
e.currentTarget.setCustomValidity('أدخل كلمة المرور.')} onInput={e => e.currentTarget.setCustomValidity('')} />
نسيت كلمة المرور؟
{status}
أو
استعد الوصول إلى حسابك

ليس لديك حساب؟ أنشئ حساباً جديداً

بالمتابعة، أنت توافق على شروط الاستخدام وسياسة الخصوصية.

) }