From d8ee87d63303472d5689f8ce37cc6b3501bbf26a Mon Sep 17 00:00:00 2001 From: sylwia-werner Date: Thu, 6 Nov 2025 10:49:17 +0100 Subject: [PATCH 01/10] fix: adapt login ui to design --- .../molecules/LoginForm/LoginForm.tsx | 76 ++++++++++++------- 1 file changed, 48 insertions(+), 28 deletions(-) diff --git a/src/components/molecules/LoginForm/LoginForm.tsx b/src/components/molecules/LoginForm/LoginForm.tsx index f0b47b51..283faf63 100644 --- a/src/components/molecules/LoginForm/LoginForm.tsx +++ b/src/components/molecules/LoginForm/LoginForm.tsx @@ -14,6 +14,7 @@ import { loginFormSchema, LoginFormData } from "./schema" import { useState } from "react" import { login } from "@/lib/data/customer" import { useRouter } from "next/navigation" +import Link from "next/link" export const LoginForm = () => { const methods = useForm({ @@ -56,36 +57,55 @@ const Form = () => { return (
-

- Log in to your account -

-
-
- - - {error &&

{error}

} - + + {error && ( +

{error}

+ )} + +
+ +
+

+ Don't have an account yet? +

+ + + -

- Don't have an account yet?{" "} - - Sign up! - -

+
- +
) } From cdf05c6df1b9c0337ade98239cb9db95e2c1b647 Mon Sep 17 00:00:00 2001 From: sylwia-werner Date: Thu, 6 Nov 2025 10:49:47 +0100 Subject: [PATCH 02/10] fix: correct heading levels, remove unnecessary paragraph --- .../molecules/RegisterForm/RegisterForm.tsx | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/components/molecules/RegisterForm/RegisterForm.tsx b/src/components/molecules/RegisterForm/RegisterForm.tsx index 2f456118..a8498425 100644 --- a/src/components/molecules/RegisterForm/RegisterForm.tsx +++ b/src/components/molecules/RegisterForm/RegisterForm.tsx @@ -129,19 +129,17 @@ const Form = () => { -

+

Already have an account? -

-

- - - -

+ + + +
) From 5aaa6beb3dacd511cc60107ca3ab25611b28bd13 Mon Sep 17 00:00:00 2001 From: sylwia-werner Date: Thu, 6 Nov 2025 12:52:36 +0100 Subject: [PATCH 03/10] fix: comment not functional link --- .../molecules/LoginForm/LoginForm.tsx | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/components/molecules/LoginForm/LoginForm.tsx b/src/components/molecules/LoginForm/LoginForm.tsx index 283faf63..fe2a7855 100644 --- a/src/components/molecules/LoginForm/LoginForm.tsx +++ b/src/components/molecules/LoginForm/LoginForm.tsx @@ -77,11 +77,12 @@ const Form = () => { /> -

+ {/* TODO: Add forgot password link when forgot password page is implemented */} + {/* Forgot your password? -

+ */} - @@ -96,13 +97,12 @@ const Form = () => { Don't have an account yet? - - + From 72f1cb1974dd90ea4ded6015fcc3ad6243ca44f7 Mon Sep 17 00:00:00 2001 From: sylwia-werner Date: Thu, 6 Nov 2025 17:47:11 +0100 Subject: [PATCH 04/10] feat: add forgot password page --- .../(main)/user/forgot-password/page.tsx | 16 ++++ .../ForgotPasswordForm/ForgotPasswordForm.tsx | 96 +++++++++++++++++++ .../molecules/ForgotPasswordForm/schema.ts | 7 ++ .../molecules/LoginForm/LoginForm.tsx | 5 +- 4 files changed, 121 insertions(+), 3 deletions(-) create mode 100644 src/app/[locale]/(main)/user/forgot-password/page.tsx create mode 100644 src/components/molecules/ForgotPasswordForm/ForgotPasswordForm.tsx create mode 100644 src/components/molecules/ForgotPasswordForm/schema.ts diff --git a/src/app/[locale]/(main)/user/forgot-password/page.tsx b/src/app/[locale]/(main)/user/forgot-password/page.tsx new file mode 100644 index 00000000..8f587156 --- /dev/null +++ b/src/app/[locale]/(main)/user/forgot-password/page.tsx @@ -0,0 +1,16 @@ +import { ForgotPasswordForm } from "@/components/molecules/ForgotPasswordForm/ForgotPasswordForm" +import { Metadata } from "next" + +export const metadata: Metadata = { + title: "Forgot password", + description: "Create a new password", +} + +export default function ForgotPasswordPage() { + + return ( +
+ +
+ ) +} diff --git a/src/components/molecules/ForgotPasswordForm/ForgotPasswordForm.tsx b/src/components/molecules/ForgotPasswordForm/ForgotPasswordForm.tsx new file mode 100644 index 00000000..135a81e3 --- /dev/null +++ b/src/components/molecules/ForgotPasswordForm/ForgotPasswordForm.tsx @@ -0,0 +1,96 @@ +"use client" +import { + FieldError, + FormProvider, + useForm, + useFormContext, +} from "react-hook-form" +import { Button } from "@/components/atoms" +import { zodResolver } from "@hookform/resolvers/zod" +import { LabeledInput } from "@/components/cells" +import { forgotPasswordSchema, ForgotPasswordFormData } from "./schema" +import { useState } from "react" +import { sendResetPasswordEmail } from "@/lib/data/customer" +import { toast } from "@/lib/helpers/toast" +import Link from "next/link" +import { FetchError } from "@medusajs/js-sdk" + +export const ForgotPasswordForm = () => { + const methods = useForm({ + resolver: zodResolver(forgotPasswordSchema), + defaultValues: { + email: "", + }, + }) + + return ( + +
+ + ) +} + +const Form = () => { + const [error, setError] = useState("") + const { + handleSubmit, + register, + formState: { errors, isSubmitting }, + reset, + } = useFormContext() + + const submit = async (data: ForgotPasswordFormData) => { + if (!data.email) return + + const result = await sendResetPasswordEmail(data.email) + + if (!result.success) { + setError(result.error || "An error occurred. Please try again.") + return + } + + setError("") + reset({ email: "" }) + + toast.success({ + title: `A password reset has been requested for ${data.email}. Check your inbox and spam folder. Remember, the link is only active for one hour.`, + }) + } + + return ( +
+

Forgot your password?

+

+ Enter the email you used to sign up and we’ll send you a password reset + email. +

+ +
+ + + {error &&

{error}

} +
+ +
+ + + + + +
+ +
+ ) +} diff --git a/src/components/molecules/ForgotPasswordForm/schema.ts b/src/components/molecules/ForgotPasswordForm/schema.ts new file mode 100644 index 00000000..144057ce --- /dev/null +++ b/src/components/molecules/ForgotPasswordForm/schema.ts @@ -0,0 +1,7 @@ +import { z } from "zod" + +export const forgotPasswordSchema = z.object({ + email: z.string().nonempty("Please enter email").email("Please enter a valid email"), +}) + +export type ForgotPasswordFormData = z.infer diff --git a/src/components/molecules/LoginForm/LoginForm.tsx b/src/components/molecules/LoginForm/LoginForm.tsx index fe2a7855..993b1b79 100644 --- a/src/components/molecules/LoginForm/LoginForm.tsx +++ b/src/components/molecules/LoginForm/LoginForm.tsx @@ -77,10 +77,9 @@ const Form = () => { /> - {/* TODO: Add forgot password link when forgot password page is implemented */} - {/* + Forgot your password? - */} + - - {error && ( -

{error}

- )} @@ -107,4 +116,4 @@ const Form = () => { ) -} +} \ No newline at end of file From 8bf6ad2a1c7bd7e375c8bef897f40fb4dd83cbad Mon Sep 17 00:00:00 2001 From: sylwia-werner Date: Sat, 8 Nov 2025 15:09:56 +0100 Subject: [PATCH 08/10] fix: update logic to handle credentials error correctly --- .../molecules/LoginForm/LoginForm.tsx | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/components/molecules/LoginForm/LoginForm.tsx b/src/components/molecules/LoginForm/LoginForm.tsx index abfb5b72..1f730ba1 100644 --- a/src/components/molecules/LoginForm/LoginForm.tsx +++ b/src/components/molecules/LoginForm/LoginForm.tsx @@ -8,7 +8,6 @@ import { } from "react-hook-form" import { Button } from "@/components/atoms" import { zodResolver } from "@hookform/resolvers/zod" -import LocalizedClientLink from "@/components/molecules/LocalizedLink/LocalizedLink" import { LabeledInput } from "@/components/cells" import { loginFormSchema, LoginFormData } from "./schema" import { useState } from "react" @@ -34,7 +33,7 @@ export const LoginForm = () => { } const Form = () => { - const [error, setError] = useState(false); + const [isAuthError, setIsAuthError] = useState(false); const { handleSubmit, register, @@ -49,16 +48,23 @@ const Form = () => { const res = await login(formData) if (res) { - setError(true); + // Temporary solution. API returns 200 code in case of auth error. To change when API is updated. + const isCredentialsError = + res.toLowerCase().includes("invalid email or password") || + res.toLowerCase().includes("unauthorized") || + res.toLowerCase().includes("incorrect") || + res.toLowerCase().includes("credentials"); + + setIsAuthError(isCredentialsError); toast.error({ title: res || "An error occurred. Please try again." }) return } - setError(false); + setIsAuthError(false); router.push("/user") } const clearApiError = () => { - error && setError(false); + isAuthError && setIsAuthError(false); } return ( @@ -71,7 +77,7 @@ const Form = () => { { label="Password" placeholder="Your password" type="password" - error={(errors.password as FieldError) || (error ? { message: '' } as FieldError : undefined)} + error={(errors.password as FieldError) || (isAuthError ? { message: '' } as FieldError : undefined)} {...register("password", { onChange: clearApiError })} From e6e08cac162e78e7ebe6cb3cf4abe8aedfb33bd3 Mon Sep 17 00:00:00 2001 From: sylwia-werner Date: Sat, 8 Nov 2025 15:10:17 +0100 Subject: [PATCH 09/10] fix: show error toast on api validation --- .../molecules/ForgotPasswordForm/ForgotPasswordForm.tsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/components/molecules/ForgotPasswordForm/ForgotPasswordForm.tsx b/src/components/molecules/ForgotPasswordForm/ForgotPasswordForm.tsx index 135a81e3..61bc3ee6 100644 --- a/src/components/molecules/ForgotPasswordForm/ForgotPasswordForm.tsx +++ b/src/components/molecules/ForgotPasswordForm/ForgotPasswordForm.tsx @@ -31,7 +31,6 @@ export const ForgotPasswordForm = () => { } const Form = () => { - const [error, setError] = useState("") const { handleSubmit, register, @@ -45,11 +44,10 @@ const Form = () => { const result = await sendResetPasswordEmail(data.email) if (!result.success) { - setError(result.error || "An error occurred. Please try again.") + toast.error({ title: result.error || "An error occurred. Please try again." }) return } - setError("") reset({ email: "" }) toast.success({ @@ -72,8 +70,6 @@ const Form = () => { error={errors.email as FieldError} {...register("email")} /> - - {error &&

{error}

}
From 5f4029f2d7393c7be83390c002df73b5930ee75c Mon Sep 17 00:00:00 2001 From: sylwia-werner Date: Mon, 17 Nov 2025 12:23:50 +0100 Subject: [PATCH 10/10] fix: PR fixes --- .../molecules/ForgotPasswordForm/ForgotPasswordForm.tsx | 4 +--- src/components/molecules/LoginForm/schema.ts | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/components/molecules/ForgotPasswordForm/ForgotPasswordForm.tsx b/src/components/molecules/ForgotPasswordForm/ForgotPasswordForm.tsx index 61bc3ee6..75e1e1f4 100644 --- a/src/components/molecules/ForgotPasswordForm/ForgotPasswordForm.tsx +++ b/src/components/molecules/ForgotPasswordForm/ForgotPasswordForm.tsx @@ -9,11 +9,9 @@ import { Button } from "@/components/atoms" import { zodResolver } from "@hookform/resolvers/zod" import { LabeledInput } from "@/components/cells" import { forgotPasswordSchema, ForgotPasswordFormData } from "./schema" -import { useState } from "react" import { sendResetPasswordEmail } from "@/lib/data/customer" import { toast } from "@/lib/helpers/toast" import Link from "next/link" -import { FetchError } from "@medusajs/js-sdk" export const ForgotPasswordForm = () => { const methods = useForm({ @@ -57,7 +55,7 @@ const Form = () => { return (
-

Forgot your password?

+

Forgot your password?

Enter the email you used to sign up and we’ll send you a password reset email. diff --git a/src/components/molecules/LoginForm/schema.ts b/src/components/molecules/LoginForm/schema.ts index e5f56675..4de5c439 100644 --- a/src/components/molecules/LoginForm/schema.ts +++ b/src/components/molecules/LoginForm/schema.ts @@ -1,7 +1,7 @@ import { z } from "zod" export const loginFormSchema = z.object({ - email: z.string().nonempty("Please enter email").email("Invalid email"), + email: z.string().nonempty("Please enter email").email("Please enter a valid email"), password: z.string().nonempty("Please enter password"), })