diff --git a/logify-frontend/src/components/ui/PasswordInput.jsx b/logify-frontend/src/components/ui/PasswordInput.jsx new file mode 100644 index 0000000..7c4ede8 --- /dev/null +++ b/logify-frontend/src/components/ui/PasswordInput.jsx @@ -0,0 +1,73 @@ +import { useState } from "react"; +import { Eye, EyeOff } from "lucide-react"; +import PropTypes from "prop-types"; + +function PasswordInput({ + label, + name, + value, + onChange, + placeholder = "Enter your password", + error, + className = "", + id, + ...props +}) { + const [isVisible, setIsVisible] = useState(false); + const inputId = id || `password-input-${name}`; + + const toggleVisibility = () => { + setIsVisible(!isVisible); + }; + + return ( +
+ {label && ( + + )} +
+ + +
+ {error &&

{error}

} +
+ ); +} + +PasswordInput.propTypes = { + label: PropTypes.string, + name: PropTypes.string.isRequired, + value: PropTypes.string.isRequired, + onChange: PropTypes.func.isRequired, + placeholder: PropTypes.string, + error: PropTypes.string, + className: PropTypes.string, + id: PropTypes.string, +}; + +export default PasswordInput; diff --git a/logify-frontend/src/pages/AdminSignupPage.jsx b/logify-frontend/src/pages/AdminSignupPage.jsx index 6de8074..c031f79 100644 --- a/logify-frontend/src/pages/AdminSignupPage.jsx +++ b/logify-frontend/src/pages/AdminSignupPage.jsx @@ -4,6 +4,7 @@ import { Link, useNavigate } from "react-router-dom"; import { api } from "../config/api.js"; import { AuthContext } from "../contexts/AuthContext"; import Loading from "../components/ui/Loading"; +import PasswordInput from "../components/ui/PasswordInput"; import AuthActionButton from "../components/ui/AuthActionButton"; import AuthLayout from "./auth/AuthLayout"; import GuestOnlyRoute from "./auth/GuestOnlyRoute"; @@ -307,43 +308,23 @@ const AdminSignupPage = () => { )} -
- - - {fieldErrors.password && ( -

- {fieldErrors.password} -

- )} -
+ -
- - - {fieldErrors.confirmPassword && ( -

- {fieldErrors.confirmPassword} -

- )} -
+ {error && (
diff --git a/logify-frontend/src/pages/LoginPage.jsx b/logify-frontend/src/pages/LoginPage.jsx index 82ae31b..81ed922 100644 --- a/logify-frontend/src/pages/LoginPage.jsx +++ b/logify-frontend/src/pages/LoginPage.jsx @@ -3,6 +3,7 @@ import { Link, useLocation } from "react-router-dom"; import { AuthContext } from "../contexts/AuthContext"; import Loading from "../components/ui/Loading"; +import PasswordInput from "../components/ui/PasswordInput"; import AuthLayout from "./auth/AuthLayout"; import GuestOnlyRoute from "./auth/GuestOnlyRoute"; @@ -76,23 +77,13 @@ const LoginPage = () => { />
-
- - -
+ {error && (
diff --git a/logify-frontend/src/pages/StudentSignupPage.jsx b/logify-frontend/src/pages/StudentSignupPage.jsx index 06fab2c..4259edc 100644 --- a/logify-frontend/src/pages/StudentSignupPage.jsx +++ b/logify-frontend/src/pages/StudentSignupPage.jsx @@ -1,6 +1,7 @@ import { useContext, useEffect, useState } from "react"; import { AuthContext } from "../contexts/AuthContext"; import Loading from "../components/ui/Loading"; +import PasswordInput from "../components/ui/PasswordInput"; import AuthLayout from "./auth/AuthLayout"; import GuestOnlyRoute from "./auth/GuestOnlyRoute"; import { api } from "../config/api.js"; @@ -442,43 +443,23 @@ const StudentSignupPage = () => { )}
-
- - - {fieldErrors.password && ( -

- {fieldErrors.password} -

- )} -
- -
- - - {fieldErrors.confirmPassword && ( -

- {fieldErrors.confirmPassword} -

- )} -
+ + + {error && (
diff --git a/logify-frontend/src/pages/SupervisorSignupPage.jsx b/logify-frontend/src/pages/SupervisorSignupPage.jsx index fc21d8a..0d72bd4 100644 --- a/logify-frontend/src/pages/SupervisorSignupPage.jsx +++ b/logify-frontend/src/pages/SupervisorSignupPage.jsx @@ -4,6 +4,7 @@ import { Link, useNavigate, useLocation } from "react-router-dom"; import { api } from "../config/api.js"; import { AuthContext } from "../contexts/AuthContext"; import Loading from "../components/ui/Loading"; +import PasswordInput from "../components/ui/PasswordInput"; import AuthActionButton from "../components/ui/AuthActionButton"; import AuthLayout from "./auth/AuthLayout"; import GuestOnlyRoute from "./auth/GuestOnlyRoute"; @@ -400,43 +401,23 @@ const SupervisorSignupPage = () => {
)} -
- - - {fieldErrors.password && ( -

- {fieldErrors.password} -

- )} -
+ -
- - - {fieldErrors.confirmPassword && ( -

- {fieldErrors.confirmPassword} -

- )} -
+ {error && (
diff --git a/logify-frontend/src/tests/authRoutes.test.jsx b/logify-frontend/src/tests/authRoutes.test.jsx index 0368dc5..b8fa197 100644 --- a/logify-frontend/src/tests/authRoutes.test.jsx +++ b/logify-frontend/src/tests/authRoutes.test.jsx @@ -151,7 +151,7 @@ test("login page forwards the original destination to the login action", async ( fireEvent.change(screen.getByLabelText(/email \/ webmail/i), { target: { value: "student@example.com" }, }); - fireEvent.change(screen.getByLabelText(/password/i), { + fireEvent.change(screen.getByLabelText(/^password$/i), { target: { value: "password123" }, }); fireEvent.click(screen.getByRole("button", { name: /login/i }));