| @@ -0,0 +1,122 @@ | |||||
| // import { useFormik } from 'formik'; | |||||
| // import * as yup from 'yup'; | |||||
| import * as React from "react"; | |||||
| // import * as HttpUtils from "utils/HttpUtils"; | |||||
| // import * as UrlUtils from "utils/ApiPathConst"; | |||||
| // import { useNavigate } from "react-router-dom"; | |||||
| // import { useDispatch } from "react-redux"; | |||||
| // import { handleLogoutFunction, handleLogin} from 'auth/index'; | |||||
| // import useJwt from "auth/jwt/useJwt"; | |||||
| import { | |||||
| Grid, | |||||
| Typography, | |||||
| Button, | |||||
| // RadioGroup, | |||||
| // Dialog, DialogTitle, DialogContent, DialogActions, | |||||
| Stack, | |||||
| // InputLabel, | |||||
| // OutlinedInput, | |||||
| // FormHelperText, | |||||
| // TextField, | |||||
| // IconButton, InputAdornment, | |||||
| // Box, | |||||
| // FormControl | |||||
| } from '@mui/material'; | |||||
| import Loadable from 'components/Loadable'; | |||||
| const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | |||||
| import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' | |||||
| // import ForwardIcon from '@mui/icons-material/Forward'; | |||||
| import MainCard from 'components/MainCard'; | |||||
| // import {PNSPS_LONG_BUTTON_THEME} from "themes/buttonConst"; | |||||
| // import {ThemeProvider} from "@emotion/react"; | |||||
| import {FormattedMessage, | |||||
| // useIntl | |||||
| } from "react-intl"; | |||||
| // import { EyeInvisibleOutlined, EyeOutlined } from '@ant-design/icons'; | |||||
| // import axios from 'axios'; | |||||
| import { | |||||
| // useParams, | |||||
| Link | |||||
| } from 'react-router-dom'; | |||||
| import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline'; | |||||
| // import LocaleContext from "components/I18nProvider"; | |||||
| // ==============================|| DASHBOARD - DEFAULT ||============================== // | |||||
| const ResetPasswordSuccess = () => { | |||||
| const [isLoading, setLoding] = React.useState(true); | |||||
| React.useEffect(() => { | |||||
| setLoding(false) | |||||
| }, []); | |||||
| const BackgroundHead = { | |||||
| backgroundImage: `url(${titleBackgroundImg})`, | |||||
| width: 'auto', | |||||
| height: 'auto', | |||||
| backgroundSize: 'contain', | |||||
| backgroundRepeat: 'no-repeat', | |||||
| backgroundColor: '#0C489E', | |||||
| backgroundPosition: 'right' | |||||
| } | |||||
| return ( | |||||
| isLoading ? | |||||
| <Grid container sx={{ minHeight: '87vh', mb: 3 }} direction="column" justifyContent="center" alignItems="center"> | |||||
| <Grid item> | |||||
| <LoadingComponent /> | |||||
| </Grid> | |||||
| </Grid> | |||||
| : | |||||
| <Grid container sx={{ minHeight: '87vh', mb: 3 }} direction="column" alignItems="center"> | |||||
| <Grid item xs={12} md={12} width="100%" > | |||||
| <div style={BackgroundHead}> | |||||
| <Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center"> | |||||
| <Typography ml={15} color='#FFF' variant="h4" sx={{display: { xs: 'none', sm: 'none', md: 'block' }}}> | |||||
| <FormattedMessage id="forgotUserPassword"/> | |||||
| </Typography> | |||||
| </Stack> | |||||
| </div> | |||||
| </Grid> | |||||
| <Grid item xs={12} md={12} width={{sx:"90%", sm:"90%",md: "60%", xs: "90%"}}> | |||||
| <MainCard | |||||
| sx={{ | |||||
| maxWidth: { xs: 400, sm:730, md:800, lg: 1000 }, | |||||
| margin: { sm: 0, md: 3 }, | |||||
| '& > *': { | |||||
| flexGrow: 1, | |||||
| flexBasis: '50%' | |||||
| } | |||||
| }} | |||||
| content={false} | |||||
| border={false} | |||||
| boxShadow | |||||
| > | |||||
| <Grid container spacing={4} sx={{ minHeight: {xs:"80vh", sm:"70vh", md: "70vh", lg:"70vh", xl:"50vh"} }} direction="column" justifyContent="flex-start" alignItems="center"> | |||||
| <Grid item xs={12} md={12} lg={12} sx={{ mb: 1, mt:5, }}> | |||||
| {/* <Button disabled={true} hidden={true} variant="contained" type="submit" sx={{ fontSize: 12,height:'25px'}}>Submit</Button> */} | |||||
| <CheckCircleOutlineIcon color="success" sx={{ width: "200px", height: "200px" }} /> | |||||
| </Grid> | |||||
| <Grid item xs={12} md={12} lg={12} sx={{ mb: 1, mt:5,}}> | |||||
| <Typography display="inline" variant="h4"> | |||||
| <FormattedMessage id="resetPasswordSuccess"/> | |||||
| </Typography> | |||||
| </Grid> | |||||
| <Grid item xs={12} md={12} lg={12} sx={{ mb: 1, mt:5,}}> | |||||
| <Button color="success" variant="outlined" component={Link} to="/login"> | |||||
| <Typography variant="h5"> | |||||
| <FormattedMessage id="backToLogin"/> | |||||
| </Typography> | |||||
| </Button> | |||||
| </Grid> | |||||
| </Grid> | |||||
| </MainCard> | |||||
| </Grid> | |||||
| </Grid> | |||||
| ); | |||||
| }; | |||||
| export default ResetPasswordSuccess; | |||||
| @@ -0,0 +1,459 @@ | |||||
| import { useFormik } from 'formik'; | |||||
| import * as yup from 'yup'; | |||||
| import * as React from "react"; | |||||
| import * as HttpUtils from "utils/HttpUtils"; | |||||
| import * as UrlUtils from "utils/ApiPathConst"; | |||||
| import { useNavigate } from "react-router-dom"; | |||||
| import { useDispatch } from "react-redux"; | |||||
| import { handleLogoutFunction, | |||||
| // handleLogin | |||||
| } from 'auth/index'; | |||||
| import useJwt from "auth/jwt/useJwt"; | |||||
| import { | |||||
| Grid, | |||||
| Typography, | |||||
| Button, | |||||
| // RadioGroup, | |||||
| // Dialog, DialogTitle, DialogContent, DialogActions, | |||||
| Stack, | |||||
| InputLabel, | |||||
| // OutlinedInput, | |||||
| FormHelperText, | |||||
| TextField, | |||||
| IconButton, InputAdornment, | |||||
| // Box, | |||||
| // FormControl | |||||
| } from '@mui/material'; | |||||
| import Loadable from 'components/Loadable'; | |||||
| const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | |||||
| import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' | |||||
| // import ForwardIcon from '@mui/icons-material/Forward'; | |||||
| import MainCard from 'components/MainCard'; | |||||
| import {PNSPS_LONG_BUTTON_THEME} from "themes/buttonConst"; | |||||
| import {ThemeProvider} from "@emotion/react"; | |||||
| import {FormattedMessage, useIntl} from "react-intl"; | |||||
| import { EyeInvisibleOutlined, EyeOutlined } from '@ant-design/icons'; | |||||
| import axios from 'axios'; | |||||
| import { useParams,Link } from 'react-router-dom'; | |||||
| import CancelOutlinedIcon from '@mui/icons-material/CancelOutlined'; | |||||
| // import LocaleContext from "components/I18nProvider"; | |||||
| // ==============================|| DASHBOARD - DEFAULT ||============================== // | |||||
| const Index = () => { | |||||
| const dispatch = useDispatch() | |||||
| const navigate = useNavigate() | |||||
| const [showPassword, setShowPassword] = React.useState(false); | |||||
| const [showConfirmPassword, setshowConfirmPassword] = React.useState(false); | |||||
| const [isLoading, setLoding] = React.useState(true); | |||||
| const [verifyState, setVerifyState] = React.useState(null) | |||||
| const [enterUseEffect, setEnterUseEffect] = React.useState(false) | |||||
| const [username, setUsername] = React.useState("") | |||||
| // const { setLocale } = React.useContext(LocaleContext); | |||||
| const params = useParams() | |||||
| const intl = useIntl(); | |||||
| React.useEffect(() => { | |||||
| console.log(params); | |||||
| setEnterUseEffect(true) | |||||
| }, []); | |||||
| React.useEffect(() => { | |||||
| // console.log("if (enterUseEffect) handleVerify()"); | |||||
| if (enterUseEffect){ | |||||
| handleVerify() | |||||
| } | |||||
| }, [enterUseEffect]) | |||||
| const handleVerify = async () => { | |||||
| console.log(params); | |||||
| await axios.get(UrlUtils.GET_FORGOT_PASSWORD_VERIFY_USER_ACCOUNT, { | |||||
| params: { | |||||
| email: decodeURIComponent(params.email), | |||||
| emailVerifyHash: decodeURIComponent(params.verifyCode) | |||||
| } | |||||
| }).then( | |||||
| (response)=>{ | |||||
| if (response.status === 200 && response.data) { | |||||
| console.log(response) | |||||
| setUsername(response.data.username) | |||||
| setVerifyState(true) | |||||
| } else { | |||||
| setVerifyState(false) | |||||
| } | |||||
| setLoding(false) | |||||
| } | |||||
| ).catch(error => { | |||||
| console.log(error) | |||||
| setVerifyState(false) | |||||
| setLoding(false) | |||||
| }); | |||||
| } | |||||
| const goLogin = async (values) =>{ | |||||
| dispatch(handleLogoutFunction()); | |||||
| HttpUtils.post({ | |||||
| url: UrlUtils.POST_FORGOT_PASSWORD_NEW_PASSWORD, | |||||
| params:{ | |||||
| username: username, | |||||
| newPassword: values.password | |||||
| }, | |||||
| onSuccess: () => { | |||||
| useJwt | |||||
| .login({ username: username, password: values.password }) | |||||
| .then(( | |||||
| // response | |||||
| ) => { | |||||
| // console.log(response) | |||||
| navigate('/forgot/password/success'); | |||||
| location.reload() | |||||
| // setSumitting(false) | |||||
| }) | |||||
| .catch((error) => { | |||||
| console.error(error) | |||||
| }); | |||||
| }, | |||||
| onFail: (response)=>{ | |||||
| console.log("Fail"); | |||||
| console.log(response); | |||||
| // window.location.assign("/iamsmart/loginFail"); | |||||
| }, | |||||
| onError:(error)=>{ | |||||
| console.log(error); | |||||
| // window.location.assign("/iamsmart/loginFail"); | |||||
| } | |||||
| }); | |||||
| } | |||||
| const BackgroundHead = { | |||||
| backgroundImage: `url(${titleBackgroundImg})`, | |||||
| width: 'auto', | |||||
| height: 'auto', | |||||
| backgroundSize: 'contain', | |||||
| backgroundRepeat: 'no-repeat', | |||||
| backgroundColor: '#0C489E', | |||||
| backgroundPosition: 'right' | |||||
| } | |||||
| const handleClickShowPassword = () => { | |||||
| setShowPassword(!showPassword); | |||||
| }; | |||||
| const handleClickShowConfirmPassword = () => { | |||||
| setshowConfirmPassword(!showConfirmPassword); | |||||
| }; | |||||
| const handleMouseDownPassword = (event) => { | |||||
| event.preventDefault(); | |||||
| }; | |||||
| const changePassword = ( | |||||
| // value | |||||
| ) => { | |||||
| // const temp = strengthIndicator(value); | |||||
| // setLevel(strengthColorChi(temp)); | |||||
| }; | |||||
| const formik = useFormik({ | |||||
| enableReinitialize: true, | |||||
| initialValues: { | |||||
| // username: '', | |||||
| password: '', | |||||
| confirmPassword: '', | |||||
| // emailVerifyHash: '', | |||||
| }, | |||||
| validationSchema: yup.object().shape({ | |||||
| // emailVerifyHash: yup.string().required(intl.formatMessage({id: 'requireSecurityCode'})), | |||||
| // username: yup.string().required(intl.formatMessage({id: 'requireUsername'})), | |||||
| password: yup.string().min(8, intl.formatMessage({id: 'atLeast8CharPassword'})) | |||||
| .required(intl.formatMessage({id: 'requirePassword'})) | |||||
| .matches(/^\S*$/, { message: (intl.formatMessage({id: 'noSpacePassword'}))}) | |||||
| .matches(/^(?=.*[a-z])/, { message: intl.formatMessage({id: 'atLeastOneSmallLetter'})}) | |||||
| .matches(/^(?=.*[A-Z])/, { message: intl.formatMessage({id: 'atLeastOneCapLetter'})}) | |||||
| .matches(/^(?=.*[0-9])/, { message: intl.formatMessage({id: 'atLeast1Number'})}) | |||||
| .matches(/^(?=.*[!@#%&])/, { message: intl.formatMessage({id: 'atLeast1SpecialChar'})}), | |||||
| confirmPassword: yup.string().min(8, intl.formatMessage({id: 'atLeast8CharPassword'})) | |||||
| .required(intl.formatMessage({id: 'pleaseConfirmPassword'})) | |||||
| .oneOf([yup.ref('password'), null], intl.formatMessage({id: 'samePassword'})), | |||||
| }), | |||||
| onSubmit: values => { | |||||
| // console.log(values) | |||||
| goLogin(values) | |||||
| } | |||||
| }); | |||||
| return ( | |||||
| isLoading || verifyState == null ? | |||||
| <Grid container sx={{ minHeight: '87vh', mb: 3 }} direction="column" justifyContent="center" alignItems="center"> | |||||
| <Grid item> | |||||
| <LoadingComponent /> | |||||
| </Grid> | |||||
| </Grid> | |||||
| : | |||||
| <Grid container sx={{ minHeight: '87vh', mb: 3 }} direction="column" alignItems="center"> | |||||
| <Grid item xs={12} md={12} width="100%" > | |||||
| <div style={BackgroundHead}> | |||||
| <Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center"> | |||||
| <Typography ml={15} color='#FFF' variant="h4" sx={{display: { xs: 'none', sm: 'none', md: 'block' }}}> | |||||
| <FormattedMessage id="forgotUserPassword"/> | |||||
| </Typography> | |||||
| </Stack> | |||||
| </div> | |||||
| </Grid> | |||||
| {/* <Grid item xs={12} width={{xs:"90%", sm:"90%", md:"60%", lg:"60%"}}> | |||||
| <Button | |||||
| aria-label={intl.formatMessage({id: 'back'})} | |||||
| title={intl.formatMessage({id: 'back'})} | |||||
| sx={{ ml: 0, mt: 2.5 }} style={{ border: '2px solid' }} variant="outlined" onClick={() => { navigate(-1) }} | |||||
| > | |||||
| <ForwardIcon style={{ height: 30, width: 50, transform: "rotate(180deg)" }} /> | |||||
| </Button> | |||||
| </Grid> */} | |||||
| {/* <Grid item xs={12}> | |||||
| <Typography variant="pnspsFormParagraphBold">申請公共啟事</Typography> | |||||
| </Grid> */} | |||||
| <Grid item xs={12} md={12} width={{ sx:"90%", sm:"90%",md: "60%", xs: "90%" }}> | |||||
| <MainCard | |||||
| sx={{ | |||||
| maxWidth: { xs: 400, sm:730, md:800, lg: 1000 }, | |||||
| margin: { sm: 0, md: 3 }, | |||||
| '& > *': { | |||||
| flexGrow: 1, | |||||
| flexBasis: '50%' | |||||
| } | |||||
| }} | |||||
| content={false} | |||||
| border={false} | |||||
| boxShadow | |||||
| > | |||||
| <form onSubmit={formik.handleSubmit}> | |||||
| {verifyState ? | |||||
| // SUCCESS page | |||||
| <Grid container spacing={4} sx={{ minHeight: {xs:"80vh", sm:"50vh", md: "50vh", lg:"70vh", xl:"50vh"} }} direction="column" justifyContent="flex-start" alignItems="center"> | |||||
| <Grid container direction="column" alignItems="center"> | |||||
| <Grid item xs={12} md={12} lg={12} sx={{ mb: 1, mt:5, }}> | |||||
| <Typography display="inline" variant="h4"> | |||||
| <FormattedMessage id="verifySuccess"/> | |||||
| </Typography> | |||||
| </Grid> | |||||
| <Grid item xs={12} md={12} lg={12} sx={{ mb: 1,}}> | |||||
| <InputLabel htmlFor="email-login-title3"> | |||||
| <Typography variant="h5" > | |||||
| <FormattedMessage id="setNewPassword"/> | |||||
| </Typography> | |||||
| </InputLabel> | |||||
| </Grid> | |||||
| </Grid> | |||||
| {/* <Grid item xs={12} md={12} lg={12} width={{xs:"70%", sm:"60%",md:"50%", lg:"50%"}}> | |||||
| <Grid container direction="row" justifyContent="flex-start"> | |||||
| <Grid item xs={12} md={12} lg={12}> | |||||
| <TextField | |||||
| fullWidth | |||||
| onChange={formik.handleChange} | |||||
| id="emailVerifyHash" | |||||
| name="emailVerifyHash" | |||||
| label={intl.formatMessage({id: 'securityCode'}) + ":"} | |||||
| placeholder={intl.formatMessage({id: 'securityCode'})} | |||||
| defaultValue={formik.values.emailVerifyHash} | |||||
| value={formik.values.emailVerifyHash} | |||||
| error={Boolean(formik.touched.emailVerifyHash && formik.errors.emailVerifyHash)} | |||||
| onBlur={formik.handleBlur} | |||||
| inputProps={{ | |||||
| maxLength: 50, | |||||
| onKeyDown: (e) => { | |||||
| if (e.key === 'Enter') { | |||||
| e.preventDefault(); | |||||
| } | |||||
| }, | |||||
| }} | |||||
| InputLabelProps={{ | |||||
| shrink: true | |||||
| }} | |||||
| /> | |||||
| </Grid> | |||||
| {formik.touched.emailVerifyHash && formik.errors.emailVerifyHash && ( | |||||
| <FormHelperText error id="standard-weight-helper-text-username-login"> | |||||
| {formik.errors.emailVerifyHash} | |||||
| </FormHelperText> | |||||
| )} | |||||
| </Grid> | |||||
| </Grid> */} | |||||
| <Grid item xs={12} md={12} lg={12} width={{xs:"70%", sm:"60%",md:"50%", lg:"50%"}}> | |||||
| <Grid container direction="row" justifyContent="flex-start"> | |||||
| <Grid item xs={12} md={12} lg={12}> | |||||
| <TextField | |||||
| fullWidth | |||||
| id="username" | |||||
| name="username" | |||||
| label={intl.formatMessage({id: 'userLoginName'}) + ":"} | |||||
| placeholder={intl.formatMessage({id: 'userLoginName'})} | |||||
| // defaultValue={username} | |||||
| value={username} | |||||
| disabled={true} /> | |||||
| </Grid> | |||||
| </Grid> | |||||
| </Grid> | |||||
| <Grid item xs={12} md={12} lg={12} width={{xs:"70%", sm:"60%",md:"50%", lg:"50%"}}> | |||||
| <Grid container direction="row" justifyContent="flex-start"> | |||||
| <Grid item xs={12} md={12} lg={12}> | |||||
| <TextField | |||||
| fullWidth | |||||
| autoFocus | |||||
| onChange={(e) => { | |||||
| formik.handleChange(e); | |||||
| changePassword(e.target.value); | |||||
| }} | |||||
| id="password" | |||||
| type={showPassword ? 'text' : 'password'} | |||||
| name="password" | |||||
| label={intl.formatMessage({id: 'newPassword'}) + ":"} | |||||
| placeholder={intl.formatMessage({id: 'newPassword'})} | |||||
| // defaultValue={formik.values.password.trim()} | |||||
| value={formik.values.password.trim()} | |||||
| error={Boolean(formik.touched.password && formik.errors.password)} | |||||
| onBlur={formik.handleBlur} | |||||
| inputProps={{ | |||||
| onKeyDown: (e) => { | |||||
| if (e.key === 'Enter') { | |||||
| e.preventDefault(); | |||||
| } | |||||
| }, | |||||
| }} | |||||
| InputLabelProps={{ | |||||
| shrink: true | |||||
| }} | |||||
| InputProps={{ | |||||
| endAdornment:( | |||||
| <InputAdornment position="end"> | |||||
| <IconButton | |||||
| aria-label="toggle password visibility" | |||||
| onClick={handleClickShowPassword} | |||||
| onMouseDown={handleMouseDownPassword} | |||||
| edge="end" | |||||
| size="large" | |||||
| > | |||||
| {showPassword ? <EyeOutlined /> : <EyeInvisibleOutlined />} | |||||
| </IconButton> | |||||
| </InputAdornment> | |||||
| ) | |||||
| }} | |||||
| /> | |||||
| </Grid> | |||||
| {/* <FormControl fullWidth sx={{ mt: 2 }}> | |||||
| <Grid container spacing={2} alignItems="center"> | |||||
| <Grid item> | |||||
| <Box sx={{ bgcolor: level?.color, width: 85, height: 8, borderRadius: '7px' }} /> | |||||
| </Grid> | |||||
| <Grid item> | |||||
| <Typography variant="subtitle1"> | |||||
| <FormattedMessage id={level ? level?.label : "pwWeak" }/> | |||||
| </Typography> | |||||
| </Grid> | |||||
| </Grid> | |||||
| </FormControl> */} | |||||
| {formik.touched.password && formik.errors.password && ( | |||||
| <FormHelperText error id="helper-text-password-signup"> | |||||
| {formik.errors.password} | |||||
| </FormHelperText> | |||||
| )} | |||||
| </Grid> | |||||
| </Grid> | |||||
| <Grid item xs={12} md={12} lg={12} width={{xs:"70%", sm:"60%",md:"50%", lg:"50%"}}> | |||||
| <Grid container direction="row" justifyContent="flex-start"> | |||||
| <Grid item xs={12} md={12} lg={12}> | |||||
| <TextField | |||||
| fullWidth | |||||
| onChange={(e) => { | |||||
| formik.handleChange(e); | |||||
| // changePassword(e.target.value); | |||||
| }} | |||||
| id="confirmPassword" | |||||
| type={showConfirmPassword ? 'text' : 'password'} | |||||
| name="confirmPassword" | |||||
| label={intl.formatMessage({id: 'confirmPassword'}) + ":"} | |||||
| placeholder={intl.formatMessage({id: 'confirmPassword'})} | |||||
| // defaultValue={formik.values.confirmPassword.trim()} | |||||
| value={formik.values.confirmPassword.trim()} | |||||
| error={Boolean(formik.touched.confirmPassword && formik.errors.confirmPassword)} | |||||
| onBlur={formik.handleBlur} | |||||
| inputProps={{ | |||||
| maxLength: 50, | |||||
| onKeyDown: (e) => { | |||||
| if (e.key === 'Enter') { | |||||
| e.preventDefault(); | |||||
| } | |||||
| }, | |||||
| }} | |||||
| InputLabelProps={{ | |||||
| shrink: true | |||||
| }} | |||||
| InputProps={{ | |||||
| endAdornment:( | |||||
| <InputAdornment position="end"> | |||||
| <IconButton | |||||
| aria-label="toggle password visibility" | |||||
| onClick={handleClickShowConfirmPassword} | |||||
| onMouseDown={handleMouseDownPassword} | |||||
| edge="end" | |||||
| size="large" | |||||
| > | |||||
| {showConfirmPassword ? <EyeOutlined /> : <EyeInvisibleOutlined />} | |||||
| </IconButton> | |||||
| </InputAdornment> | |||||
| ) | |||||
| }} | |||||
| /> | |||||
| </Grid> | |||||
| {formik.touched.confirmPassword && formik.errors.confirmPassword && ( | |||||
| <FormHelperText error id="helper-text-confirmPassword-signup"> | |||||
| {formik.errors.confirmPassword} | |||||
| </FormHelperText> | |||||
| )} | |||||
| </Grid> | |||||
| </Grid> | |||||
| <Grid item xs={12} md={12} lg={12} mt={1} sx={{mb:3}}> | |||||
| <ThemeProvider theme={PNSPS_LONG_BUTTON_THEME}> | |||||
| <Button | |||||
| aria-label={intl.formatMessage({id: 'confirm'})} | |||||
| variant="contained" | |||||
| type="submit" | |||||
| // onClick={()=>goLogin()} | |||||
| > | |||||
| <FormattedMessage id="confirm"/> | |||||
| </Button> | |||||
| </ThemeProvider> | |||||
| </Grid> | |||||
| </Grid> | |||||
| : | |||||
| // ERROR page | |||||
| <Grid container spacing={4} sx={{ minHeight: {xs:"80vh", sm:"70vh", md: "70vh", lg:"70vh", xl:"50vh"} }} direction="column" justifyContent="flex-start" alignItems="center"> | |||||
| <Grid item xs={12} md={12} lg={12} sx={{ mb: 1, mt:5,}}> | |||||
| {/* <Button disabled={true} hidden={true} variant="contained" type="submit" sx={{ fontSize: 12,height:'25px'}}>Submit</Button> */} | |||||
| <CancelOutlinedIcon color="error" sx={{ width: "200px", height: "200px" }} /> | |||||
| </Grid> | |||||
| <Grid item xs={12} md={12} lg={12} sx={{ mb: 1, mt:5,}}> | |||||
| <Typography display="inline" variant="h4"> | |||||
| <FormattedMessage id="verifyFail"/> | |||||
| </Typography> | |||||
| </Grid> | |||||
| <Grid item xs={12} md={12} lg={12} sx={{ mb: 1, mt:5,}}> | |||||
| <Button color="error" variant="outlined" component={Link} to="/login"> | |||||
| <Typography variant="h5"> | |||||
| <FormattedMessage id="backToLogin"/> | |||||
| </Typography> | |||||
| </Button> | |||||
| </Grid> | |||||
| </Grid> | |||||
| } | |||||
| </form> | |||||
| </MainCard> | |||||
| </Grid> | |||||
| </Grid> | |||||
| ); | |||||
| }; | |||||
| export default Index; | |||||
| @@ -83,6 +83,7 @@ const AuthLogin = () => { | |||||
| type: response.data.type, | type: response.data.type, | ||||
| role: response.data.role, | role: response.data.role, | ||||
| abilities: response.data.abilities, | abilities: response.data.abilities, | ||||
| passwordExpiryDate: response.data.passwordExpiryDate, | |||||
| //avatar: require('src/assets/images/users/avatar-3.png').default, | //avatar: require('src/assets/images/users/avatar-3.png').default, | ||||
| } | } | ||||
| // const abilities = response.data.abilities | // const abilities = response.data.abilities | ||||
| @@ -93,6 +93,7 @@ const AuthLoginCustom = () => { | |||||
| abilities: response.data.abilities, | abilities: response.data.abilities, | ||||
| creditor: response.data.creditor, | creditor: response.data.creditor, | ||||
| locale: response.data.preferLocale, | locale: response.data.preferLocale, | ||||
| passwordExpiryDate: response.data.passwordExpiryDate, | |||||
| //avatar: require('src/assets/images/users/avatar-3.png').default, | //avatar: require('src/assets/images/users/avatar-3.png').default, | ||||
| } | } | ||||
| const data = { ...userData, accessToken: response.data.accessToken, refreshToken: response.data.refreshToken } | const data = { ...userData, accessToken: response.data.accessToken, refreshToken: response.data.refreshToken } | ||||
| @@ -45,6 +45,7 @@ const Index = () => { | |||||
| role: responseData.role, | role: responseData.role, | ||||
| abilities: responseData.abilities, | abilities: responseData.abilities, | ||||
| creditor: responseData.creditor, | creditor: responseData.creditor, | ||||
| passwordExpiryDate: response.data.passwordExpiryDate, | |||||
| //locale: responseData.preferLocale, | //locale: responseData.preferLocale, | ||||
| //avatar: require('src/assets/images/users/avatar-3.png').default, | //avatar: require('src/assets/images/users/avatar-3.png').default, | ||||
| } | } | ||||
| @@ -45,6 +45,7 @@ const Index = () => { | |||||
| role: responseData.role, | role: responseData.role, | ||||
| abilities: responseData.abilities, | abilities: responseData.abilities, | ||||
| creditor: responseData.creditor, | creditor: responseData.creditor, | ||||
| passwordExpiryDate: response.data.passwordExpiryDate, | |||||
| //avatar: require('src/assets/images/users/avatar-3.png').default, | //avatar: require('src/assets/images/users/avatar-3.png').default, | ||||
| } | } | ||||
| const data = { ...userData, accessToken: responseData.accessToken, refreshToken: responseData.refreshToken } | const data = { ...userData, accessToken: responseData.accessToken, refreshToken: responseData.refreshToken } | ||||
| @@ -5,7 +5,7 @@ import Loadable from 'components/Loadable'; | |||||
| // import MainLayout from 'layout/MainLayout'; | // import MainLayout from 'layout/MainLayout'; | ||||
| const MainLayout = Loadable(lazy(() => import('layout/MainLayout'))); | const MainLayout = Loadable(lazy(() => import('layout/MainLayout'))); | ||||
| import {isGranted, isGrantedAny} from "auth/utils"; | import {isGranted, isGrantedAny} from "auth/utils"; | ||||
| import { isPasswordExpiry } from "utils/Utils"; | |||||
| // render - dashboard | // render - dashboard | ||||
| const DashboardDefault = Loadable(lazy(() => import('pages/Dashboard/GLD'))); | const DashboardDefault = Loadable(lazy(() => import('pages/Dashboard/GLD'))); | ||||
| const ApplicationDetail = Loadable(lazy(() => import('pages/PublicNotice/Details_GLD'))); | const ApplicationDetail = Loadable(lazy(() => import('pages/PublicNotice/Details_GLD'))); | ||||
| @@ -32,163 +32,171 @@ const GazetteIssuePage = Loadable(lazy(() => import('pages/GazetteIssue/index')) | |||||
| const DrImport = Loadable(lazy(() => import('pages/Setting/DrImport'))); | const DrImport = Loadable(lazy(() => import('pages/Setting/DrImport'))); | ||||
| const AuditLogPage = Loadable(lazy(() => import('pages/AuditLog/index'))); | const AuditLogPage = Loadable(lazy(() => import('pages/AuditLog/index'))); | ||||
| const ReconReportPage = Loadable(lazy(() => import('pages/Recon'))); | const ReconReportPage = Loadable(lazy(() => import('pages/Recon'))); | ||||
| const ChangePasswordPage = Loadable(lazy(() => import('pages/User/ChangePasswordPage'))); | |||||
| // ==============================|| MAIN ROUTING ||============================== // | // ==============================|| MAIN ROUTING ||============================== // | ||||
| const GLDUserRoutes = { | const GLDUserRoutes = { | ||||
| path: '/', | path: '/', | ||||
| element: <MainLayout />, | element: <MainLayout />, | ||||
| children: [ | children: [ | ||||
| ( | |||||
| isPasswordExpiry()? | |||||
| { | |||||
| path: '/', | |||||
| element: <ChangePasswordPage /> | |||||
| }: | |||||
| { | |||||
| path: '/', | |||||
| element: <DashboardDefault /> | |||||
| } | |||||
| ), | |||||
| { | { | ||||
| path: '/', | |||||
| element: <DashboardDefault /> | |||||
| }, | |||||
| { | |||||
| path: '/', | |||||
| children: [ | |||||
| { | |||||
| path: '/dashboard', | |||||
| element: <DashboardDefault /> | |||||
| }, | |||||
| { | |||||
| path: '/application/:id', | |||||
| element: <ApplicationDetail/> | |||||
| }, | |||||
| { | |||||
| path: '/application/search', | |||||
| element: <ApplicationSearch/> | |||||
| }, | |||||
| isGranted(["MAINTAIN_PAYMENT"])? | |||||
| { | |||||
| path: '/application/markAsPaid/search', | |||||
| element: <ApplicationMarkAsPaidSearch/> | |||||
| }:{}, | |||||
| isGrantedAny(["VIEW_PROOF","MAINTAIN_PROOF"])?{ | |||||
| path: '/proof/search', | |||||
| element: <ProofSearch/> | |||||
| }:{}, | |||||
| isGranted("MAINTAIN_PROOF")? | |||||
| { | |||||
| path: '/proof/create/:id', | |||||
| element: <ProofCreate_FromApp/> | |||||
| }:{}, | |||||
| isGrantedAny(["VIEW_PROOF","MAINTAIN_PROOF"])?{ | |||||
| path: '/proof/reply/:id', | |||||
| element: <ProofReply_GLD/> | |||||
| }:{}, | |||||
| isGranted(["MAINTAIN_PAYMENT"])? | |||||
| { | |||||
| path: '/paymentPage/search', | |||||
| element: <PaymentSearch_GLD/> | |||||
| }:{}, | |||||
| isGranted(["MAINTAIN_PAYMENT"])? | |||||
| { | |||||
| path: '/paymentPage/details/:id', | |||||
| element: <PaymentDetails_GLD/> | |||||
| }:{}, | |||||
| isGranted(["MAINTAIN_DEMANDNOTE"])? | |||||
| { | |||||
| path: '/paymentPage/createDemandNote', | |||||
| element: <DemandNote_Create/> | |||||
| }:{}, | |||||
| isGranted(["MAINTAIN_DEMANDNOTE"])? | |||||
| { | |||||
| path: '/paymentPage/exportGDN', | |||||
| element: <DemandNote_Export/> | |||||
| }:{}, | |||||
| isGrantedAny(["VIEW_DEMANDNOTE","MAINTAIN_DEMANDNOTE"])? | |||||
| { | |||||
| path: '/paymentPage/demandNote', | |||||
| element: <DemandNote_Search/> | |||||
| }:{}, | |||||
| isGrantedAny(["VIEW_DEMANDNOTE","MAINTAIN_DEMANDNOTE"])? | |||||
| { | |||||
| path: '/paymentPage/demandNote/details/:id', | |||||
| element: <DemandNote_Details/> | |||||
| }:{}, | |||||
| isGranted("MAINTAIN_RECON") ? | |||||
| { | |||||
| path: '/paymentPage/reconReport', | |||||
| element: <ReconReportPage/> | |||||
| }:{}, | |||||
| isGranted("MAINTAIN_RECON") ? | |||||
| { | |||||
| path: '/gfmis/search', | |||||
| element: <GFMIS_Search/> | |||||
| }:{}, | |||||
| { | |||||
| path: '/user/profile', | |||||
| element: <UserMaintainPage /> | |||||
| }, | |||||
| isGranted("MAINTAIN_SETTING") ? | |||||
| { | |||||
| path: '/setting/sys', | |||||
| element: <SystemSetting /> | |||||
| }:{}, | |||||
| isGranted("MAINTAIN_ANNOUNCEMENT") ? | |||||
| { | |||||
| path: '/setting/announcement', | |||||
| element: <AnnouncementSearch /> | |||||
| }:{}, | |||||
| isGranted("MAINTAIN_ANNOUNCEMENT")? | |||||
| { | |||||
| path: '/setting/announcement/details/:id', | |||||
| element: <AnnouncementDetails /> | |||||
| }:{}, | |||||
| isGranted("MAINTAIN_EMAIL")? | |||||
| { | |||||
| path: '/setting/emailTemplate', | |||||
| element: <EmailTemplatePage/> | |||||
| }:{}, | |||||
| isGranted("MAINTAIN_EMAIL")? | |||||
| { | |||||
| path: '/setting/emailTemplate/:id', | |||||
| element: <EmailTemplateDetailPage/> | |||||
| }:{}, | |||||
| isGranted("MAINTAIN_GAZETTE_ISSUE")? | |||||
| { | |||||
| path: '/setting/holiday', | |||||
| element: <HolidayPage/> | |||||
| }:{}, | |||||
| isGranted("MAINTAIN_GAZETTE_ISSUE")? | |||||
| { | |||||
| path: '/setting/gazetteissuepage', | |||||
| element: <GazetteIssuePage/> | |||||
| }:{}, | |||||
| isGranted("MAINTAIN_DR")? | |||||
| { | |||||
| path: '/setting/drImport', | |||||
| element: <DrImport /> | |||||
| }:{}, | |||||
| { | |||||
| path: '/setting/auditLog', | |||||
| element: <AuditLogPage /> | |||||
| }, | |||||
| ] | |||||
| }, | |||||
| path: '/', | |||||
| children: [ | |||||
| { | |||||
| path: '/dashboard', | |||||
| element: <DashboardDefault /> | |||||
| }, | |||||
| { | |||||
| path: '/application/:id', | |||||
| element: <ApplicationDetail/> | |||||
| }, | |||||
| { | |||||
| path: '/application/search', | |||||
| element: <ApplicationSearch/> | |||||
| }, | |||||
| isGranted(["MAINTAIN_PAYMENT"])? | |||||
| { | |||||
| path: '/application/markAsPaid/search', | |||||
| element: <ApplicationMarkAsPaidSearch/> | |||||
| }:{}, | |||||
| isGrantedAny(["VIEW_PROOF","MAINTAIN_PROOF"])?{ | |||||
| path: '/proof/search', | |||||
| element: <ProofSearch/> | |||||
| }:{}, | |||||
| isGranted("MAINTAIN_PROOF")? | |||||
| { | |||||
| path: '/proof/create/:id', | |||||
| element: <ProofCreate_FromApp/> | |||||
| }:{}, | |||||
| isGrantedAny(["VIEW_PROOF","MAINTAIN_PROOF"])?{ | |||||
| path: '/proof/reply/:id', | |||||
| element: <ProofReply_GLD/> | |||||
| }:{}, | |||||
| isGranted(["MAINTAIN_PAYMENT"])? | |||||
| { | |||||
| path: '/paymentPage/search', | |||||
| element: <PaymentSearch_GLD/> | |||||
| }:{}, | |||||
| isGranted(["MAINTAIN_PAYMENT"])? | |||||
| { | |||||
| path: '/paymentPage/details/:id', | |||||
| element: <PaymentDetails_GLD/> | |||||
| }:{}, | |||||
| isGranted(["MAINTAIN_DEMANDNOTE"])? | |||||
| { | |||||
| path: '/paymentPage/createDemandNote', | |||||
| element: <DemandNote_Create/> | |||||
| }:{}, | |||||
| isGranted(["MAINTAIN_DEMANDNOTE"])? | |||||
| { | |||||
| path: '/paymentPage/exportGDN', | |||||
| element: <DemandNote_Export/> | |||||
| }:{}, | |||||
| isGrantedAny(["VIEW_DEMANDNOTE","MAINTAIN_DEMANDNOTE"])? | |||||
| { | |||||
| path: '/paymentPage/demandNote', | |||||
| element: <DemandNote_Search/> | |||||
| }:{}, | |||||
| isGrantedAny(["VIEW_DEMANDNOTE","MAINTAIN_DEMANDNOTE"])? | |||||
| { | |||||
| path: '/paymentPage/demandNote/details/:id', | |||||
| element: <DemandNote_Details/> | |||||
| }:{}, | |||||
| isGranted("MAINTAIN_RECON") ? | |||||
| { | |||||
| path: '/paymentPage/reconReport', | |||||
| element: <ReconReportPage/> | |||||
| }:{}, | |||||
| isGranted("MAINTAIN_RECON") ? | |||||
| { | |||||
| path: '/gfmis/search', | |||||
| element: <GFMIS_Search/> | |||||
| }:{}, | |||||
| { | |||||
| path: '/user/profile', | |||||
| element: <UserMaintainPage /> | |||||
| }, | |||||
| isGranted("MAINTAIN_SETTING") ? | |||||
| { | |||||
| path: '/setting/sys', | |||||
| element: <SystemSetting /> | |||||
| }:{}, | |||||
| isGranted("MAINTAIN_ANNOUNCEMENT") ? | |||||
| { | |||||
| path: '/setting/announcement', | |||||
| element: <AnnouncementSearch /> | |||||
| }:{}, | |||||
| isGranted("MAINTAIN_ANNOUNCEMENT")? | |||||
| { | |||||
| path: '/setting/announcement/details/:id', | |||||
| element: <AnnouncementDetails /> | |||||
| }:{}, | |||||
| isGranted("MAINTAIN_EMAIL")? | |||||
| { | |||||
| path: '/setting/emailTemplate', | |||||
| element: <EmailTemplatePage/> | |||||
| }:{}, | |||||
| isGranted("MAINTAIN_EMAIL")? | |||||
| { | |||||
| path: '/setting/emailTemplate/:id', | |||||
| element: <EmailTemplateDetailPage/> | |||||
| }:{}, | |||||
| isGranted("MAINTAIN_GAZETTE_ISSUE")? | |||||
| { | |||||
| path: '/setting/holiday', | |||||
| element: <HolidayPage/> | |||||
| }:{}, | |||||
| isGranted("MAINTAIN_GAZETTE_ISSUE")? | |||||
| { | |||||
| path: '/setting/gazetteissuepage', | |||||
| element: <GazetteIssuePage/> | |||||
| }:{}, | |||||
| isGranted("MAINTAIN_DR")? | |||||
| { | |||||
| path: '/setting/drImport', | |||||
| element: <DrImport /> | |||||
| }:{}, | |||||
| { | |||||
| path: '/setting/auditLog', | |||||
| element: <AuditLogPage /> | |||||
| }, | |||||
| ] | |||||
| }, | |||||
| ] | ] | ||||
| }; | }; | ||||
| @@ -4,6 +4,7 @@ import { lazy } from 'react'; | |||||
| import Loadable from 'components/Loadable'; | import Loadable from 'components/Loadable'; | ||||
| // import MainLayout from 'layout/MainLayout'; | // import MainLayout from 'layout/MainLayout'; | ||||
| const MainLayout = Loadable(lazy(() => import('layout/MainLayout'))); | const MainLayout = Loadable(lazy(() => import('layout/MainLayout'))); | ||||
| import { isPasswordExpiry } from "utils/Utils"; | |||||
| // render - dashboard | // render - dashboard | ||||
| const DashboardDefault = Loadable(lazy(() => import('pages/Dashboard/Public'))); | const DashboardDefault = Loadable(lazy(() => import('pages/Dashboard/Public'))); | ||||
| @@ -30,6 +31,7 @@ const Msg_Details = Loadable(lazy(() => import('pages/Message/Details'))); | |||||
| const Msg_Search = Loadable(lazy(() => import('pages/Message/Search'))); | const Msg_Search = Loadable(lazy(() => import('pages/Message/Search'))); | ||||
| const AnnouncementSearch = Loadable(lazy(() => import('pages/Announcement/Search_Public'))); | const AnnouncementSearch = Loadable(lazy(() => import('pages/Announcement/Search_Public'))); | ||||
| const IAmSmart_SuccessCallback = Loadable(lazy(() => import('pages/iAmSmart/SuccessCallback'))); | const IAmSmart_SuccessCallback = Loadable(lazy(() => import('pages/iAmSmart/SuccessCallback'))); | ||||
| const ChangePasswordPage = Loadable(lazy(() => import('pages/User/ChangePasswordPage'))); | |||||
| // ==============================|| MAIN ROUTING ||============================== // | // ==============================|| MAIN ROUTING ||============================== // | ||||
| @@ -38,10 +40,17 @@ const PublicDashboard = { | |||||
| path: '/', | path: '/', | ||||
| element: <MainLayout />, | element: <MainLayout />, | ||||
| children: [ | children: [ | ||||
| { | |||||
| path: '/', | |||||
| element: <DashboardDefault /> | |||||
| }, | |||||
| ( | |||||
| isPasswordExpiry()? | |||||
| { | |||||
| path: '/', | |||||
| element: <ChangePasswordPage /> | |||||
| }: | |||||
| { | |||||
| path: '/', | |||||
| element: <DashboardDefault /> | |||||
| } | |||||
| ), | |||||
| { | { | ||||
| path: '/', | path: '/', | ||||
| children: [ | children: [ | ||||
| @@ -141,8 +150,13 @@ const PublicDashboard = { | |||||
| path: '/announcement/search', | path: '/announcement/search', | ||||
| element: <AnnouncementSearch /> | element: <AnnouncementSearch /> | ||||
| }, | }, | ||||
| { | |||||
| path: '/user/changePassword', | |||||
| element: <ChangePasswordPage /> | |||||
| } | |||||
| ] | ] | ||||
| }, | |||||
| } | |||||
| ] | ] | ||||
| }; | }; | ||||
| @@ -31,16 +31,18 @@ export default function ThemeRoutes() { | |||||
| return useRoutes([{ | return useRoutes([{ | ||||
| path: '', | path: '', | ||||
| children: [ | children: [ | ||||
| (isUserLoggedIn() ? | |||||
| { | |||||
| path: '', | |||||
| element: <Navigate to="/dashboard" /> | |||||
| } | |||||
| ( | |||||
| isUserLoggedIn() ? | |||||
| { | |||||
| path: '', | |||||
| element: <Navigate to="/dashboard" /> | |||||
| } | |||||
| : | : | ||||
| { | |||||
| path: '', | |||||
| element: <Navigate to="/login" /> | |||||
| }) | |||||
| { | |||||
| path: '', | |||||
| element: <Navigate to="/login" /> | |||||
| } | |||||
| ) | |||||
| ] | ] | ||||
| }, | }, | ||||
| // isUserLoggedIn() ? MainRoutes : LoginRoutes, | // isUserLoggedIn() ? MainRoutes : LoginRoutes, | ||||
| @@ -334,7 +334,7 @@ | |||||
| "pwRemark2": "字母和数字的混合", | "pwRemark2": "字母和数字的混合", | ||||
| "pwRemark3": "英文字母大写与小写的混合", | "pwRemark3": "英文字母大写与小写的混合", | ||||
| "pwRemark4": "至少包含一个特殊符号,例如,@ # ?", | "pwRemark4": "至少包含一个特殊符号,例如,@ # ?", | ||||
| "pwRemark5": "請注意,嚴禁使用字典單字、使用者名稱或明顯短語作為密碼內容。", | |||||
| "pwRemark5": "请注意,严禁使用字典单词、用户名或明显的短语作为密码内容。", | |||||
| "pwWeak": "弱", | "pwWeak": "弱", | ||||
| "pwNormal": "普通", | "pwNormal": "普通", | ||||
| "pwGood": "良好", | "pwGood": "良好", | ||||
| @@ -337,7 +337,7 @@ | |||||
| "pwRemark2": "字母和數字的混合", | "pwRemark2": "字母和數字的混合", | ||||
| "pwRemark3": "英文字母大寫與小寫的混合", | "pwRemark3": "英文字母大寫與小寫的混合", | ||||
| "pwRemark4": "至少包含一個特殊符號,例如,@ # ?", | "pwRemark4": "至少包含一個特殊符號,例如,@ # ?", | ||||
| "pwRemark5": "请注意,严禁使用字典单词、用户名或明显的短语作为密码内容。", | |||||
| "pwRemark5": "請注意,嚴禁使用字典單字、使用者名稱或明顯短語作為密碼內容。", | |||||
| "pwWeak": "弱", | "pwWeak": "弱", | ||||
| "pwNormal": "普通", | "pwNormal": "普通", | ||||
| "pwGood": "良好", | "pwGood": "良好", | ||||
| @@ -1,3 +1,5 @@ | |||||
| import * as DateUtils from "utils/DateUtils" | |||||
| export const defaultHomePage = '/dashboard' | export const defaultHomePage = '/dashboard' | ||||
| // ** Checks if an object is empty (returns boolean) | // ** Checks if an object is empty (returns boolean) | ||||
| @@ -147,3 +149,25 @@ export const getUserId = () =>{ | |||||
| return JSON.parse(localStorage.getItem('userData')).id | return JSON.parse(localStorage.getItem('userData')).id | ||||
| } | } | ||||
| } | } | ||||
| export const isPasswordExpiry = () =>{ | |||||
| var date; | |||||
| if (localStorage.getItem('userData') != null){ | |||||
| date = JSON.parse(localStorage.getItem('userData')).passwordExpiryDate | |||||
| } | |||||
| if (date != null){ | |||||
| var currentDate = new Date(); | |||||
| var expirationDate = DateUtils.convertToDate(date); | |||||
| if (expirationDate < currentDate) { | |||||
| console.log(true) | |||||
| return true; // The date has expired | |||||
| } else { | |||||
| console.log(false) | |||||
| return false; // The date is still valid | |||||
| } | |||||
| }else{ | |||||
| return false; | |||||
| } | |||||
| } | |||||