| @@ -156,7 +156,7 @@ const SearchDemandNoteForm = ({ applySearch, orgComboData, searchCriteria, issue | |||||
| }} | }} | ||||
| renderInput={(params) => ( | renderInput={(params) => ( | ||||
| <TextField {...params} | <TextField {...params} | ||||
| label="Organisation" | |||||
| label="BR No./Organisation" | |||||
| InputLabelProps={{ | InputLabelProps={{ | ||||
| shrink: true | shrink: true | ||||
| }} | }} | ||||
| @@ -14,7 +14,7 @@ const MainCard = Loadable(React.lazy(() => import('components/MainCard'))); | |||||
| const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | ||||
| import DownloadIcon from '@mui/icons-material/Download'; | import DownloadIcon from '@mui/icons-material/Download'; | ||||
| // ==============================|| DASHBOARD - DEFAULT ||============================== // | // ==============================|| DASHBOARD - DEFAULT ||============================== // | ||||
| const PaymentDetails = ({ formData,doPrint }) => { | |||||
| const PaymentDetails = ({ formData,doPrint,onDownload }) => { | |||||
| const [data, setData] = React.useState({}); | const [data, setData] = React.useState({}); | ||||
| const [onReady, setOnReady] = React.useState(false); | const [onReady, setOnReady] = React.useState(false); | ||||
| @@ -158,10 +158,14 @@ const PaymentDetails = ({ formData,doPrint }) => { | |||||
| </FormLabel> | </FormLabel> | ||||
| </Grid> | </Grid> | ||||
| <Grid xs={6} md={5} sx={{ml:5,textAlign: "left" }}> | <Grid xs={6} md={5} sx={{ml:5,textAlign: "left" }}> | ||||
| {onDownload? | |||||
| <LoadingComponent disableText={true} alignItems="flex-start"/> | |||||
| : | |||||
| <Button className="printHidden" variant="contained" sx={{ mt:2 }} onClick={doPrint}> | <Button className="printHidden" variant="contained" sx={{ mt:2 }} onClick={doPrint}> | ||||
| <DownloadIcon/> | <DownloadIcon/> | ||||
| <Typography sx={{fontSize: "16px"}}>Download</Typography> | <Typography sx={{fontSize: "16px"}}>Download</Typography> | ||||
| </Button> | </Button> | ||||
| } | |||||
| </Grid> | </Grid> | ||||
| </Grid> | </Grid> | ||||
| </Grid> | </Grid> | ||||
| @@ -4,7 +4,7 @@ import { | |||||
| Typography, | Typography, | ||||
| Stack, | Stack, | ||||
| Box, | Box, | ||||
| // Button | |||||
| Button | |||||
| } from '@mui/material'; | } from '@mui/material'; | ||||
| import * as UrlUtils from "utils/ApiPathConst"; | import * as UrlUtils from "utils/ApiPathConst"; | ||||
| import * as React from "react"; | import * as React from "react"; | ||||
| @@ -12,6 +12,7 @@ import * as HttpUtils from "utils/HttpUtils"; | |||||
| import * as DateUtils from "utils/DateUtils"; | import * as DateUtils from "utils/DateUtils"; | ||||
| import { useParams } from "react-router-dom"; | import { useParams } from "react-router-dom"; | ||||
| import { useNavigate } from "react-router-dom"; | import { useNavigate } from "react-router-dom"; | ||||
| import ForwardIcon from '@mui/icons-material/Forward'; | |||||
| import Loadable from 'components/Loadable'; | import Loadable from 'components/Loadable'; | ||||
| const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | ||||
| @@ -37,6 +38,7 @@ const Index = () => { | |||||
| const [record, setRecord] = React.useState(); | const [record, setRecord] = React.useState(); | ||||
| const [itemList, setItemList] = React.useState([]); | const [itemList, setItemList] = React.useState([]); | ||||
| const [onReady, setOnReady] = React.useState(false); | const [onReady, setOnReady] = React.useState(false); | ||||
| const [onDownload, setOnDownload] = React.useState(false); | |||||
| // const [detailsOrder, setDetailsOrder] = React.useState(2); | // const [detailsOrder, setDetailsOrder] = React.useState(2); | ||||
| React.useEffect(() => { | React.useEffect(() => { | ||||
| @@ -54,8 +56,15 @@ const Index = () => { | |||||
| const doPrint = () => { | const doPrint = () => { | ||||
| // window.print(); | // window.print(); | ||||
| setOnDownload(true) | |||||
| HttpUtils.fileDownload({ | HttpUtils.fileDownload({ | ||||
| url: UrlUtils.GEN_PAYMENT_RECEIPT+"/"+params.id, | url: UrlUtils.GEN_PAYMENT_RECEIPT+"/"+params.id, | ||||
| onResponse:()=>{ | |||||
| setOnDownload(false) | |||||
| }, | |||||
| onError:()=>{ | |||||
| setOnDownload(false) | |||||
| } | |||||
| }); | }); | ||||
| }; | }; | ||||
| @@ -98,6 +107,15 @@ const Index = () => { | |||||
| </Stack> | </Stack> | ||||
| </div> | </div> | ||||
| </Grid> | </Grid> | ||||
| <Grid item xs={12} width={{xs:"90%", sm:"90%", md:"90%", lg:"90%"}}> | |||||
| <Button | |||||
| aria-label={"back"} | |||||
| title={"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> | |||||
| {/*row 1*/} | {/*row 1*/} | ||||
| <Grid item xs={12} md={12} sx={{textAlign: "center" }}> | <Grid item xs={12} md={12} sx={{textAlign: "center" }}> | ||||
| <Grid container justifyContent="center" direction="column" spacing={2} sx={{ p: 2 }} alignitems="stretch" > | <Grid container justifyContent="center" direction="column" spacing={2} sx={{ p: 2 }} alignitems="stretch" > | ||||
| @@ -106,6 +124,7 @@ const Index = () => { | |||||
| <PaymentDetails | <PaymentDetails | ||||
| formData={record} | formData={record} | ||||
| doPrint={doPrint} | doPrint={doPrint} | ||||
| onDownload={onDownload} | |||||
| style={{ | style={{ | ||||
| display: "flex", | display: "flex", | ||||
| height: "100%", | height: "100%", | ||||
| @@ -32,6 +32,8 @@ import UnionPayIcon from "assets/images/icons/unionpay.svg"; | |||||
| import PpsIcon from "assets/images/icons/ppshk.svg"; | import PpsIcon from "assets/images/icons/ppshk.svg"; | ||||
| import FpsIcon from "assets/images/icons/fps.svg"; | import FpsIcon from "assets/images/icons/fps.svg"; | ||||
| import {FormattedMessage, useIntl} from "react-intl"; | import {FormattedMessage, useIntl} from "react-intl"; | ||||
| import * as HttpUtils from "utils/HttpUtils" | |||||
| import * as UrlUtils from "utils/ApiPathConst" | |||||
| const MultiPaymentWindow = (props) => { | const MultiPaymentWindow = (props) => { | ||||
| const intl = useIntl(); | const intl = useIntl(); | ||||
| @@ -52,7 +54,10 @@ const MultiPaymentWindow = (props) => { | |||||
| const [pPSClass, setPPSlass] = useState(""); | const [pPSClass, setPPSlass] = useState(""); | ||||
| const [filteredPaymentMethod, setFilteredPaymentMethod] = useState([]); | const [filteredPaymentMethod, setFilteredPaymentMethod] = useState([]); | ||||
| const [onReady, setOnReady] = useState(false); | const [onReady, setOnReady] = useState(false); | ||||
| const [paymentHoldedErrText, setPaymentHoldedErrText] = React.useState(""); | |||||
| const [paymentHoldedErr, setPaymentHoldedErr] = React.useState(false); | |||||
| useEffect(() => { | useEffect(() => { | ||||
| // console.log(props.transactionData) | // console.log(props.transactionData) | ||||
| if(Object.keys(props.transactionData).length > 0){ | if(Object.keys(props.transactionData).length > 0){ | ||||
| @@ -185,7 +190,49 @@ const MultiPaymentWindow = (props) => { | |||||
| }; | }; | ||||
| const confirmPaymentHandle = () => () =>{ | const confirmPaymentHandle = () => () =>{ | ||||
| props.setConfirmPayment(true); | |||||
| handlePaymentCheck() | |||||
| }; | |||||
| const handlePaymentCheck = () => { | |||||
| let appIdList = props.appIds | |||||
| // console.log(props.appIds) | |||||
| // console.log(appIdList) | |||||
| HttpUtils.post({ | |||||
| url: UrlUtils.PAYMENT_CHECK, | |||||
| params: { | |||||
| appIds: appIdList | |||||
| }, | |||||
| onSuccess: (responseData) => { | |||||
| const latestData = {}; | |||||
| responseData.forEach(item => { | |||||
| const { appId, timeDiff } = item; | |||||
| if (latestData[appId] === undefined || timeDiff < latestData[appId].timeDiff) { | |||||
| latestData[appId] = item; | |||||
| } | |||||
| }); | |||||
| const latestDataObjects = Object.values(latestData); | |||||
| const filteredData = latestDataObjects.filter(item => item.timeDiff > 20 && item.status !== "APPR"); | |||||
| const filteredAppIds = filteredData.map(item => item.appId); | |||||
| const appIdsNotInData = appIdList.filter(appId => !latestDataObjects.some(item => item.appId === appId)); | |||||
| const combinedAppIdsArray = [...appIdsNotInData, ...filteredAppIds]; | |||||
| const readyToPayment = appIdList.every(appId => combinedAppIdsArray.includes(appId)); | |||||
| if (readyToPayment){ | |||||
| // props.setConfirmPayment(true); | |||||
| return; | |||||
| }else{ | |||||
| const appIdsInData = appIdList.filter(appId => !combinedAppIdsArray.some(item => item === appId)); | |||||
| const HoldingApplication = latestDataObjects.filter(item => appIdsInData.includes(item.appId)); | |||||
| const resultString = HoldingApplication.map(item => item.appNo).join(' , '); | |||||
| setPaymentHoldedErrText(resultString); | |||||
| // setPaymentHoldedErrText(intl.formatMessage({ id: 'MSG.paymentHolded' }, { appNo: record.appNo })); | |||||
| setPaymentHoldedErr(true); | |||||
| } | |||||
| } | |||||
| }); | |||||
| }; | }; | ||||
| const closeHandle = () => () =>{ | const closeHandle = () => () =>{ | ||||
| @@ -387,10 +434,37 @@ const MultiPaymentWindow = (props) => { | |||||
| </DialogActions> | </DialogActions> | ||||
| <DialogActions> | <DialogActions> | ||||
| <Button variant="contained" color="success" onClick={confirmPaymentHandle()} disabled={paymentMethod === "" || isLimit || isPPSLimit}> | <Button variant="contained" color="success" onClick={confirmPaymentHandle()} disabled={paymentMethod === "" || isLimit || isPPSLimit}> | ||||
| <FormattedMessage id="confirm"/> | |||||
| <FormattedMessage id="pay"/> | |||||
| </Button> | </Button> | ||||
| </DialogActions> | </DialogActions> | ||||
| </Stack> | </Stack> | ||||
| <div> | |||||
| <Dialog | |||||
| open={paymentHoldedErr} | |||||
| onClose={() => setPaymentHoldedErr(false)} | |||||
| PaperProps={{ | |||||
| sx: { | |||||
| minWidth: '40vw', | |||||
| maxWidth: { xs: '90vw', s: '90vw', m: '70vw', lg: '70vw' }, | |||||
| maxHeight: { xs: '90vh', s: '70vh', m: '70vh', lg: '60vh' } | |||||
| } | |||||
| }} | |||||
| > | |||||
| <DialogTitle></DialogTitle> | |||||
| <Typography variant="h4" style={{ paddingLeft: '24px' }}><FormattedMessage id="MSG.actionFail" /></Typography> | |||||
| <DialogContent style={{ display: 'flex', }}> | |||||
| <Stack direction="column" justifyContent="space-between"> | |||||
| <div dangerouslySetInnerHTML={{ __html: intl.formatMessage({ id: 'MSG.paymentHolded' }, { appNo: paymentHoldedErrText }) }} /> | |||||
| </Stack> | |||||
| </DialogContent> | |||||
| <DialogActions> | |||||
| <Button onClick={() => setPaymentHoldedErr(false)} aria-label={intl.formatMessage({ id: 'close' })}> | |||||
| <Typography variant="h5"> | |||||
| <FormattedMessage id="close" /> | |||||
| </Typography></Button> | |||||
| </DialogActions> | |||||
| </Dialog> | |||||
| </div> | |||||
| </Dialog> | </Dialog> | ||||
| ); | ); | ||||
| }; | }; | ||||
| @@ -157,12 +157,12 @@ const Index = () => { | |||||
| }); | }); | ||||
| } | } | ||||
| // //For testing | |||||
| //For testing | |||||
| // if (paymentMethod != "") { | // if (paymentMethod != "") { | ||||
| // HttpUtils.post({ | // HttpUtils.post({ | ||||
| // url: UrlUtils.PAYMENT_CREATE, | // url: UrlUtils.PAYMENT_CREATE, | ||||
| // params: { | // params: { | ||||
| // transNo: "test0001", | |||||
| // transNo: "test0002", | |||||
| // payMethod: paymentMethod, | // payMethod: paymentMethod, | ||||
| // payAmount: totalAmount, | // payAmount: totalAmount, | ||||
| // appIdList: location.state?.appIdList ?? [] | // appIdList: location.state?.appIdList ?? [] | ||||
| @@ -209,18 +209,18 @@ const Index = () => { | |||||
| } | } | ||||
| }); | }); | ||||
| // HttpUtils.get({ | |||||
| // url: UrlUtils.PAYMENT_LIMIT_SETTING_LIST, | |||||
| // params: {}, | |||||
| // onSuccess: (responseData) => { | |||||
| // // console.log(responseData) | |||||
| // setPaymentLimit(responseData) | |||||
| HttpUtils.get({ | |||||
| url: UrlUtils.PAYMENT_LIMIT_SETTING_LIST, | |||||
| params: {}, | |||||
| onSuccess: (responseData) => { | |||||
| // console.log(responseData) | |||||
| setPaymentLimit(responseData) | |||||
| // }, | |||||
| // onError: () =>{ | |||||
| // // setOnReady(true) | |||||
| // } | |||||
| // }); | |||||
| }, | |||||
| onError: () =>{ | |||||
| // setOnReady(true) | |||||
| } | |||||
| }); | |||||
| // const responseData = { | // const responseData = { | ||||
| // "availablepaymentmethods": [ | // "availablepaymentmethods": [ | ||||
| @@ -540,6 +540,8 @@ const Index = () => { | |||||
| onReady = {onReady} | onReady = {onReady} | ||||
| locale = {locale} | locale = {locale} | ||||
| isFullScreen={isFullScreen} | isFullScreen={isFullScreen} | ||||
| appIds={appIds} | |||||
| // appNo={itemList.appNo} | |||||
| /> | /> | ||||
| </Grid > | </Grid > | ||||
| ); | ); | ||||
| @@ -37,6 +37,9 @@ const FormPanel = ({ formData }) => { | |||||
| const [saving, setSaving] = React.useState(false); | const [saving, setSaving] = React.useState(false); | ||||
| const [proofPaymentDeadlineMin, setProofPaymentDeadlineMin] = React.useState({}); | |||||
| const [reviseDeadlineMin, setReviseDeadlineMin] = React.useState({}); | |||||
| const navigate = useNavigate() | const navigate = useNavigate() | ||||
| React.useEffect(() => { | React.useEffect(() => { | ||||
| @@ -46,6 +49,8 @@ const FormPanel = ({ formData }) => { | |||||
| setColumnPrice(ComboData.proofPrice[1]) | setColumnPrice(ComboData.proofPrice[1]) | ||||
| formData['length'] = 18; | formData['length'] = 18; | ||||
| } | } | ||||
| setProofPaymentDeadlineMin(formData.proofPaymentDeadline); | |||||
| setReviseDeadlineMin(formData.reviseDeadline); | |||||
| } | } | ||||
| }, [formData]); | }, [formData]); | ||||
| @@ -206,6 +211,7 @@ const FormPanel = ({ formData }) => { | |||||
| onChange={formik.handleChange} | onChange={formik.handleChange} | ||||
| name="reviseDeadline" | name="reviseDeadline" | ||||
| value={formik.values["reviseDeadline"]} | value={formik.values["reviseDeadline"]} | ||||
| InputProps={{ inputProps: { min: DateUtils.datetimeStr(reviseDeadlineMin) } }} | |||||
| variant="outlined" | variant="outlined" | ||||
| sx={ | sx={ | ||||
| { | { | ||||
| @@ -232,6 +238,7 @@ const FormPanel = ({ formData }) => { | |||||
| onChange={formik.handleChange} | onChange={formik.handleChange} | ||||
| name="proofPaymentDeadline" | name="proofPaymentDeadline" | ||||
| value={formik.values["proofPaymentDeadline"]} | value={formik.values["proofPaymentDeadline"]} | ||||
| InputProps={{ inputProps: { min: DateUtils.datetimeStr(proofPaymentDeadlineMin) } }} | |||||
| variant="outlined" | variant="outlined" | ||||
| sx={ | sx={ | ||||
| { | { | ||||
| @@ -45,6 +45,8 @@ const Index = () => { | |||||
| const [record, setRecord] = React.useState({}); | const [record, setRecord] = React.useState({}); | ||||
| const [onReady, setOnReady] = React.useState(false); | const [onReady, setOnReady] = React.useState(false); | ||||
| const [isPopUp, setIsPopUp] = useState(false); | const [isPopUp, setIsPopUp] = useState(false); | ||||
| const [paymentHoldedErrText, setPaymentHoldedErrText] = React.useState(""); | |||||
| const [paymentHoldedErr, setPaymentHoldedErr] = React.useState(false); | |||||
| const intl = useIntl(); | const intl = useIntl(); | ||||
| @@ -77,9 +79,48 @@ const Index = () => { | |||||
| function doPayment() { | function doPayment() { | ||||
| setIsPopUp(false); | setIsPopUp(false); | ||||
| navigate('/paymentPage', { state: { amount: fee, appIdList: [record?.appId] } }); | |||||
| let appIdList = [record?.appId] | |||||
| handlePaymentCheck(appIdList) | |||||
| } | } | ||||
| const handlePaymentCheck = (appIdList) => { | |||||
| HttpUtils.post({ | |||||
| url: UrlUtils.PAYMENT_CHECK, | |||||
| params: { | |||||
| appIds: appIdList | |||||
| }, | |||||
| onSuccess: (responseData) => { | |||||
| const latestData = {}; | |||||
| responseData.forEach(item => { | |||||
| const { appId, timeDiff } = item; | |||||
| if (latestData[appId] === undefined || timeDiff < latestData[appId].timeDiff) { | |||||
| latestData[appId] = item; | |||||
| } | |||||
| }); | |||||
| const latestDataObjects = Object.values(latestData); | |||||
| const filteredData = latestDataObjects.filter(item => item.timeDiff > 20 && item.status !== "APPR"); | |||||
| const filteredAppIds = filteredData.map(item => item.appId); | |||||
| const appIdsNotInData = appIdList.filter(appId => !latestDataObjects.some(item => item.appId === appId)); | |||||
| const combinedAppIdsArray = [...appIdsNotInData, ...filteredAppIds]; | |||||
| const readyToPayment = appIdList.every(appId => combinedAppIdsArray.includes(appId)); | |||||
| if (readyToPayment){ | |||||
| navigate('/paymentPage', { state: { amount: fee, appIdList: appIdList } }); | |||||
| }else{ | |||||
| const appIdsInData = appIdList.filter(appId => !combinedAppIdsArray.some(item => item === appId)); | |||||
| const HoldingApplication = latestDataObjects.filter(item => appIdsInData.includes(item.appId)); | |||||
| const resultString = HoldingApplication.map(item => item.appNo).join(' , '); | |||||
| setPaymentHoldedErrText(resultString); | |||||
| // setPaymentHoldedErrText(intl.formatMessage({ id: 'MSG.paymentHolded' }, { appNo: record.appNo })); | |||||
| setPaymentHoldedErr(true); | |||||
| } | |||||
| } | |||||
| }); | |||||
| }; | |||||
| return ( | return ( | ||||
| !onReady ? | !onReady ? | ||||
| <Grid container sx={{ minHeight: '87vh', mb: 3 }} direction="column" justifyContent="center" alignItems="center"> | <Grid container sx={{ minHeight: '87vh', mb: 3 }} direction="column" justifyContent="center" alignItems="center"> | ||||
| @@ -200,6 +241,33 @@ const Index = () => { | |||||
| </Dialog> | </Dialog> | ||||
| </div> | </div> | ||||
| {/*row 2*/} | {/*row 2*/} | ||||
| <div> | |||||
| <Dialog | |||||
| open={paymentHoldedErr} | |||||
| onClose={() => setPaymentHoldedErr(false)} | |||||
| PaperProps={{ | |||||
| sx: { | |||||
| minWidth: '40vw', | |||||
| maxWidth: { xs: '90vw', s: '90vw', m: '70vw', lg: '70vw' }, | |||||
| maxHeight: { xs: '90vh', s: '70vh', m: '70vh', lg: '60vh' } | |||||
| } | |||||
| }} | |||||
| > | |||||
| <DialogTitle></DialogTitle> | |||||
| <Typography variant="h4" style={{ paddingLeft: '24px' }}><FormattedMessage id="MSG.actionFail" /></Typography> | |||||
| <DialogContent style={{ display: 'flex', }}> | |||||
| <Stack direction="column" justifyContent="space-between"> | |||||
| <div dangerouslySetInnerHTML={{ __html: intl.formatMessage({ id: 'MSG.paymentHolded' }, { appNo: paymentHoldedErrText }) }} /> | |||||
| </Stack> | |||||
| </DialogContent> | |||||
| <DialogActions> | |||||
| <Button onClick={() => setPaymentHoldedErr(false)} aria-label={intl.formatMessage({ id: 'close' })}> | |||||
| <Typography variant="h5"> | |||||
| <FormattedMessage id="close" /> | |||||
| </Typography></Button> | |||||
| </DialogActions> | |||||
| </Dialog> | |||||
| </div> | |||||
| </Grid > | </Grid > | ||||
| @@ -139,7 +139,7 @@ const ApplicationDetailCard = ({ | |||||
| <Grid container alignItems={"center"}> | <Grid container alignItems={"center"}> | ||||
| <Grid item xs={12} md={3} lg={3} | <Grid item xs={12} md={3} lg={3} | ||||
| sx={{ display: 'flex', alignItems: 'center' }}> | sx={{ display: 'flex', alignItems: 'center' }}> | ||||
| <FormLabel><Typography variant="h5">App No.:</Typography></FormLabel> | |||||
| <FormLabel><Typography variant="h5">App. No.:</Typography></FormLabel> | |||||
| </Grid> | </Grid> | ||||
| <Grid item xs={12} md={9} lg={9}> | <Grid item xs={12} md={9} lg={9}> | ||||
| @@ -151,7 +151,7 @@ const ApplicationDetailCard = ({ | |||||
| <Grid container alignItems={"left"}> | <Grid container alignItems={"left"}> | ||||
| <Grid item xs={12} md={3} lg={3} | <Grid item xs={12} md={3} lg={3} | ||||
| sx={{ display: 'flex', alignItems: 'center' }}> | sx={{ display: 'flex', alignItems: 'center' }}> | ||||
| <FormLabel><Typography variant="h5">Status:</Typography></FormLabel> | |||||
| <FormLabel><Typography variant="h5">App. Status:</Typography></FormLabel> | |||||
| </Grid> | </Grid> | ||||
| <Grid item xs={12} md={9} lg={9} sx={{ display: 'flex', alignItems: 'center' }}> | <Grid item xs={12} md={9} lg={9} sx={{ display: 'flex', alignItems: 'center' }}> | ||||
| @@ -278,7 +278,9 @@ const ApplicationDetailCard = ({ formData, }) => { | |||||
| ? | ? | ||||
| <Typography variant="pnspsFormParagraph">( {data.noOfPages} {intl.formatMessage({id: 'page'})} x $6,552 )</Typography> | <Typography variant="pnspsFormParagraph">( {data.noOfPages} {intl.formatMessage({id: 'page'})} x $6,552 )</Typography> | ||||
| : | : | ||||
| <Typography variant="pnspsFormParagraph">( {data.length} cm x {data.colCount === 2 ? "$364 二格位" : "$182 一格位"} )</Typography> | |||||
| <Typography variant="pnspsFormParagraph">( {data.length} cm x {data.colCount === 2 ? | |||||
| "$364 "+intl.formatMessage({id: 'doubleCol'}) : | |||||
| "$182 "+intl.formatMessage({id: 'singleCol'})} )</Typography> | |||||
| } | } | ||||
| </Grid> | </Grid> | ||||
| </Grid> | </Grid> | ||||
| @@ -119,6 +119,7 @@ const GazetteDetailCard = ( | |||||
| // size="large" | // size="large" | ||||
| variant="contained" | variant="contained" | ||||
| onClick={groupDetailClick()} | onClick={groupDetailClick()} | ||||
| disabled={applicationDetailData.data.status!="submitted"&&applicationDetailData.data.status!="reviewed"} | |||||
| sx={{ | sx={{ | ||||
| textTransform: 'capitalize', | textTransform: 'capitalize', | ||||
| alignItems: 'end' | alignItems: 'end' | ||||
| @@ -52,6 +52,8 @@ const ApplicationDetailCard = ( | |||||
| const [isPopUp, setIsPopUp] = useState(false); | const [isPopUp, setIsPopUp] = useState(false); | ||||
| const [errorText, setErrorText] = useState(""); | const [errorText, setErrorText] = useState(""); | ||||
| const [errorPopUp, setErrorPopUp] = useState(false); | const [errorPopUp, setErrorPopUp] = useState(false); | ||||
| const [paymentHoldedErrText, setPaymentHoldedErrText] = React.useState(""); | |||||
| const [paymentHoldedErr, setPaymentHoldedErr] = React.useState(false); | |||||
| // const params = useParams(); | // const params = useParams(); | ||||
| const [currentApplicationDetailData, setCurrentApplicationDetailData] = useState({}); | const [currentApplicationDetailData, setCurrentApplicationDetailData] = useState({}); | ||||
| const [fee, setFee] = useState(0); | const [fee, setFee] = useState(0); | ||||
| @@ -113,7 +115,8 @@ const ApplicationDetailCard = ( | |||||
| }, | }, | ||||
| onSuccess: (responData) => { | onSuccess: (responData) => { | ||||
| if (responData.success == true) { | if (responData.success == true) { | ||||
| setIsPopUp(true); | |||||
| let appIdList = [currentApplicationDetailData.id] | |||||
| handlePaymentCheck(appIdList) | |||||
| return; | return; | ||||
| } | } | ||||
| setErrorText("公共啟事申請已過期"); | setErrorText("公共啟事申請已過期"); | ||||
| @@ -125,9 +128,49 @@ const ApplicationDetailCard = ( | |||||
| function doPayment() { | function doPayment() { | ||||
| setIsPopUp(false); | setIsPopUp(false); | ||||
| navigate('/paymentPage', { state: { amount: fee, appIdList: [currentApplicationDetailData.id] } }); | |||||
| let appIdList = [currentApplicationDetailData.id] | |||||
| navigate('/paymentPage', { state: { amount: fee, appIdList: appIdList } }); | |||||
| } | } | ||||
| const handlePaymentCheck = (appIdList) => { | |||||
| HttpUtils.post({ | |||||
| url: UrlUtils.PAYMENT_CHECK, | |||||
| params: { | |||||
| appIds: appIdList | |||||
| }, | |||||
| onSuccess: (responseData) => { | |||||
| const latestData = {}; | |||||
| responseData.forEach(item => { | |||||
| const { appId, timeDiff } = item; | |||||
| if (latestData[appId] === undefined || timeDiff < latestData[appId].timeDiff) { | |||||
| latestData[appId] = item; | |||||
| } | |||||
| }); | |||||
| const latestDataObjects = Object.values(latestData); | |||||
| const filteredData = latestDataObjects.filter(item => item.timeDiff > 20 && item.status !== "APPR"); | |||||
| const filteredAppIds = filteredData.map(item => item.appId); | |||||
| const appIdsNotInData = appIdList.filter(appId => !latestDataObjects.some(item => item.appId === appId)); | |||||
| const combinedAppIdsArray = [...appIdsNotInData, ...filteredAppIds]; | |||||
| const readyToPayment = appIdList.every(appId => combinedAppIdsArray.includes(appId)); | |||||
| if (readyToPayment){ | |||||
| setIsPopUp(true); | |||||
| return; | |||||
| }else{ | |||||
| const appIdsInData = appIdList.filter(appId => !combinedAppIdsArray.some(item => item === appId)); | |||||
| const HoldingApplication = latestDataObjects.filter(item => appIdsInData.includes(item.appId)); | |||||
| const resultString = HoldingApplication.map(item => item.appNo).join(' , '); | |||||
| setPaymentHoldedErrText(resultString); | |||||
| // setPaymentHoldedErrText(intl.formatMessage({ id: 'MSG.paymentHolded' }, { appNo: record.appNo })); | |||||
| setPaymentHoldedErr(true); | |||||
| } | |||||
| } | |||||
| }); | |||||
| }; | |||||
| return ( | return ( | ||||
| !onReady ? | !onReady ? | ||||
| <LoadingComponent /> | <LoadingComponent /> | ||||
| @@ -669,6 +712,33 @@ const ApplicationDetailCard = ( | |||||
| </DialogActions> | </DialogActions> | ||||
| </Dialog> | </Dialog> | ||||
| </div> | </div> | ||||
| <div> | |||||
| <Dialog | |||||
| open={paymentHoldedErr} | |||||
| onClose={() => setPaymentHoldedErr(false)} | |||||
| PaperProps={{ | |||||
| sx: { | |||||
| minWidth: '40vw', | |||||
| maxWidth: { xs: '90vw', s: '90vw', m: '70vw', lg: '70vw' }, | |||||
| maxHeight: { xs: '90vh', s: '70vh', m: '70vh', lg: '60vh' } | |||||
| } | |||||
| }} | |||||
| > | |||||
| <DialogTitle></DialogTitle> | |||||
| <Typography variant="h4" style={{ paddingLeft: '24px' }}><FormattedMessage id="MSG.actionFail" /></Typography> | |||||
| <DialogContent style={{ display: 'flex', }}> | |||||
| <Stack direction="column" justifyContent="space-between"> | |||||
| <div dangerouslySetInnerHTML={{ __html: intl.formatMessage({ id: 'MSG.paymentHolded' }, { appNo: paymentHoldedErrText }) }} /> | |||||
| </Stack> | |||||
| </DialogContent> | |||||
| <DialogActions> | |||||
| <Button onClick={() => setPaymentHoldedErr(false)} aria-label={intl.formatMessage({ id: 'close' })}> | |||||
| <Typography variant="h5"> | |||||
| <FormattedMessage id="close" /> | |||||
| </Typography></Button> | |||||
| </DialogActions> | |||||
| </Dialog> | |||||
| </div> | |||||
| </form> | </form> | ||||
| </MainCard > | </MainCard > | ||||
| ); | ); | ||||
| @@ -19,6 +19,8 @@ export default function SubmittedTab({ rows }) { | |||||
| const theme = useTheme(); | const theme = useTheme(); | ||||
| const isMdOrLg = useMediaQuery(theme.breakpoints.up('md')); | const isMdOrLg = useMediaQuery(theme.breakpoints.up('md')); | ||||
| const intl = useIntl(); | const intl = useIntl(); | ||||
| const { locale } = intl; | |||||
| const handleEditClick = (params) => () => { | const handleEditClick = (params) => () => { | ||||
| navigate('/paymentPage/details/' + params.row.id); | navigate('/paymentPage/details/' + params.row.id); | ||||
| @@ -52,7 +54,7 @@ export default function SubmittedTab({ rows }) { | |||||
| width: isMdOrLg ? 'auto' : 160, | width: isMdOrLg ? 'auto' : 160, | ||||
| flex: isMdOrLg ? 1 : undefined, | flex: isMdOrLg ? 1 : undefined, | ||||
| renderCell: (params) => { | renderCell: (params) => { | ||||
| return PaymentStatus.getStatus_Cht(params); | |||||
| return locale === 'en' ? PaymentStatus.getStatus_Eng(params):PaymentStatus.getStatus_Cht(params); | |||||
| } | } | ||||
| }, | }, | ||||
| { | { | ||||
| @@ -34,6 +34,10 @@ export default function SubmittedTab({ rows }) { | |||||
| const [selectedCareOf, setSelectedCareOf] = React.useState(null); | const [selectedCareOf, setSelectedCareOf] = React.useState(null); | ||||
| const [expiryDateErrText, setExpiryDateErrText] = React.useState(""); | const [expiryDateErrText, setExpiryDateErrText] = React.useState(""); | ||||
| const [expiryDateErr, setExpiryDateErr] = React.useState(false); | const [expiryDateErr, setExpiryDateErr] = React.useState(false); | ||||
| const [paymentHoldedErrText, setPaymentHoldedErrText] = React.useState(""); | |||||
| const [paymentHoldedErr, setPaymentHoldedErr] = React.useState(false); | |||||
| const theme = useTheme(); | const theme = useTheme(); | ||||
| const isMdOrLg = useMediaQuery(theme.breakpoints.up('md')); | const isMdOrLg = useMediaQuery(theme.breakpoints.up('md')); | ||||
| const intl = useIntl(); | const intl = useIntl(); | ||||
| @@ -103,7 +107,8 @@ export default function SubmittedTab({ rows }) { | |||||
| }, | }, | ||||
| onSuccess: (responData) => { | onSuccess: (responData) => { | ||||
| if (responData.success == true) { | if (responData.success == true) { | ||||
| setIsPopUp(true); | |||||
| // setIsPopUp(true); | |||||
| handlePaymentCheck(appIdList) | |||||
| return; | return; | ||||
| } | } | ||||
| let str = ""; | let str = ""; | ||||
| @@ -114,8 +119,45 @@ export default function SubmittedTab({ rows }) { | |||||
| setExpiryDateErr(true); | setExpiryDateErr(true); | ||||
| } | } | ||||
| }); | }); | ||||
| }; | |||||
| const handlePaymentCheck = (appIdList) => { | |||||
| HttpUtils.post({ | |||||
| url: UrlUtils.PAYMENT_CHECK, | |||||
| params: { | |||||
| appIds: appIdList | |||||
| }, | |||||
| onSuccess: (responseData) => { | |||||
| const latestData = {}; | |||||
| responseData.forEach(item => { | |||||
| const { appId, timeDiff } = item; | |||||
| if (latestData[appId] === undefined || timeDiff < latestData[appId].timeDiff) { | |||||
| latestData[appId] = item; | |||||
| } | |||||
| }); | |||||
| const latestDataObjects = Object.values(latestData); | |||||
| const filteredData = latestDataObjects.filter(item => item.timeDiff > 20 && item.status !== "APPR"); | |||||
| const filteredAppIds = filteredData.map(item => item.appId); | |||||
| const appIdsNotInData = appIdList.filter(appId => !latestDataObjects.some(item => item.appId === appId)); | |||||
| const combinedAppIdsArray = [...appIdsNotInData, ...filteredAppIds]; | |||||
| const readyToPayment = appIdList.every(appId => combinedAppIdsArray.includes(appId)); | |||||
| if (readyToPayment){ | |||||
| setIsPopUp(true); | |||||
| return; | |||||
| }else{ | |||||
| const appIdsInData = appIdList.filter(appId => !combinedAppIdsArray.some(item => item === appId)); | |||||
| const HoldingApplication = latestDataObjects.filter(item => appIdsInData.includes(item.appId)); | |||||
| const resultString = HoldingApplication.map(item => item.appNo).join(' , '); | |||||
| setPaymentHoldedErrText(resultString); | |||||
| // setPaymentHoldedErrText(intl.formatMessage({ id: 'MSG.paymentHolded' }, { appNo: record.appNo })); | |||||
| setPaymentHoldedErr(true); | |||||
| } | |||||
| } | |||||
| }); | |||||
| }; | }; | ||||
| const columns = [ | const columns = [ | ||||
| @@ -405,6 +447,33 @@ export default function SubmittedTab({ rows }) { | |||||
| </DialogActions> | </DialogActions> | ||||
| </Dialog> | </Dialog> | ||||
| </div> | </div> | ||||
| <div> | |||||
| <Dialog | |||||
| open={paymentHoldedErr} | |||||
| onClose={() => setPaymentHoldedErr(false)} | |||||
| PaperProps={{ | |||||
| sx: { | |||||
| minWidth: '40vw', | |||||
| maxWidth: { xs: '90vw', s: '90vw', m: '70vw', lg: '70vw' }, | |||||
| maxHeight: { xs: '90vh', s: '70vh', m: '70vh', lg: '60vh' } | |||||
| } | |||||
| }} | |||||
| > | |||||
| <DialogTitle></DialogTitle> | |||||
| <Typography variant="h4" style={{ paddingLeft: '24px' }}><FormattedMessage id="MSG.actionFail" /></Typography> | |||||
| <DialogContent style={{ display: 'flex', }}> | |||||
| <Stack direction="column" justifyContent="space-between"> | |||||
| <div dangerouslySetInnerHTML={{ __html: intl.formatMessage({ id: 'MSG.paymentHolded' }, { appNo: paymentHoldedErrText }) }} /> | |||||
| </Stack> | |||||
| </DialogContent> | |||||
| <DialogActions> | |||||
| <Button onClick={() => setPaymentHoldedErr(false)} aria-label={intl.formatMessage({ id: 'close' })}> | |||||
| <Typography variant="h5"> | |||||
| <FormattedMessage id="close" /> | |||||
| </Typography></Button> | |||||
| </DialogActions> | |||||
| </Dialog> | |||||
| </div> | |||||
| </> | </> | ||||
| ); | ); | ||||
| @@ -303,13 +303,13 @@ const CustomFormWizard = (props) => { | |||||
| selectedAddress4, selectedAddress5, | selectedAddress4, selectedAddress5, | ||||
| termsAndConAccept, termsAndConNotAccept, fileList]) | termsAndConAccept, termsAndConNotAccept, fileList]) | ||||
| useEffect(()=>{ | |||||
| useEffect(() => { | |||||
| setDistrictErrStr(""); | setDistrictErrStr(""); | ||||
| if(selectedAddress5?.type === "hongKong"){ | |||||
| if(selectedAddress4 ==null || selectedAddress4 == ""|| selectedAddress4 == {}) | |||||
| if (selectedAddress5?.type === "hongKong") { | |||||
| if (selectedAddress4 == null || selectedAddress4 == "" || selectedAddress4 == {}) | |||||
| setDistrictErrStr(getRequiredErrStr("district")) | setDistrictErrStr(getRequiredErrStr("district")) | ||||
| } | } | ||||
| },[selectedAddress4, selectedAddress5]) | |||||
| }, [selectedAddress4, selectedAddress5]) | |||||
| useEffect(() => { | useEffect(() => { | ||||
| props.step == 2 ? _onSubmit() : null; | props.step == 2 ? _onSubmit() : null; | ||||
| @@ -541,11 +541,11 @@ const CustomFormWizard = (props) => { | |||||
| return <Typography variant="errorMessage1">{errorMsg}</Typography> | return <Typography variant="errorMessage1">{errorMsg}</Typography> | ||||
| } | } | ||||
| function getMaxErrStr(num, fieldname){ | |||||
| return displayErrorMsg(intl.formatMessage({ id: 'noMoreThenNWords' },{num:num, fieldname:fieldname?intl.formatMessage({ id: fieldname})+": ":""})); | |||||
| function getMaxErrStr(num, fieldname) { | |||||
| return displayErrorMsg(intl.formatMessage({ id: 'noMoreThenNWords' }, { num: num, fieldname: fieldname ? intl.formatMessage({ id: fieldname }) + ": " : "" })); | |||||
| } | } | ||||
| function getRequiredErrStr(fieldname){ | |||||
| return displayErrorMsg(intl.formatMessage({ id: 'require'},{fieldname:fieldname?intl.formatMessage({ id: fieldname}):""})); | |||||
| function getRequiredErrStr(fieldname) { | |||||
| return displayErrorMsg(intl.formatMessage({ id: 'require' }, { fieldname: fieldname ? intl.formatMessage({ id: fieldname }) : "" })); | |||||
| } | } | ||||
| const formik = useFormik({ | const formik = useFormik({ | ||||
| @@ -581,14 +581,17 @@ const CustomFormWizard = (props) => { | |||||
| .matches(/^(?=.*[0-9])/, { message: displayErrorMsg(intl.formatMessage({ id: 'atLeast1Number' })) }) | .matches(/^(?=.*[0-9])/, { message: displayErrorMsg(intl.formatMessage({ id: 'atLeast1Number' })) }) | ||||
| .matches(/^(?=.*[!@#%&])/, { message: displayErrorMsg(intl.formatMessage({ id: 'atLeast1SpecialChar' })) }), | .matches(/^(?=.*[!@#%&])/, { message: displayErrorMsg(intl.formatMessage({ id: 'atLeast1SpecialChar' })) }), | ||||
| confirmPassword: yup.string().min(8, displayErrorMsg(intl.formatMessage({ id: 'atLeast8CharPassword' }))).required(displayErrorMsg(intl.formatMessage({ id: 'pleaseConfirmPassword' }))).oneOf([yup.ref('password'), null], displayErrorMsg(intl.formatMessage({ id: 'samePassword' }))), | confirmPassword: yup.string().min(8, displayErrorMsg(intl.formatMessage({ id: 'atLeast8CharPassword' }))).required(displayErrorMsg(intl.formatMessage({ id: 'pleaseConfirmPassword' }))).oneOf([yup.ref('password'), null], displayErrorMsg(intl.formatMessage({ id: 'samePassword' }))), | ||||
| enName: yup.string().max(40, getMaxErrStr(40)).required(displayErrorMsg(intl.formatMessage({ id: 'userRequireEnglishName' }))), | |||||
| chName: yup.string().max(6, getMaxErrStr(6)).required(displayErrorMsg(intl.formatMessage({ id: 'userRequireChineseName' }))), | |||||
| enName: yup.string().max(40, getMaxErrStr(40)), | |||||
| chName: yup.string().max(6, getMaxErrStr(6)).when('enName', { | |||||
| is: (enName) => enName?false:true, | |||||
| then: yup.string().required(displayErrorMsg(intl.formatMessage({ id: 'userRequireChineseName' }))) | |||||
| }), | |||||
| address1: yup.string().max(40, getMaxErrStr(40, "addressLine1")).required(displayErrorMsg(intl.formatMessage({ id: 'validateAddressLine1' }))), | address1: yup.string().max(40, getMaxErrStr(40, "addressLine1")).required(displayErrorMsg(intl.formatMessage({ id: 'validateAddressLine1' }))), | ||||
| address2: yup.string().max(40, getMaxErrStr(40, "addressLine2")), | address2: yup.string().max(40, getMaxErrStr(40, "addressLine2")), | ||||
| address3: yup.string().max(40, getMaxErrStr(40, "addressLine3")), | address3: yup.string().max(40, getMaxErrStr(40, "addressLine3")), | ||||
| email: yup.string().email(displayErrorMsg(intl.formatMessage({ id: 'validEmailFormat' }))).max(128, getMaxErrStr(128)).required(displayErrorMsg(intl.formatMessage({ id: 'requireEmail' }))), | email: yup.string().email(displayErrorMsg(intl.formatMessage({ id: 'validEmailFormat' }))).max(128, getMaxErrStr(128)).required(displayErrorMsg(intl.formatMessage({ id: 'requireEmail' }))), | ||||
| emailConfirm: yup.string().email(displayErrorMsg(intl.formatMessage({ id: 'validEmailFormat' }))).max(128, getMaxErrStr(128)).required(displayErrorMsg(intl.formatMessage({ id: 'requireEmail' }))).oneOf([yup.ref('email'), null], displayErrorMsg(intl.formatMessage({ id: 'validSameEmail' }))), | emailConfirm: yup.string().email(displayErrorMsg(intl.formatMessage({ id: 'validEmailFormat' }))).max(128, getMaxErrStr(128)).required(displayErrorMsg(intl.formatMessage({ id: 'requireEmail' }))).oneOf([yup.ref('email'), null], displayErrorMsg(intl.formatMessage({ id: 'validSameEmail' }))), | ||||
| idNo: yup.string().required(displayErrorMsg(`${intl.formatMessage({ id: 'require' })}${selectedIdDocInputType}${intl.formatMessage({ id: 'number' })}`)) | |||||
| idNo: yup.string().required(getRequiredErrStr('number')) | |||||
| .matches(/^[aA-zZ0-9\s]+$/, { message: displayErrorMsg(`${selectedIdDocInputType}${intl.formatMessage({ id: 'noSpecialCharacter' })}`) }) | .matches(/^[aA-zZ0-9\s]+$/, { message: displayErrorMsg(`${selectedIdDocInputType}${intl.formatMessage({ id: 'noSpecialCharacter' })}`) }) | ||||
| .matches(/^\S*$/, { message: displayErrorMsg(`${selectedIdDocInputType}${intl.formatMessage({ id: 'noSpace' })}`) }) | .matches(/^\S*$/, { message: displayErrorMsg(`${selectedIdDocInputType}${intl.formatMessage({ id: 'noSpace' })}`) }) | ||||
| .test('checkIDCardFormat', displayErrorMsg(`${intl.formatMessage({ id: 'requiredValid' })}${selectedIdDocInputType}${intl.formatMessage({ id: 'number' })}`), function (value) { | .test('checkIDCardFormat', displayErrorMsg(`${intl.formatMessage({ id: 'requiredValid' })}${selectedIdDocInputType}${intl.formatMessage({ id: 'number' })}`), function (value) { | ||||
| @@ -648,7 +651,7 @@ const CustomFormWizard = (props) => { | |||||
| // faxCountryCode: yup.string().min(3,'請輸入3位數字'), | // faxCountryCode: yup.string().min(3,'請輸入3位數字'), | ||||
| phone: yup.string().min(8, displayErrorMsg(intl.formatMessage({ id: 'requireAtLeast8Number' }))).required(displayErrorMsg(intl.formatMessage({ id: 'requireContactNumber' }))), | phone: yup.string().min(8, displayErrorMsg(intl.formatMessage({ id: 'requireAtLeast8Number' }))).required(displayErrorMsg(intl.formatMessage({ id: 'requireContactNumber' }))), | ||||
| // fax: yup.string().min(8,'請輸入8位數字'), | // fax: yup.string().min(8,'請輸入8位數字'), | ||||
| captchaField: yup.string().max(5, getMaxErrStr(5)).required(displayErrorMsg(intl.formatMessage({ id: 'requireVerify' }))),//.oneOf([captcha], displayErrorMsg('請輸入有效驗證')), | |||||
| captchaField: yup.string().max(5, getMaxErrStr(5)).required(displayErrorMsg(intl.formatMessage({ id: 'requireVerify' }))),//.oneOf([captcha], displayErrorMsg('請輸入有效驗證')), | |||||
| }), | }), | ||||
| }); | }); | ||||
| @@ -934,7 +937,7 @@ const CustomFormWizard = (props) => { | |||||
| /> | /> | ||||
| {formik.touched.idDocType && ( | {formik.touched.idDocType && ( | ||||
| selectedIdDocType === null || selectedIdDocType?.type == null ? | selectedIdDocType === null || selectedIdDocType?.type == null ? | ||||
| <FormHelperText error id="helper-text-idDocType-signup" sx={{fontSize:16,fontWeight: 'bold',}}> | |||||
| <FormHelperText error id="helper-text-idDocType-signup" sx={{ fontSize: 16, fontWeight: 'bold', }}> | |||||
| <FormattedMessage id="requireIdDocType" /> | <FormattedMessage id="requireIdDocType" /> | ||||
| </FormHelperText> : '' | </FormHelperText> : '' | ||||
| )} | )} | ||||
| @@ -1067,12 +1070,17 @@ const CustomFormWizard = (props) => { | |||||
| } | } | ||||
| </Grid> | </Grid> | ||||
| </Grid> | </Grid> | ||||
| <Grid item xs={12} md={12}> | |||||
| <Typography variant="subtitle1"> | |||||
| <FormattedMessage id="registerNameLabel" /> | |||||
| </Typography> | |||||
| </Grid> | |||||
| <Grid item xs={12} md={6}> | <Grid item xs={12} md={6}> | ||||
| <Stack spacing={1}> | <Stack spacing={1}> | ||||
| <InputLabel htmlFor="enName-signup"> | <InputLabel htmlFor="enName-signup"> | ||||
| <Typography variant="pnspsFormHeader"> | <Typography variant="pnspsFormHeader"> | ||||
| <FormattedMessage id="userEnglishName" /> | <FormattedMessage id="userEnglishName" /> | ||||
| {selectedIdDocType.type === "CNID" ? "" : <span style={{ color: '#f10000' }}>*</span>} | |||||
| {selectedIdDocType.type === "CNID" ? "" : <span style={{ color: '#f10000' }}></span>} | |||||
| </Typography> | </Typography> | ||||
| </InputLabel> | </InputLabel> | ||||
| <OutlinedInput | <OutlinedInput | ||||
| @@ -1105,7 +1113,7 @@ const CustomFormWizard = (props) => { | |||||
| <InputLabel htmlFor="chName-signup"> | <InputLabel htmlFor="chName-signup"> | ||||
| <Typography variant="pnspsFormHeader"> | <Typography variant="pnspsFormHeader"> | ||||
| <FormattedMessage id="userChineseName" /> | <FormattedMessage id="userChineseName" /> | ||||
| <span style={{ color: '#f10000' }}>*</span> | |||||
| <span style={{ color: '#f10000' }}></span> | |||||
| </Typography> | </Typography> | ||||
| </InputLabel> | </InputLabel> | ||||
| <OutlinedInput | <OutlinedInput | ||||
| @@ -1199,7 +1207,7 @@ const CustomFormWizard = (props) => { | |||||
| value={selectedAddress4} | value={selectedAddress4} | ||||
| options={ComboData.district} | options={ComboData.district} | ||||
| disabled={checkCountry} | disabled={checkCountry} | ||||
| error={Boolean(districtErrStr!="")} | |||||
| error={Boolean(districtErrStr != "")} | |||||
| onBlur={formik.handleBlur} | onBlur={formik.handleBlur} | ||||
| getOptionLabel={(option) => option.type ? intl.formatMessage({ id: option.type }) : ""} | getOptionLabel={(option) => option.type ? intl.formatMessage({ id: option.type }) : ""} | ||||
| onChange={(event, newValue) => { | onChange={(event, newValue) => { | ||||
| @@ -1252,7 +1260,7 @@ const CustomFormWizard = (props) => { | |||||
| {formik.errors.address3} | {formik.errors.address3} | ||||
| </FormHelperText> | </FormHelperText> | ||||
| )} | )} | ||||
| {districtErrStr!= "" && ( | |||||
| {districtErrStr != "" && ( | |||||
| <FormHelperText error > | <FormHelperText error > | ||||
| {districtErrStr} | {districtErrStr} | ||||
| </FormHelperText> | </FormHelperText> | ||||
| @@ -1685,8 +1693,8 @@ const CustomFormWizard = (props) => { | |||||
| <FormattedMessage id="idDocType" />: | <FormattedMessage id="idDocType" />: | ||||
| </Typography> | </Typography> | ||||
| <Typography variant="pnspsFormHeader" name="preview-idDocType"> | <Typography variant="pnspsFormHeader" name="preview-idDocType"> | ||||
| {intl.formatMessage({ id: selectedIdDocType?.label??" " })} | |||||
| {intl.formatMessage({ id: selectedIdDocType?.label ?? " " })} | |||||
| </Typography> | </Typography> | ||||
| </Stack> | </Stack> | ||||
| </Grid> | </Grid> | ||||
| @@ -20,13 +20,26 @@ const DashboardDefault = () => { | |||||
| backgroundColor: '#0C489E', | backgroundColor: '#0C489E', | ||||
| backgroundPosition: 'right' | backgroundPosition: 'right' | ||||
| } | } | ||||
| const getWelcomeMsg=()=>{ | |||||
| var current = new Date() | |||||
| var curHr = current.getHours() | |||||
| if (curHr < 12) { | |||||
| return "Good Morning" | |||||
| } else if (curHr < 18) { | |||||
| return "Good Afternoon" | |||||
| } else { | |||||
| //evening | |||||
| return "Good Evening" | |||||
| } | |||||
| } | |||||
| return ( | return ( | ||||
| <Grid container sx={{minHeight: '87vh', backgroundColor: "backgroundColor.default"}} direction="column"> | <Grid container sx={{minHeight: '87vh', backgroundColor: "backgroundColor.default"}} direction="column"> | ||||
| <Grid item xs={12}> | <Grid item xs={12}> | ||||
| <div style={BackgroundHead}> | <div style={BackgroundHead}> | ||||
| <Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center"> | <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' }}}> | <Typography ml={15} color='#FFF' variant="h4" sx={{display: { xs: 'none', sm: 'none', md: 'block' }}}> | ||||
| Morning, {userData.fullenName} | |||||
| {getWelcomeMsg()}, {userData.fullenName} | |||||
| </Typography> | </Typography> | ||||
| </Stack> | </Stack> | ||||
| </div> | </div> | ||||
| @@ -35,6 +35,22 @@ const DashboardDefault = () => { | |||||
| backgroundColor: '#0C489E', | backgroundColor: '#0C489E', | ||||
| backgroundPosition: 'right' | backgroundPosition: 'right' | ||||
| } | } | ||||
| const { locale } = intl; | |||||
| const getWelcomeMsg=()=>{ | |||||
| var current = new Date() | |||||
| var curHr = current.getHours() | |||||
| if (curHr < 12) { | |||||
| return <FormattedMessage id="welcomeMsg_am" /> | |||||
| } else if (curHr < 18) { | |||||
| return <FormattedMessage id="welcomeMsg_pm" /> | |||||
| } else { | |||||
| return <FormattedMessage id="welcomeMsg_night" /> | |||||
| } | |||||
| } | |||||
| return ( | return ( | ||||
| <Grid container sx={{ minHeight: '87vh' }} direction="column"> | <Grid container sx={{ minHeight: '87vh' }} direction="column"> | ||||
| <Grid item xs={12} > | <Grid item xs={12} > | ||||
| @@ -42,7 +58,7 @@ const DashboardDefault = () => { | |||||
| <Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center"> | <Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center"> | ||||
| {/* <Typography variant="h5">我的公共啟事</Typography> */} | {/* <Typography variant="h5">我的公共啟事</Typography> */} | ||||
| <Typography color='#FFF' variant="h5" sx={{ ml: 10, display: { xs: 'none', sm: 'none', md: 'block' } }}> | <Typography color='#FFF' variant="h5" sx={{ ml: 10, display: { xs: 'none', sm: 'none', md: 'block' } }}> | ||||
| {isORGLoggedIn() ? userData.fullenName : userData.fullchName}, <FormattedMessage id="welcomeMsg" /> | |||||
| {isORGLoggedIn() ? userData.fullenName: (locale === 'en' ?userData.fullenName: userData.fullchName)}, {getWelcomeMsg()} | |||||
| </Typography> | </Typography> | ||||
| </Stack> | </Stack> | ||||
| </div> | </div> | ||||
| @@ -67,6 +67,7 @@ | |||||
| "MSG.proofOutOfTime": "Response out of time, please apply again.", | "MSG.proofOutOfTime": "Response out of time, please apply again.", | ||||
| "MSG.plzSelectApp": "Please select application", | "MSG.plzSelectApp": "Please select application", | ||||
| "MSG.actionFail": "Action failed", | "MSG.actionFail": "Action failed", | ||||
| "MSG.paymentHolded": "Application number {appNo} is currently in the process of payment. If the payment is unsuccessful, please try again after 20 minutes. We apologise for any inconvenience caused.", | |||||
| "registerTitle1": "Become", | "registerTitle1": "Become", | ||||
| "registerTitle2": "Gazette Notice", | "registerTitle2": "Gazette Notice", | ||||
| @@ -96,7 +97,10 @@ | |||||
| "onlinePaymentHistory": "Online Payment History", | "onlinePaymentHistory": "Online Payment History", | ||||
| "setting": "Settings", | "setting": "Settings", | ||||
| "companyOrUserRecord": "Company/Institutional User Records", | "companyOrUserRecord": "Company/Institutional User Records", | ||||
| "welcomeMsg": "Good afternoon! Please select the required service.", | |||||
| "welcomeMsg_am": "Good morning! Please select the required service.", | |||||
| "welcomeMsg_pm": "Good afternoon! Please select the required service.", | |||||
| "welcomeMsg_night": "Good evening! Please select the required service.", | |||||
| "login": "Login", | "login": "Login", | ||||
| "logout": "Logout", | "logout": "Logout", | ||||
| @@ -147,6 +151,7 @@ | |||||
| "registerNewBusinessUser": "Apply as organisation/company user", | "registerNewBusinessUser": "Apply as organisation/company user", | ||||
| "becomeNewBusinessUser": "Become New Organisation/Company user", | "becomeNewBusinessUser": "Become New Organisation/Company user", | ||||
| "userName": "Username", | "userName": "Username", | ||||
| "registerNameLabel": "Please provide either an English name or a Chinese name, at a minimum.", | |||||
| "userChineseName": "Chinese Name", | "userChineseName": "Chinese Name", | ||||
| "userEnglishName": "English Name", | "userEnglishName": "English Name", | ||||
| "userContactName": "Name", | "userContactName": "Name", | ||||
| @@ -256,7 +261,7 @@ | |||||
| "mainlandIDCard": "Mainland ID card", | "mainlandIDCard": "Mainland ID card", | ||||
| "proCert": "Professional Practice Certificate", | "proCert": "Professional Practice Certificate", | ||||
| "idDocType": "Document Category", | "idDocType": "Document Category", | ||||
| "requireIdDocType": "Please enter the document type", | |||||
| "requireIdDocType": "Please select the document type", | |||||
| "idDocNumber": "ID number", | "idDocNumber": "ID number", | ||||
| "requireIdDocNumber": "Please enter the document ID", | "requireIdDocNumber": "Please enter the document ID", | ||||
| "requiredNumberInQuote": "Please enter the numbers or letters in brackets", | "requiredNumberInQuote": "Please enter the numbers or letters in brackets", | ||||
| @@ -354,7 +359,7 @@ | |||||
| "publicNoticeDetailTitle": "Public Notice Application Information", | "publicNoticeDetailTitle": "Public Notice Application Information", | ||||
| "applyPerson": "Applicant", | "applyPerson": "Applicant", | ||||
| "applyStatus": "Application Status", | |||||
| "applyStatus": "App. Status", | |||||
| "gazetteCount": "Gazette issues number", | "gazetteCount": "Gazette issues number", | ||||
| "gazetteCount2" :"Gazette issues number / Remarks", | "gazetteCount2" :"Gazette issues number / Remarks", | ||||
| "gazetteCount2_1" :"Care Of / Remarks", | "gazetteCount2_1" :"Care Of / Remarks", | ||||
| @@ -391,6 +396,8 @@ | |||||
| "upload": "Upload", | "upload": "Upload", | ||||
| "actionFail": "Action failed: Please check the content and submit the reply again", | "actionFail": "Action failed: Please check the content and submit the reply again", | ||||
| "issueInvalidMsg": "Action failed: The Gazette Issue invalid, please apply again", | "issueInvalidMsg": "Action failed: The Gazette Issue invalid, please apply again", | ||||
| "singleCol":"Single Column", | |||||
| "doubleCol":"Double Column", | |||||
| "transactionNo": "Transaction number", | "transactionNo": "Transaction number", | ||||
| "transactionDate": "Transaction date", | "transactionDate": "Transaction date", | ||||
| @@ -436,7 +443,7 @@ | |||||
| "noRecordFound": "No record found", | "noRecordFound": "No record found", | ||||
| "rowsPerPage": "Rows Per Page", | "rowsPerPage": "Rows Per Page", | ||||
| "date" : "Date", | "date" : "Date", | ||||
| "keyword": "Key word", | |||||
| "keyword": "Keyword", | |||||
| "dateFrom": "Date(From)", | "dateFrom": "Date(From)", | ||||
| "dateTo": "Date(To)", | "dateTo": "Date(To)", | ||||
| "of": "of", | "of": "of", | ||||
| @@ -66,7 +66,8 @@ | |||||
| "MSG.proofOutOfTime": "回覆逾时,请重新申请。", | "MSG.proofOutOfTime": "回覆逾时,请重新申请。", | ||||
| "MSG.plzSelectApp": "请选择公共启事。", | "MSG.plzSelectApp": "请选择公共启事。", | ||||
| "MSG.actionFail": "行动失败", | "MSG.actionFail": "行动失败", | ||||
| "MSG.paymentHolded": "申请编号 {appNo} 已正在付款的流程中,如相关付款没有成功,请于20分钟后再尝试付款,不便之处,请见谅!", | |||||
| "registerTitle1": "立即成为", | "registerTitle1": "立即成为", | ||||
| "registerTitle2": "宪报刊登公共启事", | "registerTitle2": "宪报刊登公共启事", | ||||
| "registerTitle3": "用户", | "registerTitle3": "用户", | ||||
| @@ -95,7 +96,9 @@ | |||||
| "onlinePaymentHistory": "网上付款记录", | "onlinePaymentHistory": "网上付款记录", | ||||
| "setting": "设置", | "setting": "设置", | ||||
| "companyOrUserRecord": "公司/机构用户记录", | "companyOrUserRecord": "公司/机构用户记录", | ||||
| "welcomeMsg": "午安! 请选择所需服务。", | |||||
| "welcomeMsg_am": "早安! 请选择所需服务。", | |||||
| "welcomeMsg_pm": "午安! 请选择所需服务。", | |||||
| "welcomeMsg_night": "晚安! 请选择所需服务。", | |||||
| "login": "登录", | "login": "登录", | ||||
| "logout": "登出", | "logout": "登出", | ||||
| @@ -142,6 +145,7 @@ | |||||
| "registerNewBusinessUser": "申请机构/公司用户", | "registerNewBusinessUser": "申请机构/公司用户", | ||||
| "becomeNewBusinessUser": "成为新的机构/公司用户", | "becomeNewBusinessUser": "成为新的机构/公司用户", | ||||
| "userName": "用户名称", | "userName": "用户名称", | ||||
| "registerNameLabel": "请至少输入英文姓名或中文姓名。", | |||||
| "userChineseName": "中文姓名", | "userChineseName": "中文姓名", | ||||
| "userEnglishName": "英文姓名", | "userEnglishName": "英文姓名", | ||||
| "userContactName": "姓名", | "userContactName": "姓名", | ||||
| @@ -251,7 +255,7 @@ | |||||
| "mainlandIDCard": "内地身份证", | "mainlandIDCard": "内地身份证", | ||||
| "proCert": "专业执业证书", | "proCert": "专业执业证书", | ||||
| "idDocType": "证件类别", | "idDocType": "证件类别", | ||||
| "requireIdDocType": "请输入证件类别", | |||||
| "requireIdDocType": "请选择证件类别", | |||||
| "idDocNumber": "证件号码", | "idDocNumber": "证件号码", | ||||
| "requireIdDocNumber": "请输入证件号码", | "requireIdDocNumber": "请输入证件号码", | ||||
| "requiredNumberInQuote": "请输入括号内的数字或字母", | "requiredNumberInQuote": "请输入括号内的数字或字母", | ||||
| @@ -386,6 +390,8 @@ | |||||
| "upload": "上载", | "upload": "上载", | ||||
| "actionFail": "行动失败: 请检查内容并再次提交回覆", | "actionFail": "行动失败: 请检查内容并再次提交回覆", | ||||
| "issueInvalidMsg": "行动失败: 无效宪报期数,请重新申请", | "issueInvalidMsg": "行动失败: 无效宪报期数,请重新申请", | ||||
| "singleCol":"一格位", | |||||
| "doubleCol":"二格位", | |||||
| "transactionNo": "交易号码", | "transactionNo": "交易号码", | ||||
| "transactionDate": "交易日期", | "transactionDate": "交易日期", | ||||
| @@ -66,6 +66,7 @@ | |||||
| "MSG.proofOutOfTime": "回覆逾時,請重新申請。", | "MSG.proofOutOfTime": "回覆逾時,請重新申請。", | ||||
| "MSG.plzSelectApp": "請選擇公共啟事。", | "MSG.plzSelectApp": "請選擇公共啟事。", | ||||
| "MSG.actionFail": "行動失敗", | "MSG.actionFail": "行動失敗", | ||||
| "MSG.paymentHolded": "申請編號 {appNo} 已正在付款的流程中,如相關付款沒有成功,請於20分鐘後再嘗試付款,不便之處,請見諒!", | |||||
| "registerTitle1": "立即成為", | "registerTitle1": "立即成為", | ||||
| "registerTitle2": "憲報刊登公共啟事", | "registerTitle2": "憲報刊登公共啟事", | ||||
| @@ -95,7 +96,9 @@ | |||||
| "onlinePaymentHistory": "網上付款記錄", | "onlinePaymentHistory": "網上付款記錄", | ||||
| "setting": "設定", | "setting": "設定", | ||||
| "companyOrUserRecord": "公司/機構用戶記錄", | "companyOrUserRecord": "公司/機構用戶記錄", | ||||
| "welcomeMsg": "午安! 請選擇所需服務。", | |||||
| "welcomeMsg_am": "早安! 請選擇所需服務。", | |||||
| "welcomeMsg_pm": "午安! 請選擇所需服務。", | |||||
| "welcomeMsg_night": "晚安! 請選擇所需服務。", | |||||
| "login": "登入", | "login": "登入", | ||||
| "logout": "登出", | "logout": "登出", | ||||
| @@ -145,6 +148,7 @@ | |||||
| "registerNewBusinessUser": "申請機構/公司用戶", | "registerNewBusinessUser": "申請機構/公司用戶", | ||||
| "becomeNewBusinessUser": "成為新的機構/公司用戶", | "becomeNewBusinessUser": "成為新的機構/公司用戶", | ||||
| "userName": "用戶名稱", | "userName": "用戶名稱", | ||||
| "registerNameLabel": "請至少輸入英文姓名或中文姓名。", | |||||
| "userChineseName": "中文姓名", | "userChineseName": "中文姓名", | ||||
| "userEnglishName": "英文姓名", | "userEnglishName": "英文姓名", | ||||
| "userContactName": "姓名", | "userContactName": "姓名", | ||||
| @@ -254,7 +258,7 @@ | |||||
| "mainlandIDCard": "內地身份證", | "mainlandIDCard": "內地身份證", | ||||
| "proCert": "專業執業證書", | "proCert": "專業執業證書", | ||||
| "idDocType": "證件類別", | "idDocType": "證件類別", | ||||
| "requireIdDocType": "請輸入證件類別", | |||||
| "requireIdDocType": "請選擇證件類別", | |||||
| "idDocNumber": "證件號碼", | "idDocNumber": "證件號碼", | ||||
| "requireIdDocNumber": "請輸入證件號碼", | "requireIdDocNumber": "請輸入證件號碼", | ||||
| "requiredNumberInQuote": "請輸入括號內的數字或字母", | "requiredNumberInQuote": "請輸入括號內的數字或字母", | ||||
| @@ -389,6 +393,8 @@ | |||||
| "upload": "上載", | "upload": "上載", | ||||
| "actionFail": "行動失敗: 請檢查內容並再次提交回覆", | "actionFail": "行動失敗: 請檢查內容並再次提交回覆", | ||||
| "issueInvalidMsg": "行動失敗: 無效憲報期數,請重新申請", | "issueInvalidMsg": "行動失敗: 無效憲報期數,請重新申請", | ||||
| "singleCol":"一格位", | |||||
| "doubleCol":"二格位", | |||||
| "transactionNo": "交易號碼", | "transactionNo": "交易號碼", | ||||
| "transactionDate": "交易日期", | "transactionDate": "交易日期", | ||||
| @@ -133,12 +133,13 @@ export const PROOF_CHECK_PRICE = apiPath+'/proof/check-price';//GET | |||||
| export const GET_PROOF_PAY = apiPath+'/proof/pay-details';//GET | export const GET_PROOF_PAY = apiPath+'/proof/pay-details';//GET | ||||
| export const CANCEL_PROOF = apiPath+'/proof/cancel';//GET | export const CANCEL_PROOF = apiPath+'/proof/cancel';//GET | ||||
| //payment | |||||
| export const PAYMENT_CREATE = apiPath+'/payment/create';//POST | export const PAYMENT_CREATE = apiPath+'/payment/create';//POST | ||||
| export const PAYMENT_SAVE = apiPath+'/payment/save';//POST | export const PAYMENT_SAVE = apiPath+'/payment/save';//POST | ||||
| export const PAYMENT_LIST = apiPath+'/payment/list';//GET | export const PAYMENT_LIST = apiPath+'/payment/list';//GET | ||||
| export const PAYMENT_LOAD = apiPath+'/payment/load';//GET | export const PAYMENT_LOAD = apiPath+'/payment/load';//GET | ||||
| export const PAYMENT_APP_LIST = apiPath+'/payment/applist';//POST | export const PAYMENT_APP_LIST = apiPath+'/payment/applist';//POST | ||||
| export const PAYMENT_CHECK = apiPath+'/payment/check-payment';//GET | |||||
| export const PAYMENT_LIMIT_SETTING_LIST = apiPath+'/settings/payment';//GET | export const PAYMENT_LIMIT_SETTING_LIST = apiPath+'/settings/payment';//GET | ||||
| export const PAYMENT_AVAILABLE_PAYMENT = paymentPath+'/api/payment/availability';//POST | export const PAYMENT_AVAILABLE_PAYMENT = paymentPath+'/api/payment/availability';//POST | ||||