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 }));