fix the login user
Build & Deploy / Build & Push Docker Image (push) Successful in 3m5s
Test / Type Check (all packages) (push) Successful in 55s
Build & Deploy / Deploy to VPS (push) Successful in 4s
Test / API Unit Tests (push) Successful in 46s
Test / Homepage Unit Tests (push) Successful in 47s
Test / Carplace Unit Tests (push) Successful in 41s
Test / Admin Unit Tests (push) Successful in 40s
Test / Dashboard Unit Tests (push) Successful in 42s
Test / API Integration Tests (push) Successful in 1m0s
Build & Deploy / Build & Push Docker Image (push) Successful in 3m5s
Test / Type Check (all packages) (push) Successful in 55s
Build & Deploy / Deploy to VPS (push) Successful in 4s
Test / API Unit Tests (push) Successful in 46s
Test / Homepage Unit Tests (push) Successful in 47s
Test / Carplace Unit Tests (push) Successful in 41s
Test / Admin Unit Tests (push) Successful in 40s
Test / Dashboard Unit Tests (push) Successful in 42s
Test / API Integration Tests (push) Successful in 1m0s
This commit is contained in:
@@ -52,6 +52,10 @@ export default function SignInPageClient({
|
|||||||
tooManyRequests: "Too many attempts. Please try again later.",
|
tooManyRequests: "Too many attempts. Please try again later.",
|
||||||
emailNotVerified:
|
emailNotVerified:
|
||||||
"Please verify your email first. Check your inbox for the verification link.",
|
"Please verify your email first. Check your inbox for the verification link.",
|
||||||
|
resendVerification: "Resend verification email",
|
||||||
|
resendingVerification: "Sending…",
|
||||||
|
verificationResent:
|
||||||
|
"If that email is registered and not yet verified, a new verification link has been sent.",
|
||||||
unexpectedError: "Something went wrong. Please try again.",
|
unexpectedError: "Something went wrong. Please try again.",
|
||||||
},
|
},
|
||||||
fr: {
|
fr: {
|
||||||
@@ -76,6 +80,10 @@ export default function SignInPageClient({
|
|||||||
tooManyRequests: "Trop de tentatives. Veuillez réessayer plus tard.",
|
tooManyRequests: "Trop de tentatives. Veuillez réessayer plus tard.",
|
||||||
emailNotVerified:
|
emailNotVerified:
|
||||||
"Veuillez vérifier votre adresse email. Consultez votre boîte de réception.",
|
"Veuillez vérifier votre adresse email. Consultez votre boîte de réception.",
|
||||||
|
resendVerification: "Renvoyer l'e-mail de vérification",
|
||||||
|
resendingVerification: "Envoi…",
|
||||||
|
verificationResent:
|
||||||
|
"Si cette adresse existe et n'est pas encore vérifiée, un nouveau lien a été envoyé.",
|
||||||
unexpectedError: "Une erreur est survenue. Veuillez réessayer.",
|
unexpectedError: "Une erreur est survenue. Veuillez réessayer.",
|
||||||
},
|
},
|
||||||
ar: {
|
ar: {
|
||||||
@@ -100,6 +108,10 @@ export default function SignInPageClient({
|
|||||||
tooManyRequests: "محاولات كثيرة جدًا. يرجى المحاولة لاحقًا.",
|
tooManyRequests: "محاولات كثيرة جدًا. يرجى المحاولة لاحقًا.",
|
||||||
emailNotVerified:
|
emailNotVerified:
|
||||||
"يرجى التحقق من بريدك الإلكتروني أولاً. تحقق من صندوق الوارد.",
|
"يرجى التحقق من بريدك الإلكتروني أولاً. تحقق من صندوق الوارد.",
|
||||||
|
resendVerification: "إعادة إرسال رسالة التحقق",
|
||||||
|
resendingVerification: "جارٍ الإرسال…",
|
||||||
|
verificationResent:
|
||||||
|
"إذا كان هذا البريد مسجلاً ولم يتم التحقق منه بعد، فقد تم إرسال رابط جديد.",
|
||||||
unexpectedError: "حدث خطأ ما. يرجى المحاولة مرة أخرى.",
|
unexpectedError: "حدث خطأ ما. يرجى المحاولة مرة أخرى.",
|
||||||
},
|
},
|
||||||
}[language];
|
}[language];
|
||||||
@@ -239,6 +251,9 @@ function LocalSignInForm({
|
|||||||
emailPlaceholder: string;
|
emailPlaceholder: string;
|
||||||
totpPlaceholder: string;
|
totpPlaceholder: string;
|
||||||
emailNotVerified: string;
|
emailNotVerified: string;
|
||||||
|
resendVerification: string;
|
||||||
|
resendingVerification: string;
|
||||||
|
verificationResent: string;
|
||||||
unexpectedError: string;
|
unexpectedError: string;
|
||||||
};
|
};
|
||||||
}) {
|
}) {
|
||||||
@@ -250,7 +265,9 @@ function LocalSignInForm({
|
|||||||
const [step, setStep] = useState<"credentials" | "totp">("credentials");
|
const [step, setStep] = useState<"credentials" | "totp">("credentials");
|
||||||
const [showPassword, setShowPassword] = useState(false);
|
const [showPassword, setShowPassword] = useState(false);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [resendingVerification, setResendingVerification] = useState(false);
|
||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
|
const [canResendVerification, setCanResendVerification] = useState(false);
|
||||||
const requestedPortal = searchParams.get("portal");
|
const requestedPortal = searchParams.get("portal");
|
||||||
const employeeRedirect = searchParams.get("redirect") || "/dashboard";
|
const employeeRedirect = searchParams.get("redirect") || "/dashboard";
|
||||||
const preferAdminAuth = requestedPortal === "admin";
|
const preferAdminAuth = requestedPortal === "admin";
|
||||||
@@ -259,6 +276,7 @@ function LocalSignInForm({
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
setError(null);
|
setError(null);
|
||||||
|
setCanResendVerification(false);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const tryAdminLogin = async () => {
|
const tryAdminLogin = async () => {
|
||||||
@@ -328,6 +346,7 @@ function LocalSignInForm({
|
|||||||
|
|
||||||
if (empJson?.error === "email_not_verified") {
|
if (empJson?.error === "email_not_verified") {
|
||||||
setError(dict.emailNotVerified);
|
setError(dict.emailNotVerified);
|
||||||
|
setCanResendVerification(true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -355,6 +374,30 @@ function LocalSignInForm({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function handleResendVerification() {
|
||||||
|
setResendingVerification(true);
|
||||||
|
setError(null);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await fetch(`${API_BASE}/auth/employee/resend-verification`, {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
credentials: "include",
|
||||||
|
body: JSON.stringify({ email }),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
||||||
|
|
||||||
|
setCanResendVerification(false);
|
||||||
|
setError(dict.verificationResent);
|
||||||
|
} catch {
|
||||||
|
setError(dict.unexpectedError);
|
||||||
|
setCanResendVerification(true);
|
||||||
|
} finally {
|
||||||
|
setResendingVerification(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function handleTotp(e: React.FormEvent) {
|
async function handleTotp(e: React.FormEvent) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
@@ -391,7 +434,17 @@ function LocalSignInForm({
|
|||||||
<>
|
<>
|
||||||
{error ? (
|
{error ? (
|
||||||
<div className="mb-5 rounded-[1.5rem] border border-red-200/80 bg-red-50/90 px-4 py-3 text-sm text-red-700 dark:border-red-900/60 dark:bg-red-950/40 dark:text-red-300">
|
<div className="mb-5 rounded-[1.5rem] border border-red-200/80 bg-red-50/90 px-4 py-3 text-sm text-red-700 dark:border-red-900/60 dark:bg-red-950/40 dark:text-red-300">
|
||||||
{error}
|
<div>{error}</div>
|
||||||
|
{canResendVerification ? (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={handleResendVerification}
|
||||||
|
disabled={resendingVerification}
|
||||||
|
className="mt-3 text-sm font-semibold underline decoration-red-300 underline-offset-4 disabled:cursor-not-allowed disabled:opacity-60 dark:decoration-red-700"
|
||||||
|
>
|
||||||
|
{resendingVerification ? dict.resendingVerification : dict.resendVerification}
|
||||||
|
</button>
|
||||||
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user