Skip to content

Commit

Permalink
Added vercel.json
Browse files Browse the repository at this point in the history
  • Loading branch information
Jovz19200 authored and gisubizo Jovan committed Jun 23, 2024
1 parent 1e93556 commit bb05637
Show file tree
Hide file tree
Showing 13 changed files with 345 additions and 8 deletions.
1 change: 1 addition & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ module.exports = {
"no-undef": "off",
"@typescript-eslint/ban-ts-comment": "off",
"react/no-unescaped-entities": "off",
"react/prop-types": "off",
"react-refresh/only-export-components": [
"warn",
{ allowConstantExport: true },
Expand Down
52 changes: 48 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"react-dom": "^18.2.0",
"react-hook-form": "^7.51.5",
"react-icons": "^5.2.1",
"react-modal": "^3.16.1",
"react-redux": "^9.1.2",
"react-router-dom": "^6.23.1",
"react-toastify": "^10.0.5",
Expand All @@ -43,6 +44,7 @@
"@types/jest": "^29.5.12",
"@types/react": "^18.2.66",
"@types/react-dom": "^18.2.22",
"@types/react-modal": "^3.16.3",
"@types/react-redux": "^7.1.33",
"@types/react-router-dom": "^5.3.3",
"@types/redux": "^3.6.0",
Expand Down
13 changes: 11 additions & 2 deletions src/components/common/auth/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,23 @@ interface ButtonProps {
text: string;
disabled?: boolean;
dataTestId?: string;
className?: string;
onClick?: () => void;
}

const Button: React.FC<ButtonProps> = ({ text, disabled, dataTestId }) => (
const Button: React.FC<ButtonProps> = ({
text,
disabled,
dataTestId,
className,
onClick,
}) => (
<button
type="submit"
className="bg-[#161616] text-white py-3 my-4 text-normal md:text-lg rounded-sm"
className={`bg-[#161616] text-white py-3 my-4 text-normal md:text-lg rounded-sm ${className}`}
disabled={disabled}
data-testid={dataTestId}
onClick={onClick}
>
{text}
</button>
Expand Down
4 changes: 3 additions & 1 deletion src/components/common/auth/InputField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ interface InputFieldProps {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
register: UseFormRegister<any>;
error: string | undefined;
className?: string;
}

const InputField: React.FC<InputFieldProps> = ({
Expand All @@ -16,10 +17,11 @@ const InputField: React.FC<InputFieldProps> = ({
placeholder,
register,
error,
className,
}) => (
<div className="py-4">
<input
className="w-full border-b bg-transparent font-normal text-normal py-1 border-transparent border-b-gray-500 outline-none"
className={`w-full border-b bg-transparent font-normal text-normal py-1 border-transparent border-b-gray-500 outline-none ${className}`}
type={type}
placeholder={placeholder}
{...register(name)}
Expand Down
74 changes: 74 additions & 0 deletions src/components/password/passwordUpdate.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { SubmitHandler, useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";

import updatePasswordSchema from "../../schemas/updatepasswordSchema";
import Button from "../common/auth/Button";
import InputField from "../common/auth/InputField";

interface UpdatePasswordFormInputs {
oldPassword: string;
newPassword: string;
confirmPassword: string;
}

interface PasswordUpdateFormProps {
onSubmit: SubmitHandler<UpdatePasswordFormInputs>;
onCancel: () => void;
loading: boolean;
}

const PasswordUpdateForm: React.FC<PasswordUpdateFormProps> = ({
onSubmit,
onCancel,
loading,
}) => {
const {
register,
handleSubmit,
formState: { errors },
} = useForm<UpdatePasswordFormInputs>({
resolver: yupResolver(updatePasswordSchema),
});

return (
<form onSubmit={handleSubmit(onSubmit)}>
<InputField
name="oldPassword"
type="password"
placeholder="Old Password"
register={register}
error={errors.oldPassword?.message}
/>
<InputField
name="newPassword"
type="password"
placeholder="New Password"
register={register}
error={errors.newPassword?.message}
/>
<InputField
name="confirmPassword"
type="password"
placeholder="Confirm Password"
register={register}
error={errors.newPassword?.message}
/>
<div className="mt-20 flex justify-center gap-10 w-full">
<Button
text="Cancel"
onClick={onCancel}
className=" border-red-500 text-#DB4444 py-3 px-4 my-4 text-normal md:text-lg"
data-testid="pw-cancel-btn"
/>
<Button
text={loading ? "Loading..." : "Save Password"}
className="bg-[#DB4444] text-white py-3 px-4 "
disabled={loading}
data-testid="pw-update-btn"
/>
</div>
</form>
);
};

export default PasswordUpdateForm;
101 changes: 101 additions & 0 deletions src/pages/passwordUpdatePage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { useState } from "react";
import Modal from "react-modal";
import { useDispatch, useSelector } from "react-redux";
import { toast, ToastContainer } from "react-toastify";

import PasswordUpdateForm from "../components/password/passwordUpdate";
import { RootState } from "../redux/store";
import { updatePassword } from "../redux/api/updatePasswordApiSlice";
import Button from "../components/common/auth/Button";

Modal.setAppElement("#root");

const UpdatePasswordPage = () => {
const [modalIsOpen, setModalIsOpen] = useState(false);
const dispatch = useDispatch();
const loading = useSelector((state: RootState) => state.password.loading);

const openModal = () => {
setModalIsOpen(true);
};

const closeModal = () => {
setModalIsOpen(false);
};

const onSubmit = async (data: {
oldPassword: string;
newPassword: string;
confirmPassword: string;
}) => {
try {
// @ts-ignore
const result = await dispatch(updatePassword(data)).unwrap();
const { message } = result;
toast.success(message);
closeModal();
} catch (error) {
toast.error("Failed to update password.");
}
};

return (
<div className="w-full h-screen flex justify-center items-center">
<ToastContainer />
<Button
onClick={openModal}
className="bg-[#DB4444] text-white py-3 px-2 my-4 text-normal md:text-lg rounded-sm"
text="Update Password"
/>
<Modal
isOpen={modalIsOpen}
onRequestClose={closeModal}
style={{
overlay: {
backgroundColor: "rgba(211, 211, 211, 0.5)", // or D0D0D0
},
content: {
top: "50%",
left: "50%",
right: "auto",
bottom: "auto",
marginRight: "-50%",
transform: "translate(-50%, -50%)",
width: "50%",
height: "80%",
},
}}
>
<div className="flex justify-center">
<h1 className="absolute top-8 font-bold text-[#DB4444]">
Update Your Password
</h1>
</div>
<div
className="mt-20"
style={{
width: "100%",
display: "flex",
justifyContent: "center",
alignItems: "center",
}}
>
<PasswordUpdateForm
onCancel={closeModal}
onSubmit={onSubmit}
loading={loading}
/>
</div>
<div className="flex justify-center">
<p className="absolute bottom-6 text-sm flex justify-center items-center">
For your own Security we recommend you to have a &nbsp;
<span className="font-bold">strong Password</span>
&nbsp;!
</p>
</div>
</Modal>
</div>
);
};

export default UpdatePasswordPage;
2 changes: 1 addition & 1 deletion src/redux/api/loginApiSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ LoginPayload,
{ rejectValue: LoginError }
>("login", async (payload, { rejectWithValue }) => {
try {
const response = await axios.post("/users/login", payload);
const response = await axios.post("/api/v1/users/login", payload);
return response.data;
} catch (error) {
const axiosError = error as AxiosError<LoginError>;
Expand Down
Loading

0 comments on commit bb05637

Please sign in to comment.