Преглед на файлове

add suspension mode, add allow login, update gfmis

CR013B2
Alex Cheung преди 5 дни
родител
ревизия
1af1b1ff78
променени са 17 файла, в които са добавени 366 реда и са изтрити 123 реда
  1. +3
    -1
      src/auth/index.js
  2. +3
    -1
      src/components/RefreshTokenProvider.js
  3. +1
    -0
      src/components/SysSettingProvider.js
  4. +44
    -23
      src/pages/GFMIS/SearchForm.js
  5. +78
    -7
      src/pages/GFMIS/index.js
  6. +37
    -27
      src/pages/Proof/Payment/Pay_Online.js
  7. +35
    -39
      src/pages/Proof/Reply_Public/ApplicationDetails.js
  8. +7
    -6
      src/pages/Proof/Reply_Public/ProofForm.js
  9. +2
    -2
      src/pages/Setting/SystemSetting/Table.js
  10. +80
    -2
      src/pages/Setting/SystemSetting/index.js
  11. +23
    -13
      src/pages/authentication/AuthWrapper.js
  12. +42
    -2
      src/pages/dashboard/Public/index.js
  13. +1
    -0
      src/translations/en.json
  14. +1
    -0
      src/translations/zh-CN.json
  15. +1
    -0
      src/translations/zh-HK.json
  16. +2
    -0
      src/utils/ApiPathConst.js
  17. +6
    -0
      src/utils/Utils.js

+ 3
- 1
src/auth/index.js Целия файл

@@ -227,7 +227,9 @@ export const handleRefreshTokenFunction = () => {
})
.catch((refreshError) => {
console.log('Failed to refresh token');
console.log(refreshError)
if (refreshError != undefined){
console.log(refreshError)
}
// token = null
isRefresh = false;
});


+ 3
- 1
src/components/RefreshTokenProvider.js Целия файл

@@ -35,7 +35,9 @@ const RefreshTokenProvider = ({ children }) => {
})
.catch((refreshError) => {
console.log('Failed to refresh token');
console.log(refreshError)
if (refreshError != undefined){
console.log(refreshError)
}
token.current = null
isRefresh.current = false;
});


+ 1
- 0
src/components/SysSettingProvider.js Целия файл

@@ -21,6 +21,7 @@ const SysSettingProvider = ({ children }) => {
// console.log(responseData)
setSysSetting(responseData);
localStorage.setItem('sysEnv', responseData.sysEnv)
localStorage.setItem('paymentSuspention', responseData.suspensionMode)
}
});
}


+ 44
- 23
src/pages/GFMIS/SearchForm.js Целия файл

