add mui lab and @resolver/yup for react hook form package and complete change password part with validation and test proccess

This commit is contained in:
2024-08-24 14:39:04 +03:30
parent c2e0420b79
commit 52e7fae709
5 changed files with 144 additions and 43 deletions

View File

@@ -14,7 +14,9 @@
"@emotion/cache": "^11.11.0", "@emotion/cache": "^11.11.0",
"@emotion/react": "^11.11.3", "@emotion/react": "^11.11.3",
"@emotion/styled": "^11.11.0", "@emotion/styled": "^11.11.0",
"@hookform/resolvers": "^3.9.0",
"@mui/icons-material": "^5.15.6", "@mui/icons-material": "^5.15.6",
"@mui/lab": "^5.0.0-alpha.173",
"@mui/material": "^5.15.6", "@mui/material": "^5.15.6",
"@mui/material-nextjs": "^5.15.6", "@mui/material-nextjs": "^5.15.6",
"@mui/x-date-pickers": "^6.19.5", "@mui/x-date-pickers": "^6.19.5",

View File

@@ -1,12 +1,48 @@
"use client"; "use client";
import { Chip, Divider, Grid, TextField } from "@mui/material"; import {
Chip,
Divider,
FormControl,
FormHelperText,
Grid,
IconButton,
InputAdornment,
InputLabel,
OutlinedInput,
} from "@mui/material";
import StyledForm from "@/core/components/StyledForm"; import StyledForm from "@/core/components/StyledForm";
import { useForm } from "react-hook-form"; import { useForm } from "react-hook-form";
import { useAuth } from "@/lib/contexts/auth";
import useRequest from "@/lib/hooks/useRequest";
import { CHANGE_USER_PASSWORD } from "@/core/utils/routes";
import { object, string } from "yup";
import { yupResolver } from "@hookform/resolvers/yup";
import { useEffect, useState } from "react";
import Visibility from "@mui/icons-material/Visibility";
import VisibilityOff from "@mui/icons-material/VisibilityOff";
const validationSchema = object({
current_password: string().required("اجباری"),
new_password: string().required("اجباری"),
repeat_new_password: string().required("اجباری").test(
"password-match",
"رمز عبور جدید و تکرار آن باید یکسان باشند",
function(value) {
return this.parent.new_password === value;
},
),
});
const Form = ({ handleCloseForm, setLoading }) => {
const [showNewPassword, setShowNewPassword] = useState();
const [showRepeatNewPassword, setShowRepeatNewPassword] = useState();
const request = useRequest();
const { getUser } = useAuth();
const Form = () => {
const defaultValues = { const defaultValues = {
old_password: "", current_password: "",
new_password: "", new_password: "",
repeat_new_password: "", repeat_new_password: "",
}; };
@@ -17,45 +53,102 @@ const Form = () => {
register, register,
handleSubmit, handleSubmit,
setValue, setValue,
formState: { isSubmitting }, formState: { isSubmitting, errors },
} = useForm({ defaultValues: defaultValues }); } = useForm({ defaultValues, resolver: yupResolver(validationSchema) });
useEffect(() => {
setLoading(isSubmitting);
}, [isSubmitting]);
const onSubmit = async (data) => {
const formData = new FormData();
formData.append("current_password", data.current_password);
formData.append("new_password", data.new_password);
try {
await request(CHANGE_USER_PASSWORD, "post", { data: formData });
handleCloseForm();
} catch (error) {
}
};
return ( return (
<> <>
<Divider sx={{ mb: 3 }}> <Divider sx={{ mb: 3 }}>
<Chip color="primary" variant="outlined" label="تغییر رمز عبور" /> <Chip color="primary" variant="outlined" label="تغییر رمز عبور" />
</Divider> </Divider>
<StyledForm id={"ChangePassword"}> <StyledForm onSubmit={handleSubmit(onSubmit)} id={"ChangePassword"}>
<Grid container columns={{ xs: 1, sm: 3 }} spacing={2}> <Grid container columns={{ xs: 1 }} spacing={3}>
<Grid item xs={1}> <Grid item xs={1}>
<TextField <FormControl error={!!errors.current_password} size="small" fullWidth variant="outlined">
autoComplete="off" <InputLabel htmlFor="current_password">رمز عبور فعلی</InputLabel>
{...register("old_password")} <OutlinedInput
id="current_password"
label="رمز عبور فعلی" label="رمز عبور فعلی"
autoComplete="off"
{...register("current_password")}
size="small" size="small"
fullWidth fullWidth
type="text" type="text"
/> />
<FormHelperText
id="current_password">{errors.current_password ? errors.current_password.message : null}</FormHelperText>
</FormControl>
</Grid> </Grid>
<Grid item xs={1}> <Grid item xs={1}>
<TextField <FormControl error={!!errors.new_password} size="small" fullWidth variant="outlined">
<InputLabel htmlFor="new_password">رمز عبور جدید</InputLabel>
<OutlinedInput
id="new_password"
autoComplete="off" autoComplete="off"
{...register("new_password")} {...register("new_password")}
label="رمز عبور جدید" label="رمز عبور جدید"
size="small" size="small"
fullWidth fullWidth
type="text" type={showNewPassword ? "text" : "password"}
endAdornment={
<InputAdornment position="end">
<IconButton
aria-label="toggle password visibility"
onClick={() => setShowNewPassword(!showNewPassword)}
onMouseDown={(event) => event.preventDefault()}
edge="end"
>
{showNewPassword ? <VisibilityOff /> : <Visibility />}
</IconButton>
</InputAdornment>
}
/> />
<FormHelperText
id="new_password">{errors.new_password ? errors.new_password.message : null}</FormHelperText>
</FormControl>
</Grid> </Grid>
<Grid item xs={1}> <Grid item xs={1}>
<TextField <FormControl error={!!errors.repeat_new_password} size="small" fullWidth variant="outlined">
<InputLabel htmlFor="repeat_new_password">تکرار رمز عبور جدید</InputLabel>
<OutlinedInput
id="repeat_new_password"
autoComplete="off" autoComplete="off"
{...register("repeat_new_password")} {...register("repeat_new_password")}
label="تکرار رمز عبور جدید"
size="small" size="small"
fullWidth fullWidth
type="text" label="تکرار رمز عبور جدید"
type={showRepeatNewPassword ? "text" : "password"}
endAdornment={
<InputAdornment position="end">
<IconButton
aria-label="toggle password visibility"
onClick={() => setShowRepeatNewPassword(!showRepeatNewPassword)}
onMouseDown={(event) => event.preventDefault()}
edge="end"
>
{showRepeatNewPassword ? <VisibilityOff /> : <Visibility />}
</IconButton>
</InputAdornment>
}
/> />
<FormHelperText
id="repeat_new_password">{errors.repeat_new_password ? errors.repeat_new_password.message : null}</FormHelperText>
</FormControl>
</Grid> </Grid>
</Grid> </Grid>
</StyledForm> </StyledForm>

View File

@@ -3,29 +3,34 @@
import { Button, Dialog, DialogActions, DialogContent } from "@mui/material"; import { Button, Dialog, DialogActions, DialogContent } from "@mui/material";
import { useTheme } from "@mui/material/styles"; import { useTheme } from "@mui/material/styles";
import Form from "./Form"; import Form from "./Form";
import SaveIcon from "@mui/icons-material/Save";
import { LoadingButton } from "@mui/lab";
import { useState } from "react";
const ChangePass = ({ open, setOpen }) => { const ChangePass = ({ open, setOpen }) => {
const theme = useTheme(); const theme = useTheme();
const [loading, setLoading] = useState(false);
const handleCloseForm = () => {
setOpen(false);
};
return ( return (
<Dialog maxWidth="sm" fullWidth={true} open={open} <Dialog maxWidth="xs" fullWidth={true} open={open}
onClose={() => { onClose={handleCloseForm}>
setOpen(false);
}}>
<DialogContent dividers> <DialogContent dividers>
<Form /> <Form handleCloseForm={handleCloseForm} setLoading={setLoading} />
</DialogContent> </DialogContent>
<DialogActions> <DialogActions>
<Button autoFocus variant="outlined" color="error" onClick={() => { <Button size="large" autoFocus variant="outlined" color="error" onClick={handleCloseForm}>
setOpen(false);
}}>
بستن بستن
</Button> </Button>
<Button autoFocus variant="contained" onClick={() => { <LoadingButton type="submit" loading={loading} form={"ChangePassword"} size="large" autoFocus
setOpen(false); variant="contained"
}}> loadingPosition="end"
endIcon={<SaveIcon />}>
ثبت ثبت
</Button> </LoadingButton>
</DialogActions> </DialogActions>
</Dialog> </Dialog>
); );

View File

@@ -1,6 +1,7 @@
const api = process.env.NEXT_PUBLIC_API_URL; const api = process.env.NEXT_PUBLIC_API_URL;
export const GET_USER_ROUTE = api + "/api/v3/profile/info"; export const GET_USER_ROUTE = api + "/api/v3/profile/info";
export const CHANGE_USER_PASSWORD = api + "/api/v3/profile/change_password";
export const GET_LOGIN_ROUTE = api + "/login_dev"; export const GET_LOGIN_ROUTE = api + "/login_dev";
export const GET_INQUIRY_PRIVACY_FENCING_ROUTE = api + "/api/v3/harim/divarkeshi"; export const GET_INQUIRY_PRIVACY_FENCING_ROUTE = api + "/api/v3/harim/divarkeshi";
export const GET_PERMISSIONS_ROUTE = api + "/webapi/user/get-permission"; export const GET_PERMISSIONS_ROUTE = api + "/webapi/user/get-permission";