Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

501 linhas
30 KiB

  1. import { useFormik } from 'formik';
  2. import * as yup from 'yup';
  3. import * as React from "react";
  4. import * as HttpUtils from "utils/HttpUtils";
  5. import * as UrlUtils from "utils/ApiPathConst";
  6. import { useNavigate } from "react-router-dom";
  7. import {
  8. Grid,
  9. Typography,
  10. Button,
  11. // RadioGroup,
  12. Dialog, DialogTitle, DialogContent, DialogActions,
  13. Stack,
  14. // InputLabel,
  15. // OutlinedInput,
  16. FormHelperText,
  17. TextField,
  18. IconButton, InputAdornment,
  19. // Box,
  20. // FormControl
  21. } from '@mui/material';
  22. import Loadable from 'components/Loadable';
  23. const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent')));
  24. import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png'
  25. // import ForwardIcon from '@mui/icons-material/Forward';
  26. import MainCard from 'components/MainCard';
  27. import {PNSPS_LONG_BUTTON_THEME} from "themes/buttonConst";
  28. import {ThemeProvider} from "@emotion/react";
  29. import {FormattedMessage, useIntl} from "react-intl";
  30. import { EyeInvisibleOutlined, EyeOutlined } from '@ant-design/icons';
  31. import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline';
  32. import { useDispatch } from "react-redux";
  33. import { handleLogoutFunction} from 'auth/index';
  34. import { isPasswordExpiry } from "utils/Utils";
  35. import usePageTitle from "components/usePageTitle";
  36. // ==============================|| DASHBOARD - DEFAULT ||============================== //
  37. const Index = () => {
  38. usePageTitle("userChangePassword");
  39. const dispatch = useDispatch()
  40. const navigate = useNavigate()
  41. const [showPassword, setShowPassword] = React.useState(false);
  42. const [showNewPassword, setShowNewPassword] = React.useState(false);
  43. const [showConfirmPassword, setshowConfirmPassword] = React.useState(false);
  44. const [isLoading, setLoding] = React.useState(true);
  45. const [isChanged, setIsChanged] = React.useState(false);
  46. const [comfirmChangeMessage, setComfirmChangeMessage] = React.useState(false);
  47. const [expiryErr, setExpiryErr] = React.useState(false);
  48. const [expiryErrText, setExpiryErrText] = React.useState("");
  49. const [changePasswordValues, setChangePasswordValues] = React.useState();
  50. const intl = useIntl();
  51. React.useEffect(() => {
  52. setLoding(false)
  53. }, []);
  54. const goLogin = (values) =>{
  55. // console.log(values)
  56. setComfirmChangeMessage(false)
  57. HttpUtils.post({
  58. url: UrlUtils.PATCH_CHANGE_PASSWORD,
  59. params:{
  60. password: values.password,
  61. newPassword: values.newPassword
  62. },
  63. onSuccess: function (){
  64. setIsChanged(true);
  65. },
  66. onError:function (error) {
  67. // console.log(error.response.data);
  68. setExpiryErrText(intl.formatMessage({ id: error.response.data.error }))
  69. setExpiryErr(true)
  70. // window.location.assign("/iamsmart/loginFail");
  71. }
  72. });
  73. }
  74. const BackgroundHead = {
  75. backgroundImage: `url(${titleBackgroundImg})`,
  76. width: 'auto',
  77. height: 'auto',
  78. backgroundSize: 'contain',
  79. backgroundRepeat: 'no-repeat',
  80. backgroundColor: '#0C489E',
  81. backgroundPosition: 'right'
  82. }
  83. const handleClickShowPassword = () => {
  84. setShowPassword(!showPassword);
  85. };
  86. const handleClickShowNewPassword = () => {
  87. setShowNewPassword(!showNewPassword);
  88. };
  89. const handleClickShowConfirmPassword = () => {
  90. setshowConfirmPassword(!showConfirmPassword);
  91. };
  92. const handleMouseDownPassword = (event) => {
  93. event.preventDefault();
  94. };
  95. const handleMouseDownNewPassword = (event) => {
  96. event.preventDefault();
  97. };
  98. const changePassword = (
  99. // value
  100. ) => {
  101. // const temp = strengthIndicator(value);
  102. // setLevel(strengthColorChi(temp));
  103. };
  104. const logout = () => {
  105. dispatch(handleLogoutFunction());
  106. navigate('/login');
  107. };
  108. const formik = useFormik({
  109. enableReinitialize: true,
  110. initialValues: {
  111. // username: '',
  112. password: '',
  113. newPassword: '',
  114. confirmPassword: '',
  115. // emailVerifyHash: '',
  116. },
  117. validationSchema: yup.object().shape({
  118. // emailVerifyHash: yup.string().required(intl.formatMessage({id: 'requireSecurityCode'})),
  119. // username: yup.string().required(intl.formatMessage({id: 'requireUsername'})),
  120. password: yup.string().min(8, intl.formatMessage({id: 'atLeast8CharPassword'}))
  121. .required(intl.formatMessage({id: 'requirePassword'}))
  122. .matches(/^\S*$/, { message: (intl.formatMessage({id: 'noSpacePassword'}))})
  123. .matches(/^(?=.*[a-z])/, { message: intl.formatMessage({id: 'atLeastOneSmallLetter'})})
  124. .matches(/^(?=.*[A-Z])/, { message: intl.formatMessage({id: 'atLeastOneCapLetter'})})
  125. .matches(/^(?=.*[0-9])/, { message: intl.formatMessage({id: 'atLeast1Number'})})
  126. .matches(/^(?=.*\W)/, { message: intl.formatMessage({id: 'atLeast1SpecialChar'})}),
  127. newPassword: yup.string().min(8, intl.formatMessage({id: 'atLeast8CharPassword'}))
  128. .required(intl.formatMessage({id: 'requirePassword'}))
  129. .matches(/^\S*$/, { message: (intl.formatMessage({id: 'noSpacePassword'}))})
  130. .matches(/^(?=.*[a-z])/, { message: intl.formatMessage({id: 'atLeastOneSmallLetter'})})
  131. .matches(/^(?=.*[A-Z])/, { message: intl.formatMessage({id: 'atLeastOneCapLetter'})})
  132. .matches(/^(?=.*[0-9])/, { message: intl.formatMessage({id: 'atLeast1Number'})})
  133. .matches(/^(?=.*\W)/, { message: intl.formatMessage({id: 'atLeast1SpecialChar'})}),
  134. confirmPassword: yup.string().min(8, intl.formatMessage({id: 'atLeast8CharPassword'}))
  135. .required(intl.formatMessage({id: 'pleaseConfirmPassword'}))
  136. .oneOf([yup.ref('newPassword'), null], intl.formatMessage({id: 'samePassword'})),
  137. }),
  138. onSubmit: values => {
  139. // console.log(values)
  140. setChangePasswordValues(values)
  141. setComfirmChangeMessage(true)
  142. }
  143. });
  144. const handleCCPChange = (e) => {
  145. e.preventDefault();
  146. };
  147. return (
  148. isLoading ?
  149. <Grid container sx={{ minHeight: '87vh', mb: 3 }} direction="column" justifyContent="center" alignItems="center">
  150. <Grid item>
  151. <LoadingComponent />
  152. </Grid>
  153. </Grid>
  154. :
  155. <Grid container sx={{ minHeight: '87vh', mb: 3 }} direction="column" alignItems="center">
  156. <Grid item xs={12} md={12} width="100%" >
  157. <div style={BackgroundHead}>
  158. <Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center">
  159. <Typography component="h1" ml={15} color='#FFF' variant="h4" sx={{display: { xs: 'none', sm: 'none', md: 'block' }}}>
  160. <FormattedMessage id="userChangePassword"/>
  161. </Typography>
  162. </Stack>
  163. </div>
  164. </Grid>
  165. <Grid item xs={12} md={12} width={{ sx:"90%", sm:"90%",md: "60%", xs: "90%" }}>
  166. <MainCard
  167. sx={{
  168. maxWidth: { xs: 400, sm:730, md:800, lg: 1000 },
  169. margin: { sm: 0, md: 3 },
  170. '& > *': {
  171. flexGrow: 1,
  172. flexBasis: '50%'
  173. }
  174. }}
  175. content={false}
  176. border={false}
  177. boxShadow
  178. >
  179. {
  180. !isChanged ?
  181. <form onSubmit={formik.handleSubmit}>
  182. <Grid container spacing={4} sx={{ minHeight: {xs:"80vh", sm:"50vh", md: "50vh", lg:"70vh", xl:"50vh"} }} direction="column" justifyContent="flex-start" alignItems="center">
  183. {isPasswordExpiry()?
  184. <Grid item width="70%" xs={12} md={12} lg={12} sx={{ mb: 1, mt:2 }}>
  185. <Typography variant="h5">
  186. <FormattedMessage id="passwordExpired"/>
  187. </Typography>
  188. </Grid>
  189. :
  190. <Grid item xs={12} md={12} lg={12} sx={{ mb: 1, mt:2 }}>
  191. <Typography variant="h5" >
  192. <FormattedMessage id="setNewPassword"/>
  193. </Typography>
  194. </Grid>
  195. }
  196. <Grid item xs={12} md={12} lg={12} width={{xs:"70%", sm:"60%",md:"50%", lg:"50%"}}>
  197. <Grid container direction="row" justifyContent="flex-start">
  198. <Grid item xs={12} md={12} lg={12}>
  199. <TextField
  200. fullWidth
  201. autoFocus
  202. onChange={(e) => {
  203. formik.handleChange(e);
  204. changePassword(e.target.value);
  205. }}
  206. id="password"
  207. type={showPassword ? 'text' : 'password'}
  208. name="password"
  209. label={intl.formatMessage({id: 'oldPassword'}) + ":"}
  210. placeholder={intl.formatMessage({id: 'oldPassword'})}
  211. // defaultValue={formik.values.password.trim()}
  212. value={formik.values.password.trim()}
  213. error={Boolean(formik.touched.password && formik.errors.password)}
  214. onBlur={formik.handleBlur}
  215. inputProps={{
  216. onKeyDown: (e) => {
  217. if (e.key === 'Enter') {
  218. e.preventDefault();
  219. }
  220. },
  221. }}
  222. InputLabelProps={{
  223. shrink: true
  224. }}
  225. InputProps={{
  226. endAdornment:(
  227. <InputAdornment position="end">
  228. <IconButton
  229. aria-label={intl.formatMessage({
  230. id: showPassword ? "ariaHidePassword" : "ariaShowPassword"
  231. })}
  232. onClick={handleClickShowPassword}
  233. onMouseDown={handleMouseDownPassword}
  234. edge="end"
  235. size="large"
  236. >
  237. {showPassword ? <EyeOutlined /> : <EyeInvisibleOutlined />}
  238. </IconButton>
  239. </InputAdornment>
  240. )
  241. }}
  242. />
  243. </Grid>
  244. {formik.touched.password && formik.errors.password && (
  245. <FormHelperText error id="helper-text-password-signup">
  246. {formik.errors.password}
  247. </FormHelperText>
  248. )}
  249. </Grid>
  250. </Grid>
  251. <Grid item xs={12} md={12} lg={12} width={{xs:"70%", sm:"60%",md:"50%", lg:"50%"}}>
  252. <Grid container direction="row" justifyContent="flex-start">
  253. <Grid item xs={12} md={12} lg={12}>
  254. <TextField
  255. fullWidth
  256. // autoFocus
  257. onChange={(e) => {
  258. formik.handleChange(e);
  259. changePassword(e.target.value);
  260. }}
  261. id="newPassword"
  262. type={showNewPassword ? 'text' : 'password'}
  263. name="newPassword"
  264. label={intl.formatMessage({id: 'newPassword'}) + ":"}
  265. placeholder={intl.formatMessage({id: 'newPassword'})}
  266. // defaultValue={formik.values.password.trim()}
  267. value={formik.values.newPassword.trim()}
  268. error={Boolean(formik.touched.newPassword && formik.errors.newPassword)}
  269. onBlur={formik.handleBlur}
  270. inputProps={{
  271. onKeyDown: (e) => {
  272. if (e.key === 'Enter') {
  273. e.preventDefault();
  274. }
  275. },
  276. }}
  277. InputLabelProps={{
  278. shrink: true
  279. }}
  280. InputProps={{
  281. endAdornment:(
  282. <InputAdornment position="end">
  283. <IconButton
  284. aria-label={intl.formatMessage({ id: 'ariaToggleNewPasswordVisibility' })}
  285. onClick={handleClickShowNewPassword}
  286. onMouseDown={handleMouseDownNewPassword}
  287. edge="end"
  288. size="large"
  289. >
  290. {showNewPassword ? <EyeOutlined /> : <EyeInvisibleOutlined />}
  291. </IconButton>
  292. </InputAdornment>
  293. )
  294. }}
  295. />
  296. </Grid>
  297. {formik.touched.newPassword && formik.errors.newPassword && (
  298. <FormHelperText error id="helper-text-newPassword-signup">
  299. {formik.errors.newPassword}
  300. </FormHelperText>
  301. )}
  302. </Grid>
  303. </Grid>
  304. <Grid item xs={12} md={12} lg={12} width={{xs:"70%", sm:"60%",md:"50%", lg:"50%"}}>
  305. <Grid container direction="row" justifyContent="flex-start">
  306. <Grid item xs={12} md={12} lg={12}>
  307. <TextField
  308. fullWidth
  309. onChange={(e) => {
  310. formik.handleChange(e);
  311. // changePassword(e.target.value);
  312. }}
  313. id="confirmPassword"
  314. type={showConfirmPassword ? 'text' : 'password'}
  315. name="confirmPassword"
  316. label={intl.formatMessage({id: 'confirmNewPassword'}) + ":"}
  317. placeholder={intl.formatMessage({id: 'confirmNewPassword'})}
  318. // defaultValue={formik.values.confirmPassword.trim()}
  319. value={formik.values.confirmPassword.trim()}
  320. error={Boolean(formik.touched.confirmPassword && formik.errors.confirmPassword)}
  321. onBlur={formik.handleBlur}
  322. onCut={handleCCPChange}
  323. onCopy={handleCCPChange}
  324. onPaste={handleCCPChange}
  325. inputProps={{
  326. maxLength: 50,
  327. onKeyDown: (e) => {
  328. // console.log(e)
  329. if (e.key === 'Enter') {
  330. e.preventDefault();
  331. }
  332. },
  333. }}
  334. InputLabelProps={{
  335. shrink: true
  336. }}
  337. InputProps={{
  338. endAdornment:(
  339. <InputAdornment position="end">
  340. <IconButton
  341. aria-label={intl.formatMessage({
  342. id: showConfirmPassword ? "ariaHidePassword" : "ariaShowPassword"
  343. })}
  344. onClick={handleClickShowConfirmPassword}
  345. onMouseDown={handleMouseDownPassword}
  346. edge="end"
  347. size="large"
  348. >
  349. {showConfirmPassword ? <EyeOutlined /> : <EyeInvisibleOutlined />}
  350. </IconButton>
  351. </InputAdornment>
  352. )
  353. }}
  354. />
  355. </Grid>
  356. {formik.touched.confirmPassword && formik.errors.confirmPassword && (
  357. <FormHelperText error id="helper-text-confirmPassword-signup">
  358. {formik.errors.confirmPassword}
  359. </FormHelperText>
  360. )}
  361. </Grid>
  362. <Grid container spacing={2} alignItems="center">
  363. <Grid item sx={{ mt: 1 }}>
  364. <Typography variant="subtitle1">
  365. •<FormattedMessage id="pwRemark1" /><br />
  366. •<FormattedMessage id="pwRemark2" /><br />
  367. •<FormattedMessage id="pwRemark3" /><br />
  368. •<FormattedMessage id="pwRemark4" /><br />
  369. •<FormattedMessage id="pwRemark5"/><br />
  370. </Typography>
  371. </Grid>
  372. </Grid>
  373. </Grid>
  374. <Grid item xs={12} md={12} lg={12} mt={1} sx={{mb:3}}>
  375. <ThemeProvider theme={PNSPS_LONG_BUTTON_THEME}>
  376. <Button
  377. aria-label={intl.formatMessage({id: 'confirm'})}
  378. variant="contained"
  379. type="submit"
  380. // onClick={()=>goLogin()}
  381. >
  382. <FormattedMessage id="confirm"/>
  383. </Button>
  384. </ThemeProvider>
  385. </Grid>
  386. </Grid>
  387. <div>
  388. <Dialog
  389. open={comfirmChangeMessage}
  390. onClose={() => setComfirmChangeMessage(false)}
  391. PaperProps={{
  392. sx: {
  393. minWidth: '40vw',
  394. maxWidth: { xs: '90vw', s: '90vw', m: '70vw', lg: '70vw' },
  395. maxHeight: { xs: '90vh', s: '70vh', m: '70vh', lg: '60vh' }
  396. }
  397. }}
  398. >
  399. <DialogTitle></DialogTitle>
  400. <DialogContent style={{ display: 'flex', }}>
  401. <Stack direction="column" justifyContent="space-between">
  402. <Typography variant="h5" style={{ padding: '10px' }}>
  403. <FormattedMessage id ="changePasswordConfirm"/>
  404. </Typography>
  405. </Stack>
  406. </DialogContent>
  407. <DialogActions>
  408. <Button onClick={() => setComfirmChangeMessage(false)}>
  409. <Typography variant="h5">
  410. <FormattedMessage id="close"/>
  411. </Typography>
  412. </Button>
  413. <Button onClick={() => goLogin(changePasswordValues)}>
  414. <Typography variant="h5">
  415. <FormattedMessage id="confirm"/>
  416. </Typography>
  417. </Button>
  418. </DialogActions>
  419. </Dialog>
  420. <Dialog
  421. open={expiryErr}
  422. onClose={() => setExpiryErr(false)}
  423. PaperProps={{
  424. sx: {
  425. minWidth: '40vw',
  426. maxWidth: { xs: '90vw', s: '90vw', m: '70vw', lg: '70vw' },
  427. maxHeight: { xs: '90vh', s: '70vh', m: '70vh', lg: '60vh' }
  428. }
  429. }}
  430. >
  431. <DialogTitle>
  432. <Typography variant="h5" style={{ padding: '10px' }}>
  433. <FormattedMessage id ="MSG.actionFail"/>
  434. </Typography>
  435. </DialogTitle>
  436. <DialogContent style={{ display: 'flex', }}>
  437. <Stack direction="column" justifyContent="space-between">
  438. <Typography variant="h5">
  439. {
  440. expiryErrText
  441. }
  442. </Typography>
  443. </Stack>
  444. </DialogContent>
  445. <DialogActions>
  446. <Button onClick={() => setExpiryErr(false)}>
  447. <Typography variant="h5">
  448. <FormattedMessage id="close"/>
  449. </Typography>
  450. </Button>
  451. </DialogActions>
  452. </Dialog>
  453. </div>
  454. </form>
  455. :
  456. <Grid container spacing={4} sx={{ minHeight: {xs:"80vh", sm:"70vh", md: "70vh", lg:"70vh", xl:"50vh"} }} direction="column" justifyContent="flex-start" alignItems="center">
  457. <Grid item xs={12} md={12} lg={12} sx={{ mb: 1, mt:5, }}>
  458. {/* <Button disabled={true} hidden={true} variant="contained" type="submit" sx={{ fontSize: 12,height:'25px'}}>Submit</Button> */}
  459. <CheckCircleOutlineIcon color="success" sx={{ width: "200px", height: "200px" }} />
  460. </Grid>
  461. <Grid item xs={12} md={12} lg={12} sx={{ mb: 1, mt:5,}}>
  462. <Typography display="inline" variant="h4">
  463. <FormattedMessage id="resetPasswordSuccess"/>
  464. </Typography>
  465. </Grid>
  466. <Grid item xs={12} md={12} lg={12} sx={{ mb: 1, mt:5,}}>
  467. <Button color="success" variant="outlined" onClick={()=>logout()}>
  468. <Typography variant="h5">
  469. <FormattedMessage id="backToLogin"/>
  470. </Typography>
  471. </Button>
  472. </Grid>
  473. </Grid>
  474. }
  475. </MainCard>
  476. </Grid>
  477. </Grid>
  478. );
  479. };
  480. export default Index;