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

308 line
14 KiB

  1. // material-ui
  2. import {
  3. Grid,
  4. Typography,
  5. Stack,
  6. Button,
  7. Dialog, DialogTitle, DialogContent, DialogActions
  8. } from '@mui/material';
  9. import * as UrlUtils from "utils/ApiPathConst";
  10. import * as React from "react";
  11. import * as HttpUtils from "utils/HttpUtils";
  12. import { useParams } from "react-router-dom";
  13. import { useNavigate } from "react-router-dom";
  14. import * as DateUtils from "utils/DateUtils"
  15. import * as FormatUtils from "utils/FormatUtils";
  16. import { checkPaymentSuspention } from "utils/Utils";
  17. import Loadable from 'components/Loadable';
  18. const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent')));
  19. import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png'
  20. const BackgroundHead = {
  21. backgroundImage: `url(${titleBackgroundImg})`,
  22. width: '100%',
  23. height: '100%',
  24. backgroundSize: 'contain',
  25. backgroundRepeat: 'no-repeat',
  26. backgroundColor: '#0C489E',
  27. backgroundPosition: 'right'
  28. }
  29. import {
  30. // useEffect,
  31. useState
  32. } from "react";
  33. import { PNSPS_BUTTON_THEME,
  34. // PNSPS_LONG_BUTTON_THEME
  35. } from "../../../themes/buttonConst";
  36. import { ThemeProvider } from "@emotion/react";
  37. import { FormattedMessage, useIntl } from "react-intl";
  38. // ==============================|| DASHBOARD - DEFAULT ||============================== //
  39. const Index = () => {
  40. const params = useParams();
  41. const navigate = useNavigate()
  42. const [fee, setFee] = useState(0);
  43. const [record, setRecord] = React.useState({});
  44. const [onReady, setOnReady] = React.useState(false);
  45. const [isPopUp, setIsPopUp] = useState(false);
  46. const [paymentHoldedErrText, setPaymentHoldedErrText] = React.useState("");
  47. const [paymentHoldedErr, setPaymentHoldedErr] = React.useState(false);
  48. const intl = useIntl();
  49. const { locale } = intl;
  50. React.useEffect(() => {
  51. loadForm();
  52. }, []);
  53. React.useEffect(() => {
  54. setOnReady(true);
  55. }, [record]);
  56. const loadForm = () => {
  57. if (params.id > 0) {
  58. HttpUtils.get({
  59. url: UrlUtils.GET_PROOF_PAY + "/" + params.id,
  60. onSuccess: (responseData) => {
  61. // if (!responseData.data?.id) {
  62. // navigate("/proof/search");
  63. // }
  64. setRecord(responseData.data);
  65. setFee(responseData.data.fee);
  66. },
  67. onError: () => {
  68. }
  69. });
  70. }
  71. }
  72. function doPayment() {
  73. setIsPopUp(false);
  74. let appIdList = [record?.appId]
  75. handlePaymentCheck(appIdList)
  76. }
  77. const handlePaymentCheck = (appIdList) => {
  78. HttpUtils.post({
  79. url: UrlUtils.PAYMENT_CHECK,
  80. params: {
  81. appIds: appIdList
  82. },
  83. onSuccess: (responseData) => {
  84. const latestData = {};
  85. responseData.forEach(item => {
  86. const { appId, timeDiff } = item;
  87. if (latestData[appId] === undefined || timeDiff < latestData[appId].timeDiff) {
  88. latestData[appId] = item;
  89. }
  90. });
  91. const latestDataObjects = Object.values(latestData);
  92. const filteredData = latestDataObjects.filter(item => item.timeDiff > 30 || item.status !== "APPR");
  93. const filteredAppIds = filteredData.map(item => item.appId);
  94. const appIdsNotInData = appIdList.filter(appId => !latestDataObjects.some(item => item.appId === appId));
  95. const combinedAppIdsArray = [...appIdsNotInData, ...filteredAppIds];
  96. const readyToPayment = appIdList.every(appId => combinedAppIdsArray.includes(appId));
  97. if (readyToPayment) {
  98. navigate('/paymentPage', { state: { amount: fee, appIdList: appIdList } });
  99. } else {
  100. const appIdsInData = appIdList.filter(appId => !combinedAppIdsArray.some(item => item === appId));
  101. const HoldingApplication = latestDataObjects.filter(item => appIdsInData.includes(item.appId));
  102. const resultString = HoldingApplication.map(item => item.appNo).join(' , ');
  103. setPaymentHoldedErrText(resultString);
  104. // setPaymentHoldedErrText(intl.formatMessage({ id: 'MSG.paymentHolded' }, { appNo: record.appNo }));
  105. setPaymentHoldedErr(true);
  106. }
  107. }
  108. });
  109. };
  110. return (
  111. !onReady ?
  112. <Grid container sx={{ minHeight: '87vh', mb: 3 }} direction="column" justifyContent="center" alignItems="center">
  113. <Grid item>
  114. <LoadingComponent />
  115. </Grid>
  116. </Grid>
  117. :
  118. (
  119. <Grid container sx={{ minHeight: '110vh', backgroundColor: '#fff' }} direction="column" justifyContent="flex-start" alignItems="center" >
  120. <Grid item xs={12} width="100%">
  121. <div style={BackgroundHead} width="100%" >
  122. <Stack direction="row" height='70px'>
  123. <Typography ml={15} color='#FFF' variant="h4" sx={{ display: { xs: 'none', sm: 'none', md: 'block' }, pt: 2 }}>
  124. <FormattedMessage id="proofRecord" />
  125. </Typography>
  126. </Stack>
  127. </div>
  128. </Grid>
  129. {/*row 1*/}
  130. <Grid item xs={12} md={12} >
  131. <Grid container justifyContent="flex-start" alignItems="center" >
  132. <center>
  133. <Grid item xs={12} md={8} >
  134. <Typography variant="h4" sx={{ textAlign: "left", ml: 4, mr: 4, mt: 4, borderBottom: "1px solid black" }}>
  135. <FormattedMessage id="proofPaymentHeader_online" />
  136. </Typography>
  137. <Typography variant="h5" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}>
  138. <div dangerouslySetInnerHTML={{
  139. __html: intl.formatMessage(
  140. {
  141. id: 'proofPaymentBody_online'
  142. },
  143. {
  144. appNo: record?.appNo,
  145. }
  146. )
  147. }} />
  148. <br />
  149. <div dangerouslySetInnerHTML={{
  150. __html: intl.formatMessage(
  151. {
  152. id: 'proofPaymentBody_online2'
  153. },
  154. {
  155. paymentDeadline: DateUtils.formatDateForLocale(record?.expiryDate, intl, locale),
  156. }
  157. )
  158. }} />
  159. <br />
  160. {checkPaymentSuspention()?
  161. <div>
  162. <Typography style={{ textAlign: "flex-start", color: "red" }}>
  163. <div dangerouslySetInnerHTML={{ __html: intl.formatMessage({ id: "suspensionMessageText" }) }} />
  164. </Typography>
  165. <br />
  166. </div>:null
  167. }
  168. </Typography>
  169. {!checkPaymentSuspention()?
  170. <Typography variant="h4" sx={{ ml: 8, textAlign: "left" }}>
  171. <ThemeProvider theme={PNSPS_BUTTON_THEME}>
  172. <Button
  173. component="span"
  174. variant="contained"
  175. // sx={{ ml: { sm: 4, md: 4, lg: 4 }, mr: 4, mt: { xs: 2, sm: 2 }, mb: { xs: 2, sm: 2 } }}
  176. sx={{mr: 4 }}
  177. onClick={() => { setIsPopUp(true) }}
  178. >
  179. <FormattedMessage id="payInstantly" />
  180. </Button>
  181. </ThemeProvider>
  182. <FormattedMessage id="or" />
  183. <ThemeProvider theme={PNSPS_BUTTON_THEME}>
  184. <Button
  185. component="span"
  186. variant="contained"
  187. sx={{ ml: { sm: 4, md: 4, lg: 4 }, mr: 4, mt: { xs: 2, sm: 2 }, mb: { xs: 2, sm: 2 } }}
  188. onClick={() => {
  189. navigate("/publicNotice");
  190. }}
  191. >
  192. <FormattedMessage id="payLater" />
  193. </Button>
  194. </ThemeProvider>
  195. </Typography>:null
  196. }
  197. <Typography variant="h4" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}>
  198. <div dangerouslySetInnerHTML={{
  199. __html: intl.formatMessage(
  200. {
  201. id: 'proofPaymentBody_online3'
  202. }
  203. )
  204. }} />
  205. <br />
  206. </Typography>
  207. </Grid>
  208. </center>
  209. </Grid>
  210. </Grid>
  211. <div>
  212. <Dialog
  213. open={isPopUp}
  214. onClose={() => setIsPopUp(false)}
  215. PaperProps={{
  216. sx: {
  217. minWidth: '40vw',
  218. maxWidth: { xs: '90vw', s: '90vw', m: '70vw', lg: '30vw' },
  219. maxHeight: { xs: '90vh', s: '70vh', m: '70vh', lg: '50vh' }
  220. }
  221. }}
  222. >
  223. <DialogTitle>
  224. <Typography variant="h3" >
  225. <FormattedMessage id="payConfirm" />
  226. </Typography>
  227. </DialogTitle>
  228. <DialogContent style={{ display: 'flex', }}>
  229. <Stack direction="column" justifyContent="space-between">
  230. <Typography variant="h4">
  231. <FormattedMessage id="totalAmount" /> ($): {FormatUtils.currencyFormat(fee)}
  232. </Typography>
  233. </Stack>
  234. </DialogContent>
  235. <DialogActions>
  236. <Button onClick={() => setIsPopUp(false)}>
  237. <Typography variant="h5">
  238. <FormattedMessage id="close" />
  239. </Typography></Button>
  240. <Button onClick={() => doPayment()}><Typography variant="h5">
  241. <FormattedMessage id="confirm" />
  242. </Typography></Button>
  243. </DialogActions>
  244. </Dialog>
  245. </div>
  246. {/*row 2*/}
  247. <div>
  248. <Dialog
  249. open={paymentHoldedErr}
  250. onClose={() => setPaymentHoldedErr(false)}
  251. PaperProps={{
  252. sx: {
  253. minWidth: '40vw',
  254. maxWidth: { xs: '90vw', s: '90vw', m: '70vw', lg: '70vw' },
  255. maxHeight: { xs: '90vh', s: '70vh', m: '70vh', lg: '60vh' }
  256. }
  257. }}
  258. >
  259. <DialogTitle></DialogTitle>
  260. <Typography variant="h4" style={{ paddingLeft: '24px' }}><FormattedMessage id="MSG.actionFail" /></Typography>
  261. <DialogContent style={{ display: 'flex', }}>
  262. <Stack direction="column" justifyContent="space-between">
  263. <div dangerouslySetInnerHTML={{ __html: intl.formatMessage({ id: 'MSG.paymentHolded' }, { appNo: paymentHoldedErrText }) }} />
  264. </Stack>
  265. </DialogContent>
  266. <DialogActions>
  267. <Button onClick={() => setPaymentHoldedErr(false)} aria-label={intl.formatMessage({ id: 'close' })}>
  268. <Typography variant="h5">
  269. <FormattedMessage id="close" />
  270. </Typography></Button>
  271. </DialogActions>
  272. </Dialog>
  273. </div>
  274. </Grid >
  275. )
  276. );
  277. };
  278. export default Index;