您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 

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