25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 

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