You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

412 line
22 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 { useDispatch } from "react-redux";
  8. import { handleLogoutFunction,
  9. } from 'auth/index';
  10. import useJwt from "auth/jwt/useJwt";
  11. import {
  12. Grid,
  13. Typography,
  14. Button,
  15. Stack,
  16. InputLabel,
  17. FormHelperText,
  18. TextField,
  19. IconButton, InputAdornment,
  20. } from '@mui/material';
  21. import Loadable from 'components/Loadable';
  22. const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent')));
  23. import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png'
  24. import MainCard from 'components/MainCard';
  25. import {PNSPS_LONG_BUTTON_THEME} from "themes/buttonConst";
  26. import {ThemeProvider} from "@emotion/react";
  27. import {FormattedMessage, useIntl} from "react-intl";
  28. import { EyeInvisibleOutlined, EyeOutlined } from '@ant-design/icons';
  29. import axios from 'axios';
  30. import { useParams,Link } from 'react-router-dom';
  31. import CancelOutlinedIcon from '@mui/icons-material/CancelOutlined';
  32. // ==============================|| DASHBOARD - DEFAULT ||============================== //
  33. const Index = () => {
  34. const dispatch = useDispatch()
  35. const navigate = useNavigate()
  36. const [showPassword, setShowPassword] = React.useState(false);
  37. const [showConfirmPassword, setshowConfirmPassword] = React.useState(false);
  38. const [isLoading, setLoding] = React.useState(true);
  39. const [verifyState, setVerifyState] = React.useState(null)
  40. const [enterUseEffect, setEnterUseEffect] = React.useState(false)
  41. const [username, setUsername] = React.useState("")
  42. const params = useParams()
  43. const intl = useIntl();
  44. React.useEffect(() => {
  45. console.log(params);
  46. setEnterUseEffect(true)
  47. }, []);
  48. React.useEffect(() => {
  49. if (enterUseEffect){
  50. handleVerify()
  51. }
  52. }, [enterUseEffect])
  53. const handleVerify = async () => {
  54. console.log(params);
  55. await axios.get(UrlUtils.GET_FORGOT_PASSWORD_VERIFY_USER_ACCOUNT, {
  56. params: {
  57. email: decodeURIComponent(params.email),
  58. emailVerifyHash: decodeURIComponent(params.verifyCode)
  59. }
  60. }).then(
  61. (response)=>{
  62. if (response.status === 200 && response.data) {
  63. console.log(response)
  64. setUsername(response.data.username)
  65. setVerifyState(true)
  66. } else {
  67. setVerifyState(false)
  68. }
  69. setLoding(false)
  70. }
  71. ).catch(error => {
  72. console.log(error)
  73. setVerifyState(false)
  74. setLoding(false)
  75. });
  76. }
  77. const goLogin = async (values) =>{
  78. dispatch(handleLogoutFunction());
  79. HttpUtils.post({
  80. url: UrlUtils.POST_FORGOT_PASSWORD_NEW_PASSWORD,
  81. params:{
  82. username: username,
  83. newPassword: values.password
  84. },
  85. onSuccess: () => {
  86. useJwt
  87. .login({ username: username, password: values.password })
  88. .then((
  89. // response
  90. ) => {
  91. // console.log(response)
  92. navigate('/forgot/password/success');
  93. location.reload()
  94. // setSumitting(false)
  95. })
  96. .catch((error) => {
  97. console.error(error)
  98. });
  99. },
  100. onFail: (response)=>{
  101. console.log("Fail");
  102. console.log(response);
  103. window.location.assign("/iamsmart/loginFail");
  104. },
  105. onError:(error)=>{
  106. console.log(error);
  107. window.location.assign("/iamsmart/loginFail");
  108. }
  109. });
  110. }
  111. const BackgroundHead = {
  112. backgroundImage: `url(${titleBackgroundImg})`,
  113. width: 'auto',
  114. height: 'auto',
  115. backgroundSize: 'contain',
  116. backgroundRepeat: 'no-repeat',
  117. backgroundColor: '#0C489E',
  118. backgroundPosition: 'right'
  119. }
  120. const handleClickShowPassword = () => {
  121. setShowPassword(!showPassword);
  122. };
  123. const handleClickShowConfirmPassword = () => {
  124. setshowConfirmPassword(!showConfirmPassword);
  125. };
  126. const handleMouseDownPassword = (event) => {
  127. event.preventDefault();
  128. };
  129. const changePassword = (
  130. // value
  131. ) => {
  132. // const temp = strengthIndicator(value);
  133. // setLevel(strengthColorChi(temp));
  134. };
  135. const formik = useFormik({
  136. enableReinitialize: true,
  137. initialValues: {
  138. password: '',
  139. confirmPassword: '',
  140. },
  141. validationSchema: yup.object().shape({
  142. password: yup.string().min(8, intl.formatMessage({id: 'atLeast8CharPassword'}))
  143. .required(intl.formatMessage({id: 'requirePassword'}))
  144. .matches(/^\S*$/, { message: (intl.formatMessage({id: 'noSpacePassword'}))})
  145. .matches(/^(?=.*[a-z])/, { message: intl.formatMessage({id: 'atLeastOneSmallLetter'})})
  146. .matches(/^(?=.*[A-Z])/, { message: intl.formatMessage({id: 'atLeastOneCapLetter'})})
  147. .matches(/^(?=.*[0-9])/, { message: intl.formatMessage({id: 'atLeast1Number'})})
  148. .matches(/^(?=.*\W)/, { message: intl.formatMessage({id: 'atLeast1SpecialChar'})}),
  149. confirmPassword: yup.string().min(8, intl.formatMessage({id: 'atLeast8CharPassword'}))
  150. .required(intl.formatMessage({id: 'pleaseConfirmPassword'}))
  151. .oneOf([yup.ref('password'), null], intl.formatMessage({id: 'samePassword'})),
  152. }),
  153. onSubmit: values => {
  154. // console.log(values)
  155. goLogin(values)
  156. }
  157. });
  158. const handleCCPChange = (e) => {
  159. e.preventDefault();
  160. };
  161. return (
  162. isLoading || verifyState == null ?
  163. <Grid container sx={{ minHeight: '87vh', mb: 3 }} direction="column" justifyContent="center" alignItems="center">
  164. <Grid item>
  165. <LoadingComponent />
  166. </Grid>
  167. </Grid>
  168. :
  169. <Grid container sx={{ minHeight: '87vh', mb: 3 }} direction="column" alignItems="center">
  170. <Grid item xs={12} md={12} width="100%" >
  171. <div style={BackgroundHead}>
  172. <Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center">
  173. <Typography ml={15} color='#FFF' variant="h4" sx={{display: { xs: 'none', sm: 'none', md: 'block' }}}>
  174. <FormattedMessage id="forgotUserPassword"/>
  175. </Typography>
  176. </Stack>
  177. </div>
  178. </Grid>
  179. <Grid item xs={12} md={12} width={{ sx:"90%", sm:"90%",md: "60%", xs: "90%" }}>
  180. <MainCard
  181. sx={{
  182. maxWidth: { xs: 400, sm:730, md:800, lg: 1000 },
  183. margin: { sm: 0, md: 3 },
  184. '& > *': {
  185. flexGrow: 1,
  186. flexBasis: '50%'
  187. }
  188. }}
  189. content={false}
  190. border={false}
  191. boxShadow
  192. >
  193. <form onSubmit={formik.handleSubmit}>
  194. {verifyState ?
  195. // SUCCESS page
  196. <Grid container spacing={4} sx={{ minHeight: {xs:"80vh", sm:"50vh", md: "50vh", lg:"70vh", xl:"50vh"} }} direction="column" justifyContent="flex-start" alignItems="center">
  197. <Grid container direction="column" alignItems="center">
  198. <Grid item xs={12} md={12} lg={12} sx={{ mb: 1, mt:5, }}>
  199. <Typography display="inline" variant="h4">
  200. <FormattedMessage id="verifySuccess"/>
  201. </Typography>
  202. </Grid>
  203. <Grid item xs={12} md={12} lg={12} sx={{ mb: 1,}}>
  204. <InputLabel htmlFor="email-login-title3">
  205. <Typography variant="h5" >
  206. <FormattedMessage id="setNewPassword"/>
  207. </Typography>
  208. </InputLabel>
  209. </Grid>
  210. </Grid>
  211. <Grid item xs={12} md={12} lg={12} width={{xs:"70%", sm:"60%",md:"50%", lg:"50%"}}>
  212. <Grid container direction="row" justifyContent="flex-start">
  213. <Grid item xs={12} md={12} lg={12}>
  214. <TextField
  215. fullWidth
  216. id="username"
  217. name="username"
  218. label={intl.formatMessage({id: 'userLoginName'}) + ":"}
  219. placeholder={intl.formatMessage({id: 'userLoginName'})}
  220. value={username}
  221. disabled={true} />
  222. </Grid>
  223. </Grid>
  224. </Grid>
  225. <Grid item xs={12} md={12} lg={12} width={{xs:"70%", sm:"60%",md:"50%", lg:"50%"}}>
  226. <Grid container direction="row" justifyContent="flex-start">
  227. <Grid item xs={12} md={12} lg={12}>
  228. <TextField
  229. fullWidth
  230. autoFocus
  231. onChange={(e) => {
  232. formik.handleChange(e);
  233. changePassword(e.target.value);
  234. }}
  235. id="password"
  236. type={showPassword ? 'text' : 'password'}
  237. name="password"
  238. label={intl.formatMessage({id: 'newPassword'}) + ":"}
  239. placeholder={intl.formatMessage({id: 'newPassword'})}
  240. value={formik.values.password.trim()}
  241. error={Boolean(formik.touched.password && formik.errors.password)}
  242. onBlur={formik.handleBlur}
  243. inputProps={{
  244. onKeyDown: (e) => {
  245. if (e.key === 'Enter') {
  246. e.preventDefault();
  247. }
  248. },
  249. }}
  250. InputLabelProps={{
  251. shrink: true
  252. }}
  253. InputProps={{
  254. endAdornment:(
  255. <InputAdornment position="end">
  256. <IconButton
  257. aria-label="toggle password visibility"
  258. onClick={handleClickShowPassword}
  259. onMouseDown={handleMouseDownPassword}
  260. edge="end"
  261. size="large"
  262. >
  263. {showPassword ? <EyeOutlined /> : <EyeInvisibleOutlined />}
  264. </IconButton>
  265. </InputAdornment>
  266. )
  267. }}
  268. />
  269. </Grid>
  270. {formik.touched.password && formik.errors.password && (
  271. <FormHelperText error id="helper-text-password-signup">
  272. {formik.errors.password}
  273. </FormHelperText>
  274. )}
  275. </Grid>
  276. </Grid>
  277. <Grid item xs={12} md={12} lg={12} width={{xs:"70%", sm:"60%",md:"50%", lg:"50%"}}>
  278. <Grid container direction="row" justifyContent="flex-start">
  279. <Grid item xs={12} md={12} lg={12}>
  280. <TextField
  281. fullWidth
  282. onChange={(e) => {
  283. formik.handleChange(e);
  284. }}
  285. id="confirmPassword"
  286. type={showConfirmPassword ? 'text' : 'password'}
  287. name="confirmPassword"
  288. label={intl.formatMessage({id: 'confirmPassword'}) + ":"}
  289. placeholder={intl.formatMessage({id: 'confirmPassword'})}
  290. value={formik.values.confirmPassword.trim()}
  291. error={Boolean(formik.touched.confirmPassword && formik.errors.confirmPassword)}
  292. onBlur={formik.handleBlur}
  293. onCut={handleCCPChange}
  294. onCopy={handleCCPChange}
  295. onPaste={handleCCPChange}
  296. inputProps={{
  297. maxLength: 50,
  298. onKeyDown: (e) => {
  299. if (e.key === 'Enter') {
  300. e.preventDefault();
  301. }
  302. },
  303. }}
  304. InputLabelProps={{
  305. shrink: true
  306. }}
  307. InputProps={{
  308. endAdornment:(
  309. <InputAdornment position="end">
  310. <IconButton
  311. aria-label="toggle password visibility"
  312. onClick={handleClickShowConfirmPassword}
  313. onMouseDown={handleMouseDownPassword}
  314. edge="end"
  315. size="large"
  316. >
  317. {showConfirmPassword ? <EyeOutlined /> : <EyeInvisibleOutlined />}
  318. </IconButton>
  319. </InputAdornment>
  320. )
  321. }}
  322. />
  323. </Grid>
  324. {formik.touched.confirmPassword && formik.errors.confirmPassword && (
  325. <FormHelperText error id="helper-text-confirmPassword-signup">
  326. {formik.errors.confirmPassword}
  327. </FormHelperText>
  328. )}
  329. </Grid>
  330. <Grid container spacing={2} alignItems="center">
  331. <Grid item sx={{ mt: 1 }}>
  332. <Typography variant="subtitle1">
  333. •<FormattedMessage id="pwRemark1" /><br />
  334. •<FormattedMessage id="pwRemark2" /><br />
  335. •<FormattedMessage id="pwRemark3" /><br />
  336. •<FormattedMessage id="pwRemark4" /><br />
  337. •<FormattedMessage id="pwRemark5"/><br />
  338. </Typography>
  339. </Grid>
  340. </Grid>
  341. </Grid>
  342. <Grid item xs={12} md={12} lg={12} mt={1} sx={{mb:3}}>
  343. <ThemeProvider theme={PNSPS_LONG_BUTTON_THEME}>
  344. <Button
  345. aria-label={intl.formatMessage({id: 'confirm'})}
  346. variant="contained"
  347. type="submit"
  348. // onClick={()=>goLogin()}
  349. >
  350. <FormattedMessage id="confirm"/>
  351. </Button>
  352. </ThemeProvider>
  353. </Grid>
  354. </Grid>
  355. :
  356. // ERROR page
  357. <Grid container spacing={4} sx={{ minHeight: {xs:"80vh", sm:"70vh", md: "70vh", lg:"70vh", xl:"50vh"} }} direction="column" justifyContent="flex-start" alignItems="center">
  358. <Grid item xs={12} md={12} lg={12} sx={{ mb: 1, mt:5,}}>
  359. <CancelOutlinedIcon color="error" sx={{ width: "200px", height: "200px" }} />
  360. </Grid>
  361. <Grid item xs={12} md={12} lg={12} sx={{ mb: 1, mt:5,}}>
  362. <Typography display="inline" variant="h4">
  363. <FormattedMessage id="verifyFail"/>
  364. </Typography>
  365. </Grid>
  366. <Grid item xs={12} md={12} lg={12} sx={{ mb: 1, mt:5,}}>
  367. <Button color="error" variant="outlined" component={Link} to="/login">
  368. <Typography variant="h5">
  369. <FormattedMessage id="backToLogin"/>
  370. </Typography>
  371. </Button>
  372. </Grid>
  373. </Grid>
  374. }
  375. </form>
  376. </MainCard>
  377. </Grid>
  378. </Grid>
  379. );
  380. };
  381. export default Index;