diff --git a/AceJobAgency.client/src/components/ChangePasswordView.tsx b/AceJobAgency.client/src/components/ChangePasswordView.tsx new file mode 100644 index 0000000..efa79b4 --- /dev/null +++ b/AceJobAgency.client/src/components/ChangePasswordView.tsx @@ -0,0 +1,77 @@ +import { useState } from "react"; +import { Button, Divider, Input } from "@heroui/react"; +import { toast } from "react-toastify"; +import http from "../http"; +import { validatePassword } from "./SignupView"; + +export default function ChangePasswordView({ + onClose, +}: { + onClose: () => void; +}) { + const [oldPassword, setOldPassword] = useState(""); + const [newPassword, setNewPassword] = useState(""); + const [confirmNewPassword, setConfirmNewPassword] = useState(""); + + const handleChangePassword = async () => { + if (newPassword !== confirmNewPassword) { + toast.error("New password and confirm new password do not match."); + return; + } + + if (!validatePassword(newPassword)) { + toast.error( + "Password must be at least 12 characters long and include uppercase, lowercase, number, and special character." + ); + return; + } + + const changePasswordRequest = { + currentPassword: oldPassword, + newPassword: newPassword, + }; + + try { + const response = await http.put( + "/User/change-password", + changePasswordRequest + ); + toast.success(response.data); + onClose(); + } catch (error) { + toast.error( + (error as any).response?.data || + "Something went wrong! Please try again." + ); + } + }; + + return ( +
+

Change password

+ +
+ setOldPassword(e.target.value)} + /> +
+ setNewPassword(e.target.value)} + /> + setConfirmNewPassword(e.target.value)} + /> +
+ +
+ ); +} diff --git a/AceJobAgency.client/src/components/SignupView.tsx b/AceJobAgency.client/src/components/SignupView.tsx index e1cadf5..296f8cd 100644 --- a/AceJobAgency.client/src/components/SignupView.tsx +++ b/AceJobAgency.client/src/components/SignupView.tsx @@ -4,6 +4,12 @@ import { useState } from "react"; import { toast } from "react-toastify"; import http, { login } from "../http"; +export const validatePassword = (password: string): boolean => { + const passwordComplexityRegex = + /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^A-Za-z\d])[A-Za-z\d@$!%*?&\\]{12,}$/; + return passwordComplexityRegex.test(password); +}; + export default function SignupView({ onLogin, email = "", @@ -21,12 +27,6 @@ export default function SignupView({ const [confirmPassword, setConfirmPassword] = useState(""); const [signupEnabled, setSignupEnabled] = useState(true); - const validatePassword = (password: string): boolean => { - const passwordComplexityRegex = - /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^A-Za-z\d])[A-Za-z\d@$!%*?&\\]{12,}$/; - return passwordComplexityRegex.test(password); - }; - const validateFields = () => { if ( !firstName || diff --git a/AceJobAgency.client/src/pages/MemberPage.tsx b/AceJobAgency.client/src/pages/MemberPage.tsx index 0eef687..21c97c2 100644 --- a/AceJobAgency.client/src/pages/MemberPage.tsx +++ b/AceJobAgency.client/src/pages/MemberPage.tsx @@ -2,15 +2,28 @@ import { useEffect, useState } from "react"; import http, { getAccessToken, logout } from "../http"; import { useNavigate } from "react-router-dom"; import { UserProfile } from "../models/user-profile"; -import { Button, Card, Divider, Input } from "@heroui/react"; +import { + Button, + Card, + Divider, + Input, + Modal, + ModalBody, + ModalContent, + ModalFooter, + ModalHeader, + useDisclosure, +} from "@heroui/react"; import Markdown from "react-markdown"; import remarkGfm from "remark-gfm"; -import { IconDownload, IconUpload } from "@tabler/icons-react"; +import { IconDownload, IconEdit, IconUpload } from "@tabler/icons-react"; import { toast } from "react-toastify"; +import ChangePasswordView from "../components/ChangePasswordView"; export default function MemberPage() { const accessToken = getAccessToken(); const navigate = useNavigate(); + const { isOpen, onOpen, onOpenChange } = useDisclosure(); const [userProfile, setUserProfile] = useState(null); @@ -137,7 +150,20 @@ export default function MemberPage() {
-

Who am I

+
+

Who am I

+ +
{userProfile.whoAmI.length > 0 ? ( Log out -
)} + + + {(onClose) => ( + <> + + + + + + + )} + + ); }