From 0c0fc5515eb46175d9f3d356d4f012e17ca3e392 Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Sun, 17 Sep 2023 15:18:46 +0330 Subject: [PATCH] add RegEx for password field and add chnage password option for expert management and a bit debug on update of expert --- public/locales/fa/app.json | 6 ++ .../ChangePassword/ChangePasswordContent.jsx | 91 +++++++++++++++++++ .../Form/ChangePassword/index.jsx | 33 +++++++ .../Form/CreateForm/CreateContent.jsx | 29 +++++- .../Form/UpdateForm/UpdateContent.jsx | 3 +- .../Form/UpdateForm/index.jsx | 23 ----- .../expert-management/TableRowActions.jsx | 7 ++ 7 files changed, 164 insertions(+), 28 deletions(-) create mode 100644 src/components/dashboard/expert-management/Form/ChangePassword/ChangePasswordContent.jsx create mode 100644 src/components/dashboard/expert-management/Form/ChangePassword/index.jsx diff --git a/public/locales/fa/app.json b/public/locales/fa/app.json index 60482e2..8aa65ff 100644 --- a/public/locales/fa/app.json +++ b/public/locales/fa/app.json @@ -345,6 +345,7 @@ "button-confirm": "ثبت", "create": "افزودن کارشناس", "update": "ویرایش کارشناس", + "change_password": "تغییر رمز عبور", "text_field_name": "نام", "text_field_username": "نام کاربری", "text_field_email": "پست الکترونیک", @@ -362,21 +363,26 @@ "text_field_please_select_province": "ابتدا استان خود را انتخاب کنید", "text_field_loading_cities_list": "درحال دریافت شهر ها", "text_field_error_fetching_cities": "خطا در دریافت شهر ها", + "text_field_new_password": "رمز عبور جدید", "error_message_name": "نام خود را وارد کنید", "error_message_username": "نام کاربری خود را وارد کنید", "error_message_email": "پست الکترونیک خود را وارد کنید", "error_message_phone_number": "شماره همراه خود را وارد کنید", "error_message_national_id": "کد ملی خود را وارد کنید", "error_message_password": "رمز عبور خود را وارد کنید", + "error_message_password_regex": "رمز عبور باید حداقل 8 کاراکتر و متشکل از عدد، حرف یا سمبل باشد", "error_message_position": "سمت خود را وارد کنید", "error_message_province_id": "استان خود را وارد کنید", "error_message_city_id": "شهر خود را وارد کنید", "error_message_role_id": "نقش خود را وارد کنید", + "error_message_new_password": "رمز عبور جدید را وارد کنید", + "error_message_new_password_regex": "رمز عبور باید حداقل 8 کاراکتر و متشکل از عدد، حرف یا سمبل باشد", "personal_info": "مشخصات کارشناس", "user_info": "اطلاعات کاربری", "rest_info": "اطلاعات تکمیلی", "delete_tooltip": "حذف", "update_tooltip": "ویرایش کارشناس", + "change_password_tooltip": "تغییر رمز عبور", "delete_expert": "حذف کارشناس", "are_you_sure_text": "آیا از انجام این عملیات اطمینان دارید؟" } diff --git a/src/components/dashboard/expert-management/Form/ChangePassword/ChangePasswordContent.jsx b/src/components/dashboard/expert-management/Form/ChangePassword/ChangePasswordContent.jsx new file mode 100644 index 0000000..da9abab --- /dev/null +++ b/src/components/dashboard/expert-management/Form/ChangePassword/ChangePasswordContent.jsx @@ -0,0 +1,91 @@ +import {useTranslations} from "next-intl"; +import {Button, DialogActions, DialogContent, IconButton, InputAdornment, TextField} from "@mui/material"; +import {CHANGE_PASSWORD_EXPERT_MANAGEMENT} from "@/core/data/apiRoutes"; +import {useFormik} from "formik"; +import * as Yup from "yup"; +import {Visibility, VisibilityOff} from "@mui/icons-material"; +import {useState} from "react"; +import useRequest from "@/lib/app/hooks/useRequest"; + + +const ChnagePasswordContent = ({rowId, fetchUrl, mutate, setOpenChangePasswordDialog}) => { + const t = useTranslations(); + const requestServer = useRequest(); + const [showPassword, setShowPassword] = useState(false); + + const handleClickShowPassword = () => { + setShowPassword(!showPassword); + }; + + const validationSchema = Yup.object().shape({ + new_password: Yup.string() + .required(t("ExpertMangement.error_message_new_password")) + .matches( + /^(?=.*[0-9])(?=.*[A-Za-z!@#$%^&*])[A-Za-z!@#$%^&*\d]{8,}$/, + t("ExpertMangement.error_message_new_password_regex") + ), + }); + + const formik = useFormik({ + initialValues: { + new_password: "", + }, + validationSchema, + onSubmit: (values, {setSubmitting}) => { + const formData = new FormData(); + formData.append("new_password", values.new_password); + + requestServer(`${CHANGE_PASSWORD_EXPERT_MANAGEMENT}/${rowId}`, 'post', { + auth: true, + data: formData + }) + .then((response) => { + mutate(fetchUrl) + }).catch(() => { + }).finally(() => { + setSubmitting(false); + }); + }, + }); + + return ( + <> + + + + {showPassword ? : } + + + ), + }} + sx={{width: "100%"}} + /> + + + + + + + ); +}; +export default ChnagePasswordContent; \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/ChangePassword/index.jsx b/src/components/dashboard/expert-management/Form/ChangePassword/index.jsx new file mode 100644 index 0000000..958d1c8 --- /dev/null +++ b/src/components/dashboard/expert-management/Form/ChangePassword/index.jsx @@ -0,0 +1,33 @@ +import {useTranslations} from "next-intl"; +import {Dialog, DialogTitle, IconButton, Tooltip} from "@mui/material"; +import KeyIcon from '@mui/icons-material/Key'; +import {useState} from "react"; +import ChangePasswordContent from "./ChangePasswordContent"; + + +const ChangePassword = ({rowId, fetchUrl, mutate}) => { + const t = useTranslations(); + const [openChnagePasswordDialog, setOpenChangePasswordDialog] = useState(false); + + return ( + <> + + { + setOpenChangePasswordDialog(true) + }} + > + + + + + {t("ExpertMangement.change_password")} + + + + ); +}; +export default ChangePassword; \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent.jsx b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent.jsx index f2e43cb..c22783a 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent.jsx +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent.jsx @@ -8,6 +8,8 @@ import { FormControl, FormHelperText, Grid, + IconButton, + InputAdornment, InputLabel, MenuItem, Select, @@ -16,11 +18,12 @@ import { import {useFormik} from "formik"; import {useTranslations} from "next-intl"; import * as Yup from "yup"; -import {useEffect, useState} from "react"; -import {CREATE_EXPERT_MANAGEMENT, GET_CITY_LIST, GET_ROLE_LIST} from "@/core/data/apiRoutes"; +import {useState} from "react"; +import {CREATE_EXPERT_MANAGEMENT, GET_CITY_LIST} from "@/core/data/apiRoutes"; import useRequest from "@/lib/app/hooks/useRequest"; import useProvince from "@/lib/app/hooks/useProvince"; import useRole from "@/lib/app/hooks/useRole"; +import {Visibility, VisibilityOff} from "@mui/icons-material"; const CreateContent = ({setOpenCreateDialog, mutate, fetchUrl}) => { const t = useTranslations(); @@ -29,6 +32,11 @@ const CreateContent = ({setOpenCreateDialog, mutate, fetchUrl}) => { const [cityTextField, setCityTextField] = useState(t("ExpertMangement.text_field_please_select_province")); const {provinceList, isLoadingProvinceList, errorProvinceList} = useProvince(); const {roleList, isLoadingRoleList, errorRoleList} = useRole(); + const [showPassword, setShowPassword] = useState(false); + + const handleClickShowPassword = () => { + setShowPassword(!showPassword); + }; function getCities(province_id) { formik.setFieldTouched("city_id", false, false); @@ -56,7 +64,12 @@ const CreateContent = ({setOpenCreateDialog, mutate, fetchUrl}) => { email: Yup.string().required(t("ExpertMangement.error_message_email")), phone_number: Yup.string().required(t("ExpertMangement.error_message_phone_number")), national_id: Yup.string().required(t("ExpertMangement.error_message_national_id")), - password: Yup.string().required(t("ExpertMangement.error_message_password")), + password: Yup.string() + .required(t("ExpertMangement.error_message_password")) + .matches( + /^(?=.*[0-9])(?=.*[A-Za-z!@#$%^&*])[A-Za-z!@#$%^&*\d]{8,}$/, + t("ExpertMangement.error_message_password_regex") + ), position: Yup.string().required(t("ExpertMangement.error_message_position")), province_id: Yup.string().required(t("ExpertMangement.error_message_province_id")), city_id: Yup.string().required(t("ExpertMangement.error_message_city_id")), @@ -208,6 +221,16 @@ const CreateContent = ({setOpenCreateDialog, mutate, fetchUrl}) => { onBlur={formik.handleBlur} error={formik.touched.password && !!formik.errors.password} helperText={formik.touched.password && formik.errors.password ? formik.errors.password : null} + type={showPassword ? "text" : "password"} + InputProps={{ + endAdornment: ( + + + {showPassword ? : } + + + ), + }} sx={{width: "100%"}} /> diff --git a/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent.jsx b/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent.jsx index 45edcde..0b8ae58 100644 --- a/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent.jsx +++ b/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent.jsx @@ -59,7 +59,6 @@ const UpdateContent = ({row, fetchUrl, mutate, setOpenUpdateDialog}) => { email: Yup.string().required(t("ExpertMangement.error_message_email")), phone_number: Yup.string().required(t("ExpertMangement.error_message_phone_number")), national_id: Yup.string().required(t("ExpertMangement.error_message_national_id")), - password: Yup.string().required(t("ExpertMangement.error_message_password")), position: Yup.string().required(t("ExpertMangement.error_message_position")), province_id: Yup.string().required(t("ExpertMangement.error_message_province_id")), city_id: Yup.string().required(t("ExpertMangement.error_message_city_id")), @@ -300,7 +299,7 @@ const UpdateContent = ({row, fetchUrl, mutate, setOpenUpdateDialog}) => {