Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 62 additions & 46 deletions frontend/src/pages/ChangePassword.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,31 @@ import { useState } from "react";
import { Spinner } from "react-activity";
import useAuth from "../hooks/context-hooks/useAuth";
import { AuthContextType } from "../types/user.types";
import { AiOutlineEye, AiOutlineEyeInvisible } from "react-icons/ai";

interface ShowPasswordState {
currentPassword: boolean;
newPassword: boolean;
confirmNewPassword: boolean;
}

const ChangePassword = () => {
const navigate = useNavigate();
const { loading, changePassword } = useChangePassword();
const { auth }: AuthContextType = useAuth();

const [data, setData] = useState({
currentPassword: "",
newPassword: "",
confirmNewPassword: "",
});
const { auth }: AuthContextType = useAuth();

// Explicitly define the type for showPassword state
const [showPassword, setShowPassword] = useState<ShowPasswordState>({
currentPassword: false,
newPassword: false,
confirmNewPassword: false,
});

const handleCancelButton = () => {
navigate(auth?.isAdmin ? "/admin" : "/homepage");
Expand All @@ -24,6 +40,13 @@ const ChangePassword = () => {
setData((prev) => ({ ...prev, [name]: value }));
};

const togglePasswordVisibility = (field: keyof ShowPasswordState) => {
setShowPassword((prev) => ({
...prev,
[field]: !prev[field],
}));
};

const handleSubmitButton = () => {
changePassword(data);
};
Expand All @@ -34,54 +57,47 @@ const ChangePassword = () => {
<Header />
</div>
<div className="h-auto w-[30rem] px-7 py-5 bg-zinc-400 rounded-md bg-clip-padding backdrop-filter backdrop-blur-sm bg-opacity-10">
<div className="space-y-5 w-full max-w-md">
<div className="flex flex-col space-y-4">
<div className="text-textgreen">
<h1 className="text-4xl font-syke-bold">Change Password</h1>
<div className="font-syke-light">Please enter your current and new password.</div>
</div>
<div className="flex-1">
<h1 className="text-white font-syke-light text-xl">
Current Password
</h1>
<input
title="currentpw"
type="password"
className="bg-secondgrey border-b font-syke-regular text-[1.2rem] w-full mt-1 px-4 py-2 h-10 border-none focus:outline-none focus:shadow-inner focus:ring-1 focus:ring-textgreen text-white placeholder-white placeholder-opacity-25 rounded-sm"
name="currentPassword"
onChange={handleChange}
required
/>
</div>

<div className="flex-1">
<h1 className="text-white font-syke-light text-xl">New Password</h1>
<input
title="newpw"
type="password"
className="bg-secondgrey border-b font-syke-regular text-[1.2rem] w-full mt-1 px-4 py-2 h-10 border-none focus:outline-none focus:shadow-inner focus:ring-1 focus:ring-textgreen text-white placeholder-white placeholder-opacity-25 rounded-sm"
name="newPassword"
onChange={handleChange}
required
/>
</div>
<div className="space-y-5 w-full max-w-md">
<div className="flex flex-col space-y-4">
<div className="text-textgreen">
<h1 className="text-4xl font-syke-bold">Change Password</h1>
<div className="font-syke-light">Please enter your current and new password.</div>
</div>

<div className="flex-1">
<h1 className="text-white font-syke-light text-xl">
Confirm Password
</h1>
<input
title="confirmpw"
type="password"
className="bg-secondgrey border-b font-syke-regular text-[1.2rem] w-full mt-1 px-4 py-2 h-10 border-none focus:outline-none focus:shadow-inner focus:ring-1 focus:ring-textgreen text-white placeholder-white placeholder-opacity-25 rounded-sm"
name="confirmNewPassword"
onChange={handleChange}
required
/>
{["currentPassword", "newPassword", "confirmNewPassword"].map((field) => (
<div className="flex-1" key={field}>
<h1 className="text-white font-syke-light text-xl">
{field === "currentPassword"
? "Current Password"
: field === "newPassword"
? "New Password"
: "Confirm Password"}
</h1>
<div className="flex items-center bg-secondgrey border-b font-syke-regular text-[1.2rem] w-full mt-1 px-2 py-2 h-10 border-none focus:outline-none focus:shadow-inner focus:ring-1 focus:ring-textgreen text-white placeholder-white placeholder-opacity-25 rounded-sm">
<input
title={field}
type={showPassword[field as keyof ShowPasswordState] ? "text" : "password"}
className="bg-secondgrey font-syke-regular w-full px-4 border-none focus:outline-none text-white placeholder-white"
name={field}
onChange={handleChange}
required
/>
<span
onMouseDown={(e) => e.preventDefault()}
onClick={() => togglePasswordVisibility(field as keyof ShowPasswordState)}
className="cursor-pointer text-textgreen ml-2"
>
{showPassword[field as keyof ShowPasswordState] ? (
<AiOutlineEyeInvisible size={20} />
) : (
<AiOutlineEye size={20} />
)}
</span>
</div>
</div>
))}
</div>
</div>
</div>

</div>

<div className="flex justify-between w-full max-w-sm p-5">
Expand Down
62 changes: 36 additions & 26 deletions frontend/src/pages/LoginPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ import React, { useState } from "react";
import { useNavigate } from "react-router-dom";
import useLogin from "../hooks/useLogin";
import { Spinner } from "react-activity";
import { AiOutlineEye, AiOutlineEyeInvisible } from "react-icons/ai";
import LandingPageHeader from "../components/LandingPageHeader";

const LoginPage = () => {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [showPassword, setShowPassword] = useState(false);
const { loading, submitLogin } = useLogin();
const navigate = useNavigate();

Expand All @@ -20,11 +23,8 @@ const LoginPage = () => {

return (
<div className="flex flex-col items-center bg-login-bg bg-cover bg-center sm:bg-cover md:bg-contain lg:bg-cover h-screen">

<div
className="mb-24"
>
<LandingPageHeader/ >
<div className="mb-24">
<LandingPageHeader />
</div>

<div className="flex bg-transparent p-6 rounded-lg w-full max-w-3xl mx-auto space-x-5">
Expand All @@ -42,61 +42,71 @@ const LoginPage = () => {
type="button"
data-testid="signup-button"
onClick={handleSignUpButton}
>
>
Sign Up
</button>
</h1>

<form
onSubmit={handleLogin}
className="space-y-2">
<form onSubmit={handleLogin} className="space-y-2">
<div>
<input
type="text"
id="email"
value={email}
onChange={(e) => {
if (e.target.value.length <= 50) {
setEmail(e.target.value);
}
}}
setEmail(e.target.value);
}
}}
className="bg-secondgrey font-syke-regular w-full mt-1 px-4 py-2 focus:shadow-inner border-none focus:outline-none focus:ring-1 focus:ring-textgreen text-white placeholder-white rounded-sm lg:text-sm md:text-xs text-xxs"
placeholder="Email address"
pattern="[\-a-zA-Z0-9~!$%^&amp;*_=+\}\{'?]+(\.[\-a-zA-Z0-9~!$%^&amp;*_=+\}\{'?]+)*@[a-zA-Z0-9_][\-a-zA-Z0-9_]*(\.[\-a-zA-Z0-9_]+)*\.[cC][oO][mM](:[0-9]{1,5})?"
required
/>
</div>
<div>

<div className="flex items-center bg-secondgrey font-syke-regular w-full mt-1 px-4 py-2 focus:shadow-inner border-none focus:outline-none focus:ring-1 focus:ring-textgreen rounded-sm text-white placeholder-white lg:text-sm md:text-xs text-xxs">
<input
type="password"
type={showPassword ? "text" : "password"}
id="password"
value={password}
onChange={(e) => {
if (e.target.value.length <= 20) {
setPassword(e.target.value);
}
}}
className="bg-secondgrey font-syke-regular w-full mt-1 px-4 py-2 focus:shadow-inner border-none focus:outline-none focus:ring-1 focus:ring-textgreen rounded-sm text-white placeholder-white lg:text-sm md:text-xs text-xxs"
setPassword(e.target.value);
}
}}
className="flex-grow bg-transparent focus:outline-none"
placeholder="Enter your password"
required
/>
<h1 className="mt-2 mb-2 text-buttongreen font-syke-medium lg:text-sm md:text-xs text-xxs">

<span
onMouseDown={(e) => e.preventDefault()}
onClick={(e) => {
e.preventDefault();
setShowPassword((prev) => !prev);
}}
className="cursor-pointer text-textgreen ml-2"
>
{showPassword ? <AiOutlineEyeInvisible size={20} /> : <AiOutlineEye size={20} />}
</span>
</div>

<div>
<h1 className="mt-2 mb-2 text-buttongreen font-syke-medium lg:text-sm md:text-xs text-xxs">
Please remember your password!
<br />
Store it somewhere safe.
</h1>
</div>

<button
type="submit"
data-testid="login-button"
className="flex w-auto bg-buttongreen text-white py-2 px-5 hover:bg-[#33471a] font-syke-regular transition-colors rounded-sm justify-center items-center lg:text-sm text-xs">
className="flex w-auto bg-buttongreen text-white py-2 px-5 hover:bg-[#33471a] font-syke-regular transition-colors rounded-sm justify-center items-center lg:text-sm text-xs"
>
{loading ? (
<Spinner
size={15}
color="#fff"
animating={loading}
/>

<Spinner size={15} color="#fff" animating={loading} />
) : (
"Login"
)}
Expand Down
65 changes: 42 additions & 23 deletions frontend/src/pages/SignUpPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { UserSignUp } from "../types/user.types";
import useSignUp from "../hooks/useSignUp";
import { Spinner } from "react-activity";
import LandingPageHeader from "../components/LandingPageHeader";
import { AiOutlineEye, AiOutlineEyeInvisible } from "react-icons/ai";

const initialFormData = {
last_name: "",
Expand All @@ -15,9 +16,10 @@ const initialFormData = {

const SignUpPage = () => {
const navigate = useNavigate();

const [signUpForm, setSignUpForm] = useState<UserSignUp>(initialFormData);
const { submitSignUp, loading } = useSignUp();
const [showPassword, setShowPassword] = useState(false);
const [showConfirmPassword, setShowConfirmPassword] = useState(false);

const handleFormChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setSignUpForm((prevFormData) => ({
Expand All @@ -38,11 +40,8 @@ const SignUpPage = () => {

return (
<div className="flex flex-col items-center bg-login-bg bg-cover bg-center sm:bg-cover md:bg-contain lg:bg-cover h-screen">

<div
className="mb-24"
>
<LandingPageHeader/ >
<div className="mb-24">
<LandingPageHeader />
</div>

<div className="flex bg-transparent p-6 rounded-lg w-full max-w-3xl mt-10 space-x-5">
Expand All @@ -52,22 +51,21 @@ const SignUpPage = () => {
</div>

<div className="w-1/2">
<h2 className="lg:text-3xl md:text-2xl sm:text-xl text-lg text-textgreen font-syke-regular-">
<h2 className="lg:text-3xl md:text-2xl sm:text-xl text-lg text-textgreen font-syke-regular">
Create new account
</h2>
<h1 className="lg:text-sm md:text-xs text-xxs mb-1 text-white">
Already have an account?{" "}
<button
className="text-buttongreen font-syke-medium"
type="button"
onClick={handleLogInButton}>
onClick={handleLogInButton}
>
Log In
</button>
</h1>

<form
className="space-y-2"
onSubmit={handleSubmit}>
<form className="space-y-2" onSubmit={handleSubmit}>
<div className="flex space-x-2.5">
<div className="flex-1">
<input
Expand Down Expand Up @@ -103,37 +101,58 @@ const SignUpPage = () => {
/>
</div>

<div>
{/* Password Field */}
<div className="flex items-center bg-secondgrey w-full px-4 py-2 rounded-sm">
<input
type="password"
className="bg-secondgrey font-syke-regular w-full mt-1 px-4 py-2 border border-none focus:outline-none focus:shadow-inner focus:ring-1 focus:ring-textgreen text-white placeholder-white rounded-sm lg:text-sm md:text-xs text-xxs"
type={showPassword ? "text" : "password"}
className="flex-grow bg-transparent focus:outline-none text-white placeholder-white lg:text-sm md:text-xs text-xxs"
placeholder="Password"
name="password"
onChange={handleFormChange}
required
/>
<span
onMouseDown={(e) => e.preventDefault()}
onClick={() => setShowPassword((prev) => !prev)}
className="cursor-pointer text-textgreen ml-2"
>
{showPassword ? (
<AiOutlineEyeInvisible size={20} />
) : (
<AiOutlineEye size={20} />
)}
</span>
</div>

<div>
{/* Confirm Password Field */}
<div className="flex items-center bg-secondgrey w-full px-4 py-2 rounded-sm">
<input
type="password"
className="bg-secondgrey font-syke-regular w-full mt-1 px-4 py-2 mb-3 border border-none focus:outline-none focus:shadow-inner focus:ring-1 focus:ring-textgreen text-white placeholder-white rounded-sm lg:text-sm md:text-xs text-xxs"
type={showConfirmPassword ? "text" : "password"}
className="flex-grow bg-transparent focus:outline-none text-white placeholder-white lg:text-sm md:text-xs text-xxs"
placeholder="Confirm Password"
name="confirm_password"
onChange={handleFormChange}
required
/>
<span
onMouseDown={(e) => e.preventDefault()}
onClick={() => setShowConfirmPassword((prev) => !prev)}
className="cursor-pointer text-textgreen ml-2"
>
{showConfirmPassword ? (
<AiOutlineEyeInvisible size={20} />
) : (
<AiOutlineEye size={20} />
)}
</span>
</div>

<button
type="submit"
className="flex justify-center items-center justify-self-end w-auto bg-buttongreen font-syke-regular text-white py-2 px-5 hover:bg-[#33471a] transition-colors rounded-sm lg:text-sm md:text-xs text-xxs">
className="flex justify-center items-center w-auto bg-buttongreen font-syke-regular text-white py-2 px-5 hover:bg-[#33471a] transition-colors rounded-sm lg:text-sm md:text-xs text-xxs"
>
{loading ? (
<Spinner
size={15}
color="#fff"
animating={loading}
/>
<Spinner size={15} color="#fff" animating={loading} />
) : (
"Create account"
)}
Expand Down
Loading
Loading