diff --git a/build20240126.zip b/build20240126.zip deleted file mode 100644 index 22353ee..0000000 Binary files a/build20240126.zip and /dev/null differ diff --git a/src/layout/MainLayout/Header/index.js b/src/layout/MainLayout/Header/index.js index 14fcfa6..46d68be 100644 --- a/src/layout/MainLayout/Header/index.js +++ b/src/layout/MainLayout/Header/index.js @@ -263,8 +263,7 @@ function Header(props) {
  • - {/* */} - User Profile +
  • diff --git a/src/pages/Organization/DetailPage/OrganizationCard.js b/src/pages/Organization/DetailPage/OrganizationCard.js index f69e130..52cc841 100644 --- a/src/pages/Organization/DetailPage/OrganizationCard.js +++ b/src/pages/Organization/DetailPage/OrganizationCard.js @@ -18,7 +18,7 @@ import Loadable from 'components/Loadable'; import { lazy } from 'react'; import { notifySaveSuccess } from 'utils/CommonFunction'; import { useIntl } from "react-intl"; -import {PNSPS_BUTTON_THEME} from "../../../themes/buttonConst"; +import {PNSPS_BUTTON_THEME} from "themes/buttonConst"; import {ThemeProvider} from "@emotion/react"; // ==============================|| DASHBOARD - DEFAULT ||============================== // @@ -173,14 +173,15 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => { {createMode ? <> - - - + + + : <> @@ -211,12 +212,13 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => { <> - + @@ -236,13 +238,13 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => { : - + } diff --git a/src/pages/Organization/DetailPage/OrganizationPubCard.js b/src/pages/Organization/DetailPage/OrganizationPubCard.js index 1fe6b5d..1a53a8c 100644 --- a/src/pages/Organization/DetailPage/OrganizationPubCard.js +++ b/src/pages/Organization/DetailPage/OrganizationPubCard.js @@ -20,7 +20,7 @@ import Loadable from 'components/Loadable'; import { lazy } from 'react'; import { notifySaveSuccess } from 'utils/CommonFunction'; import {FormattedMessage, useIntl} from "react-intl"; -import {PNSPS_BUTTON_THEME} from "../../../themes/buttonConst"; +import {PNSPS_BUTTON_THEME} from "themes/buttonConst"; import {ThemeProvider} from "@emotion/react"; // ==============================|| DASHBOARD - DEFAULT ||============================== // @@ -129,36 +129,37 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => { <> - + : <> - + - + @@ -168,12 +169,13 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => { <> - + diff --git a/src/pages/authentication/ForgotPassword/AfterForgotPasswordPage.js b/src/pages/authentication/ForgotPassword/AfterForgotPasswordPage.js new file mode 100644 index 0000000..84ca616 --- /dev/null +++ b/src/pages/authentication/ForgotPassword/AfterForgotPasswordPage.js @@ -0,0 +1,391 @@ +// material-ui +import { + Grid, + Typography, + Button, + // RadioGroup, + Dialog, DialogTitle, DialogContent, DialogActions, + Stack, + InputLabel, + // OutlinedInput, + FormHelperText, + TextField, + IconButton, InputAdornment, + // Box, + // FormControl +} from '@mui/material'; +import { EyeInvisibleOutlined, EyeOutlined } from '@ant-design/icons'; +// import { strengthColorChi, strengthIndicator } from 'utils/password-strength'; + +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 * as FieldUtils from "utils/FieldUtils"; +import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' +import ForwardIcon from '@mui/icons-material/Forward'; +import MainCard from 'components/MainCard'; + + +import { useNavigate } from "react-router-dom"; +// import { notifyActionSuccess } from 'utils/CommonFunction'; +import {PNSPS_LONG_BUTTON_THEME} from "themes/buttonConst"; +import {ThemeProvider} from "@emotion/react"; +import {FormattedMessage, useIntl} from "react-intl"; + +// ==============================|| DASHBOARD - DEFAULT ||============================== // + +const AfterForgotPasswordPage = () => { + const [isWarningPopUp, setIsWarningPopUp] = React.useState(false); + const [showPassword, setShowPassword] = React.useState(false); + const [showConfirmPassword, setshowConfirmPassword] = React.useState(false); + // const [level, setLevel] = React.useState(); + const intl = useIntl(); + + // const [issueId, setIssueId] = React.useState(loadedData.issueId); + const navigate = useNavigate(); + + 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) + } + }); + + return ( + + +
    + + + + + +
    +
    + + + + {/* + 申請公共啟事 + */} + + *': { + flexGrow: 1, + flexBasis: '50%' + } + }} + content={false} + border={false} + boxShadow + > +
    + + + + + + + + + + + + + + + + + + + + + + { + if (e.key === 'Enter') { + e.preventDefault(); + } + }, + }} + InputLabelProps={{ + shrink: true + }} + /> + + {formik.touched.emailVerifyHash && formik.errors.emailVerifyHash && ( + + {formik.errors.emailVerifyHash} + + )} + + + + + + { + if (e.key === 'Enter') { + e.preventDefault(); + } + }, + }} + InputLabelProps={{ + shrink: true + }} + /> + + {formik.touched.username && formik.errors.username && ( + + {formik.errors.username} + + )} + + + + + + { + formik.handleChange(e); + changePassword(e.target.value); + }} + id="password" + type={showPassword ? 'text' : 'password'} + name="password" + placeholder={intl.formatMessage({id: 'userPassword'})} + label={intl.formatMessage({id: 'userPassword'}) + ":"} + // 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:( + + + {showPassword ? : } + + + ) + }} + /> + + {/* + + + + + + + + + + + */} + {formik.touched.password && formik.errors.password && ( + + {formik.errors.password} + + )} + + + + + + { + formik.handleChange(e); + // changePassword(e.target.value); + }} + id="confirmPassword" + type={showConfirmPassword ? 'text' : 'password'} + name="confirmPassword" + placeholder={intl.formatMessage({id: 'confirmPassword'})} + label={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:( + + + {showConfirmPassword ? : } + + + ) + }} + /> + + {formik.touched.confirmPassword && formik.errors.confirmPassword && ( + + {formik.errors.confirmPassword} + + )} + + + + + + + + +
    +
    +
    +
    + setIsWarningPopUp(false)} + PaperProps={{ + sx: { + minWidth: '40vw', + maxWidth: { xs: '90vw', s: '90vw', m: '70vw', lg: '70vw' }, + maxHeight: { xs: '90vh', s: '70vh', m: '70vh', lg: '60vh' } + } + }} + > + + + + + {/* {warningText} */} + + + + + +
    +
    + ); +}; + + +export default AfterForgotPasswordPage; diff --git a/src/pages/authentication/ForgotPassword/AuthCallback/index.js b/src/pages/authentication/ForgotPassword/AuthCallback/index.js new file mode 100644 index 0000000..cf89e89 --- /dev/null +++ b/src/pages/authentication/ForgotPassword/AuthCallback/index.js @@ -0,0 +1,86 @@ + +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 Loadable from 'components/Loadable'; +const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); + + +// ==============================|| DASHBOARD - DEFAULT ||============================== // + +const Index = () => { + + const dispatch = useDispatch() + const navigate = useNavigate() + + React.useEffect(() => { + goLogin(); + }, []); + + function goLogin(){ + dispatch(handleLogoutFunction()); + + let params = new URLSearchParams(window.location.search) + if(params.get("code")){ + HttpUtils.post({ + url: UrlUtils.GET_SMART_LOGIN, + params:{ + code: params.get("code") + }, + onSuccess: (responseData) => { + console.log("responseData"); + console.log(responseData); + const userData = { + id: responseData.id, + fullenName: responseData.name, + fullchName: responseData.chName, + email: responseData.email, + type: responseData.type, + role: responseData.role, + abilities: responseData.abilities, + creditor: responseData.creditor, + locale: responseData.preferLocale, + //avatar: require('src/assets/images/users/avatar-3.png').default, + } + const data = { ...userData, accessToken: responseData.accessToken, refreshToken: responseData.refreshToken } + if(responseData.type === "GLD"){ + setLocale("en"); + localStorage.setItem('locale','en'); + }else{ + if (responseData.preferLocale ==="zh_HK"){ + setLocale("zh-HK"); + localStorage.setItem('locale','zh-HK'); + } + if (responseData.preferLocale ==="zh-CN"){ + setLocale("zh-CN"); + localStorage.setItem('locale','zh-CN'); + } + } + dispatch(handleLogin(data)) + navigate('/dashboard'); + }, + onFail: (response)=>{ + console.log("Fail"); + console.log(response); + window.location.assign("/iamsmart/loginFail"); + }, + onError:(error)=>{ + console.log(error); + window.location.assign("/iamsmart/loginFail"); + } + }); + }else{ + window.location.assign("/iamsmart/loginFail"); + } + } + + return ( + + ); +}; + +export default Index; \ No newline at end of file diff --git a/src/pages/authentication/ForgotPassword/ForgotPasswordApplyForm.js b/src/pages/authentication/ForgotPassword/ForgotPasswordApplyForm.js new file mode 100644 index 0000000..daf877f --- /dev/null +++ b/src/pages/authentication/ForgotPassword/ForgotPasswordApplyForm.js @@ -0,0 +1,229 @@ +// material-ui +import { + Grid, + Typography, + Button, + // RadioGroup, + Dialog, DialogTitle, DialogContent, DialogActions, + Stack, + InputLabel, + // OutlinedInput, + FormHelperText, + TextField, + // Box +} from '@mui/material'; +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 * as FieldUtils from "utils/FieldUtils"; +import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' +import ForwardIcon from '@mui/icons-material/Forward'; +import MainCard from 'components/MainCard'; + + +import { useNavigate } from "react-router-dom"; +// import { notifyActionSuccess } from 'utils/CommonFunction'; +import {PNSPS_LONG_BUTTON_THEME} from "themes/buttonConst"; +import {ThemeProvider} from "@emotion/react"; +import {FormattedMessage, useIntl} from "react-intl"; + +// ==============================|| DASHBOARD - DEFAULT ||============================== // + +const ForgotPasswordApplyForm = () => { + const [isWarningPopUp, setIsWarningPopUp] = React.useState(false); + // const [warningText, setWarningText] = React.useState("");s + // const [attachment, setAttachment] = React.useState({}); + const intl = useIntl(); + + // const [issueId, setIssueId] = React.useState(loadedData.issueId); + const navigate = useNavigate(); + + const BackgroundHead = { + backgroundImage: `url(${titleBackgroundImg})`, + width: 'auto', + height: 'auto', + backgroundSize: 'contain', + backgroundRepeat: 'no-repeat', + backgroundColor: '#0C489E', + backgroundPosition: 'right' + } + + const formik = useFormik({ + enableReinitialize: true, + initialValues: { + username: '', + }, + validationSchema: yup.object().shape({ + username: yup.string().required(intl.formatMessage({id: 'requireUsername'})), + }), + onSubmit: values => { + console.log(values) + + // HttpUtils.postWithFiles({ + // url: UrlUtils.POST_PUBLIC_NOTICE_APPLY, + // params: { + // id: 0, + // contactPerson: values.contactPerson, + // contactTelNo: { + // countryCode: values.tel_countryCode, + // phoneNumber: values.phoneNumber + // }, + // contactFaxNo: { + // countryCode: values.fax_countryCode, + // faxNumber: values.faxNumber + // }, + // issueId: issueId, + // careOf: values.careOf ? values.careOf: "", + // remarks: values.remarks ? values.remarks : "", + // }, + // // files: [attachment], + // onSuccess: function () { + // notifyActionSuccess(intl.formatMessage({id: 'submissionSuccess'}) + '!') + // navigate("/publicNotice"); + // // location.reload(); + // } + // }); + } + }); + + return ( + + +
    + + + + + +
    +
    + + + + {/* + 申請公共啟事 + */} + + *': { + flexGrow: 1, + flexBasis: '50%' + } + }} + content={false} + border={false} + boxShadow + > +
    + + + + + + + + + + + + + + + + + + + + + + { + if (e.key === 'Enter') { + e.preventDefault(); + } + }, + }} + InputLabelProps={{ + shrink: true + }} + /> + + {formik.touched.username && formik.errors.username && ( + + {formik.errors.username} + + )} + + + + + + + + +
    +
    +
    +
    + setIsWarningPopUp(false)} + PaperProps={{ + sx: { + minWidth: '40vw', + maxWidth: { xs: '90vw', s: '90vw', m: '70vw', lg: '70vw' }, + maxHeight: { xs: '90vh', s: '70vh', m: '70vh', lg: '60vh' } + } + }} + > + + + + + {/* {warningText} */} + + + + + +
    +
    + ); +}; + + +export default ForgotPasswordApplyForm; diff --git a/src/pages/authentication/ForgotPassword/index.js b/src/pages/authentication/ForgotPassword/index.js new file mode 100644 index 0000000..50628b6 --- /dev/null +++ b/src/pages/authentication/ForgotPassword/index.js @@ -0,0 +1,46 @@ +// material-ui +import * as React from "react"; +// import * as HttpUtils from "utils/HttpUtils"; +// import * as UrlUtils from "utils/ApiPathConst"; +// import * as DateUtils from "utils/DateUtils"; +// import * as FormatUtils from "utils/FormatUtils"; + +// import { +// Radio, +// FormControlLabel +// } from '@mui/material'; + +import Loadable from 'components/Loadable'; +import { lazy } from 'react'; +const LoadingComponent = Loadable(lazy(() => import('../../extra-pages/LoadingComponent'))); +const ForgotPasswordApplyForm = Loadable(lazy(() => import('./ForgotPasswordApplyForm'))); + + +// ==============================|| DASHBOARD - DEFAULT ||============================== // + +const ApplyForm = () => { + // const [userData, setUserData] = React.useState(null); + // const [selections, setSelection] = React.useState([]); + const [isLoading, setLoding] = React.useState(true); + + React.useEffect(() => { + loadUserData(); + }, []); + + const loadUserData = () => { + setLoding(false); + }; + + return ( + isLoading ? + + : + + ); +}; + + +export default ApplyForm; diff --git a/src/pages/authentication/auth-forms/AuthLoginCustom.js b/src/pages/authentication/auth-forms/AuthLoginCustom.js index 771c143..94798c2 100644 --- a/src/pages/authentication/auth-forms/AuthLoginCustom.js +++ b/src/pages/authentication/auth-forms/AuthLoginCustom.js @@ -337,7 +337,7 @@ const AuthLoginCustom = () => { - + ? diff --git a/src/routes/LoginRoutes.js b/src/routes/LoginRoutes.js index b3c7533..56e8166 100644 --- a/src/routes/LoginRoutes.js +++ b/src/routes/LoginRoutes.js @@ -12,6 +12,9 @@ const RegisterForm = Loadable(lazy(() => import('pages/authentication/Register') const BusRegisterForm = Loadable(lazy(() => import('pages/authentication/BusRegister'))); const IAmSmartRegister = Loadable(lazy(() => import('pages/authentication/IAmSmartRegister'))); const ErrorPage = Loadable(lazy(() => import('pages/extra-pages/ErrorPage'))); +const ForgotPassword = Loadable(lazy(() => import('pages/authentication/ForgotPassword'))); +const AfterForgotPasswordPage = Loadable(lazy(() => import('pages/authentication/ForgotPassword/AfterForgotPasswordPage'))); + const IAmSmart_DirectLoginCallback = Loadable(lazy(() => import('pages/iAmSmart/DirectLoginCallback'))); //const IAmSmart_FallCallback = Loadable(lazy(() => import('pages/iAmSmart/FallCallback'))); const IAmSmart_FailCallback = Loadable(lazy(() => import('pages/iAmSmart/FailCallback'))); @@ -98,7 +101,15 @@ const LoginRoutes = { { path: 'testfpscallback', element: - } + }, + { + path: 'forgot/password', + element: + }, + { + path: 'forgot/password/verify', + element: + }, ] }; diff --git a/src/themes/buttonConst.js b/src/themes/buttonConst.js index 7d74ea4..6ac414b 100644 --- a/src/themes/buttonConst.js +++ b/src/themes/buttonConst.js @@ -44,9 +44,15 @@ export const PNSPS_BUTTON_THEME = createTheme({ contrastText: '#FFFFFF', }, success:{ - main: '#6A8B9E', + main: '#448DF2', contrastText: '#FFFFFF', - } + }, + orange: { + main: '#ed9740', + light: '#ff5e5e', + dark: '#b0671e', + contrastText: '#fff', + }, }, components: { MuiDataGrid: { @@ -129,7 +135,17 @@ export const PNSPS_LONG_BUTTON_THEME = createTheme({ exportExcel:{ main: '#60667E', contrastText: '#FFFFFF', - } + }, + success:{ + main: '#3f50b5', + contrastText: '#FFFFFF', + }, + orange: { + main: '#ed9740', + light: '#ff5e5e', + dark: '#b0671e', + contrastText: '#fff', + }, }, components: { MuiDataGrid: { diff --git a/src/translations/en.json b/src/translations/en.json index 698559f..343441b 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -70,6 +70,12 @@ "userLoginName": "Username", "userPassword": "Password", "forgotUserPassword": "Forgot Password", + "forgotPasswordTitle": "Find Your Account", + "forgotPasswordSubTitle": "Please enter your username to receive the code to reset your password", + "forgotPasswordSubTitle1": "Please enter your username to receive", + "forgotPasswordSubTitle2": "the code to reset your password", + "securityCode": "Security Code", + "requireSecurityCode": "Please enter security code", "learnMore": "Learn More", "createOrReActivate": "Create account", "usernameTaken": "This user login name has been registered, please use another user login name", diff --git a/src/translations/zh-CN.json b/src/translations/zh-CN.json index 97df504..da341ce 100644 --- a/src/translations/zh-CN.json +++ b/src/translations/zh-CN.json @@ -70,6 +70,12 @@ "userLoginName": "用户登入名称", "userPassword": "密码", "forgotUserPassword": "忘记密码", + "forgotPasswordTitle": "寻找你的帐号", + "forgotPasswordSubTitle": "请输入你的用户登入名称以重设密码", + "forgotPasswordSubTitle1": "请输入你的用户登入名称收", + "forgotPasswordSubTitle2": "以重设密码", + "securityCode": "安全验证码", + "requireSecurityCode": "请输入安全验证码", "learnMore": "了解更多", "createOrReActivate": "建立帐户", "usernameTaken": "此用户登入名称已被注册,请使用其他用户登入名称", diff --git a/src/translations/zh-HK.json b/src/translations/zh-HK.json index 3a89070..1febe82 100644 --- a/src/translations/zh-HK.json +++ b/src/translations/zh-HK.json @@ -70,6 +70,12 @@ "userLoginName": "用戶登入名稱", "userPassword": "密碼", "forgotUserPassword": "忘記密碼", + "forgotPasswordTitle": "尋找你的帳號", + "forgotPasswordSubTitle": "請輸入你的用戶登入名稱以重設密碼", + "forgotPasswordSubTitle1": "請輸入你的用戶登入名稱", + "forgotPasswordSubTitle2": "以重設密碼", + "securityCode": "安全驗證碼", + "requireSecurityCode": "請輸入安全驗證碼", "learnMore": "了解更多", "createOrReActivate": "建立帳戶", "usernameTaken": "此用戶登入名稱已被注冊,請使用其他用戶登入名稱",