No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 

600 líneas
27 KiB

  1. // material-ui
  2. import * as React from 'react';
  3. import {
  4. Stack,
  5. Typography,
  6. Button,
  7. Autocomplete,
  8. TextField,
  9. Grid,
  10. Dialog, DialogTitle, DialogContent, DialogActions, useMediaQuery,
  11. } from '@mui/material';
  12. import { FiDataGrid } from "components/FiDataGrid";
  13. import * as HttpUtils from "utils/HttpUtils"
  14. import * as utils from "auth/utils"
  15. import {
  16. PAYMENT_CHECK,
  17. POST_CHECK_APP_EXPRITY_DATE,
  18. GET_PUBLIC_NOTICE_LIST_ListByStatus_pendingPayment_careOfCombo
  19. } from "utils/ApiPathConst"
  20. import * as DateUtils from "utils/DateUtils"
  21. import * as FormatUtils from "utils/FormatUtils"
  22. import * as StatusUtils from "utils/statusUtils/PublicNoteStatusUtils";
  23. import { useNavigate } from "react-router-dom";
  24. import {
  25. isORGLoggedIn,
  26. isDummyLoggedIn,
  27. } from "utils/Utils";
  28. // import { dateStr } from "utils/DateUtils";
  29. import { ThemeProvider, useTheme } from "@emotion/react";
  30. import { PNSPS_BUTTON_THEME } from "../../../themes/buttonConst";
  31. import { FormattedMessage, useIntl } from "react-intl";
  32. import { PRIMARY_TEXT_BUTTON_SX, PRIMARY_CONTAINED_BUTTON_SX } from "themes/colorConst";
  33. // ==============================|| EVENT TABLE ||============================== //
  34. export default function SubmittedTab({ setCount, url }) {
  35. const [rowList, setRowList] = React.useState([]);
  36. const [selectedRowItems, setSelectedRowItems] = React.useState([]);
  37. const [isPopUp, setIsPopUp] = React.useState(false);
  38. const [checkCareOf, setCheckCareOf] = React.useState(false);
  39. const [careOfComboList, setCareOfComboList] = React.useState([]);
  40. const [selectedCareOf, setSelectedCareOf] = React.useState(null);
  41. const [expiryDateErrText, setExpiryDateErrText] = React.useState("");
  42. const [expiryDateErr, setExpiryDateErr] = React.useState(false);
  43. const [paymentHoldedErrText, setPaymentHoldedErrText] = React.useState("");
  44. const [paymentHoldedErr, setPaymentHoldedErr] = React.useState(false);
  45. const [_searchCriteria, set_searchCriteria] = React.useState({});
  46. // const [checkPaymentMethod, setCheckPaymentMethod] = React.useState(false);
  47. const theme = useTheme();
  48. const isMdOrLg = useMediaQuery(theme.breakpoints.up('md'));
  49. const intl = useIntl();
  50. const { locale } = intl;
  51. //const [amount, setAmount] = React.useState(0);
  52. const navigate = useNavigate()
  53. React.useEffect(() => {
  54. getCareOfList();
  55. }, []);
  56. React.useEffect(() => {
  57. if (selectedCareOf != null) {
  58. set_searchCriteria({ "careOf": selectedCareOf.label });
  59. } else {
  60. set_searchCriteria({});
  61. }
  62. }, [selectedCareOf]);
  63. const getCareOfList = () => {
  64. HttpUtils.get({
  65. url: GET_PUBLIC_NOTICE_LIST_ListByStatus_pendingPayment_careOfCombo,
  66. params: {},
  67. onSuccess: function (responData) {
  68. setCareOfComboList(responData);
  69. }
  70. });
  71. }
  72. const handleDetailClick = (params) => () => {
  73. navigate('/publicNotice/' + params.id);
  74. };
  75. const renderHeaderWithAria = (params) => (
  76. <span aria-label={params.colDef.headerName}>{params.colDef.headerName}</span>
  77. );
  78. const handlePaymentBtn = () => {
  79. let appIdList = [];
  80. let paymentCheckList = [];
  81. const _datas = rowList;
  82. const datas = _datas?.filter((row) =>
  83. selectedRowItems.includes(row.id)
  84. );
  85. // console.log(datas)
  86. for (var i = 0; i < datas?.length; i++) {
  87. appIdList.push(datas[i].id);
  88. if ( datas[i].paymentMethod != "online"){
  89. paymentCheckList.push(datas[i].paymentMethod)
  90. }
  91. }
  92. // console.log(paymentCheckList)
  93. if(paymentCheckList.length == 0){
  94. if (appIdList.length < 1) {
  95. setExpiryDateErrText(intl.formatMessage({ id: 'MSG.plzSelectApp' }));
  96. setExpiryDateErr(true);
  97. return;
  98. }
  99. HttpUtils.post({
  100. url: POST_CHECK_APP_EXPRITY_DATE,
  101. params: {
  102. ids: appIdList
  103. },
  104. onSuccess: (responData) => {
  105. if (responData.success == true) {
  106. // setIsPopUp(true);
  107. handlePaymentCheck(appIdList)
  108. return;
  109. }
  110. let str = "";
  111. responData.msg.forEach((item) => {
  112. str += "App: " + item.appNo + ", 到期日: " + DateUtils.datetimeStr_Cht(item.expiryDate) + "\n";
  113. });
  114. setExpiryDateErrText(str.split('\n').map(str => <>{str}<br /></>));
  115. setExpiryDateErr(true);
  116. }
  117. });
  118. } else {
  119. setExpiryDateErrText(intl.formatMessage({ id: 'MSG.plzonlinePayment' }));
  120. setExpiryDateErr(true);
  121. return;
  122. }
  123. };
  124. const handlePaymentCheck = (appIdList) => {
  125. HttpUtils.post({
  126. url: PAYMENT_CHECK,
  127. params: {
  128. appIds: appIdList
  129. },
  130. onSuccess: (responseData) => {
  131. const latestData = {};
  132. responseData.forEach(item => {
  133. // console.log(item)
  134. const { appId, timeDiff } = item;
  135. if (latestData[appId] === undefined || timeDiff < latestData[appId].timeDiff) {
  136. latestData[appId] = item;
  137. }
  138. });
  139. const latestDataObjects = Object.values(latestData);
  140. const filteredData = latestDataObjects.filter(item => item.timeDiff > 30 || item.status == "CANC" || item.status == "REJT");
  141. const filteredAppIds = filteredData.map(item => item.appId);
  142. const appIdsNotInData = appIdList.filter(appId => !latestDataObjects.some(item => item.appId === appId));
  143. const combinedAppIdsArray = [...appIdsNotInData, ...filteredAppIds];
  144. const readyToPayment = appIdList.every(appId => combinedAppIdsArray.includes(appId));
  145. if (readyToPayment) {
  146. setIsPopUp(true);
  147. return;
  148. } else {
  149. const appIdsInData = appIdList.filter(appId => !combinedAppIdsArray.some(item => item === appId));
  150. const HoldingApplication = latestDataObjects.filter(item => appIdsInData.includes(item.appId));
  151. const resultString = HoldingApplication.map(item => item.appNo).join(' , ');
  152. setPaymentHoldedErrText(resultString);
  153. // setPaymentHoldedErrText(intl.formatMessage({ id: 'MSG.paymentHolded' }, { appNo: record.appNo }));
  154. setPaymentHoldedErr(true);
  155. }
  156. }
  157. });
  158. };
  159. const columns = [
  160. {
  161. id: 'appNo',
  162. field: 'appNo',
  163. headerName: intl.formatMessage({ id: 'applicationId' }),
  164. width: isMdOrLg ? 'auto' : 160,
  165. flex: isMdOrLg ? 1 : undefined,
  166. renderHeader: renderHeaderWithAria,
  167. },
  168. {
  169. id: 'created',
  170. field: 'created',
  171. headerName: intl.formatMessage({ id: 'submitDate' }),
  172. width: isMdOrLg ? 'auto' : 160,
  173. flex: isMdOrLg ? 1 : undefined,
  174. renderHeader: renderHeaderWithAria,
  175. valueGetter: (params) => {
  176. return DateUtils.datetimeStr(params.value);
  177. }
  178. },
  179. {
  180. id: 'remarks',
  181. field: 'remarks',
  182. headerName: isORGLoggedIn() ? intl.formatMessage({ id: 'gazetteCount2_1' }) : intl.formatMessage({ id: 'myRemarks' }),
  183. width: isMdOrLg ? 'auto' : 400,
  184. flex: isMdOrLg ? 3 : undefined,
  185. renderHeader: renderHeaderWithAria,
  186. renderCell: (params) => (
  187. isORGLoggedIn() ?
  188. isDummyLoggedIn()?
  189. <div>
  190. <FormattedMessage id="gazetteCount" />: {params.row.issueVolume + "/" + params.row.issueYear
  191. + " No. " + params.row.issueNo}<br />
  192. GLD: {params.row.custName} <br />
  193. <FormattedMessage id="careOf" />: {params.row.careOf} <br />
  194. <FormattedMessage id="myRemarks" />: {params.row.remarks}
  195. </div>:
  196. <div>
  197. <FormattedMessage id="gazetteCount" />: {params.row.issueVolume + "/" + params.row.issueYear
  198. + " No. " + params.row.issueNo}<br />
  199. <FormattedMessage id="careOf" />: {params.row.careOf} <br />
  200. <FormattedMessage id="myRemarks" />: {params.row.remarks}
  201. </div>
  202. :
  203. <div>
  204. <FormattedMessage id="gazetteCount" />: {params.row.issueVolume + "/" + params.row.issueYear
  205. + " No. " + params.row.issueNo}<br />
  206. <FormattedMessage id="myRemarks" />:{params.row.remarks}
  207. </div>
  208. )
  209. },
  210. {
  211. id: 'fee',
  212. field: 'fee',
  213. headerName: intl.formatMessage({ id: 'price' }),
  214. width: isMdOrLg ? 'auto' : 160,
  215. flex: isMdOrLg ? 1 : undefined,
  216. renderHeader: renderHeaderWithAria,
  217. renderCell: (params) => {
  218. return FormatUtils.currencyFormat(params.row.fee)
  219. },
  220. },
  221. {
  222. id: 'paymentMethodAndDeadLine',
  223. field: 'paymentMethodAndDeadLine',
  224. headerName: intl.formatMessage({ id: 'paymentMethodAndDeadLine' }),
  225. renderHeader: renderHeaderWithAria,
  226. width: isMdOrLg ? 'auto' : 250,
  227. flex: isMdOrLg ? 2 : undefined,
  228. renderCell: (params) => (
  229. <div>
  230. <FormattedMessage id={utils.getPaymentMethod(params.row.paymentMethod)} /><br />
  231. <div>
  232. {/* {dateStr(params.row.closingDate)} */}
  233. {
  234. DateUtils.is18_00(params.row.expiryDate) ?
  235. DateUtils.formatDateForLocale(params.row.expiryDate, intl, locale):
  236. params.row.paymentMethod=="online"?
  237. locale === 'en' ?
  238. `${DateUtils.dateFormatWithFix(params.row.expiryDate, intl.formatMessage({ id: "datetimeFormate" }), 14, 30)?.replace("am", "a.m.")?.replace("pm", "p.m.")}`
  239. :
  240. `${DateUtils.dateFormatWithFix(params.row.expiryDate, intl.formatMessage({ id: "datetimeFormate" }), 14, 30)?.replace("am", "上午")?.replace("pm", "下午").replace("00分", "")}`
  241. :params.row.paymentMethod=="demandNote" ?
  242. locale === 'en' ?
  243. `${DateUtils.dateFormatWithFix(params.row.expiryDate, intl.formatMessage({ id: "datetimeFormate" }), 12, 0)?.replace("am", "a.m.")?.replace("pm", "p.m.")}`
  244. :
  245. `${DateUtils.dateFormatWithFix(params.row.expiryDate, intl.formatMessage({ id: "datetimeFormate" }), 12, 0)?.replace("am", "上午")?.replace("pm", "下午").replace("00分", "")}`
  246. :
  247. locale === 'en' ?
  248. `${DateUtils.dateFormatWithFix(params.row.expiryDate, intl.formatMessage({ id: "datetimeFormate" }), 12, 30)?.replace("am", "a.m.")?.replace("pm", "p.m.")}`
  249. :
  250. `${DateUtils.dateFormatWithFix(params.row.expiryDate, intl.formatMessage({ id: "datetimeFormate" }), 12, 30)?.replace("am", "上午")?.replace("pm", "下午").replace("00分", "")}`
  251. }
  252. {/* {
  253. locale === 'en' ?
  254. `${DateUtils.dateFormatWithFix(params.row.closingDate, intl.formatMessage({ id: "datetimeFormate" }), 14, 30)?.replace("am", "a.m.")?.replace("pm", "p.m.")}`
  255. :
  256. `${DateUtils.dateFormatWithFix(params.row.closingDate, intl.formatMessage({ id: "datetimeFormate" }), 14, 30)?.replace("am", "上午")?.replace("pm", "下午").replace("00分", "")}`
  257. }
  258. {params.row.paymentMethod=="online" ? " 2:30pm"
  259. :params.row.paymentMethod=="demandNote" ? " 12:00pm"
  260. : " 12:30pm"} */}
  261. </div>
  262. </div>
  263. )
  264. },
  265. // {
  266. // id: 'closingDateOff',
  267. // field: 'closingDateOff',
  268. // headerName: intl.formatMessage({ id: 'paymentMethod' }),
  269. // width: isMdOrLg ? 'auto' : 160,
  270. // flex: isMdOrLg ? 1 : undefined,
  271. // renderCell: (params) => {
  272. // // console.log(params)
  273. // let closingDateOff = params.row.closingDateOff;
  274. // return <div style={{ margin: 4 }}>{dateStr(closingDateOff)}</div>
  275. // },
  276. // },
  277. {
  278. id: 'status',
  279. field: 'status',
  280. headerName: intl.formatMessage({ id: 'status' }),
  281. width: isMdOrLg ? 'auto' : 160,
  282. flex: isMdOrLg ? 1 : undefined,
  283. renderHeader: renderHeaderWithAria,
  284. renderCell: (params) => {
  285. return StatusUtils.getStatusIntl(params, intl);
  286. },
  287. },
  288. {
  289. field: 'actions',
  290. type: 'actions',
  291. headerName: '',
  292. width: 150,
  293. renderHeader: renderHeaderWithAria,
  294. cellClassName: 'actions',
  295. renderCell: (params) => {
  296. return <Button aria-label={intl.formatMessage({ id: 'viewDetail' })} onClick={handleDetailClick(params)} sx={PRIMARY_TEXT_BUTTON_SX}>
  297. <FormattedMessage id="viewDetail" />
  298. </Button>;
  299. },
  300. }
  301. ];
  302. const getWindowContent = () => {
  303. var content = [];
  304. let totalAmount = 0;
  305. const _datas = rowList;
  306. const datas = _datas?.filter((row) =>
  307. selectedRowItems.includes(row.id)
  308. );
  309. for (var i = 0; i < datas?.length; i++) {
  310. content.push(
  311. <React.Fragment key={datas[i].id}>
  312. <Stack direction="row" justifyContent="space-between">
  313. <Typography variant="h5">
  314. <FormattedMessage id="applicationId" />: {datas[i].appNo}
  315. </Typography>
  316. ({DateUtils.datetimeStr(datas[i].created)})
  317. </Stack>
  318. <FormattedMessage id="extraMark" />: {datas[i].remarks}
  319. <br /><br />
  320. </React.Fragment>
  321. );
  322. totalAmount += datas[i].fee;
  323. }
  324. content.push(
  325. <Typography key="payment-total" variant="h5">
  326. <FormattedMessage id="totalAmount" /> ($): {FormatUtils.currencyFormat(totalAmount)}
  327. <br /><br />
  328. </Typography>
  329. );
  330. return content;
  331. }
  332. function handleRowDoubleClick(params) {
  333. navigate('/publicNotice/' + params.id);
  334. }
  335. function doPayment() {
  336. setIsPopUp(false);
  337. let totalAmount = 0;
  338. let appIdList = [];
  339. const _datas = rowList;
  340. const datas = _datas?.filter((row) =>
  341. selectedRowItems.includes(row.id)
  342. );
  343. // console.log(datas)
  344. for (var i = 0; i < datas?.length; i++) {
  345. totalAmount += datas[i].fee;
  346. appIdList.push(datas[i].id);
  347. }
  348. const firstCareOf = datas[0].careOf;
  349. const areAllCareOfEqual = datas.every(obj => obj.careOf === firstCareOf);
  350. if (appIdList.length > 0 && areAllCareOfEqual) {
  351. navigate('/paymentPage', { state: { amount: totalAmount, appIdList: appIdList } });
  352. } else {
  353. setCheckCareOf(true);
  354. // console.log("The selected applications should be from the same Care of.")
  355. }
  356. }
  357. function afterWarningPayment() {
  358. let totalAmount = 0;
  359. let appIdList = [];
  360. const _datas = rowList;
  361. const datas = _datas?.filter((row) =>
  362. selectedRowItems.includes(row.id)
  363. );
  364. // console.log(datas)
  365. for (var i = 0; i < datas?.length; i++) {
  366. totalAmount += datas[i].fee;
  367. appIdList.push(datas[i].id);
  368. }
  369. navigate('/paymentPage', { state: { amount: totalAmount, appIdList: appIdList } });
  370. }
  371. return (
  372. <>
  373. <div style={{ minHeight: 400, width: '100%', padding: 4 }}>
  374. {isORGLoggedIn() ?
  375. <Grid container direction="row" justifyContent="flex-start" alignItems="center" >
  376. <Grid item xs={3} md={1}>
  377. <Typography variant="h5"><FormattedMessage id="careOf" />:</Typography>
  378. </Grid>
  379. <Grid item xs={8} md={2}>
  380. <Autocomplete
  381. disablePortal
  382. id="careOfCombo"
  383. value={selectedCareOf === null ? null : selectedCareOf}
  384. options={careOfComboList}
  385. getOptionLabel={(option) => {
  386. if (option == null) return "";
  387. if (typeof option === "string") return option;
  388. return option.label != null ? String(option.label) : "";
  389. }}
  390. onChange={(event, newValue) => {
  391. // console.log(newValue)
  392. setSelectedCareOf(newValue);
  393. }}
  394. sx={{
  395. '& .MuiInputBase-root': { alignItems: 'center' },
  396. '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' },
  397. '& .MuiOutlinedInput-root': { height: 40 }
  398. }}
  399. renderInput={(params) => <TextField {...params} inputProps={{ ...params.inputProps, 'aria-label': intl.formatMessage({ id: 'careOf' }) }} />}
  400. clearText={intl.formatMessage({ id: "muiClear" })}
  401. closeText={intl.formatMessage({ id: "muiClose" })}
  402. openText={intl.formatMessage({ id: "muiOpen" })}
  403. noOptionsText={intl.formatMessage({ id: "muiNoOptions" })}
  404. />
  405. </Grid>
  406. </Grid> : null
  407. }
  408. <FiDataGrid
  409. checkboxSelection
  410. disableRowSelectionOnClick
  411. columns={columns}
  412. customPageSize={10}
  413. onRowSelectionModelChange={(newSelection) => {
  414. setSelectedRowItems(newSelection);
  415. }}
  416. onRowDoubleClick={handleRowDoubleClick}
  417. getRowHeight={() => 'auto'}
  418. doLoad={React.useMemo(() => ({
  419. url: url,
  420. params: _searchCriteria,
  421. callback: function (responseData) {
  422. setCount(responseData?.count ?? 0);
  423. setRowList(responseData?.records);
  424. }
  425. }),[url, _searchCriteria])}
  426. />
  427. <ThemeProvider theme={PNSPS_BUTTON_THEME}>
  428. <Button
  429. variant="contained"
  430. aria-label={intl.formatMessage({ id: 'payOnlineBtn' })}
  431. onClick={() => { handlePaymentBtn() }}
  432. sx={{ mt: 2, ml: 1 }}
  433. >
  434. <FormattedMessage id="payOnlineBtn" />
  435. </Button>
  436. </ThemeProvider>
  437. </div>
  438. <div>
  439. <Dialog
  440. open={isPopUp}
  441. onClose={() => setIsPopUp(false)}
  442. PaperProps={{
  443. sx: {
  444. minWidth: '40vw',
  445. maxWidth: { xs: '90vw', s: '90vw', m: '70vw', lg: '30vw' },
  446. maxHeight: { xs: '90vh', s: '70vh', m: '70vh', lg: '50vh' }
  447. }
  448. }}
  449. >
  450. <DialogTitle>
  451. <Typography variant="h3" >
  452. <FormattedMessage id="payConfirm" />
  453. </Typography>
  454. </DialogTitle>
  455. <DialogContent style={{ display: 'flex', }}>
  456. <Stack direction="column" justifyContent="space-between">
  457. {getWindowContent()}
  458. </Stack>
  459. </DialogContent>
  460. <DialogActions>
  461. <Button variant="contained" onClick={() => setIsPopUp(false)} aria-label={intl.formatMessage({ id: 'close' })} sx={PRIMARY_CONTAINED_BUTTON_SX}>
  462. <Typography variant="h5" sx={{ color: 'inherit' }}>
  463. <FormattedMessage id="close" />
  464. </Typography></Button>
  465. <Button variant="contained" onClick={() => doPayment()} aria-label={intl.formatMessage({ id: 'confirm' })} sx={PRIMARY_CONTAINED_BUTTON_SX}>
  466. <Typography variant="h5" sx={{ color: 'inherit' }}>
  467. <FormattedMessage id="confirm" />
  468. </Typography></Button>
  469. </DialogActions>
  470. </Dialog>
  471. </div>
  472. <div>
  473. <Dialog
  474. open={checkCareOf}
  475. onClose={() => setCheckCareOf(false)}
  476. PaperProps={{
  477. sx: {
  478. minWidth: '40vw',
  479. maxWidth: { xs: '90vw', s: '90vw', m: '70vw', lg: '70vw' },
  480. maxHeight: { xs: '90vh', s: '70vh', m: '70vh', lg: '60vh' }
  481. }
  482. }}
  483. >
  484. <DialogTitle></DialogTitle>
  485. <Typography variant="h2" style={{ padding: '16px' }}>
  486. <FormattedMessage id="warning" />
  487. </Typography>
  488. <DialogContent style={{ display: 'flex', }}>
  489. <Stack direction="column" justifyContent="space-between">
  490. <Typography variant="h5" color="error">
  491. <FormattedMessage id="careOfWarning" />
  492. </Typography>
  493. </Stack>
  494. </DialogContent>
  495. <DialogActions>
  496. <Button onClick={() => setCheckCareOf(false)} aria-label={intl.formatMessage({ id: 'close' })}>
  497. <Typography variant="h5">
  498. <FormattedMessage id="close" />
  499. </Typography></Button>
  500. <Button onClick={() => afterWarningPayment()} aria-label={intl.formatMessage({ id: 'confirm' })}>
  501. <Typography variant="h5">
  502. <FormattedMessage id="confirm" />
  503. </Typography></Button>
  504. </DialogActions>
  505. </Dialog>
  506. </div>
  507. <div>
  508. <Dialog
  509. open={expiryDateErr}
  510. onClose={() => setExpiryDateErr(false)}
  511. PaperProps={{
  512. sx: {
  513. minWidth: '40vw',
  514. maxWidth: { xs: '90vw', s: '90vw', m: '70vw', lg: '70vw' },
  515. maxHeight: { xs: '90vh', s: '70vh', m: '70vh', lg: '60vh' }
  516. }
  517. }}
  518. >
  519. <DialogTitle></DialogTitle>
  520. <Typography variant="h4" style={{ paddingLeft: '24px' }}><FormattedMessage id="MSG.actionFail" /></Typography>
  521. <DialogContent style={{ display: 'flex', }}>
  522. <Stack direction="column" justifyContent="space-between">
  523. {
  524. expiryDateErrText
  525. }
  526. </Stack>
  527. </DialogContent>
  528. <DialogActions>
  529. <Button onClick={() => setExpiryDateErr(false)} aria-label={intl.formatMessage({ id: 'close' })}>
  530. <Typography variant="h5">
  531. <FormattedMessage id="close" />
  532. </Typography></Button>
  533. </DialogActions>
  534. </Dialog>
  535. </div>
  536. <div>
  537. <Dialog
  538. open={paymentHoldedErr}
  539. onClose={() => setPaymentHoldedErr(false)}
  540. PaperProps={{
  541. sx: {
  542. minWidth: '40vw',
  543. maxWidth: { xs: '90vw', s: '90vw', m: '70vw', lg: '70vw' },
  544. maxHeight: { xs: '90vh', s: '70vh', m: '70vh', lg: '60vh' }
  545. }
  546. }}
  547. >
  548. <DialogTitle></DialogTitle>
  549. <Typography variant="h4" style={{ paddingLeft: '24px' }}><FormattedMessage id="MSG.actionFail" /></Typography>
  550. <DialogContent style={{ display: 'flex', }}>
  551. <Stack direction="column" justifyContent="space-between">
  552. <div dangerouslySetInnerHTML={{ __html: intl.formatMessage({ id: 'MSG.paymentHolded' }, { appNo: paymentHoldedErrText }) }} />
  553. </Stack>
  554. </DialogContent>
  555. <DialogActions>
  556. <Button onClick={() => setPaymentHoldedErr(false)} aria-label={intl.formatMessage({ id: 'close' })}>
  557. <Typography variant="h5">
  558. <FormattedMessage id="close" />
  559. </Typography></Button>
  560. </DialogActions>
  561. </Dialog>
  562. </div>
  563. </>
  564. );
  565. }