import { type FormEvent, useState } from "react"; import { parsePhoneNumberFromString } from "libphonenumber-js"; import { Eye, EyeOff, Mail, Smartphone, UserRound } from "lucide-react"; import { useNavigate } from "react-router-dom"; import { useAuth } from "@/auth/useAuth"; type LoginMode = "email" | "phone" | "username"; const loginModes: Array<{ value: LoginMode; label: string; icon: typeof Mail; placeholder: string; }> = [ { value: "email", label: "Email", icon: Mail, placeholder: "name@company.com" }, { value: "phone", label: "Phone", icon: Smartphone, placeholder: "09XXXXXXXX" }, { value: "username", label: "Username", icon: UserRound, placeholder: "username" }, ]; const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; const usernamePattern = /^[a-zA-Z0-9._-]{3,32}$/; const normalizeIdentifier = (mode: LoginMode, value: string) => { const trimmed = value.trim(); if (mode === "email") { if (!emailPattern.test(trimmed.toLowerCase())) { throw new Error("Enter a valid email address."); } return trimmed.toLowerCase(); } if (mode === "phone") { const parsed = parsePhoneNumberFromString(trimmed, "ET"); if (!parsed?.isValid()) { throw new Error("Enter a valid Ethiopian phone number."); } return parsed.number; } if (!usernamePattern.test(trimmed)) { throw new Error("Username must be 3-32 characters and use letters, numbers, ., _, or -."); } return trimmed; }; const LoginPage = () => { const navigate = useNavigate(); const { login, verifyMfa } = useAuth(); const [mode, setMode] = useState("email"); const [identifier, setIdentifier] = useState(""); const [password, setPassword] = useState(""); const [otp, setOtp] = useState(""); const [needsMfa, setNeedsMfa] = useState(false); const [submitting, setSubmitting] = useState(false); const [showPassword, setShowPassword] = useState(false); const [normalizedIdentifier, setNormalizedIdentifier] = useState(""); const [error, setError] = useState(null); const currentMode = loginModes.find((item) => item.value === mode)!; const ModeIcon = currentMode.icon; const handleSubmit = async (event: FormEvent) => { event.preventDefault(); setSubmitting(true); setError(null); try { const normalized = normalizeIdentifier(mode, identifier); setNormalizedIdentifier(normalized); const result = await login({ email: normalized, password }); if (result.mfaRequired) { setNeedsMfa(true); return; } navigate("/dashboard/overview", { replace: true }); } catch { setError("Unable to sign in with those credentials."); } finally { setSubmitting(false); } }; const handleVerifyMfa = async (event: FormEvent) => { event.preventDefault(); setSubmitting(true); setError(null); try { await verifyMfa({ email: normalizedIdentifier, otp: otp.trim() }); navigate("/dashboard/overview", { replace: true }); } catch { setError("Unable to verify the one-time code."); } finally { setSubmitting(false); } }; return (
{!needsMfa ? (

Sign in

EDR Backoffice

Use your email, phone number, or username to access the internal freight dashboard.

{error ? (
{error}
) : null}
) : (

Multi-factor verification

Confirm one-time code

We sent a verification code for {normalizedIdentifier}. Enter it below to complete sign in.

{error ? (
{error}
) : null}
)}
); }; export default LoginPage;