From ece5c222439e634977f93b688ef9fc1ee7e0c7e4 Mon Sep 17 00:00:00 2001 From: cruzzer Date: Fri, 6 Nov 2026 10:55:24 +0000 Subject: [PATCH] feat: add password visibility toggle to login form Add an eye button inside the password field that toggles between showing and hiding the typed password. The e2e login fixture now matches the password label exactly so it does not also match the toggle button's accessible name. Co-Authored-By: Claude Opus 5.5 --- e2e/fixtures/auth.fixtures.ts | 2 +- frontend/src/components/auth/login-form.tsx | 32 +++++++++++++++------ frontend/src/lib/i18n/locales/en-US.json | 1 + frontend/src/lib/i18n/locales/en.json | 1 + 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/e2e/fixtures/auth.fixtures.ts b/e2e/fixtures/auth.fixtures.ts index 73b612fc..2a937d5e 100644 --- a/e2e/fixtures/auth.fixtures.ts +++ b/e2e/fixtures/auth.fixtures.ts @@ -7,7 +7,7 @@ export class LoginFixture { async run(username: string, password: string) { await expect(this.page.getByText('Welcome back, please login')).toBeVisible(); await this.page.getByLabel('Username').fill(username); - await this.page.getByLabel('Password').fill(password); + await this.page.getByLabel('Password', { exact: true }).fill(password); await this.page.getByRole('button', { name: 'Login' }).click(); } diff --git a/frontend/src/components/auth/login-form.tsx b/frontend/src/components/auth/login-form.tsx index d76dcb6a..3ccab58a 100644 --- a/frontend/src/components/auth/login-form.tsx +++ b/frontend/src/components/auth/login-form.tsx @@ -12,6 +12,8 @@ import { } from "../ui/form"; import { loginSchema, LoginSchema } from "@/schemas/login-schema"; import z from "zod"; +import { useState } from "react"; +import { Eye, EyeOff } from "lucide-react"; interface Props { onSubmit: (data: LoginSchema) => void; @@ -23,6 +25,7 @@ interface Props { export const LoginForm = (props: Props) => { const { onSubmit, loading, formId } = props; const { t } = useTranslation(); + const [showPassword, setShowPassword] = useState(false); z.config({ customError: (iss) => @@ -61,15 +64,28 @@ export const LoginForm = (props: Props) => {
{t("loginPassword")} - - + + + + +
{ diff --git a/frontend/src/lib/i18n/locales/en-US.json b/frontend/src/lib/i18n/locales/en-US.json index 8396b225..3654a8f7 100644 --- a/frontend/src/lib/i18n/locales/en-US.json +++ b/frontend/src/lib/i18n/locales/en-US.json @@ -4,6 +4,7 @@ "loginDivider": "Or", "loginUsername": "Username", "loginPassword": "Password", + "loginPasswordToggle": "Toggle password visibility", "loginSubmit": "Login", "loginFailTitle": "Failed to log in", "loginFailSubtitle": "Please check your username and password", diff --git a/frontend/src/lib/i18n/locales/en.json b/frontend/src/lib/i18n/locales/en.json index 8396b225..3654a8f7 100644 --- a/frontend/src/lib/i18n/locales/en.json +++ b/frontend/src/lib/i18n/locales/en.json @@ -4,6 +4,7 @@ "loginDivider": "Or", "loginUsername": "Username", "loginPassword": "Password", + "loginPasswordToggle": "Toggle password visibility", "loginSubmit": "Login", "loginFailTitle": "Failed to log in", "loginFailSubtitle": "Please check your username and password",