@@ -25,11 +25,12 @@ const SearchPublicNoticeForm = ({ applySearch, generateXML, searchCriteria, onGr

// const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom);
const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom);
const [maxDate] = React.useState(searchCriteria.dateFrom);
// const [status, setStatus] = React.useState(ComboData.paymentStatus[0]);
const [maxDate,setMaxDate] = React.useState(searchCriteria.dateFrom);
const [fromDateValue, setFromDateValue] = React.useState("dd / mm / yyyy");
const [toDateValue, setToDateValue] = React.useState("dd / mm / yyyy");
// const [status, setStatus] = React.useState(ComboData.paymentStatus[0]);

const {
const {
// register,
handleSubmit,
} = useForm()
@@ -37,19 +38,27 @@ const SearchPublicNoticeForm = ({ applySearch, generateXML, searchCriteria, onGr
React.useEffect(() => {
setFromDateValue(minDate);
}, [minDate]);
React.useEffect(() => {
setToDateValue(maxDate);
}, [maxDate]);

const onSubmit = () => {
let sentDateFrom = "";
let sentDateTo = "";

if (fromDateValue != "dd / mm / yyyy") {
sentDateFrom = DateUtils.dateValue(fromDateValue)
}
if (toDateValue != "dd / mm / yyyy") {
sentDateTo = DateUtils.dateValue(toDateValue)
}
const temp = {
// code: data.code,
// transNo: data.transNo,
dateFrom: sentDateFrom,
// dateTo: data.dateTo,
dateTo: sentDateTo,
// status : (status?.type && status?.type != 'all') ? status?.type : "",
};
applySearch(temp);
@@ -57,16 +66,20 @@ const SearchPublicNoticeForm = ({ applySearch, generateXML, searchCriteria, onGr

const generateHandler = () => {
let sentDateFrom = "";
let sentDateTo = "";

if (fromDateValue != "dd / mm / yyyy") {
sentDateFrom = DateUtils.dateValue(fromDateValue)
}
if (toDateValue != "dd / mm / yyyy") {
sentDateTo = DateUtils.dateValue(toDateValue)
}
// const dateTo = getValues("dateTo")
const temp = {
// code: data.code,
// transNo: data.transNo,
dateFrom: sentDateFrom,
dateTo: "",
dateTo: sentDateTo,
// status : (status?.type && status?.type != 'all') ? status?.type : "",
};
generateXML(temp);
@@ -90,8 +103,7 @@ const SearchPublicNoticeForm = ({ applySearch, generateXML, searchCriteria, onGr
{/*row 2*/}

<Grid container display="flex" alignItems={"center"}>
<Grid item xs={9} s={6} md={4} lg={4} sx={{ ml: 3, mr: 3, mb: 3 }}>
<Grid item xs={9} s={6} md={4} lg={4} sx={{ ml: 3, mr: 3, mb: 3 }}>
<LocalizationProvider dateAdapter={AdapterDayjs}>
<DemoItem components={['DatePicker']}>
<DatePicker
@@ -104,7 +116,7 @@ const SearchPublicNoticeForm = ({ applySearch, generateXML, searchCriteria, onGr
// },
}}
format="DD/MM/YYYY"
label="Credit Date"
label="From Date"
value={minDate === null ? null : dayjs(minDate)}
maxDate={maxDate === null ? null : dayjs(maxDate)}
onChange={(newValue) => {
@@ -119,21 +131,30 @@ const SearchPublicNoticeForm = ({ applySearch, generateXML, searchCriteria, onGr
</Grid>

<Grid item xs={9} s={6} md={4} lg={4} sx={{ ml: 3, mr: 3, mb: 3 }}>
{/* <TextField
fullWidth
InputLabelProps={{
shrink: true
}}
{...register("dateTo")}
InputProps={{ inputProps: { min: minDate } }}
onChange={(newValue) => {
setMaxDate(DateUtils.dateValue(newValue));
}}
id="dateTo"
type="date"
label="To"
defaultValue={searchCriteria.dateTo}
/> */}
<LocalizationProvider dateAdapter={AdapterDayjs}>
<DemoItem components={['DatePicker']}>
<DatePicker
id="dateTo"
// onError={(newError) => setReceiptFromError(newError)}
slotProps={{
field: { readOnly: true, },
// textField: {
// helperText: receiptFromErrorMessage,
// },
}}
format="DD/MM/YYYY"
label="To Date"
value={maxDate === null ? null : dayjs(maxDate)}
minDate={minDate === null ? null : dayjs(minDate)}
onChange={(newValue) => {
// console.log(newValue)
if(newValue!=null){
setMaxDate(newValue);
}
}}
/>
</DemoItem >
</LocalizationProvider>
</Grid>

{/* <Grid item xs={9} s={6} md={4} lg={3}>


+ 78
- 7
src/pages/GFMIS/index.js Целия файл

@@ -2,7 +2,9 @@
import {
Grid,
Typography,
Stack
Stack,
Button,
Dialog, DialogTitle, DialogContent, DialogActions,
} from '@mui/material';
import MainCard from "components/MainCard";
import {GEN_GFMIS_XML} from "utils/ApiPathConst";
@@ -10,6 +12,12 @@ import * as React from "react";
import * as HttpUtils from "utils/HttpUtils";
import * as DateUtils from "utils/DateUtils";

import {DatePicker} from "@mui/x-date-pickers/DatePicker";
import dayjs from "dayjs";
import {DemoItem} from "@mui/x-date-pickers/internals/demo";
import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider";
import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs";

import Loadable from 'components/Loadable';
const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent')));
const SearchForm = Loadable(React.lazy(() => import('./SearchForm')));
@@ -31,24 +39,41 @@ const BackgroundHead = {
const Index = () => {

const [searchCriteria, setSearchCriteria] = React.useState({
dateFrom: DateUtils.dateValue(new Date()),
// dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)),
dateTo: DateUtils.dateValue(new Date()),
dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)),
});
const [onReady, setOnReady] = React.useState(false);
const [onGridReady, setGridOnReady] = React.useState(false);
const [isPopUp, setIsPopUp] = React.useState(false);
const [downloadInput, setDownloadInput] = React.useState();


const [inputDate, setInputDate] = React.useState(searchCriteria.dateTo);
const [inputDateValue, setInputDateValue] = React.useState("dd / mm / yyyy");

React.useEffect(() => {
setInputDateValue(inputDate);
}, [inputDate]);

React.useEffect(() => {
setOnReady(true);
}, [searchCriteria]);


function downloadXML(input) {
function downloadXML() {
// console.log(input)
setIsPopUp(false)
let sentDateFrom = "";
if (inputDateValue != "dd / mm / yyyy") {
sentDateFrom = DateUtils.dateValue(inputDateValue)
}
HttpUtils.get({
url: GEN_GFMIS_XML + "/today",
params:{
// dateTo: input.dateTo,
dateFrom: input.dateFrom,
dateTo: downloadInput.dateTo,
dateFrom: downloadInput.dateFrom,
inputDate: sentDateFrom
},
onSuccess: (responseData) => {
// console.log(responseData)
@@ -100,6 +125,7 @@ const Index = () => {
function applySearch(input) {
setGridOnReady(true)
setSearchCriteria(input);
setInputDate(input.dateFrom)
}

function applyGridOnReady(input) {
@@ -107,7 +133,8 @@ const Index = () => {
}

function generateXML(input) {
downloadXML(input);
setDownloadInput(input);
setIsPopUp(true)
}

return (
@@ -147,6 +174,50 @@ const Index = () => {
/>
</MainCard>
</Grid>
<Dialog
open={isPopUp}
onClose={() => setIsPopUp(false)}
PaperProps={{
sx: {
minWidth: '40vw',
maxWidth: { xs: '90vw', s: '90vw', m: '70vw', lg: '70vw' },
maxHeight: { xs: '90vh', s: '70vh', m: '70vh', lg: '60vh' }
}
}}
>
<DialogTitle> Bank Statement Collection Date </DialogTitle>
<DialogContent style={{ display: 'flex', }}>
<LocalizationProvider dateAdapter={AdapterDayjs}>
<DemoItem components={['DatePicker']}>
<DatePicker
id="dateFrom"
// onError={(newError) => setReceiptFromError(newError)}
slotProps={{
field: { readOnly: true, },
// textField: {
// helperText: receiptFromErrorMessage,
// },
}}
format="DD/MM/YYYY"
// label="Credit Date"
value={inputDate === null ? null : dayjs(inputDate)}
maxDate={searchCriteria.dateTo === null ? null : dayjs(searchCriteria.dateTo)}
minDate={searchCriteria.dateFrom === null ? null : dayjs(searchCriteria.dateFrom)}
onChange={(newValue) => {
// console.log(newValue)
if(newValue!=null){
setInputDate(newValue);
}
}}
/>
</DemoItem >
</LocalizationProvider>
</DialogContent>
<DialogActions>
<Button onClick={() => setIsPopUp(false)}><Typography variant="h5">Cancel</Typography></Button>
<Button onClick={() => downloadXML()}><Typography variant="h5">Confirm</Typography></Button>
</DialogActions>
</Dialog>
</Grid>
);
};


+ 37
- 27
src/pages/Proof/Payment/Pay_Online.js Целия файл

@@ -13,6 +13,7 @@ import { useParams } from "react-router-dom";
import { useNavigate } from "react-router-dom";
import * as DateUtils from "utils/DateUtils"
import * as FormatUtils from "utils/FormatUtils";
import { checkPaymentSuspention } from "utils/Utils";

import Loadable from 'components/Loadable';
const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent')));
@@ -150,7 +151,6 @@ const Index = () => {
<Typography variant="h4" sx={{ textAlign: "left", ml: 4, mr: 4, mt: 4, borderBottom: "1px solid black" }}>
<FormattedMessage id="proofPaymentHeader_online" />
</Typography>

<Typography variant="h5" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}>
<div dangerouslySetInnerHTML={{
__html: intl.formatMessage(
@@ -174,36 +174,46 @@ const Index = () => {
)
}} />
<br />
{checkPaymentSuspention()?
<div>
<Typography style={{ textAlign: "flex-start" }}>
<div dangerouslySetInnerHTML={{ __html: intl.formatMessage({ id: "suspensionMessage" }) }} />
</Typography>
<br />
</div>:null
}
</Typography>

<Typography variant="h4" sx={{ ml: 8, textAlign: "left" }}>
<ThemeProvider theme={PNSPS_BUTTON_THEME}>
<Button
component="span"
variant="contained"
// sx={{ ml: { sm: 4, md: 4, lg: 4 }, mr: 4, mt: { xs: 2, sm: 2 }, mb: { xs: 2, sm: 2 } }}
sx={{mr: 4 }}
onClick={() => { setIsPopUp(true) }}
>
<FormattedMessage id="payInstantly" />
</Button>
</ThemeProvider>
{!checkPaymentSuspention()?
<Typography variant="h4" sx={{ ml: 8, textAlign: "left" }}>
<ThemeProvider theme={PNSPS_BUTTON_THEME}>
<Button
component="span"
variant="contained"
// sx={{ ml: { sm: 4, md: 4, lg: 4 }, mr: 4, mt: { xs: 2, sm: 2 }, mb: { xs: 2, sm: 2 } }}
sx={{mr: 4 }}
onClick={() => { setIsPopUp(true) }}
>
<FormattedMessage id="payInstantly" />
</Button>
</ThemeProvider>

<FormattedMessage id="or" />
<FormattedMessage id="or" />

<ThemeProvider theme={PNSPS_BUTTON_THEME}>
<Button
component="span"
variant="contained"
sx={{ ml: { sm: 4, md: 4, lg: 4 }, mr: 4, mt: { xs: 2, sm: 2 }, mb: { xs: 2, sm: 2 } }}
onClick={() => {
navigate("/publicNotice");
}}
>
<FormattedMessage id="payLater" />
</Button>
</ThemeProvider>
</Typography>
<ThemeProvider theme={PNSPS_BUTTON_THEME}>
<Button
component="span"
variant="contained"
sx={{ ml: { sm: 4, md: 4, lg: 4 }, mr: 4, mt: { xs: 2, sm: 2 }, mb: { xs: 2, sm: 2 } }}
onClick={() => {
navigate("/publicNotice");
}}
>
<FormattedMessage id="payLater" />
</Button>
</ThemeProvider>
</Typography>:null
}

<Typography variant="h4" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}>
<div dangerouslySetInnerHTML={{


+ 35
- 39
src/pages/Proof/Reply_Public/ApplicationDetails.js Целия файл

@@ -258,47 +258,43 @@ const ApplicationDetailCard = ({ formData, }) => {

<Grid item xs={12} md={5} lg={5} sx={{ mb: 1, }}>
<Grid container alignItems={"center"}>
{
data.creditor == true ?
<>
<Grid item xs={12} md={12} lg={12}
sx={{ display: 'flex', alignItems: 'center' }}>
<Typography variant="h5" display="inline">

<FormattedMessage id="commentDeadline" />:
</Typography>
</Grid>
<Grid item xs={12} md={12} lg={12} sx={{ mb: 4, display: 'flex', alignItems: 'center' }}>
<Typography variant="h5">&emsp;
{locale === 'en' ?
`${intl.formatMessage({ id: 'before' })} ${DateUtils.dateFormat(data?.reviseDeadline, intl.formatMessage({ id: "paymentMethodDatetimeStrFormat" }))?.replace("am", "a.m.")?.replace("pm", "p.m.")} `
:
`${DateUtils.dateFormat(data?.reviseDeadline, intl.formatMessage({ id: "paymentMethodDatetimeStrFormat" }))?.replace("am", "上午")?.replace("pm", "下午")}${intl.formatMessage({ id: 'before' })}`
}
</Typography>
</Grid>
{data.creditor == true ?
<>
<Grid item xs={12} md={12} lg={12}
sx={{ display: 'flex', alignItems: 'center' }}>
<Typography variant="h5" display="inline">
<FormattedMessage id="commentDeadline" />:
</Typography>
</Grid>
<Grid item xs={12} md={12} lg={12} sx={{ mb: 4, display: 'flex', alignItems: 'center' }}>
<Typography variant="h5">&emsp;
{locale === 'en' ?
`${intl.formatMessage({ id: 'before' })} ${DateUtils.dateFormat(data?.reviseDeadline, intl.formatMessage({ id: "paymentMethodDatetimeStrFormat" }))?.replace("am", "a.m.")?.replace("pm", "p.m.")} `
:
`${DateUtils.dateFormat(data?.reviseDeadline, intl.formatMessage({ id: "paymentMethodDatetimeStrFormat" }))?.replace("am", "上午")?.replace("pm", "下午")}${intl.formatMessage({ id: 'before' })}`
}
</Typography>
</Grid>

<Grid item xs={12} md={12} lg={12}
sx={{ display: 'flex', alignItems: 'center' }}>
<Typography variant="h5" display="inline">
<FormattedMessage id="paymentDeadline" />:
</Typography>
</Grid>
<Grid item xs={12} md={12} lg={12} sx={{ mb: 4, display: 'flex', alignItems: 'center' }}>
<Typography variant="h5">&emsp;
{locale === 'en' ?
`${intl.formatMessage({ id: 'before' })} ${DateUtils.dateFormat(data?.proofPaymentDeadline, intl.formatMessage({ id: "paymentMethodDatetimeStrFormat" }))?.replace("am", "a.m.")?.replace("pm", "p.m.")} `
:
`${DateUtils.dateFormat(data?.proofPaymentDeadline, intl.formatMessage({ id: "paymentMethodDatetimeStrFormat" }))?.replace("am", "上午")?.replace("pm", "下午")}${intl.formatMessage({ id: 'before' })}`
}
</Typography>
</Grid>
</>
<Grid item xs={12} md={12} lg={12}
sx={{ display: 'flex', alignItems: 'center' }}>
<Typography variant="h5" display="inline">
<FormattedMessage id="paymentDeadline" />:
</Typography>
</Grid>
<Grid item xs={12} md={12} lg={12} sx={{ mb: 4, display: 'flex', alignItems: 'center' }}>
<Typography variant="h5">&emsp;
{locale === 'en' ?
`${intl.formatMessage({ id: 'before' })} ${DateUtils.dateFormat(data?.proofPaymentDeadline, intl.formatMessage({ id: "paymentMethodDatetimeStrFormat" }))?.replace("am", "a.m.")?.replace("pm", "p.m.")} `
:
`${DateUtils.dateFormat(data?.proofPaymentDeadline, intl.formatMessage({ id: "paymentMethodDatetimeStrFormat" }))?.replace("am", "上午")?.replace("pm", "下午")}${intl.formatMessage({ id: 'before' })}`
}
</Typography>
</Grid>
</>
:
<></>
}

<></>
}
<Grid item xs={12} sm={3} md={3} lg={3}
sx={{ mb: 1, display: 'flex', alignItems: 'center' }}>
<Typography>


+ 7
- 6
src/pages/Proof/Reply_Public/ProofForm.js Целия файл

@@ -28,7 +28,8 @@ import { ThemeProvider } from "@emotion/react";
import { FormattedMessage, useIntl } from "react-intl";
import {
isDummyLoggedIn,
checkIsOnlyOnlinePaymentByIssueDate
checkIsOnlyOnlinePaymentByIssueDate,
checkPaymentSuspention
} from "utils/Utils"

const UploadFileTable = Loadable(React.lazy(() => import('./UploadFileTable')));
@@ -320,8 +321,6 @@ const FormPanel = ({ formData }) => {
<FormControlLabel value={false} control={<Radio />} label={intl.formatMessage({ id: 'proofWithError' })} />
</RadioGroup>
</Grid>


{
actionValue && formData.creditor == false ?
isDummyLoggedIn() ?
@@ -436,6 +435,11 @@ const FormPanel = ({ formData }) => {
</td>
<td style={tabelStyle}>
<FormattedMessage id="payOnline" />
{checkPaymentSuspention()?
<Typography style={{ padding: '16px' }}>
<div dangerouslySetInnerHTML={{ __html: intl.formatMessage({ id: "suspensionMessage" }) }} />
</Typography>:null
}
<br /><a href="#payOnlineDetails" color='#fff' onClick={() => {
setWarningTitle(intl.formatMessage({ id: "paymentMeans" }) + ": " + intl.formatMessage({ id: "payOnline" }))
setWarningText(
@@ -661,8 +665,6 @@ const FormPanel = ({ formData }) => {
</Stack>
</Grid>
}


<Grid item xs={12} md={12} textAlign="left">
<ThemeProvider theme={PNSPS_BUTTON_THEME}>
<Button
@@ -676,7 +678,6 @@ const FormPanel = ({ formData }) => {
</Button>
</ThemeProvider>
</Grid>

</Grid>

)


+ 2
- 2
src/pages/Setting/SystemSetting/Table.js Целия файл

@@ -10,7 +10,7 @@ import { GET_SYS_PARAMS } from "utils/ApiPathConst";


// ==============================|| DASHBOARD - DEFAULT ||============================== //
const Table = ({onRowClick, searchCriteria}) => {
const Table = ({onRowClick, searchCriteria, refreshTrigger}) => {
const [_searchCriteria, set_searchCriteria] = React.useState(searchCriteria);

React.useEffect(() => {
@@ -70,7 +70,7 @@ const Table = ({onRowClick, searchCriteria}) => {
doLoad={React.useMemo(() => ({
url:GET_SYS_PARAMS,
params:_searchCriteria
}), [_searchCriteria])}
}), [_searchCriteria, refreshTrigger])}
/>
{/* </Box> */}
</div>


+ 80
- 2
src/pages/Setting/SystemSetting/index.js Целия файл

@@ -3,11 +3,13 @@ import {
Grid,
Typography,
Stack,
Button,
Dialog, DialogTitle, DialogContent, DialogActions,
// Box,
} from '@mui/material';
import * as React from "react";

import { GET_SYS_PARAMS } from "utils/ApiPathConst";
import { GET_SYS_PARAMS, GET_PAYMENT_SUSPENSION_MODE, UPDATE_PAYMENT_SUSPENSION_MODE } from "utils/ApiPathConst";

import Loadable from 'components/Loadable';
import MainCard from "components/MainCard";
@@ -36,11 +38,24 @@ const SystemSetting = () => {
const [searchCriteria, setSearchCriteria] = React.useState({});
const [selectedItem, setSelectedItem] = React.useState({});
const [reloadTime, setReloadTime] = React.useState(new Date())
const [isPopUp, setIsPopUp] = React.useState(false);
const [refreshTrigger, setRefreshTrigger] = React.useState(0);
const [suspensionMode, setSuspensionMode] = React.useState();
const [onReady, setOnReady] = React.useState(false);

const forceRefresh = () => {
setRefreshTrigger(prev => prev + 1);
};

React.useEffect(()=>{
setSearchCriteria({})
loadPaymentSuspension()
}, []);

React.useEffect(() => {
setOnReady(true);
}, [suspensionMode]);

const onRowClick = (param) => {
setSelectedItem(param.row);
}
@@ -60,6 +75,29 @@ const SystemSetting = () => {
onSuccess: () => {
notifyActionSuccess();
setReloadTime(new Date());
// forceRefresh()
}
});
}

const loadPaymentSuspension = () => {
HttpUtils.get({
url: GET_PAYMENT_SUSPENSION_MODE,
onSuccess: (responseData) => {
setSuspensionMode(responseData)
}
});
}
const onPaymentSuspension = () => {
setIsPopUp(false);
HttpUtils.post({
url: UPDATE_PAYMENT_SUSPENSION_MODE,
onSuccess: (responseData) => {
setSuspensionMode(responseData)
notifyActionSuccess();
setReloadTime(new Date());
forceRefresh()
}
});
}
@@ -90,13 +128,14 @@ const SystemSetting = () => {
<Table
searchCriteria={searchCriteria}
onRowClick={onRowClick}
refreshTrigger={refreshTrigger}
/>
</MainCard>
</Grid>
</Grid>
</Grid>
<Grid item xs={12} sm={4} md={4} lg={4}>
<Grid container>
<Grid container spacing>
<Grid item xs={12} md={12}>
<MainCard elevation={0}
border={false}
@@ -110,9 +149,48 @@ const SystemSetting = () => {
</Grid>
</Grid>
</Grid>
<Grid item xs={12} sm={4} md={4} lg={4}>
{onReady?
<Grid container mb={2}>
<Grid item xs={12} md={12}>
<Button
variant="contained"
color="red"
onClick={()=>{
setIsPopUp(true);
}}
>
{suspensionMode?"Cancel Payment Suspension Mode":"Enable Payment Suspension Mode"}
</Button>
</Grid>
</Grid>:null
}
</Grid>
</Grid>
</Grid>
{/*col 2*/}
<div>
<Dialog
open={isPopUp}
onClose={() => setIsPopUp(false)}
PaperProps={{
sx: {
minWidth: '40vw',
maxWidth: { xs: '90vw', s: '90vw', m: '70vw', lg: '70vw' },
maxHeight: { xs: '90vh', s: '70vh', m: '70vh', lg: '60vh' }
}
}}
>
<DialogTitle>Payment Suspension Mode</DialogTitle>
<DialogContent style={{ display: 'flex', }}>
<Typography variant="h5" style={{ padding: '16px' }}>{suspensionMode?"Cancel payment suspension mode?":"Enable payment suspension mode?"}</Typography>
</DialogContent>
<DialogActions>
<Button onClick={() => setIsPopUp(false)}><Typography variant="h5">Cancel</Typography></Button>
<Button onClick={() => onPaymentSuspension()}><Typography variant="h5">Confirm</Typography></Button>
</DialogActions>
</Dialog>
</div>
</>
</Grid>
);


+ 23
- 13
src/pages/authentication/AuthWrapper.js Целия файл

@@ -2,11 +2,12 @@ import PropTypes from 'prop-types';
import { Box, Grid, Typography } from '@mui/material';
// import { Stack } from '@mui/material';
import Loadable from 'components/Loadable';
import { lazy } from 'react';
import { lazy, useContext } from 'react';
import { FormattedMessage, useIntl } from "react-intl";
import { checkSysEnv } from "utils/Utils";
import { checkSysEnv, checkPaymentSuspention } from "utils/Utils";
import backbroundImg from 'assets/images/bg_ml.jpg';
import 'assets/style/loginStyles.css';
import { SysContext } from "components/SysSettingProvider"

const AuthCard = Loadable(lazy(() => import('./AuthCardCustom')));

@@ -20,6 +21,7 @@ const BackgroundHead = {
const AuthWrapper = ({ children }) => {
// Move useIntl inside component
const intl = useIntl();
const { sysSetting } = useContext(SysContext);

return (
<Box sx={{ minHeight: '87vh' }}>
@@ -41,9 +43,15 @@ const AuthWrapper = ({ children }) => {
sx={{ minHeight: { md: 'calc(87vh)' } }}
>
<Grid item xs={12} sx={{ ml: 4,}}>
{checkPaymentSuspention()?
<Typography style={{ textAlign: "flex-start" }}>
<div style={{ padding: 12 }} dangerouslySetInnerHTML={{ __html: intl.formatMessage({ id: "suspensionMessage" }) }} />
</Typography>
:
<Typography style={{ textAlign: "flex-start" }}>
<div style={{ padding: 12 }} dangerouslySetInnerHTML={{ __html: intl.formatMessage({ id: "homePageHeaderMessage" }) }} />
</Typography>
}
</Grid>
<Grid container direction="column"
justifyContent="flex-start"
@@ -73,18 +81,20 @@ const AuthWrapper = ({ children }) => {
</Grid>
</Grid>
</Grid>
<Grid item xs={12} md={4} lg={4} xl={4}>
<Grid
container
justifyContent="center"
alignItems="center"
sx={{ minHeight: { xs: 'calc(90vh - 134px)', md: 'calc(90vh - 112px)' }, }}
>
<Grid item xs={12} md={11} lg={11} xl={11}>
<AuthCard>{children}</AuthCard>
{sysSetting?.publicLogin?
<Grid item xs={12} md={4} lg={4} xl={4}>
<Grid
container
justifyContent="center"
alignItems="center"
sx={{ minHeight: { xs: 'calc(90vh - 134px)', md: 'calc(90vh - 112px)' }, }}
>
<Grid item xs={12} md={11} lg={11} xl={11}>
<AuthCard>{children}</AuthCard>
</Grid>
</Grid>
</Grid>
</Grid>
</Grid>:null
}
</Grid>
</div>
</Box>


+ 42
- 2
src/pages/dashboard/Public/index.js Целия файл

@@ -6,7 +6,8 @@ import {
Typography,
Stack,
Button,
Box
Box,
Dialog, DialogTitle, DialogContent, DialogActions,
} from '@mui/material';
import { isORGLoggedIn, } from "utils/Utils";
import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png'
@@ -17,6 +18,7 @@ import Loadable from 'components/Loadable';
import * as HttpUtils from "utils/HttpUtils";
import * as UrlUtils from "utils/ApiPathConst";
import * as DateUtils from "utils/DateUtils";
import { checkPaymentSuspention } from "utils/Utils";

const Message = Loadable(React.lazy(() => import('./Message')));
const Notice = Loadable(React.lazy(() => import('./Notice')));
@@ -49,10 +51,13 @@ const DashboardDefault = () => {
const [isLoading, setLoding] = useState(true);
const [itemList, setItemList] = React.useState([]);
const [listData, setListData] = React.useState([]);

const [paymentSuspention, setPaymentSuspention] = useState(false);
const [isPopUp, setIsPopUp] = React.useState(false);
React.useEffect(() => {
loadMessageData()
loadNoticeData()
checkPaymentSuspention()?setPaymentSuspention(true):setPaymentSuspention(false)
localStorage.setItem('searchCriteria',"")
}, []);

@@ -70,6 +75,14 @@ const DashboardDefault = () => {
}
}

React.useEffect(() => {
// console.log(messageOnReady)
// console.log(onNoticeReady)
if(paymentSuspention){
setIsPopUp(true);
}
}, [paymentSuspention]);

React.useEffect(() => {
// console.log(messageOnReady)
// console.log(onNoticeReady)
@@ -214,6 +227,33 @@ const DashboardDefault = () => {
</Grid>
</Grid>
</Grid>
<div>
<Dialog
open={isPopUp}
onClose={() => setIsPopUp(false)}
PaperProps={{
sx: {
minWidth: '40vw',
maxWidth: { xs: '90vw', s: '90vw', m: '70vw', lg: '70vw' },
maxHeight: { xs: '90vh', s: '70vh', m: '70vh', lg: '60vh' }
}
}}
>
<DialogTitle>
<Typography variant="h5">
<FormattedMessage id="systemNotice" />
</Typography>
</DialogTitle>
<DialogContent style={{ display: 'flex', }}>
<Typography variant="h5" style={{ padding: '16px' }}>
<div dangerouslySetInnerHTML={{ __html: intl.formatMessage({ id: "suspensionMessage" }) }} />
</Typography>
</DialogContent>
<DialogActions>
<Button onClick={() => setIsPopUp(false)}><Typography variant="h5"><FormattedMessage id="ok" /></Typography></Button>
</DialogActions>
</Dialog>
</div>
</Grid>
);
};


+ 1
- 0
src/translations/en.json Целия файл

@@ -21,6 +21,7 @@
"gazetteLength": "Length",
"gazetteSampleName": "Gazette Supplement No. 6",
"reason": "Reason",
"systemNotice": "System Notice",

"payInstantly": "Pay now",
"payLater": "Pay later",


+ 1
- 0
src/translations/zh-CN.json Целия файл

@@ -21,6 +21,7 @@
"gazetteLength": "长度",
"gazetteSampleName": "宪报第6号副刊公共启事",
"reason": "原因",
"systemNotice": "系统公告",

"payInstantly": "即时付款",
"payLater": "稍后付款",


+ 1
- 0
src/translations/zh-HK.json Целия файл

@@ -21,6 +21,7 @@
"gazetteLength": "長度",
"gazetteSampleName": "憲報第6號副刊公共啟事",
"reason": "原因",
"systemNotice": "系統公告",

"payInstantly": "即時付款",
"payLater": "稍後付款",


+ 2
- 0
src/utils/ApiPathConst.js Целия файл

@@ -9,6 +9,8 @@ export const CHANGE_PASSWORD_PATH = "/user/change-password"

export const GET_SYS_PARAMS = apiPath+'/settings';
export const PRIVACY_POLICY_PATH = apiPath+'/privacyPolicy';
export const UPDATE_PAYMENT_SUSPENSION_MODE = apiPath+'/settings/update-payment-suspension';
export const GET_PAYMENT_SUSPENSION_MODE = apiPath+'/settings/get-payment-suspension';

export const I_AM_SMART_PATH = apiPath+'/smart/call/iAmSmart';
export const I_AM_SMART_APP_PATH = apiPath+'/smart/call/app/iAmSmart';


+ 6
- 0
src/utils/Utils.js Целия файл

@@ -111,6 +111,12 @@ export const checkSysEnv = () =>{
return localStorage.getItem('sysEnv')
}
}
export const checkPaymentSuspention = () =>{
if (localStorage.getItem('paymentSuspention') != null){
// console.log(localStorage.getItem('sysEnv'))
return localStorage.getItem('paymentSuspention')
}
}
/**
** This function is used for demo purpose route navigation
** In real app you won't need this function because your app will navigate to same route for each users regardless of ability


Зареждане…
Отказ
Запис