feat: ( forget password ) add phone number

This commit is contained in:
Abubeker Yasin
2026-07-09 09:38:34 +03:00
parent d71ee6ed1b
commit f1452ba67e
4 changed files with 38 additions and 34 deletions

View File

@@ -29,12 +29,12 @@ export default function LoginPage() {
const [emailFocused, setEmailFocused] = useState(false);
const [passwordFocused, setPasswordFocused] = useState(false);
const [view, setView] = useState<'login' | 'forgot'>('login');
const [forgotEmail, setForgotEmail] = useState('');
const [forgotLoading, setForgotLoading] = useState(false);
const [forgotError, setForgotError] = useState('');
const [forgotSent, setForgotSent] = useState(false);
const [forgotFocused, setForgotFocused] = useState(false);
const [view, setView] = useState<'login' | 'forgot'>('login');
const [forgotIdentifier, setForgotIdentifier] = useState('');
const [forgotLoading, setForgotLoading] = useState(false);
const [forgotError, setForgotError] = useState('');
const [forgotSent, setForgotSent] = useState(false);
const [forgotFocused, setForgotFocused] = useState(false);
const router = useRouter();
const { login } = useAuthStore();
@@ -66,13 +66,13 @@ export default function LoginPage() {
setForgotLoading(true);
setForgotError('');
try {
await iamAuthApi.forgotPassword(forgotEmail);
await iamAuthApi.forgotPassword(forgotIdentifier.trim());
setForgotSent(true);
} catch (err: any) {
const msg = err.response?.data?.message || err.message || '';
setForgotError(
msg === 'user_not_found'
? 'No account found with that email address.'
? 'No account found with that email or phone number.'
: msg || 'Failed to send the reset link. Please try again.'
);
} finally {
@@ -209,7 +209,7 @@ export default function LoginPage() {
<div className="flex justify-end mt-2">
<button
type="button"
onClick={() => { setView('forgot'); setForgotEmail(email); setError(''); }}
onClick={() => { setView('forgot'); setForgotIdentifier(email); setError(''); }}
className="text-xs font-medium text-[rgb(20,113,76)] hover:underline"
>
Forgot password?
@@ -260,7 +260,7 @@ export default function LoginPage() {
Reset your password
</h2>
<p className="text-sm text-gray-500 dark:text-gray-400 mt-1">
Enter your email address and we&apos;ll send a reset link to the phone number on your account.
Enter your email or phone number and we&apos;ll send a reset link to the phone number on your account.
</p>
</div>
@@ -295,10 +295,10 @@ export default function LoginPage() {
)}
<form onSubmit={handleForgotSubmit} className="space-y-4 animate-fade-up" style={{ animationDelay: '80ms' }}>
{/* Email field */}
{/* Email or phone field */}
<div>
<label className="block text-xs font-semibold text-gray-600 dark:text-gray-400 uppercase tracking-wider mb-2">
Email address
Email or phone number
</label>
<div className={`relative rounded-xl transition-all duration-200 ${
forgotFocused
@@ -306,15 +306,15 @@ export default function LoginPage() {
: 'ring-1 ring-gray-200 dark:ring-gray-800'
}`}>
<input
type="email"
value={forgotEmail}
onChange={(e) => { setForgotEmail(e.target.value); setForgotError(''); }}
type="text"
value={forgotIdentifier}
onChange={(e) => { setForgotIdentifier(e.target.value); setForgotError(''); }}
onFocus={() => setForgotFocused(true)}
onBlur={() => setForgotFocused(false)}
className="w-full px-4 py-3 rounded-xl bg-white dark:bg-gray-900 text-gray-900 dark:text-white placeholder:text-gray-400 dark:placeholder:text-gray-600 text-sm focus:outline-none"
placeholder="name@edr.com"
placeholder="name@edr.com or +251..."
required
autoComplete="email"
autoComplete="username"
/>
</div>
</div>
@@ -322,9 +322,9 @@ export default function LoginPage() {
{/* Submit */}
<button
type="submit"
disabled={forgotLoading || !forgotEmail}
disabled={forgotLoading || !forgotIdentifier.trim()}
className="group w-full mt-2 flex items-center justify-center gap-2 py-3 px-4 rounded-xl font-semibold text-sm text-white transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed"
style={{ background: forgotLoading || !forgotEmail
style={{ background: forgotLoading || !forgotIdentifier.trim()
? 'rgb(20,113,76)'
: `linear-gradient(135deg, rgb(20,113,76) 0%, rgb(16,143,96) 100%)`
}}

View File

@@ -4,8 +4,10 @@ const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:4000';
export const iamAuthApi = {
forgotPassword: (email: string) =>
axios.post(`${API_URL}/v1/auth/forgot-password`, { email }),
// `identifier` can be an email address or a phone number — the IAM accepts
// either in the `email` field of the forgot-password body.
forgotPassword: (identifier: string) =>
axios.post(`${API_URL}/v1/auth/forgot-password`, { email: identifier }),
resetPassword: (data: {
userId: string;