@@ -0,0 +1,15 @@ | |||
{ | |||
// Use IntelliSense to learn about possible attributes. | |||
// Hover to view descriptions of existing attributes. | |||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 | |||
"version": "0.2.0", | |||
"configurations": [ | |||
{ | |||
"type": "chrome", | |||
"request": "launch", | |||
"name": "Launch Chrome against localhost", | |||
"url": "http://localhost:3000", | |||
"webRoot": "${workspaceFolder}/src" | |||
} | |||
] | |||
} |
@@ -22,7 +22,7 @@ | |||
"@testing-library/user-event": "^14.4.3", | |||
"@types/react-input-mask": "^3.0.2", | |||
"apexcharts": "^3.35.5", | |||
"axios": "^1.4.0", | |||
"axios": "^1.7.1", | |||
"date-fns": "^3.0.6", | |||
"dayjs": "^1.11.9", | |||
"formik": "^2.2.9", | |||
@@ -2,52 +2,23 @@ | |||
<html lang="en"> | |||
<head> | |||
<meta charset="utf-8" /> | |||
<link rel="icon" href="%PUBLIC_URL%/favicon.svg" /> | |||
<link rel="icon" type="image/png" sizes="32x32" href="%PUBLIC_URL%/favicon-32x32.png"> | |||
<link rel="icon" type="image/png" sizes="16x16" href="%PUBLIC_URL%/favicon-16x16.png"> | |||
<link rel="mask-icon" href="%PUBLIC_URL%/safari-pinned-tab.svg" color="#5bbad5"> | |||
<meta name="viewport" content="width=device-width, initial-scale=1" /> | |||
<meta name="theme-color" content="#1f1f1f" /> | |||
<meta name="theme-color" content="#ffffff" /> | |||
<meta name="msapplication-TileColor" content="#da532c"> | |||
<meta name="title" content="PNSPS" /> | |||
<meta | |||
name="description" | |||
content="Mantis is a free, super flexible and customizable react redux dashboard template built using MUI React components with open source MIT license." | |||
content="The Government of the Hong Kong Special Administrative Region Gazette Public Notice Submission and Payment System." | |||
/> | |||
<meta | |||
name="keywords" | |||
content="react dashboard, react admin, react redux dashboard, ant design template, saas admin, free react dashboard" | |||
content="PNSPS, GLD, react redux dashboard, Gazette, Public Notice" | |||
/> | |||
<meta name="author" content="CodedThemes" /> | |||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> | |||
<!-- Open Graph / Facebook --> | |||
<meta property="og:locale" content="en_US" /> | |||
<meta property="og:type" content="website" /> | |||
<meta property="og:url" content="https://mantisdashboard.io/" /> | |||
<meta property="og:site_name" content="mantisdashboard.io" /> | |||
<meta property="article:publisher" content="https://www.facebook.com/codedthemes" /> | |||
<meta property="og:title" content="PNSPS" /> | |||
<meta | |||
property="og:description" | |||
content="Mantis is a free, super flexible and customizable react redux dashboard template built using MUI React components with open source MIT license." | |||
/> | |||
<meta property="og:image" content="https://mantisdashboard.io/adv-banner-images/og-social.png" /> | |||
<!-- Twitter --> | |||
<meta property="twitter:card" content="summary_large_image" /> | |||
<meta property="twitter:url" content="https://mantisdashboard.io" /> | |||
<meta property="twitter:title" content="PNSPS" /> | |||
<meta | |||
property="twitter:description" | |||
content="Mantis is a free, super flexible and customizable react redux dashboard template built using MUI React components with open source MIT license." | |||
/> | |||
<meta property="twitter:image" content="https://mantisdashboard.io/adv-banner-images/og-social.png" /> | |||
<meta name="twitter:creator" content="@codedthemes" /> | |||
<!-- | |||
Notice the use of %PUBLIC_URL% in the tags above. | |||
It will be replaced with the URL of the `public` folder during the build. | |||
Only files inside the `public` folder can be referenced from the HTML. | |||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will | |||
work correctly both with client-side routing and a non-root public URL. | |||
Learn how to configure a non-root public URL by running `npm run build`. | |||
--> | |||
<meta name="author" content="Government Logistics Department" /> | |||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/apple-touch-icon.png" /> | |||
<title>PNSPS</title> | |||
<link rel="preconnect" href="https://fonts.gstatic.com" /> | |||
<link | |||
@@ -0,0 +1,54 @@ | |||
<?xml version="1.0" standalone="no"?> | |||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" | |||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> | |||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" | |||
width="680.000000pt" height="680.000000pt" viewBox="0 0 680.000000 680.000000" | |||
preserveAspectRatio="xMidYMid meet"> | |||
<metadata> | |||
Created by potrace 1.14, written by Peter Selinger 2001-2017 | |||
</metadata> | |||
<g transform="translate(0.000000,680.000000) scale(0.100000,-0.100000)" | |||
fill="#000000" stroke="none"> | |||
<path d="M2270 4555 l0 -1345 912 2 913 3 0 340 0 340 -195 2 c-107 1 -322 2 | |||
-476 3 l-282 0 -1 928 c0 510 -1 960 -1 1000 l0 72 -435 0 -435 0 0 -1345z"/> | |||
<path d="M4627 5044 c-1 -1 -45 -5 -97 -8 -85 -5 -126 -9 -210 -20 -56 -8 | |||
-159 -28 -215 -43 -33 -8 -68 -17 -78 -19 -47 -9 -204 -72 -307 -124 -170 -85 | |||
-180 -91 -181 -120 0 -14 -1 -151 -2 -306 l-2 -280 280 0 280 1 0 112 0 112 | |||
49 22 c86 37 195 69 286 84 19 3 46 7 60 10 21 4 175 17 205 17 24 1 212 -13 | |||
235 -16 14 -2 43 -7 65 -10 48 -7 203 -48 264 -71 76 -28 203 -95 291 -153 99 | |||
-66 288 -250 345 -337 22 -33 43 -62 46 -65 9 -7 98 -173 100 -185 0 -5 9 -26 | |||
19 -45 44 -86 102 -303 117 -435 13 -114 5 -428 -12 -454 -2 -4 -6 -26 -9 -49 | |||
-9 -79 -78 -288 -132 -401 -113 -237 -256 -417 -449 -561 -64 -47 -103 -70 | |||
-255 -144 -14 -7 -45 -18 -70 -25 -25 -8 -52 -15 -60 -18 -8 -2 -16 -4 -17 -4 | |||
-2 0 -16 -4 -33 -9 -87 -25 -340 -34 -472 -17 -32 4 -84 10 -115 13 -63 6 | |||
-116 13 -148 19 -11 2 -41 6 -67 10 l-47 8 -1 -260 c0 -200 2 -262 12 -270 7 | |||
-6 36 -16 63 -22 28 -7 57 -14 65 -17 186 -45 213 -49 420 -48 221 0 307 11 | |||
517 64 100 25 340 113 353 129 3 3 31 19 63 35 32 16 97 55 145 87 300 198 | |||
551 508 697 859 35 86 102 291 110 336 3 20 7 39 9 43 2 3 7 22 10 41 10 60 | |||
16 94 20 115 28 130 28 570 1 700 -3 11 -7 36 -10 55 -19 133 -79 336 -137 | |||
470 -79 181 -210 395 -312 508 -185 207 -395 366 -631 478 -103 49 -316 126 | |||
-381 138 -16 2 -40 7 -54 11 -24 5 -89 18 -155 30 -46 8 -155 19 -197 19 -21 | |||
1 -38 3 -38 6 0 4 -229 8 -233 4z"/> | |||
<path d="M1958 5035 c-2 -1 -30 -5 -63 -8 -114 -11 -231 -31 -320 -54 -33 -8 | |||
-67 -17 -75 -18 -8 -2 -15 -4 -15 -5 0 -2 -14 -5 -53 -14 -12 -3 -27 -8 -32 | |||
-11 -5 -3 -18 -8 -27 -10 -122 -25 -529 -238 -603 -315 -3 -3 -30 -25 -60 -50 | |||
-184 -148 -367 -375 -487 -605 -77 -148 -171 -436 -188 -575 -4 -30 -9 -58 | |||
-11 -61 -17 -29 -26 -431 -11 -564 9 -86 20 -157 31 -205 3 -14 8 -36 11 -50 | |||
8 -44 42 -167 49 -179 4 -6 9 -21 11 -33 15 -78 144 -348 212 -445 13 -17 23 | |||
-36 23 -41 0 -5 9 -17 20 -27 11 -10 20 -22 20 -26 0 -10 0 -10 96 -124 178 | |||
-213 410 -391 664 -512 181 -86 425 -159 595 -179 22 -2 54 -7 70 -10 17 -3 | |||
109 -7 205 -9 200 -5 254 3 420 56 3 1 19 6 35 12 17 6 30 10 30 8 0 -1 45 21 | |||
100 49 185 96 342 213 510 384 104 105 185 194 185 202 0 3 9 15 21 27 31 33 | |||
126 159 179 237 8 12 20 29 27 38 8 13 11 -62 10 -317 -1 -210 2 -339 8 -347 | |||
8 -10 285 -111 355 -129 17 -5 97 -33 120 -42 23 -9 33 -12 55 -15 20 -3 20 5 | |||
20 947 l0 950 -910 0 -910 -1 -3 -277 -2 -277 287 -1 c159 0 372 -1 475 -2 | |||
204 -1 198 1 146 -58 -13 -15 -36 -44 -53 -65 -133 -169 -383 -441 -491 -534 | |||
-282 -242 -401 -288 -684 -266 -78 6 -97 8 -167 20 -24 4 -44 7 -45 6 -2 -1 | |||
-16 3 -31 9 -15 6 -42 13 -60 16 -76 13 -364 140 -397 175 -3 3 -30 23 -60 45 | |||
-30 22 -60 44 -66 50 -82 75 -126 120 -159 161 -21 27 -42 51 -45 54 -3 3 -27 | |||
38 -53 78 -79 118 -176 337 -201 452 -8 35 -25 120 -31 150 -26 135 -26 428 0 | |||
550 3 14 8 36 10 50 24 152 133 412 226 544 16 22 37 52 47 65 45 65 157 182 | |||
237 250 167 141 481 282 685 307 19 2 46 7 59 10 14 3 57 7 95 10 39 3 76 6 | |||
81 8 6 2 10 102 10 272 l-1 269 -62 1 c-34 1 -63 0 -64 -1z"/> | |||
</g> | |||
</svg> |
@@ -32,6 +32,7 @@ export const handleLogin = data => { | |||
localStorage.setItem('accessToken', data.accessToken) | |||
localStorage.setItem('refreshToken', data.refreshToken) | |||
localStorage.setItem('axiosToken', "Bearer " + data.accessToken) | |||
localStorage.setItem('searchCriteria',"") | |||
//localStorage.setItem(config.storageUserRoleKeyName, JSON.stringify(data.role).slice(1).slice(0, -1)) | |||
localStorage.setItem(refreshIntervalName, "60") | |||
// for demo only | |||
@@ -91,6 +92,7 @@ export const handleLogoutFunction = () => { | |||
localStorage.removeItem('refreshToken') | |||
localStorage.removeItem('webtoken') | |||
localStorage.removeItem('transactionid') | |||
localStorage.removeItem('searchCriteria') | |||
//localStorage.removeItem(config.storageUserRoleKeyName) | |||
localStorage.removeItem('expiredAlertShown') | |||
localStorage.removeItem(refreshIntervalName) | |||
@@ -14,25 +14,10 @@ export const paymentPath = window.location.href.match("localhost:3000") ? `${hos | |||
export const delBugMode = true; | |||
/** | |||
* Testing: | |||
* Domain: apigw-isit.staging-eid.gov.hk | |||
* URL: hk.gov.iamsmart.testapp:// | |||
* | |||
* Production | |||
* Domain: apigw.iamsmart.gov.hk | |||
* URL: hk.gov.iamsmart:// | |||
*/ | |||
export const iAmSmartPath = `https://apigw-isit.staging-eid.gov.hk`; | |||
export const iAmSmartAppPath = `hk.gov.iamsmart.testapp://`; | |||
export const clientId = "cf61fa7c121e4869966f69c8694b1cd2"; | |||
export const iAmSmartCallbackPath = () => { | |||
let hostname = window.location.hostname; | |||
if (hostname.match("pnspsuat")) { | |||
hostname = "pnspsuat.gld.gov.hk"; | |||
} else { | |||
hostname = "pnspsdev.gld.gov.hk"; | |||
} | |||
return hostname; | |||
}; | |||
@@ -57,7 +42,10 @@ export const getBowserType = () => { | |||
if (navigator.userAgent.match(/Android/i)) return "Android_Chrome" | |||
if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) return "iOS_Chrome" | |||
return "PC_Browser" | |||
} else if (navigator.userAgent.indexOf("Safari") != -1) { | |||
} else if (navigator.userAgent.indexOf('CriOS') != -1) { | |||
if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) return "iOS_Chrome" | |||
return "PC_Browser" | |||
} else if (navigator.userAgent.indexOf("Safari") != -1 && navigator.userAgent.indexOf("Chrome") == -1) { | |||
if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) return "iOS_Safari" | |||
return "PC_Browser" | |||
} else if (navigator.userAgent.indexOf("Firefox") != -1) { | |||
@@ -89,7 +77,7 @@ export const isGranted = (auth) => { | |||
const abilities = getUserData() ? getUserData()["abilities"] : null; | |||
if (abilities == null || abilities.length == 0) return false; | |||
if (!Array.isArray(auth)) return _checkAuth(abilities, auth); | |||
if (auth.length > abilities.length) return false; | |||
let haveAuth = true; | |||
for (let i = 0; i < auth.length; i++) { | |||
@@ -138,8 +126,33 @@ export const local = { en: "en-us", zh: "zh-hk", cn: "zh-cn" }; | |||
export const preferpaymentmethods = ['visa', 'mastercard', 'pps', 'creditcard', 'fps']; | |||
export const getPaymentMethod = (paymentMethod) => { | |||
if(paymentMethod == "online") return 'payOnlineMethod'; | |||
if(paymentMethod == "demandNote") return 'payDnMethod'; | |||
if(paymentMethod == "office") return 'payNPGOMethod'; | |||
if (paymentMethod == "online") return 'payOnlineMethod'; | |||
if (paymentMethod == "demandNote") return 'payDnMethod'; | |||
if (paymentMethod == "office") return 'payNPGOMethod'; | |||
return "other"; | |||
} | |||
export const getSearchCriteria = (path) =>{ | |||
let searchCriteria = "" | |||
if (localStorage.getItem('searchCriteria')==""){ | |||
return searchCriteria | |||
} else if (Object.keys(localStorage.getItem('searchCriteria')).length>0){ | |||
searchCriteria = JSON.parse(localStorage.getItem("searchCriteria")) | |||
if (searchCriteria.path === path){ | |||
return searchCriteria.data | |||
} else { | |||
return "" | |||
} | |||
} | |||
} | |||
export const checkSearchCriteriaPath = (path) =>{ | |||
if(!path.startsWith("/application") | |||
|| path === "/application/search"){ | |||
if(!path.startsWith("/user/")){ | |||
if(!path.startsWith("/publicNotice/")|| path === "/publicNotice"){ | |||
return true | |||
} | |||
} | |||
} | |||
} |
@@ -11,6 +11,9 @@ import Logo from './AdminLogo'; | |||
import config from 'config'; | |||
import { activeItem } from 'store/reducers/menu'; | |||
import { Stack } from '@mui/material'; | |||
import { | |||
checkSysEnv | |||
} from "utils/Utils"; | |||
// ==============================|| MAIN LOGO ||============================== // | |||
@@ -28,7 +31,7 @@ const LogoSection = ({ sx, to }) => { | |||
> | |||
<Logo /> | |||
</ButtonBase> | |||
<span id="systemTitle" >PNSPS</span> | |||
<span style={{ color: checkSysEnv()!=''?'red':'#0C489E'}} id="systemTitle">PNSPS</span> | |||
</Stack> | |||
); | |||
@@ -5,7 +5,8 @@ import { handleLogoutFunction } from 'auth/index'; | |||
import { useDispatch } from "react-redux"; | |||
import { | |||
isUserLoggedIn, | |||
isGLDLoggedIn, | |||
isGLDLoggedIn, | |||
isPasswordExpiry | |||
} from "utils/Utils"; | |||
const TimerContext = createContext(); | |||
@@ -81,6 +82,9 @@ const AutoLogoutProvider = ({ children }) => { | |||
// console.log(logoutInterval) | |||
const interval = setInterval(async () => { | |||
const currentTime = Date.now(); | |||
if (isPasswordExpiry()){ | |||
navigate('/user/changePassword'); | |||
} | |||
// getRemainingTime(); | |||
if(state !== "Active" && lastActiveTab){ | |||
const timeElapsed = currentTime - lastRequestTime; | |||
@@ -1,17 +1,18 @@ | |||
// material-ui | |||
import {useState, useEffect} from 'react'; | |||
import { useState, useEffect } from 'react'; | |||
import { | |||
DataGrid, GridOverlay, | |||
} from "@mui/x-data-grid"; | |||
import * as HttpUtils from "utils/HttpUtils"; | |||
import {FormattedMessage, useIntl} from "react-intl"; | |||
import {TablePagination, Typography} from '@mui/material'; | |||
import { FormattedMessage, useIntl } from "react-intl"; | |||
import { TablePagination, Typography } from '@mui/material'; | |||
import { getSearchCriteria, checkSearchCriteriaPath } from "auth/utils"; | |||
// ==============================|| EVENT TABLE ||============================== // | |||
export function FiDataGrid({ rows, columns, sx, autoHeight, | |||
hideFooterSelectedRowCount, rowModesModel, editMode, | |||
pageSizeOptions, filterItems, customPageSize, doLoad, ...props }) { | |||
hideFooterSelectedRowCount, rowModesModel, editMode, | |||
pageSizeOptions, filterItems, customPageSize, doLoad, applyGridOnReady, applySearch, tab, ...props }) { | |||
const intl = useIntl(); | |||
const [_rows, set_rows] = useState([]); | |||
const [_doLoad, set_doLoad] = useState({}); | |||
@@ -20,6 +21,7 @@ export function FiDataGrid({ rows, columns, sx, autoHeight, | |||
const [_editMode, set_editMode] = useState("row"); | |||
const [_pageSizeOptions, set_pageSizeOptions] = useState([10]); | |||
const [_filterItems, set_filterItems] = useState([]); | |||
const [loading, setLoading] = useState(false); | |||
const [page, setPage] = useState(0); | |||
const [pageSize, setPageSize] = useState(10); | |||
@@ -27,6 +29,7 @@ export function FiDataGrid({ rows, columns, sx, autoHeight, | |||
const [myHideFooterSelectedRowCount, setMyHideFooterSelectedRowCount] = useState(true); | |||
const [_sx, set_sx] = useState({ | |||
padding: "4 2 4 2", | |||
lineHeight: "normal", | |||
'& .MuiDataGrid-cell': { | |||
borderTop: 1, | |||
borderBottom: 1, | |||
@@ -36,18 +39,38 @@ export function FiDataGrid({ rows, columns, sx, autoHeight, | |||
border: 1, | |||
borderColor: "#EEE" | |||
}, | |||
"& .MuiDataGrid-columnHeaderTitle": { | |||
whiteSpace: "normal", | |||
lineHeight: "normal" | |||
}, | |||
"& .MuiDataGrid-columnHeader": { | |||
// Forced to use important since overriding inline styles | |||
height: "unset !important" | |||
}, | |||
}); | |||
const [rowCount, setRowCount] = useState(0); | |||
useEffect(() => { | |||
setPage(0); | |||
set_doLoad(doLoad); | |||
useEffect(() => { | |||
if (doLoad !== undefined && Object.keys(doLoad).length>0 ){ | |||
if(applySearch!=undefined){ | |||
if (Object.keys(getSearchCriteria(window.location.pathname)).length>0){ | |||
const localStorageSearchCriteria = getSearchCriteria(window.location.pathname) | |||
if(localStorageSearchCriteria.start!=undefined){ | |||
setPage(localStorageSearchCriteria.start/pageSize); | |||
} | |||
} | |||
}else{ | |||
setPage(0); | |||
} | |||
set_doLoad(doLoad); | |||
setLoading(true) | |||
} | |||
}, [doLoad]); | |||
useEffect(()=>{ | |||
useEffect(() => { | |||
getDataList(); | |||
},[_doLoad, page]); | |||
}, [_doLoad, page]); | |||
useEffect(() => { | |||
@@ -70,18 +93,25 @@ export function FiDataGrid({ rows, columns, sx, autoHeight, | |||
if (pageSizeOptions) { | |||
set_pageSizeOptions(pageSizeOptions) | |||
} | |||
if(autoHeight !== undefined){ | |||
if (autoHeight !== undefined) { | |||
set_autoHeight(autoHeight) | |||
} | |||
if(editMode){ | |||
if (editMode) { | |||
set_editMode(editMode); | |||
} | |||
if(filterItems){ | |||
if (filterItems) { | |||
set_filterItems(filterItems); | |||
} | |||
if(customPageSize){ | |||
if (customPageSize) { | |||
setPageSize(customPageSize); | |||
} | |||
// console.log(_doLoad) | |||
if (_doLoad !== undefined && Object.keys(_doLoad).length==0 ){ | |||
setLoading(false) | |||
if (applyGridOnReady !== undefined){ | |||
applyGridOnReady(false) | |||
} | |||
} | |||
}, [sx, hideFooterSelectedRowCount, rowModesModel, rows, columns, pageSizeOptions, autoHeight, editMode, filterItems, customPageSize]); | |||
const handleChangePage = (event, newPage) => { | |||
@@ -103,21 +133,51 @@ export function FiDataGrid({ rows, columns, sx, autoHeight, | |||
); | |||
} | |||
function getDataList() { | |||
if(_doLoad?.url == null) return; | |||
if(_doLoad.params == null) _doLoad.params = {}; | |||
_doLoad.params.start = page*pageSize; | |||
// console.log(Object.keys(_doLoad.params).length > 0) | |||
// console.log(Object.keys(_doLoad.params).length > 0) | |||
if (_doLoad?.url == null){ | |||
setLoading(false) | |||
return; | |||
} | |||
if (_doLoad.params == undefined) return; | |||
if (_doLoad.params.searchCriteria !== undefined) return; | |||
if (_doLoad.params == null) _doLoad.params = {}; | |||
_doLoad.params.start = page * pageSize; | |||
_doLoad.params.limit = pageSize; | |||
if(checkSearchCriteriaPath(window.location.pathname)){ | |||
if(window.location.pathname === "/publicNotice"){ | |||
if (tab != undefined && tab ==="application"){ | |||
localStorage.setItem('searchCriteria', JSON.stringify({path:window.location.pathname,data:_doLoad.params})) | |||
} | |||
}else if (window.location.pathname != "/publicNotice"){ | |||
localStorage.setItem('searchCriteria', JSON.stringify({path:window.location.pathname,data:_doLoad.params})) | |||
} | |||
} | |||
HttpUtils.get({ | |||
url: _doLoad.url, | |||
params: _doLoad.params, | |||
onSuccess: function (responseData) { | |||
set_rows(responseData?.records); | |||
setRowCount(responseData?.count); | |||
if(_doLoad.callback != null){ | |||
if (_doLoad.callback != null) { | |||
_doLoad.callback(responseData); | |||
} | |||
setLoading(false) | |||
// console.log(applyGridOnReady) | |||
if (applyGridOnReady !== undefined){ | |||
applyGridOnReady(false) | |||
} | |||
}, | |||
onError: function (error){ | |||
console.log(error) | |||
setLoading(false) | |||
if (applyGridOnReady !== undefined){ | |||
applyGridOnReady(false) | |||
} | |||
} | |||
}); | |||
} | |||
@@ -127,9 +187,11 @@ export function FiDataGrid({ rows, columns, sx, autoHeight, | |||
<DataGrid | |||
{...props} | |||
rows={_rows} | |||
rowCount={rowCount ? rowCount : 0} | |||
columns={_columns} | |||
paginationMode="server" | |||
disableColumnMenu | |||
shrinkWrap={true} | |||
rowModesModel={_rowModesModel} | |||
pageSizeOptions={_pageSizeOptions} | |||
editMode={_editMode} | |||
@@ -137,16 +199,17 @@ export function FiDataGrid({ rows, columns, sx, autoHeight, | |||
hideFooterSelectedRowCount={myHideFooterSelectedRowCount} | |||
filterModel={{ items: _filterItems }} | |||
sx={_sx} | |||
loading={loading} | |||
components={{ | |||
noRowsOverlay: CustomNoRowsOverlay, | |||
Pagination: () => ( | |||
<TablePagination | |||
count={rowCount?rowCount:0} | |||
count={rowCount ? rowCount : 0} | |||
page={page} | |||
rowsPerPage={pageSize} | |||
rowsPerPageOptions={_pageSizeOptions} | |||
labelDisplayedRows={() => | |||
`${(_rows?.length?page*pageSize+1:0)}-${page*pageSize+(_rows?.length??0)} ${intl.formatMessage({ id: "of" })} ${rowCount}` | |||
`${(_rows?.length ? page * pageSize + 1 : 0)}-${page * pageSize + (_rows?.length ?? 0)} ${intl.formatMessage({ id: "of" })} ${rowCount}` | |||
} | |||
labelRowsPerPage={intl.formatMessage({ id: "rowsPerPage" }) + ":"} | |||
onPageChange={handleChangePage} | |||
@@ -19,6 +19,7 @@ export default function FileList({ refType, refId, allowDelete, sx, dateHideable | |||
const theme = useTheme(); | |||
const isMdOrLg = useMediaQuery(theme.breakpoints.up('md')); | |||
const intl = useIntl(); | |||
const [onDownload, setOnDownload] = React.useState(false); | |||
React.useEffect(() => { | |||
loadData(); | |||
@@ -41,10 +42,17 @@ export default function FileList({ refType, refId, allowDelete, sx, dateHideable | |||
}; | |||
const onDownloadClick = (fileId, skey, filename) => () => { | |||
setOnDownload(true) | |||
HttpUtils.fileDownload({ | |||
fileId: fileId, | |||
skey: skey, | |||
filename: filename, | |||
onResponse:()=>{ | |||
setOnDownload(false) | |||
}, | |||
onError:()=>{ | |||
setOnDownload(false) | |||
} | |||
}); | |||
}; | |||
@@ -91,6 +99,7 @@ export default function FileList({ refType, refId, allowDelete, sx, dateHideable | |||
className="textPrimary" | |||
onClick={onDownloadClick(params.id, params.row.skey, params.row.filename)} | |||
color="primary" | |||
disabled={onDownload} | |||
/>] | |||
}, | |||
}, | |||
@@ -139,6 +148,7 @@ export default function FileList({ refType, refId, allowDelete, sx, dateHideable | |||
className="textPrimary" | |||
onClick={onDownloadClick(params.id, params.row.skey, params.row.filename)} | |||
color="primary" | |||
disabled={onDownload} | |||
/>] | |||
}, | |||
}, | |||
@@ -0,0 +1,35 @@ | |||
import { useState, useEffect, createContext } from 'react'; | |||
import { get } from "utils/HttpUtils" | |||
import {GET_SYS_SETTING} from "utils/ApiPathConst" | |||
const SysContext = createContext(); | |||
const SysSettingProvider = ({ children }) => { | |||
const [sysSetting, setSysSetting] = useState({}); | |||
useEffect(() => { | |||
loadSysSetting(); | |||
}, []); | |||
const loadSysSetting = () => { | |||
get({ | |||
url: GET_SYS_SETTING, | |||
onSuccess: (responseData) => { | |||
// console.log(responseData) | |||
setSysSetting(responseData); | |||
localStorage.setItem('sysEnv', responseData.sysEnv) | |||
} | |||
}); | |||
} | |||
return ( | |||
<SysContext.Provider value={{ sysSetting, setSysSetting }} > | |||
{children} | |||
</SysContext.Provider> | |||
); | |||
} | |||
export {SysContext, SysSettingProvider}; |
@@ -26,7 +26,7 @@ const AuthFooter = () => { | |||
variant="subtitle2" | |||
color="secondary" | |||
component={Link} | |||
// href="https://material-ui.com/store/contributors/codedthemes/" | |||
href="/importantNotice" | |||
target="_blank" | |||
underline="hover" | |||
> | |||
@@ -36,8 +36,7 @@ const AuthFooter = () => { | |||
variant="subtitle2" | |||
color="secondary" | |||
component={Link} | |||
href="https://www.gld.gov.hk/zh-hk/privacy-policy/" | |||
//href="/testMailPage" | |||
href="/privacyPolicy" | |||
target="_blank" | |||
underline="hover" | |||
> | |||
@@ -16,9 +16,10 @@ import 'assets/third-party/apex-chart.css'; | |||
import App from './App'; | |||
import { store } from 'store'; | |||
import reportWebVitals from './reportWebVitals'; | |||
import {I18nProvider} from "components/I18nProvider"; | |||
import {AutoLogoutProvider} from "components/AutoLogoutProvider"; | |||
import {RefreshTokenProvider} from "components/RefreshTokenProvider"; | |||
import { I18nProvider } from "components/I18nProvider"; | |||
import { AutoLogoutProvider } from "components/AutoLogoutProvider"; | |||
import { RefreshTokenProvider } from "components/RefreshTokenProvider"; | |||
import { SysSettingProvider } from "components/SysSettingProvider"; | |||
// ==============================|| MAIN - REACT DOM RENDER ||============================== // | |||
@@ -26,18 +27,21 @@ const container = document.getElementById('root'); | |||
const root = createRoot(container); // createRoot(container!) if you use TypeScript | |||
//const NotAuthorized = lazy(() => import('../views/NotAuthorized')) | |||
//const Error = lazy(() => import('../views/Error')) | |||
root.render( | |||
<StrictMode> | |||
<ReduxProvider store={store}> | |||
<SysSettingProvider> | |||
<I18nProvider> | |||
<BrowserRouter basename="/"> | |||
<RefreshTokenProvider> | |||
<AutoLogoutProvider> | |||
<App /> | |||
<App /> | |||
</AutoLogoutProvider> | |||
</RefreshTokenProvider> | |||
</BrowserRouter> | |||
</I18nProvider> | |||
</SysSettingProvider> | |||
</ReduxProvider> | |||
</StrictMode> | |||
); | |||
@@ -1,9 +1,10 @@ | |||
import PropTypes from 'prop-types'; | |||
import React | |||
, { useState } | |||
, { useState, useContext } | |||
from 'react'; | |||
import { useDispatch } from "react-redux"; | |||
import { useNavigate } from "react-router-dom"; | |||
import { SysContext } from "components/SysSettingProvider" | |||
// material-ui | |||
// import { useTheme } from '@mui/material/styles'; | |||
@@ -47,7 +48,10 @@ import { | |||
isPrimaryLoggedIn, | |||
isCreditorLoggedIn, | |||
isINDLoggedIn, | |||
// isORGLoggedIn, | |||
isPasswordExpiry, | |||
haveOrgPaymentRecord, | |||
isORGLoggedIn, | |||
checkSysEnv | |||
// getUserId | |||
} from "utils/Utils"; | |||
import { handleLogoutFunction } from 'auth/index'; | |||
@@ -66,6 +70,7 @@ const drawerWidth = 300; | |||
// ==============================|| MAIN LAYOUT - HEADER ||============================== // | |||
function Header(props) { | |||
const { sysSetting } = useContext(SysContext); | |||
const { window } = props; | |||
const [mobileOpen, setMobileOpen] = useState(false); | |||
const dispatch = useDispatch() | |||
@@ -76,346 +81,438 @@ function Header(props) { | |||
}; | |||
const handleLogout = async () => { | |||
dispatch(handleLogoutFunction()); | |||
await dispatch(handleLogoutFunction()); | |||
//await handleLogoutFunction(); | |||
navigate('/login'); | |||
await navigate('/login'); | |||
}; | |||
const loginContent = ( | |||
isGLDLoggedIn() ? | |||
<div id="adminContent"> | |||
<li> | |||
<Link className="dashboard" to='/dashboard'> | |||
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }} > | |||
Dashboard | |||
</Typography> | |||
</Link> | |||
</li> | |||
<li> | |||
<Link className="application" to='/application/search'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Application</Typography></Link> | |||
</li> | |||
{ | |||
isGrantedAny(["VIEW_PROOF", "MAINTAIN_PROOF"]) ? | |||
{isPasswordExpiry() ? | |||
<div id="passwordExpiryedContent"> | |||
<li> | |||
<Link className="proof" to='/proof/search'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Proof</Typography></Link> | |||
<Link className="manageUser" to={'/user/changePassword'}> | |||
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}> | |||
<FormattedMessage id="userChangePassword" /> | |||
</Typography> | |||
</Link> | |||
</li> | |||
: <></> | |||
} | |||
{ | |||
isGrantedAny(["MAINTAIN_PAYMENT", "MAINTAIN_RECON", "VIEW_DEMANDNOTE", "MAINTAIN_DEMANDNOTE"]) ? | |||
</div> | |||
: | |||
<div id="adminContentList"> | |||
<li> | |||
<Link className="paymentTop" ><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Payment</Typography><KeyboardArrowDownIcon sx={{ fontSize: '1vw' }} /></Link> | |||
<ul className='dropdown'> | |||
{ | |||
isGranted("MAINTAIN_DEMANDNOTE") ? | |||
<li> | |||
<Link className="exportDemandNote" to='/paymentPage/exportGDN' ><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Export for GDN</Typography></Link> | |||
</li> | |||
: | |||
<></> | |||
} | |||
<Link className="dashboard" to='/dashboard'> | |||
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }} > | |||
Dashboard | |||
</Typography> | |||
</Link> | |||
</li> | |||
{ | |||
isGrantedAny(["VIEW_APPLICATION", "MAINTAIN_APPLICATION"]) ? | |||
<li> | |||
<Link className="application" to='/application/search'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Application</Typography></Link> | |||
</li> | |||
: <></> | |||
} | |||
{ | |||
isGrantedAny(["VIEW_PROOF", "MAINTAIN_PROOF"]) ? | |||
<li> | |||
<Link className="proof" to='/proof/search'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Proof</Typography></Link> | |||
</li> | |||
: <></> | |||
} | |||
{ | |||
isGranted("MAINTAIN_PAYMENT") ? | |||
<li> | |||
<Link className="application" to='/application/markAsPaid/search'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Mark Payment</Typography></Link> | |||
</li> | |||
: | |||
<></> | |||
} | |||
{ | |||
isGrantedAny(["MAINTAIN_PROOF", "MAINTAIN_PAYMENT", "MAINTAIN_RECON", "VIEW_DEMANDNOTE", "MAINTAIN_DEMANDNOTE"]) ? | |||
<li> | |||
<Link className="paymentTop" ><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Payment</Typography><KeyboardArrowDownIcon sx={{ fontSize: '1vw' }} /></Link> | |||
<ul className='dropdown'> | |||
{ | |||
isGranted("MAINTAIN_PROOF") ? | |||
<li> | |||
<Link className="exportDemandNote" to='/paymentPage/exportGDN' ><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Export for GDN</Typography></Link> | |||
</li> | |||
: | |||
<></> | |||
} | |||
{ | |||
isGranted("MAINTAIN_PAYMENT") ? | |||
<li> | |||
<Link className="application" to='/application/markAsPaid/search'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Mark Payment</Typography></Link> | |||
</li> | |||
: | |||
<></> | |||
} | |||
{ | |||
isGranted("MAINTAIN_PAYMENT") ? | |||
<li> | |||
<Link className="payment" to='/paymentPage/search'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Online Payment Record</Typography></Link> | |||
</li> | |||
: | |||
<></> | |||
} | |||
{ | |||
isGranted("MAINTAIN_RECON") ? | |||
<> | |||
<li> | |||
<Link className="downloadXML" to='/gfmis/search'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>GFMIS Generate XML</Typography></Link> | |||
</li> | |||
</> | |||
: | |||
<></> | |||
} | |||
{ | |||
isGranted("MAINTAIN_DEMANDNOTE") ? | |||
<li> | |||
<Link className="createDemandNote" to='/paymentPage/createDemandNote' ><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Create Demand Note</Typography></Link> | |||
</li> | |||
: | |||
<></> | |||
} | |||
{ | |||
isGrantedAny(["VIEW_DEMANDNOTE", "MAINTAIN_DEMANDNOTE"]) ? | |||
<li> | |||
<Link className="demandNote" to='/paymentPage/demandNote' ><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Demand Note</Typography></Link> | |||
</li> | |||
: | |||
<></> | |||
} | |||
{ | |||
isGranted("MAINTAIN_RECON") ? | |||
<> | |||
<li> | |||
<Link className="reconReport" to='/paymentPage/reconReport'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Recon Report</Typography></Link> | |||
</li> | |||
</> | |||
: | |||
<></> | |||
} | |||
</ul> | |||
</li> | |||
: | |||
<></> | |||
} | |||
{ | |||
isGrantedAny(["VIEW_USER", "MAINTAIN_USER", "VIEW_ORG", "MAINTAIN_ORG", "VIEW_GROUP", "MAINTAIN_GROUP", "VIEW_GLD_USER", "VIEW_IND_USER", "VIEW_ORG_USER", "MAINTAIN_GLD_USER", "MAINTAIN_IND_USER", "MAINTAIN_ORG_USER"]) ? | |||
<li> | |||
<Link className="client" ><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Client</Typography><KeyboardArrowDownIcon sx={{ fontSize: '1vw' }} /></Link> | |||
<ul className='dropdown'> | |||
{ | |||
isGrantedAny(["VIEW_USER","MAINTAIN_USER"]) ? | |||
<> | |||
<li> | |||
<Link className="userSearchview" to='/userSearchview'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Users (GLD)</Typography></Link> | |||
</li> | |||
<li> | |||
<Link className="indUser" to='/indUser'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Users (Individual)</Typography></Link> | |||
</li> | |||
<li> | |||
<Link className="orgUser" to='/orgUser'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Users (Organisation)</Typography></Link> | |||
</li> | |||
</> | |||
: | |||
<> | |||
{ | |||
isGrantedAny(["VIEW_GLD_USER" ,"MAINTAIN_GLD_USER"]) ? | |||
<li> | |||
<Link className="userSearchview" to='/userSearchview'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Users (GLD)</Typography></Link> | |||
</li> : <></> | |||
} | |||
{ | |||
isGrantedAny(["VIEW_IND_USER", "MAINTAIN_IND_USER"]) ? | |||
<li> | |||
<Link className="indUser" to='/indUser'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Users (Individual)</Typography></Link> | |||
</li> : <></> | |||
} | |||
{ | |||
isGrantedAny(["VIEW_ORG_USER", "MAINTAIN_ORG_USER"]) ? | |||
<li> | |||
<Link className="orgUser" to='/orgUser'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Users (Organisation)</Typography></Link> | |||
</li> : <></> | |||
} | |||
</> | |||
} | |||
{ | |||
isGrantedAny(["VIEW_ORG", "MAINTAIN_ORG"]) ? | |||
<li> | |||
<Link className="org" to='/org'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Organisation</Typography></Link> | |||
</li> | |||
: | |||
<></> | |||
} | |||
{ | |||
isGrantedAny(["VIEW_GROUP", "MAINTAIN_GROUP"]) ? | |||
<li> | |||
<Link className="usergroupSearchview" to='/usergroupSearchview'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>User Group</Typography></Link> | |||
</li> | |||
: | |||
<></> | |||
} | |||
</ul> | |||
</li> | |||
: | |||
<></> | |||
} | |||
<li> | |||
<Link className="setting" ><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Settings</Typography><KeyboardArrowDownIcon sx={{ fontSize: '1vw' }} /></Link> | |||
<ul className='dropdown'> | |||
<li> | |||
<Link className="userProfileGld" to='/user/profile'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>My Profile</Typography></Link> | |||
</li> | |||
<li> | |||
<Link className="manageUser" to={'/user/changePassword'}> | |||
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}> | |||
<FormattedMessage id="userChangePassword" /> | |||
</Typography> | |||
</Link> | |||
</li> | |||
{ | |||
isGranted("MAINTAIN_PAYMENT") ? | |||
<li> | |||
<Link className="payment" to='/paymentPage/search'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Online Payment Record</Typography></Link> | |||
</li> | |||
: | |||
<></> | |||
} | |||
{ | |||
isGranted("MAINTAIN_RECON") ? | |||
isGranted("VIEW_GAZETTE_ISSUE", "MAINTAIN_GAZETTE_ISSUE") ? | |||
<> | |||
<li> | |||
<Link className="downloadXML" to='/gfmis/search'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>GFMIS Generate XML</Typography></Link> | |||
<Link className="holidaySetting" to='/setting/holiday'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Holiday Settings</Typography></Link> | |||
</li> | |||
<li> | |||
<Link className="gazetteissueSetting" to='/setting/gazetteissuepage'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Gazette Issues</Typography></Link> | |||
</li> | |||
</> | |||
: | |||
<></> | |||
} | |||
{ | |||
isGranted("MAINTAIN_DEMANDNOTE") ? | |||
<li> | |||
<Link className="createDemandNote" to='/paymentPage/createDemandNote' ><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Create Demand Note</Typography></Link> | |||
</li> | |||
: | |||
<></> | |||
} | |||
{ | |||
isGrantedAny(["VIEW_DEMANDNOTE", "MAINTAIN_DEMANDNOTE"]) ? | |||
isGranted("MAINTAIN_ANNOUNCEMENT") ? | |||
<li> | |||
<Link className="demandNote" to='/paymentPage/demandNote' ><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Demand Note</Typography></Link> | |||
<Link className="announcement" to='/setting/announcement'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Announcement</Typography></Link> | |||
</li> | |||
: | |||
<></> | |||
} | |||
{ | |||
isGranted("MAINTAIN_RECON") ? | |||
<> | |||
<li> | |||
<Link className="reconReport" to='/paymentPage/reconReport'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Recon Report</Typography></Link> | |||
</li> | |||
</> | |||
: | |||
<></> | |||
{isGranted("MAINTAIN_EMAIL") ? | |||
<li> | |||
<Link className="emailTemplate" to='/setting/emailTemplate'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Email Template</Typography></Link> | |||
</li> | |||
: | |||
<></> | |||
} | |||
</ul> | |||
</li> | |||
: | |||
<></> | |||
} | |||
{ | |||
isGrantedAny(["VIEW_USER", "MAINTAIN_USER", "VIEW_ORG", "MAINTAIN_ORG", "VIEW_GROUP", "MAINTAIN_GROUP"]) ? | |||
<li> | |||
<Link className="client" ><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Client</Typography><KeyboardArrowDownIcon sx={{ fontSize: '1vw' }} /></Link> | |||
<ul className='dropdown'> | |||
{ | |||
isGrantedAny(["VIEW_USER", "MAINTAIN_USER"]) ? | |||
<> | |||
<li> | |||
<Link className="userSearchview" to='/userSearchview'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Users (GLD)</Typography></Link> | |||
</li> | |||
<li> | |||
<Link className="indUser" to='/indUser'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Users (Individual)</Typography></Link> | |||
</li> | |||
<li> | |||
<Link className="orgUser" to='/orgUser'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Users (Organisation)</Typography></Link> | |||
</li> | |||
</> | |||
isGranted("MAINTAIN_DR") ? | |||
<li> | |||
<Link className="drImport" to='/setting/drImport'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>DR Import</Typography></Link> | |||
</li> | |||
: | |||
<></> | |||
} | |||
{ | |||
isGrantedAny(["VIEW_ORG", "MAINTAIN_ORG"]) ? | |||
isGranted("MAINTAIN_SETTING") ? | |||
<li> | |||
<Link className="org" to='/org'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Organisation</Typography></Link> | |||
<Link className="systemSetting" to='/setting/sys'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>System Settings</Typography></Link> | |||
</li> | |||
: | |||
<></> | |||
} | |||
{ | |||
isGrantedAny(["VIEW_GROUP", "MAINTAIN_GROUP"]) ? | |||
isGranted("MAINTAIN_SETTING") ? | |||
<li> | |||
<Link className="usergroupSearchview" to='/usergroupSearchview'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>User Group</Typography></Link> | |||
<Link className="auditLogSetting" to='/setting/auditLog'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Audit Log</Typography></Link> | |||
</li> | |||
: | |||
<></> | |||
} | |||
</ul> | |||
</li> | |||
: | |||
<></> | |||
} | |||
<li> | |||
<Link className="setting" ><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Settings</Typography><KeyboardArrowDownIcon sx={{ fontSize: '1vw' }} /></Link> | |||
<ul className='dropdown'> | |||
<li> | |||
<Link className="userProfileGld" to='/user/profile'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>My Profile</Typography></Link> | |||
</li> | |||
{ | |||
isGranted("MAINTAIN_GAZETTE_ISSUE") ? | |||
<> | |||
<li> | |||
<Link className="holidaySetting" to='/setting/holiday'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Holiday Settings</Typography></Link> | |||
</li> | |||
<li> | |||
<Link className="gazetteissueSetting" to='/setting/gazetteissuepage'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Gazette Issues</Typography></Link> | |||
</li> | |||
</> | |||
: | |||
<></> | |||
} | |||
{ | |||
isGranted("MAINTAIN_ANNOUNCEMENT") ? | |||
<li> | |||
<Link className="announcement" to='/setting/announcement'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Announcement</Typography></Link> | |||
</li> | |||
: | |||
<></> | |||
} | |||
{isGranted("MAINTAIN_EMAIL") ? | |||
<Box sx={{ display: { xs: 'none', sm: 'none', md: 'block' } }}> | |||
<li> | |||
<Link className="emailTemplate" to='/setting/emailTemplate'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Email Template</Typography></Link> | |||
<Link className="logout" onClick={handleLogout}><Typography variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>Logout</Typography></Link> | |||
</li> | |||
: | |||
<></> | |||
} | |||
{ | |||
isGranted("MAINTAIN_DR") ? | |||
<li> | |||
<Link className="drImport" to='/setting/drImport'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>DR Import</Typography></Link> | |||
</li> | |||
: | |||
<></> | |||
} | |||
{ | |||
isGranted("MAINTAIN_SETTING") ? | |||
<li> | |||
<Link className="systemSetting" to='/setting/sys'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>System Settings</Typography></Link> | |||
</li> | |||
: | |||
<></> | |||
} | |||
<li> | |||
<Link className="auditLogSetting" to='/setting/auditLog'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Audit Log</Typography></Link> | |||
</li> | |||
</ul> | |||
</li> | |||
<Box sx={{ display: { xs: 'none', sm: 'none', md: 'block' } }}> | |||
<li> | |||
<Link className="logout" onClick={handleLogout}><Typography variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>Logout</Typography></Link> | |||
</li> | |||
</Box> | |||
</Box> | |||
</div> | |||
} | |||
</div> | |||
: | |||
<div id="individualUserContent"> | |||
<li> | |||
<Link className="dashboard" to='/dashboard'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}> | |||
<FormattedMessage id="mainPage" /> | |||
</Typography></Link> | |||
</li> | |||
<li> | |||
<Link className="myDocumet" to='/publicNotice'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}> | |||
<FormattedMessage id="myPublicNotice" /> | |||
</Typography></Link> | |||
</li> | |||
<li> | |||
<Link className="documentRecord" to='/proof/search'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}> | |||
<FormattedMessage id="proofRecord" /> | |||
</Typography></Link> | |||
</li> | |||
<li> | |||
{isCreditorLoggedIn() ? | |||
<> | |||
<Link className="paymentRecord"> | |||
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}> | |||
<FormattedMessage id="paymentHistory" /> | |||
{isPasswordExpiry() ? | |||
<div id="passwordExpiryedContent"> | |||
<li> | |||
<Link className="manageUser" to={'/user/changePassword'}> | |||
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}> | |||
<FormattedMessage id="userChangePassword" /> | |||
</Typography> | |||
<KeyboardArrowDownIcon sx={{ fontSize: '1.0rem' }} /> | |||
</Link> | |||
<ul className='dropdown'> | |||
<li> | |||
<Link className="manageOrgUser" to='/paymentPage/search'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}> | |||
<FormattedMessage id="onlinePaymentHistory" /> | |||
</Typography></Link> | |||
</li> | |||
<li> | |||
</li> | |||
</div> | |||
: | |||
<div id="individualUserContentList"> | |||
<li> | |||
<Link className="dashboard" to='/dashboard'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}> | |||
<FormattedMessage id="mainPage" /> | |||
</Typography></Link> | |||
</li> | |||
<li> | |||
<Link className="myDocumet" to='/publicNotice'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}> | |||
<FormattedMessage id="myPublicNotice" /> | |||
</Typography></Link> | |||
</li> | |||
<li> | |||
<Link className="documentRecord" to='/proof/search'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}> | |||
<FormattedMessage id="proofRecord" /> | |||
</Typography></Link> | |||
</li> | |||
<li> | |||
{isCreditorLoggedIn() ? | |||
haveOrgPaymentRecord() ? | |||
<> | |||
<Link className="paymentRecord"> | |||
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}> | |||
<FormattedMessage id="paymentHistory" /> | |||
</Typography> | |||
<KeyboardArrowDownIcon sx={{ fontSize: '1.0rem' }} /> | |||
</Link> | |||
<ul className='dropdown'> | |||
<li> | |||
<Link className="manageOrgUser" to='/paymentPage/search'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}> | |||
<FormattedMessage id="onlinePaymentHistory" /> | |||
</Typography></Link> | |||
</li> | |||
<li> | |||
<Link className="manageOrgUser" to='/paymentPage/demandNote'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}> | |||
<FormattedMessage id="paymentInfoRecord" /> | |||
</Typography></Link> | |||
</li> | |||
</ul> | |||
</> | |||
: | |||
<Link className="manageOrgUser" to='/paymentPage/demandNote'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}> | |||
<FormattedMessage id="paymentInfoRecord" /> | |||
</Typography></Link> | |||
</li> | |||
</ul> | |||
</> | |||
: | |||
<Link className="manageOrgUser" to='/paymentPage/search'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}> | |||
<FormattedMessage id="onlinePaymentHistory" /> | |||
</Typography></Link> | |||
} | |||
</li> | |||
<li> | |||
{isPrimaryLoggedIn() ? | |||
<> | |||
<Link className="userSetting" > | |||
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }} onClick={(event) => console.log(event)}> | |||
<FormattedMessage id="setting" /> | |||
</Typography> | |||
<KeyboardArrowDownIcon sx={{ fontSize: '1.0rem' }} /> | |||
</Link> | |||
<ul className='dropdown' style={{ width: "max-content" }}> | |||
<li> | |||
<Link className="manageOrgUser" to='setting/manageUser'> | |||
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}> | |||
<FormattedMessage id="companyOrUserRecord" /> | |||
</Typography> | |||
</Link> | |||
</li> | |||
<li> | |||
<Link className="manageUser" to={'/orgUser'}> | |||
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}> | |||
{/* <FormattedMessage id="companyOrUserRecord" /> */} | |||
<FormattedMessage id="userProfile" /> | |||
</Typography> | |||
</Link> | |||
</li> | |||
<li> | |||
<Link className="manageUser" to={'/org'}> | |||
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}> | |||
{/* <FormattedMessage id="companyOrUserRecord" /> */} | |||
<FormattedMessage id="organizationProfile" /> | |||
: | |||
isORGLoggedIn() ? | |||
haveOrgPaymentRecord() ? | |||
<Link className="manageOrgUser" to='/paymentPage/search'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}> | |||
<FormattedMessage id="onlinePaymentHistory" /> | |||
</Typography></Link> | |||
: | |||
<Link className="manageOrgUser" to='/paymentPage/demandNote'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}> | |||
<FormattedMessage id="paymentInfoRecord" /> | |||
</Typography></Link> | |||
: | |||
<Link className="manageOrgUser" to='/paymentPage/search'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}> | |||
<FormattedMessage id="onlinePaymentHistory" /> | |||
</Typography></Link> | |||
} | |||
</li> | |||
<li> | |||
{isPrimaryLoggedIn() ? | |||
<> | |||
<Link className="userSetting" > | |||
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }} onClick={(event) => console.log(event)}> | |||
<FormattedMessage id="setting" /> | |||
</Typography> | |||
<KeyboardArrowDownIcon sx={{ fontSize: '1.0rem' }} /> | |||
</Link> | |||
</li> | |||
</ul> | |||
</> | |||
: | |||
isINDLoggedIn() ? | |||
<> | |||
<Link className="userSetting" > | |||
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }} onClick={(event) => console.log(event)}> | |||
<FormattedMessage id="setting" /> | |||
</Typography> | |||
<KeyboardArrowDownIcon sx={{ fontSize: '1.0rem' }} /> | |||
</Link> | |||
<ul className='dropdown' style={{ width: "max-content" }}> | |||
<li> | |||
<Link className="manageUser" to={'/indUser'}> | |||
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}> | |||
{/* <FormattedMessage id="companyOrUserRecord" /> */} | |||
<FormattedMessage id="userProfile" /> | |||
<ul className='dropdown' style={{ width: "max-content" }}> | |||
<li> | |||
<Link className="manageOrgUser" to='setting/manageUser'> | |||
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}> | |||
<FormattedMessage id="companyOrUserRecord" /> | |||
</Typography> | |||
</Link> | |||
</li> | |||
<li> | |||
<Link className="manageUser" to={'/org'}> | |||
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}> | |||
{/* <FormattedMessage id="companyOrUserRecord" /> */} | |||
<FormattedMessage id="organizationProfile" /> | |||
</Typography> | |||
</Link> | |||
</li> | |||
<li> | |||
<Link className="manageUser" to={'/orgUser'}> | |||
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}> | |||
{/* <FormattedMessage id="companyOrUserRecord" /> */} | |||
<FormattedMessage id="userProfile" /> | |||
</Typography> | |||
</Link> | |||
</li> | |||
<li> | |||
<Link className="manageUser" to={'/user/changePassword'}> | |||
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}> | |||
<FormattedMessage id="userChangePassword" /> | |||
</Typography> | |||
</Link> | |||
</li> | |||
</ul> | |||
</> | |||
: | |||
isINDLoggedIn() ? | |||
<> | |||
<Link className="userSetting" > | |||
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }} onClick={(event) => console.log(event)}> | |||
<FormattedMessage id="setting" /> | |||
</Typography> | |||
<KeyboardArrowDownIcon sx={{ fontSize: '1.0rem' }} /> | |||
</Link> | |||
</li> | |||
</ul> | |||
</> | |||
: | |||
<> | |||
<Link className="userSetting" > | |||
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }} onClick={(event) => console.log(event)}> | |||
<FormattedMessage id="setting" /> | |||
</Typography> | |||
<KeyboardArrowDownIcon sx={{ fontSize: '1.0rem' }} /> | |||
</Link> | |||
<ul className='dropdown' style={{ width: "max-content" }}> | |||
<li> | |||
<Link className="manageUser" to={'/orgUser'}> | |||
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}> | |||
<FormattedMessage id="userProfile" /> | |||
<ul className='dropdown' style={{ width: "max-content" }}> | |||
<li> | |||
<Link className="manageUser" to={'/indUser'}> | |||
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}> | |||
{/* <FormattedMessage id="companyOrUserRecord" /> */} | |||
<FormattedMessage id="userProfile" /> | |||
</Typography> | |||
</Link> | |||
</li> | |||
<li> | |||
<Link className="manageUser" to={'/user/changePassword'}> | |||
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}> | |||
<FormattedMessage id="userChangePassword" /> | |||
</Typography> | |||
</Link> | |||
</li> | |||
</ul> | |||
</> | |||
: | |||
<> | |||
<Link className="userSetting" > | |||
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }} onClick={(event) => console.log(event)}> | |||
<FormattedMessage id="setting" /> | |||
</Typography> | |||
<KeyboardArrowDownIcon sx={{ fontSize: '1.0rem' }} /> | |||
</Link> | |||
</li> | |||
</ul> | |||
</> | |||
} | |||
</li> | |||
<ul className='dropdown' style={{ width: "max-content" }}> | |||
<li> | |||
<Link className="manageUser" to={'/orgUser'}> | |||
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}> | |||
<FormattedMessage id="userProfile" /> | |||
</Typography> | |||
</Link> | |||
</li> | |||
<li> | |||
<Link className="manageUser" to={'/user/changePassword'}> | |||
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}> | |||
<FormattedMessage id="userChangePassword" /> | |||
</Typography> | |||
</Link> | |||
</li> | |||
</ul> | |||
</> | |||
} | |||
</li> | |||
</div> | |||
} | |||
<Box sx={{ display: { xs: 'none', sm: 'none', md: 'block' } }}> | |||
<li> | |||
<Link className="logout" onClick={handleLogout}><Typography variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}> | |||
@@ -429,19 +526,38 @@ function Header(props) { | |||
const logoutContent = ( | |||
<div> | |||
<li> | |||
<Link className="login" to='/login'> | |||
<Link className="login" to={'/aboutUs'}> | |||
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}> | |||
<FormattedMessage id="login" /> | |||
<FormattedMessage id="aboutUs" /> | |||
</Typography> | |||
</Link> | |||
</li> | |||
<li> | |||
<Link className="login" to={'/userGuidePub'}> | |||
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}> | |||
<FormattedMessage id="userGuide" /> | |||
</Typography> | |||
</Link> | |||
</li> | |||
<li> | |||
<Link className="register" to='/register'> | |||
<Link className="login" to='/login'> | |||
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}> | |||
<FormattedMessage id="register" /> | |||
<FormattedMessage id="login" /> | |||
</Typography> | |||
</Link> | |||
</li> | |||
{ | |||
sysSetting?.allowRegistration ? | |||
<li> | |||
<Link className="register" to='/register'> | |||
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}> | |||
<FormattedMessage id="register" /> | |||
</Typography> | |||
</Link> | |||
</li> | |||
: | |||
<></> | |||
} | |||
</div> | |||
); | |||
@@ -453,7 +569,7 @@ function Header(props) { | |||
</Typography> */} | |||
<Box sx={{ mr: 2, mt: 1, display: { md: 'none' } }}> | |||
<MobileLogo /> | |||
<span id="mobileTitle" >PNSPS</span> | |||
<span style={{ color: checkSysEnv()!=''?'red':'#0C489E'}} id="mobileTitle" >PNSPS</span> | |||
</Box> | |||
<Divider /> | |||
<ul id="sidebartop"> | |||
@@ -472,7 +588,7 @@ function Header(props) { | |||
<Stack id="sidebar" direction="column" justifyContent="center" alignItems="center" onClick={handleDrawerToggle} sx={{ textAlign: 'center' }}> | |||
<Box sx={{ mr: 2, mt: 1, display: { md: 'none' } }}> | |||
<MobileLogo /> | |||
<span id="mobileTitle" >PNSPS</span> | |||
<span style={{ color: checkSysEnv()!=''?'red':'#0C489E'}} id="mobileTitle" >PNSPS</span> | |||
</Box> | |||
<Divider /> | |||
<ul id="logoutContent"> | |||
@@ -495,8 +611,9 @@ function Header(props) { | |||
justifyContent="flex-start" | |||
alignItems="center" | |||
spacing={0} | |||
sx={{ width: { xs: '100%', md: '5%' } }} | |||
> | |||
<Box mt={0.5} sx={{ display: { xs: 'none', sm: 'none', md: 'block' } }}> | |||
<Box mt={0.5} sx={{ flexGrow: 1, display: { xs: 'none', sm: 'none', md: 'block' } }}> | |||
<AdminLogo /> | |||
</Box> | |||
<IconButton | |||
@@ -508,9 +625,16 @@ function Header(props) { | |||
> | |||
<MenuIcon style={{ color: '#0C489E' }} /> | |||
</IconButton> | |||
<Box sx={{ mr: 2, display: { md: 'none' } }}> | |||
<MobileLogo /> | |||
<span id="mobileTitle" >PNSPS</span> | |||
<Box sx={{ flexGrow: 1, mr: 2, display: { sm: 'block', md: 'none' } }}> | |||
<Stack direction="row" justifyContent="space-between" alignItems="center" width="100%"> | |||
<MobileLogo /> | |||
<Stack justifyContent="flex-start" alignItems="flex-start" width="100%" ml={2}> | |||
<span style={{ color: checkSysEnv()!=''?'red':'#0C489E'}} id="mobileTitle">PNSPS</span> | |||
</Stack> | |||
<Stack justifyContent="flex-end" alignItems="center"> | |||
<span style={{color:"#B11B1B",fontWeight:'bold',fontSize:'15px'}}>RESTRICTED</span> | |||
</Stack> | |||
</Stack> | |||
</Box> | |||
</Stack> : | |||
<Stack | |||
@@ -520,13 +644,13 @@ function Header(props) { | |||
spacing={0} | |||
sx={{ width: { xs: '100%', md: '25%' } }} | |||
> | |||
<Box sx={{ width: '260px', flexGrow: 1, display: { xs: 'none', sm: 'none', md: 'block' } }}> | |||
<Box sx={{ width: '450px', flexGrow: 1, display: { xs: 'none', sm: 'none', md: 'block' } }}> | |||
<Stack direction="row" justifyContent="flex-start" alignItems="center"> | |||
<Logo /> | |||
<Stack justifyContent="flex-start" alignItems="center"> | |||
{/*<span id="systemTitle">公共啟事提交</span>*/} | |||
{/*<span id="systemTitle">及繳費系統</span>*/} | |||
<span id="systemTitle"> | |||
<span style={{ color: checkSysEnv()!=''?'red':'#0C489E'}} id="systemTitle"> | |||
<FormattedMessage id="PNSPS" /> | |||
</span> | |||
</Stack> | |||
@@ -545,7 +669,7 @@ function Header(props) { | |||
<Stack direction="row" justifyContent="space-between" alignItems="center" width="100%"> | |||
<MobileLogo /> | |||
<Stack justifyContent="flex-start" alignItems="flex-start" width="100%" ml={2}> | |||
<span id="mobileTitle"> | |||
<span style={{ color: checkSysEnv()!=''?'red':'#0C489E'}} id="mobileTitle"> | |||
<FormattedMessage id="PNSPS" /> | |||
</span> | |||
</Stack> | |||
@@ -576,7 +700,9 @@ function Header(props) { | |||
> | |||
{ | |||
isGLDLoggedIn() ? | |||
<Grid item /> | |||
<Grid item > | |||
<span style={{color:"#B11B1B",fontWeight:'bold',fontSize:'15px'}}>RESTRICTED</span> | |||
</Grid> | |||
: | |||
<Grid item> | |||
<LocaleSelector /> | |||
@@ -642,7 +768,7 @@ function Header(props) { | |||
<Stack direction="row" justifyContent="space-between" alignItems="center" width="100%"> | |||
<MobileLogo /> | |||
<Stack justifyContent="flex-start" alignItems="flex-start" width="100%" ml={2}> | |||
<span id="mobileTitle"> | |||
<span style={{ color: checkSysEnv()!=''?'red':'#0C489E'}} id="mobileTitle"> | |||
<FormattedMessage id="PNSPS" /> | |||
</span> | |||
</Stack> | |||
@@ -1,6 +1,7 @@ | |||
import { useEffect, useState } from 'react'; | |||
import { Outlet } from 'react-router-dom'; | |||
import { useDispatch, useSelector } from 'react-redux'; | |||
import { useLocation } from 'react-router-dom'; | |||
// material-ui | |||
import { useTheme } from '@mui/material/styles'; | |||
@@ -31,7 +32,8 @@ const MainLayout = () => { | |||
const theme = useTheme(); | |||
const matchDownLG = useMediaQuery(theme.breakpoints.down('lg')); | |||
const dispatch = useDispatch(); | |||
const location = useLocation(); | |||
const hideNavbarRoutes = ['/databaseHealthCheck'] | |||
const { drawerOpen } = useSelector((state) => state.menu); | |||
// drawer toggler | |||
@@ -55,18 +57,26 @@ const MainLayout = () => { | |||
}, [drawerOpen]); | |||
return ( | |||
<Box sx={{backgroundColor:'#ffffff', display: 'flex', width: '100%', flexDirection: "column", paddingTop: { xs: "5px", sm: "25px", md: "43px" }}}> | |||
<Header/> | |||
{/* <Drawer open={open} handleDrawerToggle={handleDrawerToggle} /> */} | |||
<Box style={{ width: '100%', flexGrow: 1 } } sx={{ paddingTop: "38px" }}> | |||
{/* <Toolbar /> */} | |||
{/* <Breadcrumbs navigation={navigation} title /> */} | |||
<Outlet /> | |||
</Box> | |||
<Box sx={{borderTop: "3px solid #0C489E"}}> | |||
<Footer/> | |||
</Box> | |||
</Box> | |||
<> | |||
{!hideNavbarRoutes.includes(location.pathname) && ( | |||
<Box sx={{backgroundColor:'#ffffff', display: 'flex', width: '100%', flexDirection: "column", paddingTop: { xs: "5px", sm: "25px", md: "43px" }}}> | |||
<Header/> | |||
{/* <Drawer open={open} handleDrawerToggle={handleDrawerToggle} /> */} | |||
<Box style={{ width: '100%', flexGrow: 1 } } sx={{ paddingTop: "38px" }}> | |||
{/* <Toolbar /> */} | |||
{/* <Breadcrumbs navigation={navigation} title /> */} | |||
<Outlet /> | |||
</Box> | |||
<Box sx={{borderTop: "3px solid #0C489E"}}> | |||
<Footer/> | |||
</Box> | |||
</Box> | |||
)} | |||
{hideNavbarRoutes.includes(location.pathname) && ( | |||
<Outlet /> | |||
)} | |||
</> | |||
); | |||
}; | |||
@@ -10,7 +10,7 @@ import { clickableLink } from 'utils/CommonFunction'; | |||
import {GET_ANNOUNCE_LIST} from "utils/ApiPathConst"; | |||
// ==============================|| EVENT TABLE ||============================== // | |||
export default function SearchPublicNoticeTable({ searchCriteria }) { | |||
export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnReady, applySearch}) { | |||
const navigate = useNavigate() | |||
@@ -73,10 +73,16 @@ export default function SearchPublicNoticeTable({ searchCriteria }) { | |||
customPageSize={10} | |||
getRowHeight={() => 'auto'} | |||
onRowDoubleClick={handleRowDoubleClick} | |||
doLoad={{ | |||
applyGridOnReady={applyGridOnReady} | |||
applySearch = {applySearch} | |||
// doLoad={{ | |||
// url: GET_ANNOUNCE_LIST, | |||
// params: _searchCriteria, | |||
// }} | |||
doLoad={React.useMemo(() => ({ | |||
url: GET_ANNOUNCE_LIST, | |||
params: _searchCriteria, | |||
}} | |||
}), [_searchCriteria])} | |||
/> | |||
</div> | |||
); | |||
@@ -17,8 +17,9 @@ 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"; | |||
// ==============================|| DASHBOARD - DEFAULT ||============================== // | |||
const SearchPublicNoticeForm = ({ applySearch, searchCriteria}) => { | |||
const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady}) => { | |||
const navigate = useNavigate() | |||
const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom); | |||
@@ -58,7 +59,8 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria}) => { | |||
function resetForm() { | |||
setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14))) | |||
setMaxDate(DateUtils.dateValue(new Date())) | |||
reset(); | |||
reset({key:""}); | |||
localStorage.setItem('searchCriteria',"") | |||
} | |||
@@ -180,6 +182,7 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria}) => { | |||
<Button | |||
variant="contained" | |||
type="submit" | |||
disabled={onGridReady} | |||
> | |||
Submit | |||
</Button> | |||
@@ -7,6 +7,7 @@ import { | |||
import MainCard from "components/MainCard"; | |||
import * as React from "react"; | |||
import * as DateUtils from "utils/DateUtils"; | |||
import { getSearchCriteria } from "auth/utils"; | |||
import Loadable from 'components/Loadable'; | |||
const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | |||
@@ -28,20 +29,37 @@ const BackgroundHead = { | |||
const UserSearchPage_Individual = () => { | |||
const [searchCriteria, setSearchCriteria] = React.useState({ | |||
dateTo: DateUtils.dateValue(new Date()), | |||
dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate() - 90)), | |||
}); | |||
const [searchCriteria, setSearchCriteria] = React.useState({}); | |||
const [onReady, setOnReady] = React.useState(false); | |||
const [onGridReady, setGridOnReady] = React.useState(false); | |||
React.useEffect(() => { | |||
if (Object.keys(getSearchCriteria(window.location.pathname)).length>0){ | |||
setSearchCriteria(getSearchCriteria(window.location.pathname)) | |||
}else{ | |||
localStorage.setItem('searchCriteria',"") | |||
setSearchCriteria({ | |||
dateTo: DateUtils.dateValue(new Date()), | |||
dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)), | |||
}) | |||
} | |||
}, []); | |||
React.useEffect(() => { | |||
setOnReady(true); | |||
}, [searchCriteria]); | |||
function applySearch(input) { | |||
setGridOnReady(true) | |||
setSearchCriteria(input); | |||
localStorage.setItem('searchCriteria', JSON.stringify({path:window.location.pathname,data:input})) | |||
} | |||
function applyGridOnReady(input) { | |||
setGridOnReady(input); | |||
} | |||
return ( | |||
!onReady ? | |||
<Grid container sx={{ minHeight: '95vh', mb: 3 }} direction="column" justifyContent="center" alignItems="center"> | |||
@@ -63,6 +81,7 @@ const UserSearchPage_Individual = () => { | |||
<SearchForm | |||
applySearch={applySearch} | |||
searchCriteria={searchCriteria} | |||
onGridReady={onGridReady} | |||
/> | |||
</Grid> | |||
{/*row 2*/} | |||
@@ -73,7 +92,9 @@ const UserSearchPage_Individual = () => { | |||
sx={{ backgroundColor: '#fff' }} | |||
> | |||
<EventTable | |||
searchCriteria={searchCriteria} | |||
searchCriteria={searchCriteria} | |||
applyGridOnReady={applyGridOnReady} | |||
applySearch={applySearch} | |||
/> | |||
</MainCard> | |||
</Grid> | |||
@@ -6,7 +6,7 @@ import { FormattedMessage, useIntl } from "react-intl"; | |||
import {GET_ANNOUNCE_LIST} from "utils/ApiPathConst"; | |||
// ==============================|| EVENT TABLE ||============================== // | |||
export default function SearchPublicNoticeTable({ searchCriteria }) { | |||
export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnReady,applySearch }) { | |||
const intl = useIntl(); | |||
const { locale } = intl; | |||
@@ -57,10 +57,16 @@ export default function SearchPublicNoticeTable({ searchCriteria }) { | |||
columns={columns} | |||
customPageSize={10} | |||
getRowHeight={() => 'auto'} | |||
doLoad={{ | |||
applyGridOnReady={applyGridOnReady} | |||
applySearch={applySearch} | |||
// doLoad={{ | |||
// url: GET_ANNOUNCE_LIST, | |||
// params: _searchCriteria | |||
// }} | |||
doLoad={React.useMemo(() => ({ | |||
url: GET_ANNOUNCE_LIST, | |||
params: _searchCriteria | |||
}} | |||
params: _searchCriteria, | |||
}), [_searchCriteria])} | |||
/> | |||
</div> | |||
); | |||
@@ -19,7 +19,7 @@ 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"; | |||
// ==============================|| DASHBOARD - DEFAULT ||============================== // | |||
const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => { | |||
const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady }) => { | |||
// const navigate = useNavigate() | |||
const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom); | |||
@@ -39,6 +39,22 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => { | |||
setToDateValue(maxDate); | |||
}, [maxDate]); | |||
const _sx = { | |||
padding: "4 2 4 2", | |||
boxShadow: 1, | |||
border: 1, | |||
borderColor: '#DDD', | |||
'& .MuiDataGrid-cell': { | |||
borderTop: 1, | |||
borderBottom: 1, | |||
borderColor: "#EEE" | |||
}, | |||
'& .MuiDataGrid-footerContainer': { | |||
border: 1, | |||
borderColor: "#EEE" | |||
} | |||
} | |||
const marginBottom = 2.5; | |||
const { reset, register, handleSubmit } = useForm() | |||
const onSubmit = (data) => { | |||
@@ -60,7 +76,8 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => { | |||
function resetForm() { | |||
setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14))) | |||
setMaxDate(DateUtils.dateValue(new Date())) | |||
reset(); | |||
reset({key:""}); | |||
localStorage.setItem('searchCriteria',"") | |||
} | |||
@@ -68,7 +85,7 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => { | |||
<MainCard xs={12} md={12} lg={12} | |||
border={false} | |||
content={false} | |||
sx={{ backgroundColor: '#fff' }} | |||
sx={_sx} | |||
> | |||
<form onSubmit={handleSubmit(onSubmit)}> | |||
@@ -186,6 +203,8 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => { | |||
<Button | |||
variant="contained" | |||
type="submit" | |||
disabled={onGridReady} | |||
aria-label={intl.formatMessage({id: 'submit'})} | |||
> | |||
<FormattedMessage id="submit"></FormattedMessage> | |||
</Button> | |||
@@ -14,6 +14,7 @@ const SearchForm = Loadable(React.lazy(() => import('./SearchForm'))); | |||
const EventTable = Loadable(React.lazy(() => import('./DataGrid'))); | |||
import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' | |||
import { FormattedMessage } from "react-intl"; | |||
import { getSearchCriteria } from "auth/utils"; | |||
const BackgroundHead = { | |||
backgroundImage: `url(${titleBackgroundImg})`, | |||
@@ -29,19 +30,36 @@ const BackgroundHead = { | |||
const UserSearchPage_Individual = () => { | |||
const [searchCriteria, setSearchCriteria] = React.useState({ | |||
dateTo: DateUtils.dateValue(new Date()), | |||
dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate() - 90)), | |||
}); | |||
const [searchCriteria, setSearchCriteria] = React.useState({}); | |||
const [onReady, setOnReady] = React.useState(false); | |||
const [onGridReady, setGridOnReady] = React.useState(false); | |||
React.useEffect(() => { | |||
setOnReady(true); | |||
if (Object.keys(getSearchCriteria(window.location.pathname)).length>0){ | |||
setSearchCriteria(getSearchCriteria(window.location.pathname)) | |||
}else{ | |||
localStorage.setItem('searchCriteria',"") | |||
setSearchCriteria({ | |||
dateTo: DateUtils.dateValue(new Date()), | |||
dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)), | |||
}) | |||
} | |||
}, []); | |||
React.useEffect(() => { | |||
if(Object.keys(searchCriteria).length>0){ | |||
setOnReady(true); | |||
} | |||
}, [searchCriteria]); | |||
function applySearch(input) { | |||
setSearchCriteria(input); | |||
localStorage.setItem('searchCriteria', JSON.stringify({path:window.location.pathname,data:input})) | |||
} | |||
function applyGridOnReady(input) { | |||
setGridOnReady(input); | |||
} | |||
return ( | |||
@@ -65,6 +83,7 @@ const UserSearchPage_Individual = () => { | |||
<SearchForm | |||
applySearch={applySearch} | |||
searchCriteria={searchCriteria} | |||
onGridReady={onGridReady} | |||
/> | |||
</Grid> | |||
{/*row 2*/} | |||
@@ -76,6 +95,8 @@ const UserSearchPage_Individual = () => { | |||
> | |||
<EventTable | |||
searchCriteria={searchCriteria} | |||
applyGridOnReady={applyGridOnReady} | |||
applySearch={applySearch} | |||
/> | |||
</MainCard> | |||
</Grid> | |||
@@ -21,16 +21,18 @@ import {ThemeProvider} from "@emotion/react"; | |||
import * as DateUtils from "utils/DateUtils"; | |||
import * as UrlUtils from "utils/ApiPathConst"; | |||
import * as HttpUtils from "utils/HttpUtils"; | |||
import Loadable from 'components/Loadable'; | |||
const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | |||
// import Loadable from 'components/Loadable'; | |||
// const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | |||
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 { isGranted } from "auth/utils"; | |||
// ==============================|| DASHBOARD - DEFAULT ||============================== // | |||
const AuditLogSearchForm = ({ applySearch, searchCriteria}) => { | |||
const AuditLogSearchForm = ({ applySearch, searchCriteria, onGridReady}) => { | |||
// const navigate = useNavigate(); | |||
const [minDate, setMinDate] = React.useState(searchCriteria.modifiedFrom); | |||
@@ -77,6 +79,7 @@ const AuditLogSearchForm = ({ applySearch, searchCriteria}) => { | |||
setOnDownload(true) | |||
HttpUtils.fileDownload({ | |||
url: UrlUtils.AUDIT_LOG_EXPORT, | |||
params: searchCriteria, | |||
onResponse:()=>{ | |||
setOnDownload(false) | |||
}, | |||
@@ -185,18 +188,17 @@ const AuditLogSearchForm = ({ applySearch, searchCriteria}) => { | |||
<ThemeProvider theme={PNSPS_BUTTON_THEME}> | |||
<Grid item xs={12} md={12}> | |||
<Grid container maxWidth justifyContent="flex-end"> | |||
<Grid item sx={{ ml: 3, mr: 3, mb: 3,}}> | |||
{onDownload? | |||
<LoadingComponent disableText={true} alignItems="flex-start"/> | |||
: | |||
{isGranted("MAINTAIN_SETTING") ? | |||
<Grid item sx={{ ml: 3, mr: 3, mb: 3,}}> | |||
<Button | |||
variant="contained" | |||
onClick={exportExcel} | |||
disabled={onDownload} | |||
> | |||
Export | |||
</Button> | |||
} | |||
</Grid> | |||
</Grid> : null | |||
} | |||
<Grid item sx={{ ml: 3, mr: 3, mb: 3,}}> | |||
<Button | |||
variant="contained" | |||
@@ -210,6 +212,7 @@ const AuditLogSearchForm = ({ applySearch, searchCriteria}) => { | |||
<Button | |||
variant="contained" | |||
type="submit" | |||
disabled={onGridReady} | |||
> | |||
Search | |||
</Button> | |||
@@ -12,7 +12,7 @@ import { | |||
} from '@mui/material'; | |||
// ==============================|| EVENT TABLE ||============================== // | |||
export default function AuditLogTable({searchCriteria}) { | |||
export default function AuditLogTable({searchCriteria, applyGridOnReady,applySearch}) { | |||
const [_searchCriteria, set_searchCriteria] = React.useState(searchCriteria); | |||
useEffect(() => { | |||
@@ -87,10 +87,16 @@ export default function AuditLogTable({searchCriteria}) { | |||
columns={columns} | |||
customPageSize={10} | |||
getRowHeight={() => 'auto'} | |||
doLoad={{ | |||
applyGridOnReady={applyGridOnReady} | |||
applySearch={applySearch} | |||
// doLoad={{ | |||
// url: GET_AUDIT_LOG_LIST, | |||
// params: _searchCriteria | |||
// }} | |||
doLoad={React.useMemo(() => ({ | |||
url: GET_AUDIT_LOG_LIST, | |||
params: _searchCriteria | |||
}} | |||
params: _searchCriteria, | |||
}), [_searchCriteria])} | |||
/> | |||
</div> | |||
); | |||
@@ -8,6 +8,7 @@ import { | |||
import MainCard from "components/MainCard"; | |||
import { useEffect, useState } from "react"; | |||
import * as DateUtils from "utils/DateUtils"; | |||
import * as React from "react"; | |||
import Loadable from 'components/Loadable'; | |||
import { lazy } from 'react'; | |||
@@ -33,15 +34,21 @@ const AuditLogPage = () => { | |||
modifiedFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)), | |||
}); | |||
const [onReady, setOnReady] = useState(false); | |||
const [onGridReady, setGridOnReady] = React.useState(false); | |||
useEffect(() => { | |||
setOnReady(true); | |||
}, [searchCriteria]); | |||
function applySearch(input) { | |||
setGridOnReady(true) | |||
setSearchCriteria(input); | |||
} | |||
function applyGridOnReady(input) { | |||
setGridOnReady(input); | |||
} | |||
return ( | |||
!onReady ? | |||
<Grid container sx={{ minHeight: '87vh', mb: 3 }} direction="column" justifyContent="center" alignItems="center"> | |||
@@ -64,7 +71,7 @@ const AuditLogPage = () => { | |||
<SearchForm | |||
applySearch={applySearch} | |||
searchCriteria={searchCriteria} | |||
onGridReady={onGridReady} | |||
/> | |||
</Grid> | |||
{/*row 2*/} | |||
@@ -75,6 +82,8 @@ const AuditLogPage = () => { | |||
> | |||
<EventTable | |||
searchCriteria={searchCriteria} | |||
applyGridOnReady={applyGridOnReady} | |||
applySearch={applySearch} | |||
/> | |||
</MainCard> | |||
</Grid> | |||
@@ -143,7 +143,7 @@ const ApplicationDetailCard = ({ data }) => { | |||
</Grid> | |||
<Grid container direction="row" justifyContent="space-between" | |||
alignItems="center"> | |||
<Grid item xs={12} md={6} lg={6} mt={1}> | |||
<Grid item xs={12} md={6} lg={6} mt={1} mb={2}> | |||
<Grid container alignItems={"center"}> | |||
<Grid item xs={12} md={12} lg={12}> | |||
<Grid container direction="row"> | |||
@@ -77,9 +77,9 @@ export default function SearchPublicNoticeTable({ searchCriteria,}) { | |||
// let user = params.row.enCompanyName != null ? params.row.enCompanyName : params.row.chCompanyName; | |||
let user = params.row.contactPerson; | |||
// user = user != null ? user : ""; | |||
if (params.row.sysType != null && params.row.sysType == "dummy"){ | |||
user = "Dummy - PD" | |||
} | |||
// if (params.row.sysType != null && params.row.sysType == "dummy"){ | |||
// user = "Dummy - PD" | |||
// } | |||
return <div> | |||
{user} | |||
</div>; | |||
@@ -95,7 +95,7 @@ export default function SearchPublicNoticeTable({ searchCriteria,}) { | |||
let company = params.row.enCompanyName != null ? params.row.enCompanyName : params.row.chCompanyName; | |||
company = company != null ? company : ""; | |||
if (params.row.sysType != null && params.row.sysType == "dummy"){ | |||
company = params.row.contactPerson | |||
company = params.row.custName | |||
} | |||
return <div> | |||
{company} | |||
@@ -109,7 +109,13 @@ export default function SearchPublicNoticeTable({ searchCriteria,}) { | |||
flex: 2, | |||
minWidth: 200, | |||
renderCell: (params) => { | |||
return <>{(params?.value)}</>; | |||
let careOf = params.row.careOf | |||
// if (params.row.sysType != null && params.row.sysType == "dummy"){ | |||
// careOf = '' | |||
// } | |||
return <div> | |||
{careOf} | |||
</div>; | |||
} | |||
}, | |||
{ | |||
@@ -120,13 +126,13 @@ export default function SearchPublicNoticeTable({ searchCriteria,}) { | |||
minWidth: 100, | |||
valueGetter: (params) => { | |||
let length = params.row.length | |||
let colCount = params.row.colCount | |||
// let colCount = params.row.colCount | |||
let noOfPages = params.row.noOfPages | |||
let dimension = 0 | |||
if (noOfPages != null){ | |||
dimension = length*colCount*noOfPages | |||
dimension = length*noOfPages | |||
}else{ | |||
dimension = length*colCount | |||
dimension = length | |||
} | |||
return dimension; | |||
} | |||
@@ -134,7 +140,7 @@ export default function SearchPublicNoticeTable({ searchCriteria,}) { | |||
{ | |||
id: 'fee', | |||
field: 'fee', | |||
headerName: 'Amount(HK$)', | |||
headerName: 'Amount($)', | |||
flex: 1, | |||
minWidth: 100, | |||
valueGetter: (params) => { | |||
@@ -19,7 +19,8 @@ import { | |||
DEMAND_NOTE_SEND, | |||
DEMAND_NOTE_ATTACH, | |||
DEMAND_NOTE_MARK_PAID, | |||
DEMAND_NOTE_LIST_ALL | |||
DEMAND_NOTE_LIST_ALL, | |||
DEMAND_NOTE_REVOKE_PAID | |||
} from "utils/ApiPathConst"; | |||
import * as HttpUtils from "utils/HttpUtils"; | |||
import { PNSPS_BUTTON_THEME } from "themes/buttonConst"; | |||
@@ -27,23 +28,26 @@ import { ThemeProvider } from "@emotion/react"; | |||
import { isGrantedAny } from "auth/utils"; | |||
// ==============================|| EVENT TABLE ||============================== // | |||
export default function SearchDemandNote({ searchCriteria, applySearch }) { | |||
export default function SearchDemandNote({ applySearch, searchCriteria, applyGridOnReady }) { | |||
const [isConfirmPopUp, setConfirmPopUp] = useState(false); | |||
const [isRevokePopUp, setRevokePopUp] = useState(false); | |||
const [isSendPopUp, setSendPopUp] = useState(false); | |||
const [isErrorPopUp, setIsErrorPopUp] = useState(false); | |||
const [selectonWarning, setSelectonWarning] = useState(false); | |||
const [wait, setWait] = useState(false); | |||
const [reload, setReload] = useState(new Date()); | |||
const [rows, setRows] = useState([]); | |||
const [_searchCriteria, set_searchCriteria] = useState(searchCriteria); | |||
const [_searchCriteria, set_searchCriteria] = useState({}); | |||
const [selectedRowItems, setSelectedRowItems] = useState([]); | |||
const navigate = useNavigate() | |||
const [onDownload, setOnDownload] = useState(false); | |||
useEffect(() => { | |||
set_searchCriteria(searchCriteria); | |||
}, [searchCriteria]); | |||
const handleDnClick = (params) => () => { | |||
navigate('/paymentPage/demandNote/details/' + params.id); | |||
}; | |||
@@ -83,10 +87,17 @@ export default function SearchDemandNote({ searchCriteria, applySearch }) { | |||
} | |||
const onDownloadClick = (params) => () => { | |||
setOnDownload(true) | |||
HttpUtils.fileDownload({ | |||
fileId: params.row.fileId, | |||
skey: params.row.skey, | |||
filename: params.row.filename, | |||
onResponse:()=>{ | |||
setOnDownload(false) | |||
}, | |||
onError:()=>{ | |||
setOnDownload(false) | |||
} | |||
}); | |||
}; | |||
@@ -109,7 +120,7 @@ export default function SearchDemandNote({ searchCriteria, applySearch }) { | |||
dnIdList: idList | |||
}, | |||
onSuccess: () => { | |||
if (reloadFun) reloadFun(); | |||
setReload(new Date()); | |||
} | |||
}); | |||
@@ -133,13 +144,36 @@ export default function SearchDemandNote({ searchCriteria, applySearch }) { | |||
}, | |||
files: [file], | |||
onSuccess() { | |||
setWait(false); | |||
if (reloadFun) reloadFun(); | |||
setReload(new Date()); | |||
}, | |||
}); | |||
document.getElementById("uploadFileBtn").value = ""; | |||
} | |||
const revokePaid = () => { | |||
setRevokePopUp(false); | |||
let idList = []; | |||
const datas = rows?.filter((row) => | |||
selectedRowItems.includes(row.id) | |||
); | |||
if (datas?.length < 1) { | |||
setSelectonWarning(true); | |||
return; | |||
} | |||
for (var i = 0; i < datas?.length; i++) { | |||
idList.push(datas[i].id); | |||
} | |||
HttpUtils.post({ | |||
url: DEMAND_NOTE_REVOKE_PAID, | |||
params: { | |||
dnIdList: idList | |||
}, | |||
onSuccess: () => { | |||
setReload(new Date()); | |||
} | |||
}); | |||
} | |||
const markPaid = () => { | |||
setConfirmPopUp(false); | |||
let idList = []; | |||
@@ -159,7 +193,7 @@ export default function SearchDemandNote({ searchCriteria, applySearch }) { | |||
dnIdList: idList | |||
}, | |||
onSuccess: () => { | |||
if (reloadFun) reloadFun(); | |||
setReload(new Date()); | |||
} | |||
}); | |||
} | |||
@@ -240,9 +274,11 @@ export default function SearchDemandNote({ searchCriteria, applySearch }) { | |||
width: 300, | |||
renderCell: (params) => { | |||
return (<table> | |||
<tr><td>Issue:</td><td>{DateUtils.dateStr(params?.row.issueDate)}</td></tr> | |||
<tr><td>Due:</td><td>{params?.value ? DateUtils.dateStr(params?.value) : "--"}</td></tr> | |||
<tr><td>Sent:</td><td>{params.row.sentDate ? <> {DateUtils.datetimeStr(params.row.sentDate)} - {params.row.sentBy} </> : <> To be sent</>}</td></tr> | |||
<tbody> | |||
<tr><td>Issue:</td><td>{DateUtils.dateStr(params?.row.issueDate)}</td></tr> | |||
<tr><td>Due:</td><td>{params?.value ? DateUtils.dateStr(params?.value) : "--"}</td></tr> | |||
<tr><td>Sent:</td><td>{params.row.sentDate ? DateUtils.datetimeStr(params.row.sentDate) +" - "+ params.row.sentBy : "To be sent"}</td></tr> | |||
</tbody> | |||
</table>); | |||
} | |||
}, | |||
@@ -254,7 +290,7 @@ export default function SearchDemandNote({ searchCriteria, applySearch }) { | |||
), | |||
width: 280, | |||
renderCell: (params) => { | |||
return <Button onClick={onDownloadClick(params)}><u>{params.row.filename}</u></Button>; | |||
return <Button disabled={onDownload} onClick={onDownloadClick(params)}><u>{params.row.filename}</u></Button>; | |||
}, | |||
}, | |||
{ | |||
@@ -262,7 +298,7 @@ export default function SearchDemandNote({ searchCriteria, applySearch }) { | |||
headerName: 'Status', | |||
width: 175, | |||
renderCell: (params) => { | |||
return [StatusUtils.getStatus_Eng(params)] | |||
return StatusUtils.getStatus_Eng(params) | |||
}, | |||
}, | |||
]; | |||
@@ -300,6 +336,7 @@ export default function SearchDemandNote({ searchCriteria, applySearch }) { | |||
</Button> | |||
</label> | |||
</Grid> | |||
<Grid item sx={{ ml: 3, mr: 3, mb: 3, mt: 3 }}> | |||
<Button | |||
variant="contained" | |||
@@ -334,13 +371,23 @@ export default function SearchDemandNote({ searchCriteria, applySearch }) { | |||
Mark as Paid | |||
</Button> | |||
</Grid> | |||
<Grid item sx={{ ml: 3, mr: 3, mb: 3, mt: 3 }}> | |||
<Button | |||
variant="contained" | |||
onClick={() => setRevokePopUp(true)} | |||
> | |||
Revoke payment | |||
</Button> | |||
</Grid> | |||
</ThemeProvider> | |||
</Grid> | |||
: <></> | |||
} | |||
<Box sx={{ backgroundColor: "#fff", ml: 2 }} width="98%"> | |||
<FiDataGrid | |||
checkboxSelection = {isGrantedAny(["MAINTAIN_DEMANDNOTE"])} | |||
checkboxSelection={isGrantedAny(["MAINTAIN_DEMANDNOTE"])} | |||
disableRowSelectionOnClick | |||
onRowSelectionModelChange={(newSelection) => { | |||
setSelectedRowItems(newSelection); | |||
@@ -349,13 +396,15 @@ export default function SearchDemandNote({ searchCriteria, applySearch }) { | |||
customPageSize={100} | |||
getRowHeight={() => 'auto'} | |||
onRowDoubleClick={handleRowDoubleClick} | |||
applyGridOnReady={applyGridOnReady} | |||
applySearch={applySearch} | |||
doLoad={useMemo(() => ({ | |||
url: DEMAND_NOTE_LIST_ALL, | |||
params: _searchCriteria, | |||
callback: function (responseData) { | |||
setRows(responseData?.records); | |||
} | |||
}), [_searchCriteria])} | |||
}), [_searchCriteria, reload])} | |||
/> | |||
</Box> | |||
<div> | |||
@@ -422,6 +471,28 @@ export default function SearchDemandNote({ searchCriteria, applySearch }) { | |||
</DialogActions> | |||
</Dialog> | |||
</div> | |||
<div> | |||
<Dialog | |||
open={isRevokePopUp} | |||
onClose={() => setRevokePopUp(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="h3">Confirm</Typography></DialogTitle> | |||
<DialogContent style={{ display: 'flex', }}> | |||
<Typography variant="h4" style={{ padding: '16px' }}>Are you sure to revoke DN as To Be Paid?</Typography> | |||
</DialogContent> | |||
<DialogActions> | |||
<Button onClick={() => setRevokePopUp(false)}><Typography variant="h5">Cancel</Typography></Button> | |||
<Button onClick={() => revokePaid()}><Typography variant="h5">Confirm</Typography></Button> | |||
</DialogActions> | |||
</Dialog> | |||
</div> | |||
<div> | |||
<Dialog | |||
open={isSendPopUp} | |||
@@ -21,7 +21,7 @@ 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"; | |||
// ==============================|| DASHBOARD - DEFAULT ||============================== // | |||
const SearchDemandNoteForm = ({ applySearch, orgComboData, searchCriteria, issueComboData | |||
const SearchDemandNoteForm = ({ applySearch, orgComboData, searchCriteria, issueComboData, onGridReady | |||
}) => { | |||
const [type, setType] = React.useState([]); | |||
@@ -44,6 +44,28 @@ const SearchDemandNoteForm = ({ applySearch, orgComboData, searchCriteria, issue | |||
const intl = useIntl(); | |||
const { locale } = intl; | |||
React.useEffect(() => { | |||
if(searchCriteria.status!=undefined){ | |||
if(searchCriteria.status === ""){ | |||
ComboData.denmandNoteStatus[0] | |||
}else{ | |||
setSelectedStatus(ComboData.denmandNoteStatus.find(item => item.type === searchCriteria.status)) | |||
} | |||
if(searchCriteria.dueDateFrom != ""){ | |||
setMinDueDate(DateUtils.dateValue(searchCriteria.dueDateFrom)) | |||
}else{ | |||
setMinDueDate(null) | |||
} | |||
if(searchCriteria.dueDateTo != ""){ | |||
setMaxDueDate(DateUtils.dateValue(searchCriteria.dueDateTo)) | |||
}else{ | |||
setMaxDueDate(null); | |||
} | |||
}else{ | |||
setSelectedStatus(ComboData.denmandNoteStatus[0]) | |||
} | |||
}, [searchCriteria]); | |||
React.useEffect(() => { | |||
setFromDateValue(minDate); | |||
}, [minDate]); | |||
@@ -101,12 +123,18 @@ const SearchDemandNoteForm = ({ applySearch, orgComboData, searchCriteria, issue | |||
React.useEffect(() => { | |||
if (orgComboData && orgComboData.length > 0) { | |||
setOrgCombo(orgComboData); | |||
if(searchCriteria.orgId!=undefined){ | |||
setOrgSelected(orgComboData.find(item => item.key === searchCriteria.orgId)) | |||
} | |||
} | |||
}, [orgComboData]); | |||
React.useEffect(() => { | |||
if (issueComboData && issueComboData.length > 0) { | |||
setIssueCombo(issueComboData); | |||
if(searchCriteria.issueId!=undefined){ | |||
setIssueSelected(issueComboData.find(item => item.id === searchCriteria.issueId)) | |||
} | |||
} | |||
}, [issueComboData]); | |||
@@ -117,9 +145,13 @@ const SearchDemandNoteForm = ({ applySearch, orgComboData, searchCriteria, issue | |||
setSelectedStatus(ComboData.denmandNoteStatus[0]); | |||
setMinDueDate(null); | |||
setMaxDueDate(null); | |||
setMinDate(searchCriteria.dateFrom); | |||
setMaxDate(searchCriteria.dateTo); | |||
reset(); | |||
setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14))) | |||
setMaxDate(DateUtils.dateValue(new Date())) | |||
reset({ | |||
appNo:"", | |||
dnNo:"", | |||
}); | |||
localStorage.setItem('searchCriteria',"") | |||
} | |||
function getIssueLabel(data) { | |||
@@ -209,10 +241,12 @@ const SearchDemandNoteForm = ({ applySearch, orgComboData, searchCriteria, issue | |||
disablePortal | |||
id="orgId" | |||
options={orgCombo} | |||
groupBy={(option) => option.groupType} | |||
size="small" | |||
value={orgSelected} | |||
getOptionLabel={(option) => option.name? option.name : ""} | |||
inputValue={orgSelected ? orgSelected.name : ""} | |||
inputValue={orgSelected ? orgSelected.name!=undefined?orgSelected.name:"" : ""} | |||
onChange={(event, newValue) => { | |||
if (newValue !== null) { | |||
setOrgSelected(newValue); | |||
@@ -228,12 +262,19 @@ const SearchDemandNoteForm = ({ applySearch, orgComboData, searchCriteria, issue | |||
}} | |||
/> | |||
)} | |||
renderGroup={(params) => ( | |||
<Grid item key={params.key}> | |||
<Typography fontSize={20} fontStyle="italic" p={1}> | |||
{params.group} | |||
</Typography> | |||
{params.children} | |||
</Grid> | |||
)} | |||
/> | |||
</Grid> | |||
: <></> | |||
} | |||
<Grid item xs={9} s={6} md={5} lg={3} sx={{ ml: 3, mr: 3, mb: 3 }}> | |||
<TextField | |||
fullWidth | |||
@@ -411,6 +452,7 @@ const SearchDemandNoteForm = ({ applySearch, orgComboData, searchCriteria, issue | |||
<Button | |||
variant="contained" | |||
type="submit" | |||
disabled={onGridReady} | |||
> | |||
Submit | |||
</Button> | |||
@@ -10,6 +10,7 @@ import * as React from "react"; | |||
import * as UrlUtils from "utils/ApiPathConst"; | |||
import * as HttpUtils from "utils/HttpUtils"; | |||
import * as DateUtils from "utils/DateUtils"; | |||
import { getSearchCriteria } from "auth/utils"; | |||
import Loadable from 'components/Loadable'; | |||
const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | |||
@@ -35,16 +36,26 @@ const UserSearchPage_Individual = () => { | |||
const [orgCombo, setOrgCombo] = React.useState([]); | |||
const [issueCombo, setIssueCombo] = React.useState([]); | |||
const [searchCriteria, setSearchCriteria] = React.useState({ | |||
dateTo: 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)), | |||
// dueDateTo: DateUtils.dateValue(new Date()), | |||
// dueDateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate() - 14)), | |||
}); | |||
const [onReady, setOnReady] = React.useState(false); | |||
const [onGridReady, setGridOnReady] = React.useState(false); | |||
React.useEffect(() => { | |||
getOrgCombo(); | |||
getIssueCombo(); | |||
if (Object.keys(getSearchCriteria(window.location.pathname)).length>0){ | |||
setSearchCriteria(getSearchCriteria(window.location.pathname)) | |||
}else{ | |||
localStorage.setItem('searchCriteria',"") | |||
setSearchCriteria({ | |||
dateTo: DateUtils.dateValue(new Date()), | |||
dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)), | |||
}) | |||
} | |||
}, []); | |||
React.useEffect(() => { | |||
@@ -72,9 +83,14 @@ const UserSearchPage_Individual = () => { | |||
}); | |||
} | |||
function applySearch(input) { | |||
setGridOnReady(true) | |||
setSearchCriteria(input); | |||
localStorage.setItem('searchCriteria', JSON.stringify({path:window.location.pathname,data:input})) | |||
} | |||
function applyGridOnReady(input) { | |||
setGridOnReady(input); | |||
} | |||
return ( | |||
@@ -102,7 +118,7 @@ const UserSearchPage_Individual = () => { | |||
orgComboData={orgCombo} | |||
issueComboData={issueCombo} | |||
searchCriteria={searchCriteria} | |||
onGridReady={onGridReady} | |||
/> | |||
</Grid> | |||
{/*row 2*/} | |||
@@ -115,6 +131,7 @@ const UserSearchPage_Individual = () => { | |||
<EventTable | |||
applySearch={applySearch} | |||
searchCriteria={searchCriteria} | |||
applyGridOnReady={applyGridOnReady} | |||
/> | |||
</MainCard> | |||
</Grid> | |||
@@ -15,11 +15,12 @@ import {useIntl} from "react-intl"; | |||
import {DEMAND_NOTE_LIST} from "utils/ApiPathConst"; | |||
// ==============================|| EVENT TABLE ||============================== // | |||
export default function SearchDemandNote({ searchCriteria }) { | |||
export default function SearchDemandNote({ searchCriteria, applyGridOnReady,applySearch }) { | |||
const intl = useIntl(); | |||
const theme = useTheme(); | |||
const isMdOrLg = useMediaQuery(theme.breakpoints.up('md')); | |||
const { locale } = intl; | |||
const [_searchCriteria, set_searchCriteria] = React.useState(searchCriteria); | |||
@@ -52,7 +53,7 @@ export default function SearchDemandNote({ searchCriteria }) { | |||
{ | |||
id: 'issueDate', | |||
field: 'issueDate', | |||
headerName: intl.formatMessage({id: 'receiptDate'}), | |||
headerName: intl.formatMessage({id: 'sendDate'}), | |||
width: isMdOrLg ? 'auto' : 175, | |||
flex: isMdOrLg ? 1 : undefined, | |||
valueGetter: (params) => { | |||
@@ -65,12 +66,13 @@ export default function SearchDemandNote({ searchCriteria }) { | |||
width: isMdOrLg ? 'auto' : 175, | |||
flex: isMdOrLg ? 1 : undefined, | |||
renderCell: (params) => { | |||
return [StatusUtils.getStatus_Cht(params)] | |||
return [StatusUtils.getStatus_i18n(params, locale) ] | |||
}, | |||
}, | |||
{ | |||
field: 'sentDate', | |||
headerName: intl.formatMessage({id: 'sendDate'}), | |||
headerName: intl.formatMessage({id: 'sendDateTime'}), | |||
width: isMdOrLg ? 'auto' : 200, | |||
flex: isMdOrLg ? 1 : undefined, | |||
valueGetter: (params) => { | |||
@@ -95,10 +97,16 @@ export default function SearchDemandNote({ searchCriteria }) { | |||
columns={columns} | |||
customPageSize={10} | |||
getRowHeight={() => 'auto'} | |||
doLoad={{ | |||
applyGridOnReady={applyGridOnReady} | |||
applySearch={applySearch} | |||
// doLoad={{ | |||
// url: DEMAND_NOTE_LIST, | |||
// params: _searchCriteria, | |||
// }} | |||
doLoad={React.useMemo(() => ({ | |||
url: DEMAND_NOTE_LIST, | |||
params: _searchCriteria, | |||
}} | |||
}), [_searchCriteria])} | |||
/> | |||
</Box> | |||
</div> | |||
@@ -22,7 +22,7 @@ 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"; | |||
// ==============================|| DASHBOARD - DEFAULT ||============================== // | |||
const SearchDemandNoteForm = ({ applySearch, searchCriteria, issueComboData | |||
const SearchDemandNoteForm = ({ applySearch, searchCriteria, issueComboData, onGridReady | |||
}) => { | |||
const intl = useIntl(); | |||
@@ -38,6 +38,18 @@ const SearchDemandNoteForm = ({ applySearch, searchCriteria, issueComboData | |||
const [fromDateValue, setFromDateValue] = React.useState("dd / mm / yyyy"); | |||
const [toDateValue, setToDateValue] = React.useState("dd / mm / yyyy"); | |||
React.useEffect(() => { | |||
if(searchCriteria.status!=undefined){ | |||
if(searchCriteria.status === ""){ | |||
ComboData.denmandNoteStatus_Public[0] | |||
}else{ | |||
setSelectedStatus(ComboData.denmandNoteStatus_Public.find(item => item.type === searchCriteria.status)) | |||
} | |||
}else{ | |||
setSelectedStatus(ComboData.denmandNoteStatus_Public[0]) | |||
} | |||
}, [searchCriteria]); | |||
React.useEffect(() => { | |||
setFromDateValue(minDate); | |||
}, [minDate]); | |||
@@ -76,17 +88,23 @@ const SearchDemandNoteForm = ({ applySearch, searchCriteria, issueComboData | |||
React.useEffect(() => { | |||
if (issueComboData && issueComboData.length > 0) { | |||
setIssueCombo(issueComboData); | |||
if(searchCriteria.issueId!=undefined){ | |||
setIssueSelected(issueComboData.find(item => item.id === searchCriteria.issueId)) | |||
} | |||
} | |||
}, [issueComboData]); | |||
function resetForm() { | |||
setType([]); | |||
// setStatus({ key: 0, label: 'All', type: 'all' }); | |||
setSelectedStatus(ComboData.denmandNoteStatus_Public[0]); | |||
// setOrgSelected({}); | |||
setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14))) | |||
setMaxDate(DateUtils.dateValue(new Date())) | |||
setIssueSelected({}); | |||
reset(); | |||
reset({ | |||
appNo:"", | |||
dnNo:"", | |||
}); | |||
} | |||
function getIssueLabel(data) { | |||
@@ -246,6 +264,7 @@ const SearchDemandNoteForm = ({ applySearch, searchCriteria, issueComboData | |||
{...register("status")} | |||
id="status" | |||
size="small" | |||
disableClearable | |||
options={ComboData.denmandNoteStatus_Public} | |||
getOptionLabel={(option) => option?.i18nLabel ? intl.formatMessage({ id: option.i18nLabel }) : ""} | |||
inputValue={selectedStatus?.i18nLabel ? intl.formatMessage({ id: selectedStatus.i18nLabel }) : ""} | |||
@@ -288,6 +307,7 @@ const SearchDemandNoteForm = ({ applySearch, searchCriteria, issueComboData | |||
<Button | |||
variant="contained" | |||
type="submit" | |||
disabled={onGridReady} | |||
> | |||
<FormattedMessage id="submit" /> | |||
</Button> | |||
@@ -10,6 +10,7 @@ import * as React from "react"; | |||
import {GET_ORG_COMBO, GET_ISSUE_COMBO} from "utils/ApiPathConst"; | |||
import * as HttpUtils from "utils/HttpUtils"; | |||
import * as DateUtils from "utils/DateUtils"; | |||
import { getSearchCriteria } from "auth/utils"; | |||
import Loadable from 'components/Loadable'; | |||
const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | |||
@@ -34,15 +35,22 @@ const SearchPage_DemandNote_Pub = () => { | |||
const [orgCombo, setOrgCombo] = React.useState([]); | |||
const [issueCombo, setIssueCombo] = React.useState([]); | |||
const [searchCriteria, setSearchCriteria] = React.useState({ | |||
dateTo: DateUtils.dateValue(new Date()), | |||
dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate() - 14)), | |||
}); | |||
const [searchCriteria, setSearchCriteria] = React.useState({}); | |||
const [onReady, setOnReady] = React.useState(false); | |||
const [onGridReady, setGridOnReady] = React.useState(false); | |||
React.useEffect(() => { | |||
getOrgCombo(); | |||
getIssueCombo(); | |||
if (Object.keys(getSearchCriteria(window.location.pathname)).length>0){ | |||
setSearchCriteria(getSearchCriteria(window.location.pathname)) | |||
}else{ | |||
localStorage.setItem('searchCriteria',"") | |||
setSearchCriteria({ | |||
dateTo: DateUtils.dateValue(new Date()), | |||
dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)), | |||
}) | |||
} | |||
}, []); | |||
React.useEffect(() => { | |||
@@ -72,7 +80,13 @@ const SearchPage_DemandNote_Pub = () => { | |||
function applySearch(input) { | |||
setGridOnReady(true) | |||
setSearchCriteria(input); | |||
localStorage.setItem('searchCriteria', JSON.stringify({path:window.location.pathname,data:input})) | |||
} | |||
function applyGridOnReady(input) { | |||
setGridOnReady(input); | |||
} | |||
return ( | |||
@@ -100,6 +114,7 @@ const SearchPage_DemandNote_Pub = () => { | |||
orgComboData={orgCombo} | |||
issueComboData={issueCombo} | |||
searchCriteria={searchCriteria} | |||
onGridReady={onGridReady} | |||
/> | |||
</Grid> | |||
{/*row 2*/} | |||
@@ -110,7 +125,9 @@ const SearchPage_DemandNote_Pub = () => { | |||
sx={{ backgroundColor: '#fff' }} | |||
> | |||
<EventTable | |||
searchCriteria={searchCriteria} | |||
searchCriteria={searchCriteria} | |||
applyGridOnReady={applyGridOnReady} | |||
applySearch={applySearch} | |||
/> | |||
</MainCard> | |||
</Grid> | |||
@@ -50,7 +50,7 @@ const Index = () => { | |||
axios.get(`${UrlUtils.GET_EMAIL}/${params.id}`) | |||
.then((response) => { | |||
if (response.status === 200) { | |||
console.log(response) | |||
// console.log(response) | |||
setRecord(response.data.data) | |||
} | |||
}) | |||
@@ -95,14 +95,14 @@ const Index = () => { | |||
console.log(error); | |||
return false; | |||
}); | |||
console.log(data) | |||
// console.log(data) | |||
} | |||
const handleDelete = () => { | |||
axios.delete(`${UrlUtils.DELETE_EMAIL}/${params.id}`, | |||
) | |||
.then((response) => { | |||
console.log(response) | |||
// console.log(response) | |||
if (response.status === 204) { | |||
// location.reload(); | |||
navigate('/setting/emailTemplate'); | |||
@@ -97,10 +97,14 @@ export default function EmailTemplateTable({ responseData }) { | |||
customPageSize={10} | |||
onRowDoubleClick={handleRowDoubleClick} | |||
getRowHeight={() => 'auto'} | |||
doLoad={{ | |||
url:GET_EMAIL_LIST, | |||
params: _responseData | |||
}} | |||
// doLoad={{ | |||
// url:GET_EMAIL_LIST, | |||
// params: _responseData | |||
// }} | |||
doLoad={React.useMemo(() => ({ | |||
url: GET_EMAIL_LIST, | |||
params: _responseData, | |||
}), [_responseData])} | |||
/> | |||
</div> | |||
); |
@@ -6,7 +6,7 @@ import { useNavigate } from "react-router-dom"; | |||
import { FiDataGrid } from "components/FiDataGrid"; | |||
// ==============================|| EVENT TABLE ||============================== // | |||
export default function SearchTable({ searchCriteria }) { | |||
export default function SearchTable({ searchCriteria, applyGridOnReady }) { | |||
const [_searchCriteria, set_searchCriteria] = React.useState(searchCriteria); | |||
const navigate = useNavigate() | |||
// const [rows, setRows] = React.useState([]); | |||
@@ -67,6 +67,7 @@ export default function SearchTable({ searchCriteria }) { | |||
columns={columns} | |||
customPageSize={10} | |||
onRowDoubleClick={handleEditClick} | |||
applyGridOnReady={applyGridOnReady} | |||
doLoad={React.useMemo(() => ({ | |||
url: GFIMIS_LIST, | |||
params: _searchCriteria, | |||
@@ -21,7 +21,7 @@ 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"; | |||
// ==============================|| DASHBOARD - DEFAULT ||============================== // | |||
const SearchPublicNoticeForm = ({ applySearch, generateXML, searchCriteria }) => { | |||
const SearchPublicNoticeForm = ({ applySearch, generateXML, searchCriteria, onGridReady }) => { | |||
// const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom); | |||
const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom); | |||
@@ -146,6 +146,7 @@ const SearchPublicNoticeForm = ({ applySearch, generateXML, searchCriteria }) => | |||
<Button | |||
variant="contained" | |||
type="submit" | |||
disabled={onGridReady} | |||
> | |||
Preview | |||
</Button> | |||
@@ -35,6 +35,7 @@ const Index = () => { | |||
// dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)), | |||
}); | |||
const [onReady, setOnReady] = React.useState(false); | |||
const [onGridReady, setGridOnReady] = React.useState(false); | |||
React.useEffect(() => { | |||
setOnReady(true); | |||
@@ -50,7 +51,7 @@ const Index = () => { | |||
dateFrom: input.dateFrom, | |||
}, | |||
onSuccess: (responseData) => { | |||
console.log(responseData) | |||
// console.log(responseData) | |||
const parser = new DOMParser(); | |||
const xmlDoc = parser.parseFromString(responseData, 'application/xml'); | |||
// Get the DCBHeader element | |||
@@ -75,7 +76,7 @@ const Index = () => { | |||
const updatedXmlString = new XMLSerializer().serializeToString(xmlDoc); | |||
const filename = xmlDoc.querySelector('FileHeader').getAttribute('H_Filename'); | |||
console.log(updatedXmlString) | |||
// console.log(updatedXmlString) | |||
const blob = new Blob([updatedXmlString], { type: 'application/xml' }); | |||
// Create a download link | |||
const link = document.createElement('a'); | |||
@@ -97,9 +98,14 @@ const Index = () => { | |||
function applySearch(input) { | |||
setGridOnReady(true) | |||
setSearchCriteria(input); | |||
} | |||
function applyGridOnReady(input) { | |||
setGridOnReady(input); | |||
} | |||
function generateXML(input) { | |||
downloadXML(input); | |||
} | |||
@@ -121,9 +127,10 @@ const Index = () => { | |||
{/*row 1*/} | |||
<Grid item xs={12} md={12} lg={12} sx={{mb:-1}}> | |||
<SearchForm | |||
applySearch={applySearch} | |||
generateXML={generateXML} | |||
searchCriteria={searchCriteria} | |||
applySearch={applySearch} | |||
generateXML={generateXML} | |||
searchCriteria={searchCriteria} | |||
onGridReady={onGridReady} | |||
/> | |||
</Grid> | |||
{/*row 2*/} | |||
@@ -135,6 +142,8 @@ const Index = () => { | |||
> | |||
<EventTable | |||
searchCriteria={searchCriteria} | |||
applyGridOnReady={applyGridOnReady} | |||
applySearch={applySearch} | |||
/> | |||
</MainCard> | |||
</Grid> | |||
@@ -7,7 +7,7 @@ import {GET_ISSUE} from "utils/ApiPathConst"; | |||
// ==============================|| EVENT TABLE ||============================== // | |||
export default function GazetteIssueTable({ searchCriteria }) { | |||
export default function GazetteIssueTable({ searchCriteria, applyGridOnReady }) { | |||
const [_searchCriteria, set_searchCriteria] = React.useState(searchCriteria); | |||
React.useEffect(() => { | |||
@@ -100,10 +100,15 @@ export default function GazetteIssueTable({ searchCriteria }) { | |||
customPageSize={10} | |||
// onRowDoubleClick={handleRowDoubleClick} | |||
getRowHeight={() => 'auto'} | |||
doLoad={{ | |||
applyGridOnReady={applyGridOnReady} | |||
// doLoad={{ | |||
// url: GET_ISSUE, | |||
// params: _searchCriteria, | |||
// }} | |||
doLoad={React.useMemo(() => ({ | |||
url: GET_ISSUE, | |||
params: _searchCriteria, | |||
}} | |||
}), [_searchCriteria])} | |||
/> | |||
</div> | |||
); |
@@ -27,9 +27,9 @@ const SearchGazetteIssueForm = ({ applyExport, comboData, waitDownload}) => { | |||
handleSubmit } = useForm() | |||
const onSubmit = () => { | |||
console.log(selectedYear) | |||
// console.log(selectedYear) | |||
if (selectedYear !=null && Object.keys(selectedYear).length>0){ | |||
console.log("okkkkkkkkkkkkkkkk") | |||
// console.log("okkkkkkkkkkkkkkkk") | |||
const temp = { | |||
year: selectedYear.label, | |||
}; | |||
@@ -16,7 +16,7 @@ import {ThemeProvider} from "@emotion/react"; | |||
// ==============================|| DASHBOARD - DEFAULT ||============================== // | |||
const SearchGazetteIssueForm = ({ applySearch, comboData}) => { | |||
const SearchGazetteIssueForm = ({ applySearch, comboData, onGridReady}) => { | |||
const [selectedYear, setSelectedYear] = React.useState([]); | |||
// const [defaultYear, setDefaultYear] = React.useState(searchCriteria.year); | |||
const [comboList, setComboList] = React.useState([]); | |||
@@ -114,6 +114,7 @@ const SearchGazetteIssueForm = ({ applySearch, comboData}) => { | |||
<Button | |||
variant="contained" | |||
type="submit" | |||
disabled={onGridReady} | |||
> | |||
Search | |||
</Button> | |||
@@ -31,6 +31,7 @@ import {PNSPS_LONG_BUTTON_THEME} from "themes/buttonConst"; | |||
import {ThemeProvider} from "@emotion/react"; | |||
import { dateStr_Year } from "utils/DateUtils"; | |||
import { notifySaveSuccess } from 'utils/CommonFunction'; | |||
import { isGrantedAny } from "auth/utils"; | |||
// ==============================|| DASHBOARD - DEFAULT ||============================== // | |||
@@ -38,6 +39,8 @@ const Index = () => { | |||
const [comboData, setComboData] = React.useState([]); | |||
const [holidayComboData, setHolidayComboData] = React.useState([]); | |||
const [onReady, setOnReady] = React.useState(false); | |||
const [onGridReady, setGridOnReady] = React.useState(false); | |||
const [onSearchReady, setOnSearchReady] = React.useState(false); | |||
const [onExportReady, setOnExportReady] = React.useState(false); | |||
const [searchCriteria, setSearchCriteria] = React.useState({ | |||
@@ -89,6 +92,7 @@ const Index = () => { | |||
} | |||
function applySearch(input) { | |||
setGridOnReady(true) | |||
setSearchCriteria(input); | |||
} | |||
@@ -96,6 +100,10 @@ const Index = () => { | |||
setExportCriteria(input); | |||
} | |||
function applyGridOnReady(input) { | |||
setGridOnReady(input); | |||
} | |||
React.useEffect(() => { | |||
if (Object.keys(exportCriteria).length > 0) { | |||
// console.log(exportCriteria) | |||
@@ -185,40 +193,43 @@ const Index = () => { | |||
/> | |||
</Grid> | |||
} | |||
<Grid item xs={12} md={12} lg={6} width="100%"> | |||
<Stack direction="row" justifyContent="flex-start" alignItems="center" spacing={2} sx={{ml:2,mt:1}} > | |||
<ThemeProvider theme={PNSPS_LONG_BUTTON_THEME}> | |||
<input | |||
id="uploadFileBtn" | |||
name="file" | |||
type="file" | |||
accept=".xlsx" | |||
style={{ display: 'none' }} | |||
disabled={waitImport} | |||
onChange={(event) => { | |||
readFile(event) | |||
}} | |||
/> | |||
<label htmlFor="uploadFileBtn"> | |||
<Button | |||
component="span" | |||
variant="contained" | |||
size="large" | |||
{isGrantedAny(["MAINTAIN_GAZETTE_ISSUE"]) ? | |||
<Grid item xs={12} md={12} lg={6} width="100%"> | |||
<Stack direction="row" justifyContent="flex-start" alignItems="center" spacing={2} sx={{ml:2,mt:1}} > | |||
<ThemeProvider theme={PNSPS_LONG_BUTTON_THEME}> | |||
<input | |||
id="uploadFileBtn" | |||
name="file" | |||
type="file" | |||
accept=".xlsx" | |||
style={{ display: 'none' }} | |||
disabled={waitImport} | |||
> | |||
<Typography variant="h5">Upload Files</Typography> | |||
</Button> | |||
</label> | |||
</ThemeProvider> | |||
</Stack> | |||
</Grid> | |||
onChange={(event) => { | |||
readFile(event) | |||
}} | |||
/> | |||
<label htmlFor="uploadFileBtn"> | |||
<Button | |||
component="span" | |||
variant="contained" | |||
size="large" | |||
disabled={waitImport} | |||
> | |||
<Typography variant="h5">Upload Files</Typography> | |||
</Button> | |||
</label> | |||
</ThemeProvider> | |||
</Stack> | |||
</Grid> | |||
:null | |||
} | |||
{/*row 1*/} | |||
<Grid item xs={12} md={12} lg={12} width="100%"> | |||
<SearchForm | |||
applySearch={applySearch} | |||
comboData={comboData} | |||
onGridReady={onGridReady} | |||
/> | |||
</Grid> | |||
{/*row 2*/} | |||
@@ -230,7 +241,8 @@ const Index = () => { | |||
content={false} | |||
> | |||
<GazetteIssueTable | |||
searchCriteria={searchCriteria} | |||
searchCriteria={searchCriteria} | |||
applyGridOnReady={applyGridOnReady} | |||
/> | |||
</MainCard> | |||
</Grid> | |||
@@ -9,13 +9,13 @@ import { dateStr } from "utils/DateUtils"; | |||
// ==============================|| EVENT TABLE ||============================== // | |||
export default function HolidayTable({ recordList }) { | |||
export default function HolidayTable({ recordList, applyGridOnReady }) { | |||
const [rows, setRows] = React.useState(recordList); | |||
// const navigate = useNavigate() | |||
useEffect(() => { | |||
console.log(recordList) | |||
// console.log(recordList) | |||
setRows(recordList.records); | |||
}, [recordList]); | |||
@@ -48,8 +48,13 @@ export default function HolidayTable({ recordList }) { | |||
rows={rows} | |||
columns={columns} | |||
customPageSize={20} | |||
applyGridOnReady={applyGridOnReady} | |||
// onRowDoubleClick={handleRowDoubleClick} | |||
getRowHeight={() => 'auto'} | |||
// doLoad={React.useMemo(() => ({ | |||
// url: LIST_PROOF, | |||
// params: _searchCriteria, | |||
// }), [_searchCriteria])} | |||
/> | |||
</div> | |||
); |
@@ -16,7 +16,7 @@ import {ThemeProvider} from "@emotion/react"; | |||
// ==============================|| DASHBOARD - DEFAULT ||============================== // | |||
const SearchHolidayForm = ({ applySearch, comboData}) => { | |||
const SearchHolidayForm = ({ applySearch, comboData, onGridReady}) => { | |||
const [selectedYear, setSelectedYear] = React.useState([]); | |||
// const [defaultYear, setDefaultYear] = React.useState(searchCriteria.year); | |||
const [comboList, setComboList] = React.useState([]); | |||
@@ -114,6 +114,7 @@ const SearchHolidayForm = ({ applySearch, comboData}) => { | |||
<Button | |||
variant="contained" | |||
type="submit" | |||
disabled={onGridReady} | |||
> | |||
Search | |||
</Button> | |||
@@ -32,6 +32,7 @@ import {PNSPS_LONG_BUTTON_THEME} from "themes/buttonConst"; | |||
import {ThemeProvider} from "@emotion/react"; | |||
import { dateStr_Year } from "utils/DateUtils"; | |||
import { notifySaveSuccess } from 'utils/CommonFunction'; | |||
import { isGrantedAny } from "auth/utils"; | |||
// ==============================|| DASHBOARD - DEFAULT ||============================== // | |||
@@ -41,6 +42,8 @@ const Index = () => { | |||
const [comboData, setComboData] = React.useState([]); | |||
const [onReady, setOnReady] = React.useState(false); | |||
const [onSearchReady, setOnSearchReady] = React.useState(false); | |||
const [onGridReady, setGridOnReady] = React.useState(false); | |||
// const navigate = useNavigate() | |||
const [searchCriteria, setSearchCriteria] = React.useState({ | |||
year: dateStr_Year(new Date()), | |||
@@ -97,9 +100,14 @@ const Index = () => { | |||
} | |||
function applySearch(input) { | |||
setGridOnReady(true) | |||
setSearchCriteria(input); | |||
} | |||
function applyGridOnReady(input) { | |||
setGridOnReady(input); | |||
} | |||
React.useEffect(() => { | |||
if (attachments.length > 0) { | |||
importHoliday(); | |||
@@ -187,31 +195,32 @@ const Index = () => { | |||
</Button> | |||
</label> | |||
</ThemeProvider> | |||
<ThemeProvider theme={PNSPS_LONG_BUTTON_THEME}> | |||
<input | |||
id="uploadFileBtn" | |||
name="file" | |||
type="file" | |||
accept=".xlsx" | |||
style={{ display: 'none' }} | |||
disabled={waitImport} | |||
onChange={(event) => { | |||
readFile(event) | |||
}} | |||
/> | |||
<label htmlFor="uploadFileBtn"> | |||
<Button | |||
component="span" | |||
variant="contained" | |||
size="large" | |||
{isGrantedAny(["MAINTAIN_GAZETTE_ISSUE"]) ? | |||
<ThemeProvider theme={PNSPS_LONG_BUTTON_THEME}> | |||
<input | |||
id="uploadFileBtn" | |||
name="file" | |||
type="file" | |||
accept=".xlsx" | |||
style={{ display: 'none' }} | |||
disabled={waitImport} | |||
> | |||
<Typography variant="h5">Upload Files</Typography> | |||
</Button> | |||
</label> | |||
</ThemeProvider> | |||
onChange={(event) => { | |||
readFile(event) | |||
}} | |||
/> | |||
<label htmlFor="uploadFileBtn"> | |||
<Button | |||
component="span" | |||
variant="contained" | |||
size="large" | |||
disabled={waitImport} | |||
> | |||
<Typography variant="h5">Upload Files</Typography> | |||
</Button> | |||
</label> | |||
</ThemeProvider> | |||
:null | |||
} | |||
</Stack> | |||
</Grid> | |||
@@ -222,6 +231,7 @@ const Index = () => { | |||
// generateXML={generateXML} | |||
searchCriteria={searchCriteria} | |||
comboData={comboData} | |||
onGridReady={onGridReady} | |||
/> | |||
</Grid> | |||
{/*row 2*/} | |||
@@ -234,6 +244,7 @@ const Index = () => { | |||
> | |||
<HolidayTable | |||
recordList={record} | |||
applyGridOnReady={applyGridOnReady} | |||
/> | |||
</MainCard> | |||
</Grid> | |||
@@ -0,0 +1,121 @@ | |||
// import { useState } from 'react'; | |||
// material-ui | |||
import { | |||
Grid, | |||
Typography, | |||
Stack, | |||
Paper, | |||
Box, | |||
CircularProgress, | |||
Button | |||
} from '@mui/material'; | |||
import * as React from "react"; | |||
import { GET_JVM_INFO } from "utils/ApiPathConst"; | |||
import axios from "axios"; | |||
import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' | |||
const JVMDefault = () => { | |||
const [jvmInfo, setJvmInfo] = React.useState(null); | |||
const [loading, setLoading] = React.useState(true); | |||
const [error, setError] = React.useState(null); | |||
const fetchJvmInfo = () => { | |||
setLoading(true); | |||
setError(null); | |||
axios.get(`${GET_JVM_INFO}`) | |||
.then((response) => { | |||
if (response.status === 200) { | |||
console.log(response) | |||
setJvmInfo(response.data); | |||
} | |||
}) | |||
.catch(error => { | |||
setError(error); | |||
setLoading(false); | |||
}); | |||
}; | |||
React.useEffect(() => { | |||
localStorage.setItem('searchCriteria', ""); | |||
setLoading(false); | |||
}, []); | |||
React.useEffect(() => { | |||
if(jvmInfo != null) { | |||
if (Object.keys(jvmInfo).length > 0 && jvmInfo !== undefined) { | |||
setLoading(false); | |||
} | |||
} | |||
}, [jvmInfo]); | |||
const BackgroundHead = { | |||
backgroundImage: `url(${titleBackgroundImg})`, | |||
width: '100%', | |||
height: '100%', | |||
backgroundSize: 'contain', | |||
backgroundRepeat: 'no-repeat', | |||
backgroundColor: '#0C489E', | |||
backgroundPosition: 'right' | |||
}; | |||
return ( | |||
<Grid container sx={{ minHeight: '87vh', backgroundColor: "backgroundColor.default" }} direction="column"> | |||
<Grid item xs={12}> | |||
<div style={BackgroundHead}> | |||
<Stack direction="row" height='70px' justifyContent="space-between" alignItems="center"> | |||
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0C489E" }}> | |||
JVM Information | |||
</Typography> | |||
</Stack> | |||
</div> | |||
</Grid> | |||
<Grid item xs={12} ml={15} mb={2} mt={2}> | |||
<Button | |||
size="large" | |||
variant="contained" | |||
type="submit" | |||
sx={{ | |||
textTransform: 'capitalize', | |||
alignItems: 'end' | |||
}} | |||
onClick={fetchJvmInfo} | |||
disabled={loading} | |||
> | |||
<Typography variant="h5">JVM Info</Typography> | |||
</Button> | |||
</Grid> | |||
<Grid item xs={12} ml={15} mb={2} mt={2}> | |||
<Paper elevation={3} sx={{ p: 2, bgcolor: 'background.paper' }}> | |||
{loading ? ( | |||
<Box display="flex" justifyContent="center" alignItems="center" minHeight={200}> | |||
<CircularProgress /> | |||
</Box> | |||
) : error ? ( | |||
<Typography color="error">Error: {error.message}</Typography> | |||
) : jvmInfo ? ( | |||
<Box | |||
component="pre" | |||
sx={{ | |||
p: 2, | |||
borderRadius: 1, | |||
bgcolor: 'grey.100', | |||
overflow: 'auto', | |||
maxHeight: 400, | |||
fontSize: '0.875rem', | |||
lineHeight: 1.6 | |||
}} | |||
> | |||
{JSON.stringify(jvmInfo, null, 2)} | |||
</Box> | |||
) : ( | |||
<Typography>No data available</Typography> | |||
)} | |||
</Paper> | |||
</Grid> | |||
</Grid> | |||
); | |||
}; | |||
export default JVMDefault; |
@@ -5,13 +5,21 @@ import { useNavigate } from "react-router-dom"; | |||
import { FiDataGrid } from "components/FiDataGrid"; | |||
import {useIntl} from "react-intl"; | |||
import { clickableLink } from 'utils/CommonFunction'; | |||
import {GET_MSG_LIST} from "utils/ApiPathConst"; | |||
// ==============================|| EVENT TABLE ||============================== // | |||
export default function MsgTable({ recordList }) { | |||
const [rows, setRows] = React.useState(recordList); | |||
export default function MsgTable({ searchCriteria, applyGridOnReady, applySearch}) { | |||
const navigate = useNavigate() | |||
const intl = useIntl(); | |||
const [_searchCriteria, set_searchCriteria] = React.useState(searchCriteria); | |||
React.useEffect(() => { | |||
set_searchCriteria(searchCriteria); | |||
}, [searchCriteria]); | |||
const _sx = { | |||
padding: "4 2 4 2", | |||
boxShadow: 1, | |||
@@ -25,48 +33,56 @@ export default function MsgTable({ recordList }) { | |||
'& .MuiDataGrid-footerContainer': { | |||
border: 1, | |||
borderColor: "#EEE" | |||
} | |||
}, | |||
"& .MuiDataGrid-columnHeaderTitle": { | |||
whiteSpace: "normal", | |||
lineHeight: "normal" | |||
}, | |||
"& .MuiDataGrid-columnHeader": { | |||
// Forced to use important since overriding inline styles | |||
height: "unset !important" | |||
}, | |||
} | |||
React.useEffect(() => { | |||
setRows(recordList); | |||
}, [recordList]); | |||
const handleEditClick = (params) => () => { | |||
navigate('/msg/details/' + params.row.id); | |||
}; | |||
const columns = [ | |||
{ | |||
id: 'sentDate', | |||
field: 'sentDate', | |||
headerName: intl.formatMessage({id: 'date'}), | |||
width: 160, | |||
renderCell: (params) => { | |||
return DateUtils.datetimeStr(params.row.sentDate); | |||
width: 170, | |||
valueGetter: (params) => { | |||
return DateUtils.datetimeStr(params?.value); | |||
}, | |||
}, | |||
{ | |||
field: 'actions', | |||
headerName: intl.formatMessage({id: 'payId'}), | |||
field: 'subject', | |||
headerName: intl.formatMessage({id: 'subject'}), | |||
flex: 1 , | |||
cellClassName: 'actions', | |||
cellClassName: 'subject', | |||
renderCell: (params) => { | |||
return clickableLink('/msg/details/' + params.row.id, params.row.subject); | |||
}, | |||
}, | |||
]; | |||
function handleEditClick(params) { | |||
navigate('/msg/details/' + params.row.id); | |||
} | |||
return ( | |||
<div style={{ minHeight: 400, width: '100%' }}> | |||
<div style={{ width: '100%', overflowX: 'auto'}}> | |||
<FiDataGrid | |||
sx={_sx} | |||
rowHeight={80} | |||
rows={rows} | |||
columns={columns} | |||
customPageSize={20} | |||
customPageSize={10} | |||
getRowHeight={() => 'auto'} | |||
onRowDoubleClick={handleEditClick} | |||
applyGridOnReady={applyGridOnReady} | |||
applySearch={applySearch} | |||
doLoad={React.useMemo(() => ({ | |||
url: GET_MSG_LIST, | |||
params: _searchCriteria, | |||
}), [_searchCriteria])} | |||
/> | |||
</div> | |||
); | |||
@@ -21,7 +21,7 @@ import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs"; | |||
// ==============================|| DASHBOARD - DEFAULT ||============================== // | |||
const SearchForm = ({ applySearch, searchCriteria }) => { | |||
const SearchForm = ({ applySearch, searchCriteria, onGridReady }) => { | |||
const intl = useIntl(); | |||
const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom); | |||
const [maxDate, setMaxDate] = React.useState(searchCriteria.dateTo); | |||
@@ -64,7 +64,7 @@ const SearchForm = ({ applySearch, searchCriteria }) => { | |||
sentDateTo = DateUtils.dateValue(toDateValue) | |||
} | |||
const temp = { | |||
keywork: data.keywork, | |||
keyword: data.keyword, | |||
dateFrom: sentDateFrom, | |||
dateTo: sentDateTo, | |||
}; | |||
@@ -75,6 +75,8 @@ const SearchForm = ({ applySearch, searchCriteria }) => { | |||
setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14))) | |||
setMaxDate(DateUtils.dateValue(new Date())) | |||
reset(); | |||
localStorage.setItem('searchCriteria',"") | |||
} | |||
@@ -196,6 +198,7 @@ const SearchForm = ({ applySearch, searchCriteria }) => { | |||
<Button | |||
variant="contained" | |||
type="submit" | |||
disabled={onGridReady} | |||
aria-label={intl.formatMessage({id: 'submit'})} | |||
> | |||
<FormattedMessage id="submit"/> | |||
@@ -5,9 +5,9 @@ import { | |||
Stack | |||
} from '@mui/material'; | |||
import MainCard from "components/MainCard"; | |||
import * as UrlUtils from "utils/ApiPathConst"; | |||
// import * as UrlUtils from "utils/ApiPathConst"; | |||
import * as React from "react"; | |||
import * as HttpUtils from "utils/HttpUtils"; | |||
// import * as HttpUtils from "utils/HttpUtils"; | |||
import * as DateUtils from "utils/DateUtils"; | |||
import Loadable from 'components/Loadable'; | |||
@@ -16,6 +16,7 @@ const SearchForm = Loadable(React.lazy(() => import('./SearchForm'))); | |||
const EventTable = Loadable(React.lazy(() => import('./DataGrid'))); | |||
import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' | |||
import {FormattedMessage} from "react-intl"; | |||
import { getSearchCriteria } from "auth/utils"; | |||
const BackgroundHead = { | |||
backgroundImage: `url(${titleBackgroundImg})`, | |||
@@ -31,41 +32,58 @@ const BackgroundHead = { | |||
const Index = () => { | |||
const [record,setRecord] = React.useState([]); | |||
const [searchCriteria, setSearchCriteria] = React.useState({ | |||
dateTo: DateUtils.dateValue(new Date()), | |||
dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)), | |||
}); | |||
const [searchCriteria, setSearchCriteria] = React.useState({}); | |||
const [onReady, setOnReady] = React.useState(false); | |||
const [onGridReady, setGridOnReady] = React.useState(false); | |||
React.useEffect(() => { | |||
setOnReady(true); | |||
}, [record]); | |||
if (Object.keys(getSearchCriteria(window.location.pathname)).length>0){ | |||
setSearchCriteria(getSearchCriteria(window.location.pathname)) | |||
}else{ | |||
localStorage.setItem('searchCriteria',"") | |||
setSearchCriteria({ | |||
dateTo: DateUtils.dateValue(new Date()), | |||
dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)), | |||
}) | |||
} | |||
}, []); | |||
React.useEffect(() => { | |||
loadGrid(); | |||
if(Object.keys(searchCriteria).length>0){ | |||
setOnReady(true); | |||
} | |||
}, [searchCriteria]); | |||
function loadGrid(){ | |||
HttpUtils.get({ | |||
url: UrlUtils.GET_MSG_LIST, | |||
params: searchCriteria, | |||
onSuccess: function(responseData){ | |||
setRecord(responseData); | |||
} | |||
}); | |||
} | |||
// function loadGrid(){ | |||
// HttpUtils.get({ | |||
// url: UrlUtils.GET_MSG_LIST, | |||
// params: searchCriteria, | |||
// onSuccess: function(responseData){ | |||
// setRecord(responseData); | |||
// } | |||
// }); | |||
// } | |||
function applySearch(input) { | |||
setGridOnReady(true) | |||
setSearchCriteria(input); | |||
localStorage.setItem('searchCriteria', JSON.stringify({path:window.location.pathname,data:input})) | |||
} | |||
function applyGridOnReady(input) { | |||
setGridOnReady(input); | |||
} | |||
return ( | |||
!onReady ? | |||
<LoadingComponent/> | |||
<Grid container sx={{ minHeight: '95vh', mb: 3 }} direction="column" justifyContent="center" alignItems="center"> | |||
<Grid item> | |||
<LoadingComponent /> | |||
</Grid> | |||
</Grid> | |||
: | |||
<Grid container sx={{minHeight: '85vh',backgroundColor:'#ffffff'}} direction="column"> | |||
<Grid container sx={{ minHeight: '95vh',backgroundColor: 'backgroundColor.default' }} direction="column"> | |||
<Grid item xs={12}> | |||
<div style={BackgroundHead}> | |||
<Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center"> | |||
@@ -78,8 +96,9 @@ const Index = () => { | |||
{/*row 1*/} | |||
<Grid item xs={12} md={12} lg={12}> | |||
<SearchForm | |||
applySearch={applySearch} | |||
searchCriteria={searchCriteria} | |||
applySearch={applySearch} | |||
searchCriteria={searchCriteria} | |||
onGridReady={onGridReady} | |||
/> | |||
</Grid> | |||
{/*row 2*/} | |||
@@ -90,7 +109,10 @@ const Index = () => { | |||
sx={{width: "-webkit-fill-available"}} | |||
> | |||
<EventTable | |||
recordList={record} | |||
// recordList={record} | |||
searchCriteria={searchCriteria} | |||
applyGridOnReady={applyGridOnReady} | |||
applySearch={applySearch} | |||
/> | |||
</MainCard> | |||
</Grid> | |||
@@ -24,18 +24,20 @@ import { PNSPS_BUTTON_THEME } from "themes/buttonConst"; | |||
import { ThemeProvider } from "@emotion/react"; | |||
import { isGrantedAny } from "auth/utils"; | |||
import {DatePicker} from "@mui/x-date-pickers/DatePicker"; | |||
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 { DemoItem } from "@mui/x-date-pickers/internals/demo"; | |||
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider"; | |||
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; | |||
// ==============================|| DASHBOARD - DEFAULT ||============================== // | |||
const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||
const intl = useIntl(); | |||
const [creditorConfirmPopUp, setCreditorConfirmPopUp] = React.useState(false); | |||
const [nonCreditorConfirmPopUp, setNonCreditorConfirmPopUp] = React.useState(false); | |||
const [afterSendPopUp, setAfterSendPopUp] = React.useState(false); | |||
const [currentUserData, setCurrentUserData] = useState({}); | |||
const [overduePublicNotice, setOverduePublicNotice] = useState(0); | |||
const [editMode, setEditMode] = useState(false); | |||
const [createMode, setCreateMode] = useState(false); | |||
const [onReady, setOnReady] = useState(false); | |||
@@ -44,7 +46,7 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||
const [fromDate, setFromDate] = React.useState(null); | |||
const [currentFromDate, setCurrentFromDate] = React.useState(null); | |||
const [fromDateValue, setFromDateValue] = React.useState(null); | |||
const {register, handleSubmit, reset} = useForm() | |||
const { register, handleSubmit, reset } = useForm() | |||
React.useEffect(() => { | |||
setFromDateValue(fromDate); | |||
@@ -54,14 +56,14 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||
//if state data are ready and assign to different field | |||
// console.log(currentApplicationDetailData) | |||
if (Object.keys(currentUserData).length > 0) { | |||
console.log(currentUserData) | |||
if(DateUtils.dateValue(currentUserData.brExpiryDate)>DateUtils.dateValue(minDate)){ | |||
// console.log(currentUserData) | |||
if (DateUtils.dateValue(currentUserData.brExpiryDate) > DateUtils.dateValue(minDate)) { | |||
setFromDate(currentUserData.brExpiryDate); | |||
}else{ | |||
} else { | |||
setCurrentFromDate(currentUserData.brExpiryDate); | |||
// setErrorMsg("Please select a date after today.") | |||
} | |||
setOnReady(true); | |||
} | |||
}, [currentUserData]); | |||
@@ -115,7 +117,7 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||
let sentDateFrom = ""; | |||
if (fromDateValue == null) { | |||
setErrorMsg(intl.formatMessage({ id: 'pleaseFillInBusinessRegCertValidityDate' })) | |||
}else{ | |||
} else { | |||
sentDateFrom = DateUtils.dateValue(fromDateValue) | |||
HttpUtils.post({ | |||
url: UrlUtils.POST_ORG_SAVE_PATH, | |||
@@ -123,7 +125,7 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||
id: id > 0 ? id : null, | |||
enCompanyName: values.enCompanyName, | |||
chCompanyName: values.chCompanyName, | |||
orgShortName: values.orgShortName==="N/A"?"":values.orgShortName, | |||
orgShortName: values.orgShortName === "N/A" ? "" : values.orgShortName, | |||
brNo: values.brNo, | |||
// brExpiryDate: values.brExpiryDate, | |||
brExpiryDate: sentDateFrom, | |||
@@ -188,9 +190,9 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||
const onSubmit = (data) => { | |||
let sentOrgShortName = ""; | |||
if(data.orgShortName!=null && data.orgShortName!="" && data.orgShortName!="N/A"){ | |||
sentOrgShortName = data.orgShortName | |||
if (sentOrgShortName.length <=24){ | |||
if (data.orgShortName != null && data.orgShortName != "" && data.orgShortName != "N/A") { | |||
sentOrgShortName = data.orgShortName | |||
if (sentOrgShortName.length <= 24) { | |||
const temp = { | |||
orgShortName: sentOrgShortName, | |||
}; | |||
@@ -230,6 +232,17 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||
}); | |||
} | |||
const sendDn_Overdue = () => { | |||
setNonCreditorConfirmPopUp(false); | |||
HttpUtils.get({ | |||
url: UrlUtils.GET_SEND_OVERDUE_CREDITOR_LIST + "/" + id, | |||
onSuccess: (responseData) => { | |||
setOverduePublicNotice(responseData.overduePublicNotice); | |||
setAfterSendPopUp(true); | |||
} | |||
}); | |||
} | |||
return ( | |||
<MainCard elevation={0} | |||
border={false} | |||
@@ -311,17 +324,32 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||
</ThemeProvider> | |||
</Grid> | |||
: | |||
<Grid item sx={{ ml: 3, mr: 3 }}> | |||
<ThemeProvider theme={PNSPS_BUTTON_THEME}> | |||
<Button | |||
variant="contained" | |||
color="orange" | |||
onClick={() => setCreditorConfirmPopUp(true)} | |||
> | |||
Mark as Credit Client | |||
</Button> | |||
</ThemeProvider> | |||
</Grid> | |||
<> | |||
<Grid item sx={{ ml: 3, mr: 3 }}> | |||
<ThemeProvider theme={PNSPS_BUTTON_THEME}> | |||
<Button | |||
variant="contained" | |||
color="orange" | |||
onClick={() => setCreditorConfirmPopUp(true)} | |||
> | |||
Mark as Credit Client | |||
</Button> | |||
</ThemeProvider> | |||
</Grid> | |||
{ isGrantedAny("MAINTAIN_DEMANDNOTE")? | |||
<Grid item sx={{ ml: 3, mr: 3 }}> | |||
<ThemeProvider theme={PNSPS_BUTTON_THEME}> | |||
<Button | |||
variant="contained" | |||
color="primary" | |||
onClick={() => sendDn_Overdue(true)} | |||
> | |||
Generate O/S DN List | |||
</Button> | |||
</ThemeProvider> | |||
</Grid> : null | |||
} | |||
</> | |||
} | |||
</> | |||
} | |||
@@ -396,18 +424,18 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||
<Typography variant="pnspsFormParagraphBold">{FieldUtils.notNullFieldLabel("Expiry Date:")}</Typography> | |||
</Grid> | |||
<Grid item xs={12} md={6} lg={6}> | |||
{(!editMode && !createMode)? | |||
{(!editMode && !createMode) ? | |||
<TextField | |||
fullWidth | |||
id="currentExDate" | |||
// error={(fromDate===null)} | |||
// type="date" | |||
name="currentExDate" | |||
value={fromDate!=null?DateUtils.dateStr(fromDate):DateUtils.dateStr(currentFromDate)} | |||
value={fromDate != null ? DateUtils.dateStr(fromDate) : DateUtils.dateStr(currentFromDate)} | |||
disabled={true} | |||
/>: | |||
/> : | |||
<LocalizationProvider dateAdapter={AdapterDayjs}> | |||
<DemoItem components={['DatePicker']}> | |||
<DemoItem components={['DatePicker']}> | |||
<DatePicker | |||
id="brExpiryDate" | |||
name="brExpiryDate" | |||
@@ -426,9 +454,9 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||
onChange={(newValue) => { | |||
// console.log(newValue) | |||
// setErrorMsg("") | |||
if(DateUtils.dateValue(newValue)>DateUtils.dateValue(new Date())){ | |||
if (DateUtils.dateValue(newValue) > DateUtils.dateValue(new Date())) { | |||
setFromDate(newValue); | |||
}else{ | |||
} else { | |||
// setErrorMsg("Please select a date after today.") | |||
} | |||
}} | |||
@@ -438,19 +466,20 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||
} | |||
</Grid> | |||
{ | |||
fromDate==null? | |||
(!editMode && !createMode)? | |||
<FormHelperText error id="helper-text-date"> | |||
Please select a date after today. | |||
</FormHelperText> | |||
: | |||
fromDate == null ? | |||
(!editMode && !createMode) ? | |||
// <FormHelperText error id="helper-text-date"> | |||
// Please select a date after today. | |||
// </FormHelperText> | |||
null | |||
: | |||
<FormHelperText error id="helper-text-date"> | |||
{intl.formatMessage({ id: 'pleaseFillInBusinessRegCertValidityDate' })} | |||
</FormHelperText> | |||
: | |||
: | |||
null | |||
} | |||
} | |||
</Grid> | |||
</Grid> | |||
@@ -488,27 +517,6 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||
})} | |||
</Grid> | |||
<Grid item xs={12} lg={4} > | |||
{FieldUtils.getComboField({ | |||
label: FieldUtils.notNullFieldLabel("Country:"), | |||
valueName: "country", | |||
disabled: (!editMode && !createMode), | |||
dataList: ComboData.country, | |||
getOptionLabel: (option) => option.type ? intl.formatMessage({ id: option.type }) : "", | |||
form: formik | |||
})} | |||
</Grid> | |||
<Grid item xs={12} lg={4} > | |||
{FieldUtils.getComboField({ | |||
label: FieldUtils.notNullFieldLabel("District:"), | |||
valueName: "district", | |||
disabled: (!editMode && !createMode), | |||
dataList: ComboData.district, | |||
getOptionLabel: (option) => option.type ? intl.formatMessage({ id: option.type }) : "", | |||
form: formik | |||
})} | |||
</Grid> | |||
{ | |||
currentUserData.creditor ? | |||
<Grid item xs={12} lg={4} > | |||
@@ -533,6 +541,28 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||
})} | |||
</Grid> | |||
<Grid item xs={12} lg={12} > | |||
{FieldUtils.getProfileComboField({ | |||
label: "", | |||
valueName: "district", | |||
disabled: (!editMode && !createMode), | |||
dataList: ComboData.district, | |||
getOptionLabel: (option) => option.type ? intl.formatMessage({ id: option.type }) : "", | |||
form: formik | |||
})} | |||
</Grid> | |||
<Grid item xs={12} lg={12} > | |||
{FieldUtils.getProfileComboField({ | |||
label: "", | |||
valueName: "country", | |||
disabled: true, | |||
dataList: ComboData.country, | |||
getOptionLabel: (option) => option.type ? intl.formatMessage({ id: option.type }) : "", | |||
form: formik | |||
})} | |||
</Grid> | |||
<Grid item lg={12} ></Grid> | |||
</Grid> | |||
@@ -566,7 +596,7 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||
{...register("orgShortName")} | |||
id='orgShortName' | |||
label="Organisation Short Name" | |||
defaultValue={currentUserData.orgShortName!="N/A"?currentUserData.orgShortName:""} | |||
defaultValue={currentUserData.orgShortName != "N/A" ? currentUserData.orgShortName : ""} | |||
InputLabelProps={{ | |||
shrink: true | |||
}} | |||
@@ -605,6 +635,27 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||
</DialogActions> | |||
</Dialog> | |||
</div> | |||
<div> | |||
<Dialog | |||
open={afterSendPopUp} | |||
onClose={() => setAfterSendPopUp(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="h3">Info</Typography></DialogTitle> | |||
<DialogContent style={{ display: 'flex', }}> | |||
<Typography variant="h4" style={{ padding: '16px' }}>Overdue Public Notice count: {overduePublicNotice}</Typography> | |||
</DialogContent> | |||
<DialogActions> | |||
<Button onClick={() => setAfterSendPopUp(false)}><Typography variant="h5">OK</Typography></Button> | |||
</DialogActions> | |||
</Dialog> | |||
</div> | |||
</MainCard> | |||
); | |||
}; | |||
@@ -1,6 +1,6 @@ | |||
// material-ui | |||
import { | |||
Grid, Button, | |||
Grid, Button, | |||
// Checkbox, FormControlLabel, | |||
Typography, | |||
Dialog, DialogTitle, DialogContent, DialogActions, | |||
@@ -20,9 +20,9 @@ const LoadingComponent = Loadable(lazy(() => import('../../extra-pages/LoadingCo | |||
import Loadable from 'components/Loadable'; | |||
import { lazy } from 'react'; | |||
import { notifySaveSuccess } from 'utils/CommonFunction'; | |||
import {FormattedMessage, useIntl} from "react-intl"; | |||
import {PNSPS_BUTTON_THEME} from "themes/buttonConst"; | |||
import {ThemeProvider} from "@emotion/react"; | |||
import { FormattedMessage, useIntl } from "react-intl"; | |||
import { PNSPS_BUTTON_THEME } from "themes/buttonConst"; | |||
import { ThemeProvider } from "@emotion/react"; | |||
// ==============================|| DASHBOARD - DEFAULT ||============================== // | |||
@@ -54,19 +54,19 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||
enableReinitialize: true, | |||
initialValues: currentUserData, | |||
validationSchema: yup.object().shape({ | |||
addressLine1: yup.string().max(40).required(displayErrorMsg(intl.formatMessage({id: 'validateAddressLine1'}))), | |||
addressLine2: yup.string().max(40, displayErrorMsg(intl.formatMessage({id: 'noMoreThen40Words'}))), | |||
addressLine3: yup.string().max(40, displayErrorMsg(intl.formatMessage({id: 'noMoreThen40Words'}))), | |||
tel_countryCode: yup.string().min(3, displayErrorMsg(intl.formatMessage({id: 'requireDialingCode'}))), | |||
phoneNumber: yup.string().min(8, displayErrorMsg(intl.formatMessage({id: 'requiredValidNumber'}))).required(displayErrorMsg(intl.formatMessage({id: 'requireContactNumber'}))), | |||
addressLine1: yup.string().max(40).required(displayErrorMsg(intl.formatMessage({ id: 'validateAddressLine1' }))), | |||
addressLine2: yup.string().max(40, displayErrorMsg(intl.formatMessage({ id: 'noMoreThen40Words' }))), | |||
addressLine3: yup.string().max(40, displayErrorMsg(intl.formatMessage({ id: 'noMoreThen40Words' }))), | |||
tel_countryCode: yup.string().min(3, displayErrorMsg(intl.formatMessage({ id: 'requireDialingCode' }))), | |||
phoneNumber: yup.string().min(8, displayErrorMsg(intl.formatMessage({ id: 'requiredValidNumber' }))).required(displayErrorMsg(intl.formatMessage({ id: 'requireContactNumber' }))), | |||
faxNumber: yup.string().min(8, displayErrorMsg(intl.formatMessage({ id: 'require8Number' }))).nullable(), | |||
}), | |||
onSubmit: values => { | |||
if (values.country==null){ | |||
setErrorMsg(intl.formatMessage({id: 'pleaseFillInCountry'})) | |||
if (values.country == null) { | |||
setErrorMsg(intl.formatMessage({ id: 'pleaseFillInCountry' })) | |||
} else { | |||
if (values.country.type =="hongKong" && values.district == null){ | |||
setErrorMsg(intl.formatMessage({id: 'pleaseFillInDistrict'})) | |||
if (values.country.type == "hongKong" && values.district == null) { | |||
setErrorMsg(intl.formatMessage({ id: 'pleaseFillInDistrict' })) | |||
} else { | |||
HttpUtils.post({ | |||
url: UrlUtils.POST_PUB_ORG_SAVE_PATH, | |||
@@ -100,9 +100,9 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||
} | |||
}); | |||
useEffect(()=>{ | |||
useEffect(() => { | |||
setEditModeFun(editMode); | |||
},[editMode]); | |||
}, [editMode]); | |||
useEffect(() => { | |||
if (Object.keys(userData).length > 0) { | |||
@@ -188,7 +188,7 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||
onClick={onEditClick} | |||
color="success" | |||
> | |||
< FormattedMessage id="edit" /> | |||
< FormattedMessage id="edit" /> | |||
</Button> | |||
</ThemeProvider> | |||
</Grid> | |||
@@ -202,11 +202,11 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||
<LoadingComponent /> | |||
: | |||
<Grid container spacing={1}> | |||
<Grid item xs={12}> | |||
{/* <Grid item xs={12}> | |||
<Typography variant="h4" sx={{ mb: 2, mr: 3, borderBottom: "1px solid black" }}> | |||
<FormattedMessage id="organizationDetails" /> | |||
</Typography> | |||
</Grid> | |||
</Grid> */} | |||
<Grid item xs={12}> | |||
<FormHelperText error id="helper-text-address1-signup"> | |||
<Typography variant="errorMessage1"> | |||
@@ -216,27 +216,27 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||
</Grid> | |||
<Grid item xs={12} lg={4} > | |||
{FieldUtils.getTextField({ | |||
label: intl.formatMessage({id: 'brNo'}) + ":", | |||
label: intl.formatMessage({ id: 'brNo' }) + ":", | |||
valueName: "brNo", | |||
disabled: true, | |||
form: formik | |||
})} | |||
</Grid> | |||
<Grid item xs={12} lg={4} > | |||
{/* {FieldUtils.getTextField({ | |||
label: intl.formatMessage({id: 'creditorAccount'}) + ":", | |||
valueName: "creditor", | |||
disabled: true, | |||
form: formik | |||
})} */} | |||
{FieldUtils.getTextField({ | |||
label: FieldUtils.notNullFieldLabel(intl.formatMessage({ id: 'expiryDate' }) + ":"), | |||
valueName: "brExpiryDate", | |||
disabled: true, | |||
form: formik | |||
})} | |||
</Grid> | |||
<Grid item xs={12} lg={4} ></Grid> | |||
<Grid item xs={12} lg={4} > | |||
{FieldUtils.getTextField({ | |||
label: FieldUtils.notNullFieldLabel(intl.formatMessage({id: 'nameEng'}) + ":"), | |||
label: FieldUtils.notNullFieldLabel(intl.formatMessage({ id: 'nameEng' }) + ":"), | |||
valueName: "enCompanyName", | |||
disabled: true, | |||
form: formik | |||
@@ -245,7 +245,7 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||
<Grid item xs={12} lg={4} > | |||
{FieldUtils.getTextField({ | |||
label: intl.formatMessage({id: 'nameChi'}) + ":", | |||
label: intl.formatMessage({ id: 'nameChi' }) + ":", | |||
valueName: "chCompanyName", | |||
disabled: true, | |||
form: formik | |||
@@ -253,17 +253,12 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||
</Grid> | |||
<Grid item xs={12} lg={4} > | |||
{FieldUtils.getTextField({ | |||
label: FieldUtils.notNullFieldLabel(intl.formatMessage({id: 'expiryDate'}) + ":"), | |||
valueName: "brExpiryDate", | |||
disabled: true, | |||
form: formik | |||
})} | |||
</Grid> | |||
<Grid item xs={12} lg={4} > | |||
{FieldUtils.getTextField({ | |||
label: FieldUtils.notNullFieldLabel(intl.formatMessage({id: 'contactPerson'}) + ":"), | |||
label: FieldUtils.notNullFieldLabel(intl.formatMessage({ id: 'contactPerson' }) + ":"), | |||
valueName: "contactPerson", | |||
disabled: (!editMode && !createMode), | |||
form: formik | |||
@@ -272,7 +267,7 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||
<Grid item xs={12} lg={4} > | |||
{FieldUtils.getPhoneField({ | |||
label: FieldUtils.notNullFieldLabel(intl.formatMessage({id: 'userContactNumber'}) + ":"), | |||
label: FieldUtils.notNullFieldLabel(intl.formatMessage({ id: 'userContactNumber' }) + ":"), | |||
valueName: { | |||
code: "tel_countryCode", | |||
num: "phoneNumber" | |||
@@ -284,7 +279,7 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||
<Grid item xs={12} lg={4} > | |||
{FieldUtils.getPhoneField({ | |||
label: intl.formatMessage({id: 'contactFaxNumber'}) + ":", | |||
label: intl.formatMessage({ id: 'contactFaxNumber' }) + ":", | |||
valueName: { | |||
code: "fax_countryCode", | |||
num: "faxNumber" | |||
@@ -294,34 +289,35 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||
})} | |||
</Grid> | |||
<Grid item xs={12} lg={4} > | |||
{FieldUtils.getComboField({ | |||
label: FieldUtils.notNullFieldLabel(intl.formatMessage({id: 'country'}) + ":"), | |||
valueName: "country", | |||
<Grid item xs={12} lg={12} > | |||
{FieldUtils.getAddressField({ | |||
label: FieldUtils.notNullFieldLabel(intl.formatMessage({ id: 'formAddress' }) + ":"), | |||
valueName: ["addressLine1", "addressLine2", "addressLine3"], | |||
disabled: (!editMode && !createMode), | |||
dataList: ComboData.country, | |||
getOptionLabel: (option) => option.type? intl.formatMessage({ id: option.type }) : "", | |||
form: formik | |||
})} | |||
</Grid> | |||
<Grid item xs={12} lg={4} > | |||
{FieldUtils.getComboField({ | |||
label: FieldUtils.notNullFieldLabel(intl.formatMessage({id: 'district'}) + ":"), | |||
<Grid item xs={12} lg={12} > | |||
{FieldUtils.getProfileComboField({ | |||
// label: FieldUtils.notNullFieldLabel(""), | |||
label: "", | |||
valueName: "district", | |||
disabled: (!editMode && !createMode), | |||
dataList: ComboData.district, | |||
getOptionLabel: (option) => option.type? intl.formatMessage({ id: option.type }) : "", | |||
getOptionLabel: (option) => option.type ? intl.formatMessage({ id: option.type }) : "", | |||
form: formik | |||
})} | |||
</Grid> | |||
<Grid item xs={12} lg={12} > | |||
{FieldUtils.getAddressField({ | |||
label: FieldUtils.notNullFieldLabel(intl.formatMessage({id: 'formAddress'}) + ":"), | |||
valueName: ["addressLine1", "addressLine2", "addressLine3"], | |||
disabled: (!editMode && !createMode), | |||
{FieldUtils.getProfileComboField({ | |||
// label: FieldUtils.notNullFieldLabel(""), | |||
label: "", | |||
valueName: "country", | |||
disabled: true, | |||
dataList: ComboData.country, | |||
getOptionLabel: (option) => option.type ? intl.formatMessage({ id: option.type }) : "", | |||
form: formik | |||
})} | |||
</Grid> | |||
@@ -348,7 +344,7 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||
<Typography variant="h4" style={{ padding: '16px' }}>Are you sure mark as Credit Client?</Typography> | |||
</DialogContent> | |||
<DialogActions> | |||
<Button onClick={() => setCreditorConfirmPopUp(false)}><Typography variant="h5">Cancel</Typography></Button> | |||
<Button onClick={() => setCreditorConfirmPopUp(false)}><Typography variant="h5">Cancel</Typography></Button> | |||
<Button onClick={() => markAsCreditor()}><Typography variant="h5">Confirm</Typography></Button> | |||
</DialogActions> | |||
</Dialog> | |||
@@ -370,7 +366,7 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||
<Typography variant="h4" style={{ padding: '16px' }}>Are you sure mark as Non-Credit Client?</Typography> | |||
</DialogContent> | |||
<DialogActions> | |||
<Button onClick={() => setNonCreditorConfirmPopUp(false)}><Typography variant="h5">Cancel</Typography></Button> | |||
<Button onClick={() => setNonCreditorConfirmPopUp(false)}><Typography variant="h5">Cancel</Typography></Button> | |||
<Button onClick={() => markAsNonCreditor()}><Typography variant="h5">Confirm</Typography></Button> | |||
</DialogActions> | |||
</Dialog> | |||
@@ -310,19 +310,17 @@ const OrganizationCard_loadFromUser = ({ userData, userId }) => { | |||
})} | |||
</Grid> | |||
<Grid item xs={12} lg={4}> | |||
{FieldUtils.getComboField({ | |||
label: FieldUtils.notNullFieldLabel("Country:"), | |||
valueName: "country", | |||
dataList: ComboData.country, | |||
getOptionLabel: (option) => option.type ? intl.formatMessage({ id: option.type }) : "", | |||
<Grid item xs={12}> | |||
{FieldUtils.getAddressField({ | |||
label: FieldUtils.notNullFieldLabel("Address:"), | |||
valueName: ["addressLine1", "addressLine2", "addressLine3"], | |||
form: formik | |||
})} | |||
</Grid> | |||
<Grid item xs={12} lg={4}> | |||
<Grid item xs={12} lg={12}> | |||
{FieldUtils.getComboField({ | |||
label: FieldUtils.notNullFieldLabel("District:"), | |||
label: "", | |||
valueName: "district", | |||
dataList: ComboData.district, | |||
getOptionLabel: (option) => option.type ? intl.formatMessage({ id: option.type }) : "", | |||
@@ -330,13 +328,17 @@ const OrganizationCard_loadFromUser = ({ userData, userId }) => { | |||
})} | |||
</Grid> | |||
<Grid item xs={12}> | |||
{FieldUtils.getAddressField({ | |||
label: FieldUtils.notNullFieldLabel("Address:"), | |||
valueName: ["addressLine1", "addressLine2", "addressLine3"], | |||
<Grid item xs={12} lg={12}> | |||
{FieldUtils.getComboField({ | |||
label: "", | |||
valueName: "country", | |||
disabled: true, | |||
dataList: ComboData.country, | |||
getOptionLabel: (option) => option.type ? intl.formatMessage({ id: option.type }) : "", | |||
form: formik | |||
})} | |||
</Grid> | |||
</Grid> | |||
} | |||
</form> | |||
@@ -8,7 +8,7 @@ import { | |||
import MainCard from "components/MainCard"; | |||
import { useForm } from "react-hook-form"; | |||
import { useState } from "react"; | |||
import { useState,useEffect } from "react"; | |||
import * as React from "react"; | |||
import * as UrlUtils from "utils/ApiPathConst"; | |||
@@ -19,11 +19,21 @@ import {ThemeProvider} from "@emotion/react"; | |||
// ==============================|| DASHBOARD - DEFAULT ||============================== // | |||
const OrganizationSearchForm = ({ applySearch }) => { | |||
const OrganizationSearchForm = ({ applySearch, onGridReady, searchCriteria }) => { | |||
const [type, setType] = useState([]); | |||
const [creditorSelected, setCreditorSelected] = React.useState(ComboData.CreditorStatus[0]); | |||
const { reset, register, handleSubmit } = useForm() | |||
const [onDownload, setOnDownload] = React.useState(false); | |||
useEffect(() => { | |||
if(searchCriteria.creditor!=undefined){ | |||
setCreditorSelected(ComboData.CreditorStatus.find(item => item.type === searchCriteria.creditor.toString())) | |||
}else{ | |||
setCreditorSelected(ComboData.CreditorStatus[0]); | |||
} | |||
}, [searchCriteria]); | |||
const onSubmit = (data) => { | |||
let typeArray = []; | |||
@@ -48,12 +58,23 @@ const OrganizationSearchForm = ({ applySearch }) => { | |||
function resetForm() { | |||
setType([]); | |||
setCreditorSelected(ComboData.CreditorStatus[0]); | |||
reset(); | |||
reset({ | |||
brNo: "", | |||
enCompanyName: "", | |||
chCompanyName: "", | |||
}); | |||
} | |||
const doExport=()=>{ | |||
setOnDownload(true) | |||
HttpUtils.fileDownload({ | |||
url: UrlUtils.GET_ORG_EXPORT | |||
url: UrlUtils.GET_ORG_EXPORT, | |||
onResponse:()=>{ | |||
setOnDownload(false) | |||
}, | |||
onError:()=>{ | |||
setOnDownload(false) | |||
} | |||
}); | |||
} | |||
@@ -80,6 +101,7 @@ const OrganizationSearchForm = ({ applySearch }) => { | |||
{...register("brNo")} | |||
id='brNo' | |||
label="BR No." | |||
defaultValue={searchCriteria.brNo} | |||
InputLabelProps={{ | |||
shrink: true | |||
}} | |||
@@ -92,6 +114,7 @@ const OrganizationSearchForm = ({ applySearch }) => { | |||
{...register("enCompanyName")} | |||
id="enCompanyName" | |||
label="Name (English)" | |||
defaultValue={searchCriteria.enCompanyName} | |||
InputLabelProps={{ | |||
shrink: true | |||
}} | |||
@@ -104,6 +127,7 @@ const OrganizationSearchForm = ({ applySearch }) => { | |||
{...register("chCompanyName")} | |||
id="chCompanyName" | |||
label="Name (Chinese)" | |||
defaultValue={searchCriteria.chCompanyName} | |||
InputLabelProps={{ | |||
shrink: true | |||
}} | |||
@@ -148,6 +172,7 @@ const OrganizationSearchForm = ({ applySearch }) => { | |||
<Button | |||
variant="contained" | |||
onClick={doExport} | |||
disabled={onDownload} | |||
> | |||
Export | |||
</Button> | |||
@@ -167,6 +192,7 @@ const OrganizationSearchForm = ({ applySearch }) => { | |||
<Button | |||
variant="contained" | |||
type="submit" | |||
disabled={onGridReady} | |||
> | |||
Submit | |||
</Button> | |||
@@ -11,7 +11,7 @@ import { clickableLink} from 'utils/CommonFunction'; | |||
import {GET_ORG_PATH} from "utils/ApiPathConst"; | |||
// ==============================|| EVENT TABLE ||============================== // | |||
export default function OrganizationTable({ searchCriteria }) { | |||
export default function OrganizationTable({ searchCriteria, applyGridOnReady, applySearch}) { | |||
const [_searchCriteria, set_searchCriteria] = React.useState(searchCriteria); | |||
const navigate = useNavigate() | |||
@@ -111,12 +111,18 @@ export default function OrganizationTable({ searchCriteria }) { | |||
<div style={{ height: "fit-content", width: '100%' }}> | |||
<FiDataGrid | |||
columns={columns} | |||
customPageSize={5} | |||
customPageSize={10} | |||
onRowDoubleClick={handleRowDoubleClick} | |||
doLoad={{ | |||
applyGridOnReady={applyGridOnReady} | |||
applySearch={applySearch} | |||
// doLoad={{ | |||
// url: GET_ORG_PATH, | |||
// params: _searchCriteria, | |||
// }} | |||
doLoad={React.useMemo(() => ({ | |||
url: GET_ORG_PATH, | |||
params: _searchCriteria, | |||
}} | |||
}), [_searchCriteria])} | |||
/> | |||
</div> | |||
); | |||
@@ -5,7 +5,7 @@ import { | |||
import MainCard from "components/MainCard"; | |||
import { useEffect, useState } from "react"; | |||
import * as React from "react"; | |||
import { getSearchCriteria } from "auth/utils"; | |||
// import LoadingComponent from "../extra-pages/LoadingComponent"; | |||
// import SearchForm from "./OrganizationSearchForm"; | |||
@@ -32,13 +32,29 @@ const OrganizationSearchPage = () => { | |||
const [searchCriteria, setSearchCriteria] = useState({}); | |||
const [onReady, setOnReady] = useState(false); | |||
const [onGridReady, setGridOnReady] = React.useState(false); | |||
useEffect(() => { | |||
if (Object.keys(getSearchCriteria(window.location.pathname)).length>0){ | |||
setSearchCriteria(getSearchCriteria(window.location.pathname)) | |||
}else{ | |||
localStorage.setItem('searchCriteria',"") | |||
setSearchCriteria({}) | |||
} | |||
}, []); | |||
useEffect(() => { | |||
setOnReady(true); | |||
}, [searchCriteria]); | |||
function applySearch(input) { | |||
setGridOnReady(true) | |||
setSearchCriteria(input); | |||
localStorage.setItem('searchCriteria', JSON.stringify({path:window.location.pathname,data:input})) | |||
} | |||
function applyGridOnReady(input) { | |||
setGridOnReady(input); | |||
} | |||
return ( | |||
@@ -59,7 +75,11 @@ const OrganizationSearchPage = () => { | |||
</Grid> | |||
{/*row 1*/} | |||
<Grid item xs={12} md={12} lg={12} sx={{ mb: -1 }}> | |||
<SearchForm applySearch={applySearch} /> | |||
<SearchForm | |||
applySearch={applySearch} | |||
onGridReady={onGridReady} | |||
searchCriteria={searchCriteria} | |||
/> | |||
</Grid> | |||
{/*row 2*/} | |||
<Grid item xs={12} md={12} lg={12}> | |||
@@ -69,6 +89,8 @@ const OrganizationSearchPage = () => { | |||
> | |||
<EventTable | |||
searchCriteria={searchCriteria} | |||
applyGridOnReady={applyGridOnReady} | |||
applySearch={applySearch} | |||
/> | |||
</MainCard> | |||
</Grid> | |||
@@ -43,7 +43,7 @@ export default function SearchPublicNoticeTable({ recordList }) { | |||
flex: 1, | |||
renderCell: (params) => { | |||
let appNo = params.row.appNo; | |||
console.log(params.row) | |||
// console.log(params.row) | |||
return <div style={{ margin: 4, textAlign:"left"}}>Gazette Supplement No. 6 <br/> | |||
{isORGLoggedIn()&¶ms.row.careOf!=null&¶ms.row.careOf!=""?<>{params.row.careOf}<br /></>:null} | |||
App No: {appNo}<br/> | |||
@@ -9,15 +9,19 @@ import { | |||
import * as React from "react"; | |||
import * as FormatUtils from "utils/FormatUtils"; | |||
import * as PaymentStatus from "utils/statusUtils/PaymentStatus"; | |||
import * as DateUtils from "utils/DateUtils"; | |||
import Loadable from 'components/Loadable'; | |||
const MainCard = Loadable(React.lazy(() => import('components/MainCard'))); | |||
const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | |||
import DownloadIcon from '@mui/icons-material/Download'; | |||
import {useIntl} from "react-intl"; | |||
// ==============================|| DASHBOARD - DEFAULT ||============================== // | |||
const PaymentDetails = ({ formData,doPrint,onDownload }) => { | |||
const intl = useIntl(); | |||
const [data, setData] = React.useState({}); | |||
const [onReady, setOnReady] = React.useState(false); | |||
// const { locale } = intl; | |||
React.useEffect(() => { | |||
if (formData != null && formData != undefined && Object.keys(formData).length > 0) { | |||
@@ -89,7 +93,7 @@ const PaymentDetails = ({ formData,doPrint,onDownload }) => { | |||
</Grid> | |||
<Grid item xs={6} md={5} sx={{ml:5, textAlign: "left" }}> | |||
<FormLabel sx={{ color: "#000000" }}> | |||
{data.transDateStr + " (DD/MM/YYYY)"} | |||
{DateUtils.dateFormat(data.transDateStr, intl.formatMessage({id: "dateStrFormat"})) +" ("+intl.formatMessage({id: "dateStrFormat"})+")"} | |||
</FormLabel> | |||
</Grid> | |||
</Grid> | |||
@@ -131,7 +135,7 @@ const PaymentDetails = ({ formData,doPrint,onDownload }) => { | |||
</Grid> | |||
<Grid item xs={6} md={5} sx={{ml:5, textAlign: "left" }}> | |||
<FormLabel sx={{ color: "#000000" }}> | |||
{"HK$ " + FormatUtils.currencyFormat(data.payload?.amount)} | |||
{"$ " + FormatUtils.currencyFormat(data.payload?.amount)} | |||
</FormLabel> | |||
</Grid> | |||
</Grid> | |||
@@ -161,14 +165,10 @@ const PaymentDetails = ({ formData,doPrint,onDownload }) => { | |||
</FormLabel> | |||
</Grid> | |||
<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}> | |||
<DownloadIcon/> | |||
<Typography sx={{fontSize: "16px"}}>Download</Typography> | |||
</Button> | |||
} | |||
<Button className="printHidden" variant="contained" disabled={onDownload} sx={{ mt:2 }} onClick={doPrint}> | |||
<DownloadIcon/> | |||
<Typography sx={{fontSize: "16px"}}>Download</Typography> | |||
</Button> | |||
</Grid> | |||
</Grid> | |||
</Grid> | |||
@@ -77,7 +77,7 @@ const Index = () => { | |||
if (!responseData.data?.id) { | |||
navigate("/paymentPage/search"); | |||
} | |||
responseData.data["transDateStr"] = DateUtils.dateFormat(responseData.data.transDateTime, "DD/MM/YYYY"); | |||
responseData.data["transDateStr"] = responseData.data.transDateTime; | |||
responseData.data["transTimeStr"] = DateUtils.dateFormat(responseData.data.transDateTime, "HH:mm:ss"); | |||
setItemList(responseData.paymentItemList) | |||
setRecord(responseData.data); | |||
@@ -81,7 +81,7 @@ export default function SearchPublicNoticeTable({ recordList }) { | |||
{ | |||
id: 'fee', | |||
field: 'fee', | |||
headerName: intl.formatMessage({id: 'currencyAmount'}) + ' ($)', | |||
headerName: intl.formatMessage({id: 'currencyAmount'}), | |||
width: 200, | |||
valueGetter: (params) => { | |||
return (params?.value) ? "$ " + FormatUtils.currencyFormat(params?.value) : ""; | |||
@@ -9,6 +9,7 @@ import { | |||
import * as React from "react"; | |||
import * as FormatUtils from "utils/FormatUtils"; | |||
import * as PaymentStatus from "utils/statusUtils/PaymentStatus"; | |||
import * as DateUtils from "utils/DateUtils"; | |||
import Loadable from 'components/Loadable'; | |||
const MainCard = Loadable(React.lazy(() => import('components/MainCard'))); | |||
const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | |||
@@ -24,30 +25,56 @@ const PaymentDetails = ({ formData,doPrint,onDownload }) => { | |||
React.useEffect(() => { | |||
if (formData != null && formData != undefined && Object.keys(formData).length > 0) { | |||
console.log(formData) | |||
// console.log(formData) | |||
setData(formData); | |||
} | |||
}, [formData]); | |||
React.useEffect(() => { | |||
if (data != null && data != undefined && Object.keys(data).length > 0) { | |||
console.log(data) | |||
// console.log(data) | |||
setOnReady(data != {}); | |||
} | |||
}, [data]); | |||
const getPaymentMethod=()=>{ | |||
let paymentmethod = "" | |||
// console.log(locale) | |||
if (data?.payload!=null) { | |||
paymentmethod = data.payload?.paymentdetail.paymentmethod; | |||
if("01" == paymentmethod) return "PPS"; | |||
if("02" == paymentmethod || "03" == paymentmethod) return "Credit Card"; | |||
if("04" == paymentmethod) return "FPS"; | |||
if (locale == "zh-HK"){ | |||
if("01" == paymentmethod) return "繳費靈"; | |||
if("02" == paymentmethod || "03" == paymentmethod) return "信用卡"; | |||
if("04" == paymentmethod) return "轉數快"; | |||
} | |||
else if (locale == "zh-CN"){ | |||
if("01" == paymentmethod) return "缴费灵"; | |||
if("02" == paymentmethod || "03" == paymentmethod) return "信用卡"; | |||
if("04" == paymentmethod) return "转数快"; | |||
} | |||
else { | |||
if("01" == paymentmethod) return "PPS"; | |||
if("02" == paymentmethod || "03" == paymentmethod) return "Credit Card"; | |||
if("04" == paymentmethod) return "FPS"; | |||
} | |||
} else { | |||
paymentmethod = data.payMethod; | |||
if("01,PPSB,PPS" == paymentmethod) return "PPS"; | |||
if("02,BCMP,CreditCard" == paymentmethod || "03,BCMP,CreditCard" == paymentmethod) return "Credit Card"; | |||
if("04,BCFP,FPS" == paymentmethod) return "FPS"; | |||
if (locale == "zh-HK"){ | |||
if("01,PPSB,PPS" == paymentmethod) return "繳費靈"; | |||
if("02,BCMP,CreditCard" == paymentmethod || "03,BCMP,CreditCard" == paymentmethod) return "信用卡"; | |||
if("04,BCFP,FPS" == paymentmethod) return "轉數快"; | |||
} | |||
else if (locale == "zh-CN"){ | |||
if("01,PPSB,PPS" == paymentmethod) return "缴费灵"; | |||
if("02,BCMP,CreditCard" == paymentmethod || "03,BCMP,CreditCard" == paymentmethod) return "信用卡"; | |||
if("04,BCFP,FPS" == paymentmethod) return "转数快"; | |||
} | |||
else { | |||
if("01,PPSB,PPS" == paymentmethod) return "PPS"; | |||
if("02,BCMP,CreditCard" == paymentmethod || "03,BCMP,CreditCard" == paymentmethod) return "Credit Card"; | |||
if("04,BCFP,FPS" == paymentmethod) return "FPS"; | |||
} | |||
} | |||
return paymentmethod; | |||
} | |||
@@ -109,7 +136,7 @@ const PaymentDetails = ({ formData,doPrint,onDownload }) => { | |||
</Grid> | |||
<Grid item xs={6} md={6} sx={{textAlign: "left" }}> | |||
<FormLabel sx={{ fontSize: "16px", color: "#000000" }}> | |||
{data.transDateStr + " (DD/MM/YYYY)"} | |||
{DateUtils.dateFormat(data.transDateStr, intl.formatMessage({id: "dateStrFormat"})) +" ("+intl.formatMessage({id: "dateStrFormat"})+")"} | |||
</FormLabel> | |||
</Grid> | |||
</Grid> | |||
@@ -151,7 +178,7 @@ const PaymentDetails = ({ formData,doPrint,onDownload }) => { | |||
</Grid> | |||
<Grid item xs={6} md={6} sx={{textAlign: "left" }}> | |||
<FormLabel sx={{ fontSize: "16px", color: "#000000" }}> | |||
{"HK$ " + FormatUtils.currencyFormat(data.payload?.amount?data.payload?.amount:data.payAmount)} | |||
{"$ " + FormatUtils.currencyFormat(data.payload?.amount?data.payload?.amount:data.payAmount)} | |||
</FormLabel> | |||
</Grid> | |||
</Grid> | |||
@@ -181,16 +208,12 @@ const PaymentDetails = ({ formData,doPrint,onDownload }) => { | |||
</FormLabel> | |||
</Grid> | |||
<Grid item xs={6} md={5} sx={{textAlign: "left" }}> | |||
{onDownload? | |||
<LoadingComponent disableText={true} alignItems="flex-start"/> | |||
: | |||
<Button className="printHidden" variant="contained" sx={{ mt:2 }} onClick={doPrint}> | |||
<DownloadIcon/> | |||
<Typography sx={{fontSize: "16px"}}> | |||
<FormattedMessage id="download"/> | |||
</Typography> | |||
</Button> | |||
} | |||
<Button className="printHidden" variant="contained" disabled={onDownload} sx={{ mt:2 }} onClick={doPrint}> | |||
<DownloadIcon/> | |||
<Typography sx={{fontSize: "16px"}}> | |||
<FormattedMessage id="download"/> | |||
</Typography> | |||
</Button> | |||
</Grid> | |||
</Grid> | |||
</Grid> | |||
@@ -59,9 +59,9 @@ const Index = () => { | |||
React.useEffect(() => { | |||
if (Object.keys(transactionData).length > 0) { | |||
console.log(transactionData) | |||
console.log(itemList) | |||
console.log(record) | |||
// console.log(transactionData) | |||
// console.log(itemList) | |||
// console.log(record) | |||
setOnReady(true); | |||
} | |||
}, [transactionData]); | |||
@@ -102,21 +102,21 @@ const Index = () => { | |||
"paymentId": params.id | |||
}, | |||
onSuccess: function(responseData2){ | |||
responseData2.data["transDateStr"] = DateUtils.dateFormat(responseData2.data.transDateTime, "DD/MM/YYYY"); | |||
responseData2.data["transDateStr"] = responseData2.data.transDateTime; | |||
responseData2.data["transTimeStr"] = DateUtils.dateFormat(responseData2.data.transDateTime, "HH:mm:ss"); | |||
setResponeData(responseData2.transactionData) | |||
setItemList(responseData2.paymentItemList) | |||
setRecord(responseData2.data); | |||
}, | |||
onError: function(){ | |||
responseData.data["transDateStr"] = DateUtils.dateFormat(responseData.data.transDateTime, "DD/MM/YYYY"); | |||
responseData.data["transDateStr"] = responseData.data.transDateTime; | |||
responseData.data["transTimeStr"] = DateUtils.dateFormat(responseData.data.transDateTime, "HH:mm:ss"); | |||
setResponeData(responseData) | |||
} | |||
}); | |||
}else{ | |||
responseData.data["transDateStr"] = DateUtils.dateFormat(responseData.data.transDateTime, "DD/MM/YYYY"); | |||
responseData.data["transDateStr"] = responseData.data.transDateTime; | |||
responseData.data["transTimeStr"] = DateUtils.dateFormat(responseData.data.transDateTime, "HH:mm:ss"); | |||
setResponeData(responseData) | |||
setItemList(responseData.paymentItemList) | |||
@@ -104,7 +104,7 @@ const AckPage = () => { | |||
onSuccess: function(responseData){ | |||
localStorage.removeItem("webtoken"); | |||
localStorage.removeItem("transactionid"); | |||
responseData.data["transDateStr"] = DateUtils.dateFormat(responseData.data.transDateTime, "DD/MM/YYYY"); | |||
responseData.data["transDateStr"] = DateUtils.dateFormat(responseData.data.transDateTime, intl.formatMessage({id: "dateStrFormat"})); | |||
responseData.data["transTimeStr"] = DateUtils.dateFormat(responseData.data.transDateTime, "HH:mm:ss"); | |||
setResponeDataData(responseData.transactionData) | |||
setItemList(responseData.paymentItemList) | |||
@@ -202,7 +202,8 @@ const AckPage = () => { | |||
{/*row 1*/} | |||
<Grid item xs={12} md={12} spacing={2} sx={{ textAlign: "center" }}> | |||
<Typography variant="h3" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "center" }}> | |||
您的申請和付款已收到 | |||
{/* 您的申請和付款已收到 */} | |||
<FormattedMessage id="MSG.paymentMsg"/> | |||
</Typography> | |||
<Grid container justifyContent="center" direction="column" spacing={2} sx={{ p: 2 }} alignitems="stretch" > | |||
<Grid item className="printOrder" xs={12} md={12} sx={{ pt: 2 }} style={{ height: '100%', order: 1 }}> | |||
@@ -253,21 +254,22 @@ const AckPage = () => { | |||
<center> | |||
<Grid item xs={12} md={8} > | |||
<Typography variant="h5" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}> | |||
付款取消訊息: | |||
{/* 付款取消訊息: */} | |||
<FormattedMessage id="MSG.paymentCancelMsg1"/> | |||
<br /><br /> | |||
您的付款已被取消。我們收到了您的付款請求,但由於某些原因,付款無法完成。請注意以下事項: | |||
<FormattedMessage id="MSG.paymentCancelMsg2"/> | |||
<br /><br /> | |||
如果您主動取消了支付,請確認並確保取消是您的意願。 | |||
<FormattedMessage id="MSG.paymentCancelMsg3"/> | |||
<br /> | |||
如果付款被取消是由於系統問題或其他原因,請您嘗試以下解決方法: | |||
<FormattedMessage id="MSG.paymentCancelMsg4"/> | |||
<br /><br /> | |||
檢查您的支付帳戶是否有任何異常或限制。 | |||
<FormattedMessage id="MSG.paymentCancelMsg5"/> | |||
<br /> | |||
確保您的付款資訊準確無誤。 | |||
<FormattedMessage id="MSG.paymentCancelMsg6"/> | |||
<br /> | |||
檢查您的網路連線是否正常。 | |||
<FormattedMessage id="MSG.paymentCancelMsg7"/> | |||
<br /><br /> | |||
如果您需要進一步的協助或有任何疑問,請隨時與我們聯繫,我們將盡快解決您的付款問題。謝謝! | |||
<FormattedMessage id="MSG.paymentCancelMsg8"/> | |||
</Typography> | |||
</Grid> | |||
</center> | |||
@@ -296,29 +298,39 @@ const AckPage = () => { | |||
<Grid container justifyContent="flex-start" alignItems="center" > | |||
<center> | |||
<Grid item xs={12} md={8} > | |||
<Typography variant="h5" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}> | |||
付款失敗訊息: | |||
<FormattedMessage id="MSG.paymentFailMsg1"/> | |||
<br /><br /> | |||
親愛的用戶,很遺憾地告訴您,您的付款操作未成功。我們在處理您的付款時遇到了問題。請您仔細檢查以下事項: | |||
<FormattedMessage id="MSG.paymentFailMsg2"/> | |||
<br /><br /> | |||
您的支付帳戶餘額是否足夠。 | |||
<br /> | |||
您提供的付款資訊是否準確無誤。 | |||
<br /> | |||
請檢查您的網路連線是否正常。 | |||
<ul> | |||
<li> | |||
<FormattedMessage id="MSG.paymentFailMsg3"/> | |||
</li> | |||
<li> | |||
<FormattedMessage id="MSG.paymentFailMsg4"/> | |||
</li> | |||
<li> | |||
<FormattedMessage id="MSG.paymentFailMsg5"/> | |||
</li> | |||
</ul> | |||
<br /><br /> | |||
如果您已確認以上問題無誤,但付款失敗,請您嘗試以下解決方法: | |||
<FormattedMessage id="MSG.paymentFailMsg6"/> | |||
<br /><br /> | |||
嘗試使用其他付款方式進行付款。 | |||
<br /> | |||
檢查您的支付帳戶是否有異常或限制。 | |||
<br /> | |||
聯絡我們的客服人員尋求協助。 | |||
<ul> | |||
<li> | |||
<FormattedMessage id="MSG.paymentFailMsg7"/> | |||
</li> | |||
<li> | |||
<FormattedMessage id="MSG.paymentFailMsg8"/> | |||
</li> | |||
<li> | |||
<FormattedMessage id="MSG.paymentFailMsg9"/> | |||
</li> | |||
</ul> | |||
<br /><br /> | |||
如果您需要進一步的協助或有任何疑問,請隨時與我們聯繫。非常抱歉給您帶來不便,我們將盡快解決您的付款問題。謝謝! | |||
<FormattedMessage id="MSG.paymentFailMsg10"/> | |||
</Typography> | |||
</Grid> | |||
</center> | |||
</Grid> | |||
@@ -10,6 +10,9 @@ import * as HttpUtils from "utils/HttpUtils"; | |||
import * as UrlUtils from "utils/ApiPathConst"; | |||
import { useNavigate } from "react-router-dom"; | |||
import FpsIcon from "assets/images/icons/fps.svg"; | |||
import expiredQrcodeEN from "assets/images/icons/expiredQrcodeEN.png"; | |||
import expiredQrcodeZH from "assets/images/icons/expiredQrcodeZH.png"; | |||
import expiredQrcodeCN from "assets/images/icons/expiredQrcodeCN.png"; | |||
import { useLocation } from 'react-router-dom'; | |||
// import {paymentPath} from "auth/utils"; | |||
import {currencyFormat} from "utils/FormatUtils"; | |||
@@ -19,7 +22,7 @@ import Loadable from 'components/Loadable'; | |||
const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | |||
import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' | |||
import {FormattedMessage} from "react-intl"; | |||
import {FormattedMessage, useIntl} from "react-intl"; | |||
const BackgroundHead = { | |||
backgroundImage: `url(${titleBackgroundImg})`, | |||
width: '100%', | |||
@@ -30,15 +33,21 @@ const BackgroundHead = { | |||
backgroundPosition: 'right' | |||
} | |||
// ==============================|| DASHBOARD - DEFAULT ||============================== // | |||
const Index = () => { | |||
const navigate = useNavigate() | |||
const location = useLocation(); | |||
const intl = useIntl(); | |||
const { locale } = intl; | |||
const [locationData, setLocationData] = React.useState({}); | |||
const [paymentData, setPaymentData] = React.useState({}); | |||
const [onReady, setOnReady] = React.useState(false); | |||
const [qrCodeTimeout, setqrCodeTimeout] = React.useState(false); | |||
const [paymentStatusCode, setPaymentStatusCode] = React.useState(""); | |||
const [expiredQrcode, setExpiredQrcode] = React.useState(expiredQrcodeEN); | |||
const [responeData, setResponeDataData] = React.useState({}); | |||
const [fpsTransctionData, setFpsTransctionData] = React.useState({}); | |||
@@ -49,6 +58,7 @@ const Index = () => { | |||
const [fpsqrcodeurlPrd, setFpsqrcodeurlPrd] = React.useState(""); | |||
const [fpsqrcodeurlFps, setFpsqrcodeurlFps] = React.useState(""); | |||
const [browserType, setBrowserType] = React.useState(""); | |||
const [sysEnv, setSysEnv] = React.useState(""); | |||
const mobileBrowser = "Mobile"; | |||
const desktopBrowser = "Desktop"; | |||
@@ -69,12 +79,14 @@ const Index = () => { | |||
if(Object.keys(location.state).length > 0){ | |||
// console.log (location.state) | |||
setLocationData(location.state) | |||
setBrowserType(desktopBrowser) | |||
if (/Android|webOS|iPhone|iPad|iPod|Opera Mini/i.test(navigator.userAgent)) { | |||
console.log('Mobile web browser'); | |||
// console.log('Mobile web browser'); | |||
setBrowserType(mobileBrowser) | |||
// setFpsqrcodeurl(openPASGUrl) | |||
} else { | |||
console.log('Desktop web browser'); | |||
// console.log('Desktop web browser'); | |||
setBrowserType(desktopBrowser) | |||
} | |||
} | |||
@@ -88,6 +100,17 @@ const Index = () => { | |||
} | |||
}, [locationData]); | |||
React.useEffect(() => { | |||
// console.log (locationData) | |||
if (locale === 'zh-HK'){ | |||
setExpiredQrcode(expiredQrcodeZH) | |||
} else if (locale === 'en'){ | |||
setExpiredQrcode(expiredQrcodeEN) | |||
} else { | |||
setExpiredQrcode(expiredQrcodeCN) | |||
} | |||
}, [locale]); | |||
React.useEffect(() => { | |||
// console.log (paymentData) | |||
if (Object.keys(paymentData).length > 0){ | |||
@@ -159,6 +182,7 @@ const Index = () => { | |||
*/ | |||
setResponeDataData(responseData) | |||
const timeoutdatetime = responseData.fpsmerchanttimeoutdatetime | |||
setSysEnv(responseData.sysEnv) | |||
const searchString = "[UTC]"; | |||
let convertedDateString = ""; | |||
if ( timeoutdatetime.toString().includes(searchString) ){ | |||
@@ -175,12 +199,18 @@ const Index = () => { | |||
console.log(fpsqrcodeurl) | |||
console.log(fpsqrcodeurlwithFps) | |||
const openPASGUrl = pasgPath + '?pay_req_obj=' + encodeURIComponent(fpsqrcodeurl) + '&callback=' | |||
+ encodeURIComponent("https://"+window.location.hostname+ '/paymentPage/fps/fpscallback?TRANSACTION_ID='+transactionid+"&WEB_TOKEN="+webtoken+"&PAYMENT_ID="+localStorage.getItem("paymentId")); | |||
const openPASGUrlPrd = pasgPathPrd + '?pay_req_obj=' + encodeURIComponent(fpsqrcodeurl) + '&callback=' | |||
+ encodeURIComponent("https://"+window.location.hostname+ '/paymentPage/fps/fpscallback?TRANSACTION_ID='+transactionid+"&WEB_TOKEN="+webtoken+"&PAYMENT_ID="+localStorage.getItem("paymentId")); | |||
const openPASGUrl = pasgPath + '?pay_req_obj=' + encodeURIComponent(fpsqrcodeurlwithFps) + '&callback=' | |||
+ encodeURIComponent("https://"+window.location.hostname+ '/paymentPage/fps/fpscallback?&PAYMENT_ID='+localStorage.getItem("paymentId")); | |||
const openPASGUrlPrd = pasgPathPrd + '?pay_req_obj=' + encodeURIComponent(fpsqrcodeurlwithFps) + '&callback=' | |||
+ encodeURIComponent("https://"+window.location.hostname+ '/paymentPage/fps/fpscallback?&PAYMENT_ID='+localStorage.getItem("paymentId")); | |||
const openPASGUrlPrdFps = pasgPath + '?pay_req_obj=' + encodeURIComponent(fpsqrcodeurlwithFps) + '&callback=' | |||
+ encodeURIComponent("https://"+window.location.hostname+ '/paymentPage/fps/fpscallback?TRANSACTION_ID='+transactionid+"&WEB_TOKEN="+webtoken+"&PAYMENT_ID="+localStorage.getItem("paymentId")); | |||
+ encodeURIComponent("https://"+window.location.hostname+ '/paymentPage/fps/fpscallback?&PAYMENT_ID='+localStorage.getItem("paymentId")); | |||
// const openPASGUrl = pasgPath + '?pay_req_obj=' + encodeURIComponent(fpsqrcodeurlwithFps) + '&callback=' | |||
// + encodeURIComponent("https://"+window.location.hostname+ '/paymentPage/fps/fpscallback?TRANSACTION_ID='+transactionid+"&WEB_TOKEN="+webtoken+"&PAYMENT_ID="+localStorage.getItem("paymentId")); | |||
// const openPASGUrlPrd = pasgPathPrd + '?pay_req_obj=' + encodeURIComponent(fpsqrcodeurlwithFps) + '&callback=' | |||
// + encodeURIComponent("https://"+window.location.hostname+ '/paymentPage/fps/fpscallback?TRANSACTION_ID='+transactionid+"&WEB_TOKEN="+webtoken+"&PAYMENT_ID="+localStorage.getItem("paymentId")); | |||
// const openPASGUrlPrdFps = pasgPath + '?pay_req_obj=' + encodeURIComponent(fpsqrcodeurlwithFps) + '&callback=' | |||
// + encodeURIComponent("https://"+window.location.hostname+ '/paymentPage/fps/fpscallback?TRANSACTION_ID='+transactionid+"&WEB_TOKEN="+webtoken+"&PAYMENT_ID="+localStorage.getItem("paymentId")); | |||
setFpsqrcodeurl(openPASGUrl) | |||
setFpsqrcodeurlPrd(openPASGUrlPrd) | |||
setFpsqrcodeurlFps(openPASGUrlPrdFps) | |||
@@ -188,7 +218,7 @@ const Index = () => { | |||
}); | |||
//testing | |||
// const timeoutdatetime = "2024-05-06T11:10:30Z[UTC]" | |||
// const timeoutdatetime = "2024-11-18T07:04:35Z[UTC]" | |||
// const convertedDateString = timeoutdatetime.replace("[UTC]", ""); | |||
// setFpsmerchanttimeoutdatetime(convertedDateString) | |||
// setPaymentId("C202310268000681") | |||
@@ -196,7 +226,7 @@ const Index = () => { | |||
// { | |||
// "paymentid": "C202310268000681", | |||
// "paymentstatus": "INPR", | |||
// "fpsmerchanttimeoutdatetime": "2024-05-06T11:10:30Z[UTC]", | |||
// "fpsmerchanttimeoutdatetime": "2024-11-18T07:04:35Z[UTC]", | |||
// "fpsqrcodeimgbase64": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAYAAAB5fY51AAAuyklEQVR4Xu3dfcy/d1nff2IAAAAASUVORK5CYII=", | |||
// "fpsqrcodeurl": "http://127.0.0.1:8080/api/payment/wallet/fps/enquiryfpspayload/vm.JKDDlTOavR3ASviSwUnS1Lw4-" | |||
// } | |||
@@ -231,6 +261,7 @@ const Index = () => { | |||
}, | |||
onSuccess: function(responseData){ | |||
const paymentstatuscode = responseData.paymentdetail.result.paymentstatuscode; | |||
setPaymentStatusCode(paymentstatuscode) | |||
if (paymentstatuscode != "" && paymentstatuscode != "INPR" ){ | |||
if (paymentstatuscode === 'APPR') { | |||
// const timestamp = Date.now(); | |||
@@ -249,7 +280,8 @@ const Index = () => { | |||
} | |||
}, | |||
onError: function(){ | |||
cancelPayment() | |||
alert("ERROR") | |||
// cancelPayment() | |||
// clearInterval(currentTimer.current); | |||
} | |||
}); | |||
@@ -260,35 +292,43 @@ const Index = () => { | |||
const timeOutDate = new Date(fpsmerchanttimeoutdatetime); | |||
const currentTime = new Date; | |||
const timedowncount = Math.round((timeOutDate.getTime() - currentTime.getTime()) / 1000); | |||
setTimeDownCount(timedowncount); | |||
// console.log(time) | |||
// console.log(timeOutDate) | |||
// console.log(currentTime) | |||
// console.log(timeOutDate.getTime()-currentTime.getTime()) | |||
getPaymentStatus(); | |||
if (timeOutDate.getTime()<currentTime.getTime()){ | |||
// console.log("stop"); | |||
clearInterval(currentTimer.current); | |||
cancelPayment() | |||
if (browserType === desktopBrowser){ | |||
getPaymentStatus(); | |||
if (timeOutDate.getTime()<currentTime.getTime()){ | |||
// console.log("stop"); | |||
clearInterval(currentTimer.current); | |||
setqrCodeTimeout(true) | |||
setTimeDownCount(0); | |||
cancelPayment() | |||
}else{ | |||
setTimeDownCount(timedowncount); | |||
} | |||
} | |||
},[time]) | |||
const cancelPayment = ()=>{ | |||
if (Object.keys(paymentData).length>0){ | |||
HttpUtils.post({ | |||
url: UrlUtils.CANCEL_PAYMENT_URL, | |||
params:{ | |||
"transactionid": paymentData.transactionid, | |||
"webtoken": paymentData.webtoken, | |||
"paymentid": fpsTransctionData.paymentid | |||
}, | |||
onSuccess: function(){ | |||
// navigate('/paymentPage/fps/ackpage'); | |||
let page = '/paymentPage/fps/ackpage'; | |||
let stateParams = { state: { transactionid: paymentData.transactionid} } | |||
navigate(page, stateParams); | |||
} | |||
}); | |||
getPaymentStatus() | |||
if (paymentStatusCode === "INPR"){ | |||
HttpUtils.post({ | |||
url: UrlUtils.CANCEL_PAYMENT_URL, | |||
params:{ | |||
"transactionid": paymentData.transactionid, | |||
"webtoken": paymentData.webtoken, | |||
"paymentid": fpsTransctionData.paymentid | |||
}, | |||
onSuccess: function(){ | |||
navigate('/paymentPage/fps/ackpage'); | |||
let page = '/paymentPage/fps/ackpage'; | |||
let stateParams = { state: { transactionid: paymentData.transactionid} } | |||
navigate(page, stateParams); | |||
} | |||
}); | |||
} | |||
} | |||
} | |||
@@ -330,6 +370,8 @@ const Index = () => { | |||
<Grid item xs={12} md={12} > | |||
<Typography variant="h3" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "center" }}> | |||
<FormattedMessage id="payAlert"/> | |||
<br /><br /> | |||
<img src={FpsIcon} width="80" height="80" alt="FPS"></img> | |||
<br /> | |||
<FormattedMessage id="payTotalDeatail"/> | |||
@@ -338,50 +380,69 @@ const Index = () => { | |||
</Typography> | |||
{browserType==mobileBrowser? | |||
<Typography variant="h3" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "center" }}> | |||
<Button | |||
component="span" | |||
variant="contained" | |||
size="large" | |||
color="primary" | |||
onClick={()=>{ | |||
mobliePayment(); | |||
}} | |||
sx={{ m: 4 }} | |||
>請選擇支付程式付款-Testing</Button> | |||
<Button | |||
component="span" | |||
variant="contained" | |||
size="large" | |||
color="primary" | |||
onClick={()=>{ | |||
mobliePaymentPrd(); | |||
}} | |||
sx={{ m: 4 }} | |||
>請選擇支付程式付款-PRD</Button> | |||
<Button | |||
component="span" | |||
variant="contained" | |||
size="large" | |||
color="primary" | |||
onClick={()=>{ | |||
mobliePaymentFps(); | |||
}} | |||
sx={{ m: 4 }} | |||
>請選擇支付程式付款-fps prefix</Button> | |||
{ | |||
sysEnv=="prod"? | |||
<Button | |||
component="span" | |||
variant="contained" | |||
size="large" | |||
color="primary" | |||
onClick={()=>{ | |||
mobliePaymentPrd(); | |||
}} | |||
sx={{ m: 4 }} | |||
>請選擇支付程式付款</Button> | |||
: | |||
<> | |||
<Button | |||
component="span" | |||
variant="contained" | |||
size="large" | |||
color="primary" | |||
onClick={()=>{ | |||
mobliePayment(); | |||
}} | |||
sx={{ m: 4 }} | |||
>請選擇支付程式付款-Testing</Button> | |||
<Button | |||
component="span" | |||
variant="contained" | |||
size="large" | |||
color="primary" | |||
onClick={()=>{ | |||
mobliePaymentFps(); | |||
}} | |||
sx={{ m: 4 }} | |||
>請選擇支付程式付款-fps prefix</Button> | |||
</> | |||
} | |||
</Typography> | |||
: | |||
<Typography variant="h3" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "center" }}> | |||
請掃描以下二維碼 | |||
<FormattedMessage id="fpsQrcodeTitle1"/> | |||
<br /> | |||
<img src={fpsTransctionData.fpsqrcodeimgbase64} alt="QR Code"/> | |||
{ | |||
!qrCodeTimeout? | |||
<img src={fpsTransctionData.fpsqrcodeimgbase64} alt="QR Code"/> | |||
:<img src={expiredQrcode} alt="Expired QR Code"/> | |||
} | |||
<br /> | |||
{"["+paymentId+"]"} | |||
<br/> | |||
二維碼有效期限3分鐘 | |||
<br /> | |||
請在規定時間內完成付款流程 | |||
<br /> | |||
{"剩餘時間: "+timeDownCount+ "秒"} | |||
{ | |||
timeDownCount<=0? | |||
<FormattedMessage id="fpsQrcodeExpired"/>: | |||
<> | |||
<FormattedMessage id="fpsQrcodeTitle2"/> | |||
<br /> | |||
<FormattedMessage id="fpsQrcodeTitle3"/> | |||
<br /> | |||
<FormattedMessage id="fpsQrcodeTitle4"/> | |||
{timeDownCount} | |||
<FormattedMessage id="fpsQrcodeTitle5"/> | |||
</> | |||
} | |||
</Typography> | |||
} | |||
<Typography variant="h3" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "center" }}> | |||
@@ -312,7 +312,7 @@ const Index = () => { | |||
<br/> | |||
二維碼有效期限3分鐘 | |||
<br /> | |||
請在規定時間內完成付款流程 | |||
請在限規定時間內完成付款流程 | |||
<br /> | |||
{"剩餘時間:"+timeDownCount} | |||
</Typography> | |||
@@ -76,22 +76,22 @@ const Fpscallback = () => { | |||
const loadForm = () => { | |||
const params = new URLSearchParams(window.location.search); | |||
let transactionid = params.get("TRANSACTION_ID") | |||
let webtoken = params.get("WEB_TOKEN") | |||
// let transactionid = params.get("TRANSACTION_ID") | |||
// let webtoken = params.get("WEB_TOKEN") | |||
let paymentId = params.get("PAYMENT_ID") | |||
paymentId = paymentId.split('?is_successful')[0]; | |||
console.log(transactionid) | |||
console.log(webtoken) | |||
// console.log(transactionid) | |||
// console.log(webtoken) | |||
console.log(paymentId) | |||
HttpUtils.post({ | |||
url: UrlUtils.PAYMENT_CALLBACK_STATUS_API, | |||
params:{ | |||
"apprefid": transactionid, | |||
"webtoken": webtoken, | |||
// "apprefid": transactionid, | |||
// "webtoken": webtoken, | |||
"paymentId": paymentId, | |||
"transactionid":Number(transactionid) | |||
// "transactionid":Number(transactionid) | |||
}, | |||
onSuccess: function(responseData){ | |||
setResponeDataData(responseData) | |||
@@ -99,7 +99,7 @@ const Fpscallback = () => { | |||
localStorage.removeItem("webtoken"); | |||
localStorage.removeItem("transactionid"); | |||
} | |||
responseData.data["transDateStr"] = DateUtils.dateFormat(responseData.data.transDateTime, "DD/MM/YYYY"); | |||
responseData.data["transDateStr"] = responseData.data.transDateTime; | |||
responseData.data["transTimeStr"] = DateUtils.dateFormat(responseData.data.transDateTime, "HH:mm:ss"); | |||
setResponeDataData(responseData.transactionData) | |||
setItemList(responseData.paymentItemList) | |||
@@ -191,7 +191,7 @@ const Fpscallback = () => { | |||
{/*row 1*/} | |||
<Grid item xs={12} md={12} spacing={2} sx={{ textAlign: "center" }}> | |||
<Typography variant="h3" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "center" }}> | |||
您的申請和付款已收到 | |||
<FormattedMessage id="MSG.paymentMsg"/> | |||
</Typography> | |||
<Grid container justifyContent="center" direction="column" spacing={2} sx={{ p: 2 }} alignitems="stretch" > | |||
<Grid item className="printOrder" xs={12} md={12} sx={{ pt: 2 }} style={{ height: '100%', order: 1 }}> | |||
@@ -242,21 +242,21 @@ const Fpscallback = () => { | |||
<center> | |||
<Grid item xs={12} md={8} > | |||
<Typography variant="h5" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}> | |||
付款取消訊息: | |||
<br /><br /> | |||
您的付款已被取消。我們收到了您的付款請求,但由於某些原因,付款無法完成。請注意以下事項: | |||
<br /><br /> | |||
如果您主動取消了支付,請確認並確保取消是您的意願。 | |||
<br /> | |||
如果付款被取消是由於系統問題或其他原因,請您嘗試以下解決方法: | |||
<br /><br /> | |||
檢查您的支付帳戶是否有任何異常或限制。 | |||
<br /> | |||
確保您的付款資訊準確無誤。 | |||
<br /> | |||
檢查您的網路連線是否正常。 | |||
<br /><br /> | |||
如果您需要進一步的協助或有任何疑問,請隨時與我們聯繫,我們將盡快解決您的付款問題。謝謝! | |||
<FormattedMessage id="MSG.paymentCancelMsg1"/> | |||
<br /><br /> | |||
<FormattedMessage id="MSG.paymentCancelMsg2"/> | |||
<br /><br /> | |||
<FormattedMessage id="MSG.paymentCancelMsg3"/> | |||
<br /> | |||
<FormattedMessage id="MSG.paymentCancelMsg4"/> | |||
<br /><br /> | |||
<FormattedMessage id="MSG.paymentCancelMsg5"/> | |||
<br /> | |||
<FormattedMessage id="MSG.paymentCancelMsg6"/> | |||
<br /> | |||
<FormattedMessage id="MSG.paymentCancelMsg7"/> | |||
<br /><br /> | |||
<FormattedMessage id="MSG.paymentCancelMsg8"/> | |||
</Typography> | |||
</Grid> | |||
</center> | |||
@@ -285,29 +285,39 @@ const Fpscallback = () => { | |||
<Grid container justifyContent="flex-start" alignItems="center" > | |||
<center> | |||
<Grid item xs={12} md={8} > | |||
<Typography variant="h5" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}> | |||
付款失敗訊息: | |||
<FormattedMessage id="MSG.paymentFailMsg1"/> | |||
<br /><br /> | |||
親愛的用戶,很遺憾地告訴您,您的付款操作未成功。我們在處理您的付款時遇到了問題。請您仔細檢查以下事項: | |||
<FormattedMessage id="MSG.paymentFailMsg2"/> | |||
<br /><br /> | |||
您的支付帳戶餘額是否足夠。 | |||
<br /> | |||
您提供的付款資訊是否準確無誤。 | |||
<br /> | |||
請檢查您的網路連線是否正常。 | |||
<ul> | |||
<li> | |||
<FormattedMessage id="MSG.paymentFailMsg3"/> | |||
</li> | |||
<li> | |||
<FormattedMessage id="MSG.paymentFailMsg4"/> | |||
</li> | |||
<li> | |||
<FormattedMessage id="MSG.paymentFailMsg5"/> | |||
</li> | |||
</ul> | |||
<br /><br /> | |||
如果您已確認以上問題無誤,但付款失敗,請您嘗試以下解決方法: | |||
<FormattedMessage id="MSG.paymentFailMsg6"/> | |||
<br /><br /> | |||
嘗試使用其他付款方式進行付款。 | |||
<br /> | |||
檢查您的支付帳戶是否有異常或限制。 | |||
<br /> | |||
聯絡我們的客服人員尋求協助。 | |||
<ul> | |||
<li> | |||
<FormattedMessage id="MSG.paymentFailMsg7"/> | |||
</li> | |||
<li> | |||
<FormattedMessage id="MSG.paymentFailMsg8"/> | |||
</li> | |||
<li> | |||
<FormattedMessage id="MSG.paymentFailMsg9"/> | |||
</li> | |||
</ul> | |||
<br /><br /> | |||
如果您需要進一步的協助或有任何疑問,請隨時與我們聯繫。非常抱歉給您帶來不便,我們將盡快解決您的付款問題。謝謝! | |||
<FormattedMessage id="MSG.paymentFailMsg10"/> | |||
</Typography> | |||
</Grid> | |||
</center> | |||
</Grid> | |||
@@ -64,7 +64,7 @@ const MultiPaymentWindow = (props) => { | |||
// console.log(props.transactionData) | |||
if(Object.keys(props.transactionData).length > 0){ | |||
setLoadtTransactionData(props.transactionData) | |||
console.log(props.browserType) | |||
// console.log(props.browserType) | |||
} | |||
}, [props.transactionData]); | |||
@@ -292,7 +292,7 @@ const MultiPaymentWindow = (props) => { | |||
<DialogContent> | |||
<DialogContentText> | |||
<FormLabel sx={{ fontSize: "20px", color: "#000000", textAlign: "left", ml:1}}> | |||
<FormattedMessage id="paymentProcessLimited"/>。 | |||
<FormattedMessage id="paymentProcessLimited"/> | |||
</FormLabel> | |||
<Grid item xs={12} md={12} sx={{ pt: 2 }} style={{ height: '100%' }} width="100%"> | |||
<Box xs={12} md={12} sx={{ p: 4, border: '3px solid #eee', borderRadius: '10px' }} > | |||
@@ -304,7 +304,7 @@ const MultiPaymentWindow = (props) => { | |||
</Typography> | |||
{/* <Typography variant="h5" sx={{ textAlign: "left" }}> | |||
支付金額: HK$ {FormatUtils.currencyFormat(props.totalAmount)} | |||
付款金額: HK$ {FormatUtils.currencyFormat(props.totalAmount)} | |||
</Typography> */} | |||
{!props.onReady ? | |||
<LoadingComponent /> | |||
@@ -373,7 +373,7 @@ const MultiPaymentWindow = (props) => { | |||
</Grid>: | |||
<Grid container direction="row" justifyContent="center" alignItems="center"> | |||
<FormLabel sx={{ fontSize: "20px", color: "#000000", textAlign: "center"}}> | |||
<FormattedMessage id="paymentMethodNotAvailable"/>。 | |||
<FormattedMessage id="paymentMethodNotAvailable"/> | |||
</FormLabel> | |||
</Grid> | |||
} | |||
@@ -381,12 +381,12 @@ const MultiPaymentWindow = (props) => { | |||
<Grid item xs={12} md={12}> | |||
<Grid container > | |||
<Grid item> | |||
<Typography variant="pnspsFormParagraphBold" sx={{ color: "#000000", textAlign: "left" }}> | |||
<FormattedMessage id="payTotal"/>(HK$): | |||
<Typography variant="h5" sx={{ color: "#000000", textAlign: "left" }}> | |||
<FormattedMessage id="payTotal"/> ($): | |||
</Typography> | |||
</Grid> | |||
<Grid item> | |||
<Typography variant="pnspsFormParagraphBold" sx={{color: "#000000", textAlign: "left" }}> | |||
<Typography variant="h5" sx={{color: "#000000", textAlign: "left" }}> | |||
{" HK$ " + FormatUtils.currencyFormat(props.totalAmount)} | |||
</Typography> | |||
</Grid> | |||
@@ -123,7 +123,7 @@ const Index = () => { | |||
localStorage.removeItem("webtoken"); | |||
localStorage.removeItem("transactionid"); | |||
} | |||
responseData.data["transDateStr"] = DateUtils.dateFormat(responseData.data.transDateTime, "DD/MM/YYYY"); | |||
responseData.data["transDateStr"] = responseData.data.transDateTime; | |||
responseData.data["transTimeStr"] = DateUtils.dateFormat(responseData.data.transDateTime, "HH:mm:ss"); | |||
setResponeDataData(responseData.transactionData) | |||
setItemList(responseData.paymentItemList) | |||
@@ -294,29 +294,39 @@ const Index = () => { | |||
<Grid container justifyContent="flex-start" alignItems="center" > | |||
<center> | |||
<Grid item xs={12} md={8} > | |||
<Typography variant="h5" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}> | |||
<FormattedMessage id="MSG.paymentFailMsg1"/> | |||
<br /><br /> | |||
<FormattedMessage id="MSG.paymentFailMsg2"/> | |||
<br /><br /> | |||
<FormattedMessage id="MSG.paymentFailMsg3"/> | |||
<br /> | |||
<FormattedMessage id="MSG.paymentFailMsg4"/> | |||
<br /> | |||
<FormattedMessage id="MSG.paymentFailMsg5"/> | |||
<ul> | |||
<li> | |||
<FormattedMessage id="MSG.paymentFailMsg3"/> | |||
</li> | |||
<li> | |||
<FormattedMessage id="MSG.paymentFailMsg4"/> | |||
</li> | |||
<li> | |||
<FormattedMessage id="MSG.paymentFailMsg5"/> | |||
</li> | |||
</ul> | |||
<br /><br /> | |||
<FormattedMessage id="MSG.paymentFailMsg6"/> | |||
<br /><br /> | |||
<FormattedMessage id="MSG.paymentFailMsg7"/> | |||
<br /> | |||
<FormattedMessage id="MSG.paymentFailMsg8"/> | |||
<br /> | |||
<FormattedMessage id="MSG.paymentFailMsg9"/> | |||
<ul> | |||
<li> | |||
<FormattedMessage id="MSG.paymentFailMsg7"/> | |||
</li> | |||
<li> | |||
<FormattedMessage id="MSG.paymentFailMsg8"/> | |||
</li> | |||
<li> | |||
<FormattedMessage id="MSG.paymentFailMsg9"/> | |||
</li> | |||
</ul> | |||
<br /><br /> | |||
<FormattedMessage id="MSG.paymentFailMsg10"/> | |||
</Typography> | |||
</Typography> | |||
</Grid> | |||
</center> | |||
</Grid> | |||
@@ -9,7 +9,7 @@ import { FiDataGrid } from "components/FiDataGrid"; | |||
import { clickableLink } from 'utils/CommonFunction'; | |||
// ==============================|| EVENT TABLE ||============================== // | |||
export default function SearchPaymentTable({ searchCriteria }) { | |||
export default function SearchPaymentTable({ searchCriteria, applyGridOnReady, applySearch}) { | |||
const [_searchCriteria, set_searchCriteria] = React.useState(searchCriteria); | |||
const navigate = useNavigate() | |||
@@ -96,10 +96,16 @@ export default function SearchPaymentTable({ searchCriteria }) { | |||
columns={columns} | |||
customPageSize={10} | |||
onRowDoubleClick={handleEditClick} | |||
doLoad={{ | |||
url:PAYMENT_LIST, | |||
params:_searchCriteria, | |||
}} | |||
applyGridOnReady={applyGridOnReady} | |||
applySearch={applySearch} | |||
// doLoad={{ | |||
// url:PAYMENT_LIST, | |||
// params:_searchCriteria, | |||
// }} | |||
doLoad={React.useMemo(() => ({ | |||
url: PAYMENT_LIST, | |||
params: _searchCriteria, | |||
}), [_searchCriteria])} | |||
/> | |||
</div> | |||
); | |||
@@ -19,7 +19,7 @@ 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"; | |||
// ==============================|| DASHBOARD - DEFAULT ||============================== // | |||
const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => { | |||
const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady }) => { | |||
const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom); | |||
const [maxDate, setMaxDate] = React.useState(searchCriteria.dateTo); | |||
@@ -31,6 +31,18 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => { | |||
const [fromDateValue, setFromDateValue] = React.useState("dd / mm / yyyy"); | |||
const [toDateValue, setToDateValue] = React.useState("dd / mm / yyyy"); | |||
React.useEffect(() => { | |||
if(searchCriteria.status!=undefined){ | |||
if(searchCriteria.status === ""){ | |||
ComboData.paymentStatus[0] | |||
}else{ | |||
setStatus(ComboData.paymentStatus.find(item => item.type === searchCriteria.status)) | |||
} | |||
}else{ | |||
setStatus(ComboData.paymentStatus[0]) | |||
} | |||
}, [searchCriteria]); | |||
React.useEffect(() => { | |||
setFromDateValue(minDate); | |||
}, [minDate]); | |||
@@ -62,7 +74,10 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => { | |||
setStatus(ComboData.paymentStatus[0]); | |||
setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14))) | |||
setMaxDate(DateUtils.dateValue(new Date())) | |||
reset(); | |||
reset({ | |||
code:"", | |||
transNo:"" | |||
}); | |||
} | |||
@@ -215,6 +230,7 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => { | |||
<Button | |||
variant="contained" | |||
type="submit" | |||
disabled={onGridReady} | |||
> | |||
Submit | |||
</Button> | |||
@@ -7,6 +7,7 @@ import { | |||
import MainCard from "components/MainCard"; | |||
import * as React from "react"; | |||
import * as DateUtils from "utils/DateUtils"; | |||
import { getSearchCriteria } from "auth/utils"; | |||
import Loadable from 'components/Loadable'; | |||
const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | |||
@@ -28,18 +29,34 @@ const BackgroundHead = { | |||
const Index = () => { | |||
const [searchCriteria, setSearchCriteria] = React.useState({ | |||
dateTo: DateUtils.dateValue(new Date()), | |||
dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)), | |||
}); | |||
const [searchCriteria, setSearchCriteria] = React.useState({}); | |||
const [onReady, setOnReady] = React.useState(false); | |||
const [onGridReady, setGridOnReady] = React.useState(false); | |||
React.useEffect(() => { | |||
if (Object.keys(getSearchCriteria(window.location.pathname)).length>0){ | |||
setSearchCriteria(getSearchCriteria(window.location.pathname)) | |||
}else{ | |||
localStorage.setItem('searchCriteria',"") | |||
setSearchCriteria({ | |||
dateTo: DateUtils.dateValue(new Date()), | |||
dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)), | |||
}) | |||
} | |||
}, []); | |||
React.useEffect(() => { | |||
setOnReady(true); | |||
}, [searchCriteria]); | |||
function applySearch(input) { | |||
setGridOnReady(true) | |||
setSearchCriteria(input); | |||
localStorage.setItem('searchCriteria', JSON.stringify({path:window.location.pathname,data:input})) | |||
} | |||
function applyGridOnReady(input) { | |||
setGridOnReady(input); | |||
} | |||
return ( | |||
@@ -63,8 +80,9 @@ const Index = () => { | |||
{/*row 1*/} | |||
<Grid item xs={12} md={12} lg={12} sx={{mb:-1}}> | |||
<SearchForm | |||
applySearch={applySearch} | |||
searchCriteria={searchCriteria} | |||
applySearch={applySearch} | |||
searchCriteria={searchCriteria} | |||
onGridReady={onGridReady} | |||
/> | |||
</Grid> | |||
{/*row 2*/} | |||
@@ -76,6 +94,8 @@ const Index = () => { | |||
> | |||
<EventTable | |||
searchCriteria={searchCriteria} | |||
applyGridOnReady={applyGridOnReady} | |||
applySearch={applySearch} | |||
/> | |||
</MainCard> | |||
</Grid> | |||
@@ -14,7 +14,7 @@ import { clickableLink } from 'utils/CommonFunction'; | |||
import {PAYMENT_LIST} from "utils/ApiPathConst"; | |||
// ==============================|| EVENT TABLE ||============================== // | |||
export default function SearchPublicNoticeTable({ searchCriteria }) { | |||
export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnReady, applySearch }) { | |||
const navigate = useNavigate() | |||
const theme = useTheme(); | |||
const isMdOrLg = useMediaQuery(theme.breakpoints.up('md')); | |||
@@ -94,7 +94,7 @@ export default function SearchPublicNoticeTable({ searchCriteria }) { | |||
{ | |||
id: 'payAmount', | |||
field: 'payAmount', | |||
headerName: intl.formatMessage({id: 'currencyAmount'}) + ' ($)', | |||
headerName: intl.formatMessage({id: 'currencyAmount'}), | |||
width: 150, | |||
valueGetter: (params) => { | |||
return (params?.value) ? "$ " + FormatUtils.currencyFormat(params?.value) : ""; | |||
@@ -110,10 +110,16 @@ export default function SearchPublicNoticeTable({ searchCriteria }) { | |||
columns={columns} | |||
customPageSize={10} | |||
onRowDoubleClick={handleEditDoubleClick} | |||
doLoad={{ | |||
applyGridOnReady={applyGridOnReady} | |||
applySearch={applySearch} | |||
// doLoad={{ | |||
// url: PAYMENT_LIST, | |||
// params: _searchCriteria, | |||
// }} | |||
doLoad={React.useMemo(() => ({ | |||
url: PAYMENT_LIST, | |||
params: _searchCriteria, | |||
}} | |||
}), [_searchCriteria])} | |||
/> | |||
</div> | |||
); | |||
@@ -21,11 +21,11 @@ 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"; | |||
// ==============================|| DASHBOARD - DEFAULT ||============================== // | |||
const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => { | |||
const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady }) => { | |||
const intl = useIntl(); | |||
const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom); | |||
const [maxDate, setMaxDate] = React.useState(searchCriteria.dateTo); | |||
const [status, setStatus] = React.useState(ComboData.paymentStatus[0]); | |||
const [status, setStatus] = React.useState(searchCriteria.status!=undefined?ComboData.paymentStatus.find(item => item.type === searchCriteria.status):ComboData.paymentStatus[0]); | |||
const [fromDateValue, setFromDateValue] = React.useState("dd / mm / yyyy"); | |||
const [toDateValue, setToDateValue] = React.useState("dd / mm / yyyy"); | |||
@@ -78,7 +78,11 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => { | |||
setStatus(ComboData.paymentStatus[0]); | |||
setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14))) | |||
setMaxDate(DateUtils.dateValue(new Date())) | |||
reset(); | |||
reset({ | |||
code:"", | |||
transNo:"" | |||
}); | |||
localStorage.setItem('searchCriteria',"") | |||
} | |||
@@ -181,6 +185,7 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => { | |||
disablePortal={false} | |||
id="status" | |||
size="small" | |||
disableClearable | |||
filterOptions={(options) => options} | |||
options={ComboData.paymentStatus} | |||
value={status} | |||
@@ -239,6 +244,7 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => { | |||
variant="contained" | |||
type="submit" | |||
aria-label={intl.formatMessage({id: 'submit'})} | |||
disabled={onGridReady} | |||
> | |||
<FormattedMessage id="submit"/> | |||
</Button> | |||
@@ -14,6 +14,7 @@ const SearchForm = Loadable(React.lazy(() => import('./SearchForm'))); | |||
const EventTable = Loadable(React.lazy(() => import('./DataGrid'))); | |||
import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' | |||
import {FormattedMessage} from "react-intl"; | |||
import { getSearchCriteria } from "auth/utils"; | |||
const BackgroundHead = { | |||
backgroundImage: `url(${titleBackgroundImg})`, | |||
@@ -33,13 +34,34 @@ const Index = () => { | |||
dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)), | |||
}); | |||
const [onReady, setOnReady] = React.useState(false); | |||
const [onGridReady, setGridOnReady] = React.useState(false); | |||
React.useEffect(() => { | |||
setOnReady(true); | |||
if (Object.keys(getSearchCriteria(window.location.pathname)).length>0){ | |||
setSearchCriteria(getSearchCriteria(window.location.pathname)) | |||
}else{ | |||
localStorage.setItem('searchCriteria',"") | |||
setSearchCriteria({ | |||
dateTo: DateUtils.dateValue(new Date()), | |||
dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)), | |||
}) | |||
} | |||
}, []); | |||
React.useEffect(() => { | |||
if(Object.keys(searchCriteria).length>0){ | |||
setOnReady(true); | |||
} | |||
}, [searchCriteria]); | |||
function applySearch(input) { | |||
setGridOnReady(true) | |||
setSearchCriteria(input); | |||
localStorage.setItem('searchCriteria', JSON.stringify({path:window.location.pathname,data:input})) | |||
} | |||
function applyGridOnReady(input) { | |||
setGridOnReady(input); | |||
} | |||
return ( | |||
@@ -63,8 +85,9 @@ const Index = () => { | |||
{/*row 1*/} | |||
<Grid item xs={12} md={12} lg={12}> | |||
<SearchForm | |||
applySearch={applySearch} | |||
searchCriteria={searchCriteria} | |||
applySearch={applySearch} | |||
searchCriteria={searchCriteria} | |||
onGridReady={onGridReady} | |||
/> | |||
</Grid> | |||
{/*row 2*/} | |||
@@ -76,6 +99,8 @@ const Index = () => { | |||
> | |||
<EventTable | |||
searchCriteria={searchCriteria} | |||
applyGridOnReady={applyGridOnReady} | |||
applySearch={applySearch} | |||
/> | |||
</MainCard> | |||
</Grid> | |||
@@ -520,7 +520,9 @@ const Index = () => { | |||
}} | |||
> | |||
<DialogTitle></DialogTitle> | |||
<Typography variant="h2" style={{ padding: '16px' }}>行動失敗</Typography> | |||
<Typography variant="h2" style={{ padding: '16px' }}> | |||
<FormattedMessage id ="MSG.actionFail"/> | |||
</Typography> | |||
<DialogContent style={{ display: 'flex', }}> | |||
<Stack direction="column" justifyContent="space-between"> | |||
{ | |||
@@ -27,26 +27,50 @@ const SearchPublicNoticeForm = ({ formData }) => { | |||
initialValues: data, | |||
}); | |||
const DisplayField = ({ name, width }) => { | |||
return <TextField | |||
fullWidth | |||
disabled | |||
size="small" | |||
onChange={formik.handleChange} | |||
id={name} | |||
name={name} | |||
value={formik.values[name]} | |||
variant="outlined" | |||
sx={ | |||
{ | |||
"& .MuiInputBase-input.Mui-disabled": { | |||
WebkitTextFillColor: "#000000", | |||
background: "#f8f8f8", | |||
}, | |||
width: width ? width : '100%' | |||
} | |||
const DisplayField = ({ name, width, dummyUser }) => { | |||
return <> | |||
{dummyUser? | |||
<TextField | |||
fullWidth | |||
disabled | |||
size="small" | |||
onChange={formik.handleChange} | |||
id={name} | |||
name={name} | |||
value={"GLD: "+formik.values[name]} | |||
variant="outlined" | |||
sx={ | |||
{ | |||
"& .MuiInputBase-input.Mui-disabled": { | |||
WebkitTextFillColor: "#000000", | |||
background: "#f8f8f8", | |||
}, | |||
width: width ? width : '100%' | |||
} | |||
} | |||
/> | |||
: | |||
<TextField | |||
fullWidth | |||
disabled | |||
size="small" | |||
onChange={formik.handleChange} | |||
id={name} | |||
name={name} | |||
value={formik.values[name]} | |||
variant="outlined" | |||
sx={ | |||
{ | |||
"& .MuiInputBase-input.Mui-disabled": { | |||
WebkitTextFillColor: "#000000", | |||
background: "#f8f8f8", | |||
}, | |||
width: width ? width : '100%' | |||
} | |||
} | |||
/> | |||
} | |||
/>; | |||
</> | |||
} | |||
@@ -97,9 +121,16 @@ const SearchPublicNoticeForm = ({ formData }) => { | |||
</Grid> | |||
<Grid item xs={12} md={8} lg={8}> | |||
<DisplayField | |||
name={formik.values?.orgId ? 'enCompanyName' : 'contactPerson'} | |||
/> | |||
{ | |||
formik.values?.orgId? | |||
<DisplayField | |||
name={formik.values?.enCompanyName == "GLD" ? 'custName' : 'enCompanyName'} | |||
dummyUser={true} | |||
/>: | |||
<DisplayField | |||
name={'contactPerson'} | |||
/> | |||
} | |||
</Grid> | |||
</Grid> | |||
</Grid> | |||
@@ -131,6 +131,21 @@ const FormPanel = ({ formData }) => { | |||
setSaving(false); | |||
return; | |||
} | |||
if (!values.length|| values.length <= 0) { | |||
setWarningText("Column should > 0"); | |||
setIsWarningPopUp(true); | |||
setSaving(false); | |||
return; | |||
} | |||
if(formik.values.groupType == "Private Bill" ){ | |||
if (!values.noOfPages || values.noOfPages <= 0) { | |||
setWarningText("Page should > 0"); | |||
setIsWarningPopUp(true); | |||
setSaving(false); | |||
return; | |||
} | |||
} | |||
// console.log(values); | |||
HttpUtils.postWithFiles({ | |||
url: UrlUtils.CREATE_PROOF, | |||
@@ -208,7 +223,7 @@ const FormPanel = ({ formData }) => { | |||
<Grid item xs={12} md={12}> | |||
<Stack direction="row" sx={{ display: 'flex', alignItems: 'center' }}> | |||
<FormLabel sx={{ paddingRight: 2, textAlign: "center" }}> | |||
<Typography variant="h5">Deadline for online proof with revision:</Typography> | |||
<Typography variant="h5">Deadline for online manuscript revision:</Typography> | |||
</FormLabel> | |||
<TextField | |||
fullWidth | |||
@@ -59,10 +59,10 @@ export default function UploadFileTable({ recordList, setRecordList, showPageCol | |||
...rowModesModel, | |||
[id]: { mode: GridRowModes.View, ignoreModifications: true }, | |||
}); | |||
console.log("Starting Delete") | |||
const editedRow = rows.find((row) => row.id === id); | |||
console.log(editedRow) | |||
console.log(editedRow.isNew) | |||
// console.log("Starting Delete") | |||
// const editedRow = rows.find((row) => row.id === id); | |||
// console.log(editedRow) | |||
// console.log(editedRow.isNew) | |||
setRecordList(rows.filter((row) => row.id !== id)); | |||
setRows(rows.filter((row) => row.id !== id)); | |||
} | |||
@@ -181,7 +181,7 @@ const Index = ({ record }) => { | |||
<DialogContent style={{ display: 'flex', }}> | |||
<Stack direction="column" justifyContent="space-between"> | |||
<Typography variant="h4"> | |||
<FormattedMessage id="totalAmount" /> (HK$): {FormatUtils.currencyFormat(record.fee)} | |||
<FormattedMessage id="totalAmount" /> ($): {FormatUtils.currencyFormat(record.fee)} | |||
</Typography> | |||
</Stack> | |||
</DialogContent> | |||
@@ -70,6 +70,7 @@ const Index = ({ record }) => { | |||
navigate("/publicNotice"); | |||
}} | |||
> | |||
<FormattedMessage id="backToNoticePage" /> | |||
</Button> | |||
</Typography> | |||
</Grid> | |||
@@ -44,12 +44,12 @@ const Index = ({ record }) => { | |||
<Grid container justifyContent="flex-start" alignItems="center" > | |||
<center> | |||
<Grid item xs={12} md={8} > | |||
<Typography variant="h2" sx={{ textAlign: "left", ml: 4, mr: 4, mt: 4, borderBottom: "1px solid black" }}> | |||
<Typography variant="h4" sx={{ textAlign: "left", ml: 4, mr: 4, mt: 4, borderBottom: "1px solid black" }}> | |||
<FormattedMessage id="proofPaymentHeader_demandNote" /> | |||
</Typography> | |||
<Typography variant="h3" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}> | |||
<Typography variant="h5" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}> | |||
<div dangerouslySetInnerHTML={{ | |||
__html: intl.formatMessage( | |||
{ | |||
@@ -67,7 +67,7 @@ const Index = ({ record }) => { | |||
id: 'proofPaymentBody_demandNote2' | |||
}, | |||
{ | |||
closingDateOff: DateUtils.dateStr(record.closingDateOff), | |||
closingDateOff: DateUtils.dateFormat(record?.closingDateOff, intl.formatMessage({id: "dateStrFormat"})), | |||
email: record?.mail, | |||
} | |||
) | |||
@@ -79,7 +79,7 @@ const Index = ({ record }) => { | |||
id: 'proofPaymentBody_demandNote3' | |||
}, | |||
{ | |||
paymentDeadline: DateUtils.dateStr(record?.closingDate), | |||
paymentDeadline: DateUtils.dateFormat(record?.closingDate, intl.formatMessage({id: "dateStrFormat"})), | |||
} | |||
) | |||
}} /> | |||
@@ -105,6 +105,7 @@ const Index = ({ record }) => { | |||
navigate("/publicNotice"); | |||
}} | |||
> | |||
<FormattedMessage id="backToNoticePage" /> | |||
</Button> | |||
</Typography> | |||
</Grid> | |||
@@ -44,12 +44,12 @@ const Index = ({ record }) => { | |||
<Grid container justifyContent="flex-start" alignItems="center" > | |||
<center> | |||
<Grid item xs={12} md={8} > | |||
<Typography variant="h2" sx={{ textAlign: "left", ml: 4, mr: 4, mt: 4, borderBottom: "1px solid black" }}> | |||
<Typography variant="h4" sx={{ textAlign: "left", ml: 4, mr: 4, mt: 4, borderBottom: "1px solid black" }}> | |||
<FormattedMessage id="proofPaymentHeader_office" /> | |||
</Typography> | |||
<Typography variant="h3" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}> | |||
<Typography variant="h5" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}> | |||
<div dangerouslySetInnerHTML={{ | |||
__html: intl.formatMessage( | |||
{ | |||
@@ -91,7 +91,7 @@ const Index = ({ record }) => { | |||
id: 'proofPaymentBody_office5' | |||
}, | |||
{ | |||
paymentDeadline: DateUtils.dateStr(record?.closingDate), | |||
paymentDeadline: DateUtils.dateFormat(record?.closingDate, intl.formatMessage({id: "dateStrFormat"})), | |||
} | |||
) | |||
}} /> | |||
@@ -117,6 +117,7 @@ const Index = ({ record }) => { | |||
navigate("/publicNotice"); | |||
}} | |||
> | |||
<FormattedMessage id="backToNoticePage" /> | |||
</Button> | |||
</Typography> | |||
</Grid> | |||
@@ -32,7 +32,9 @@ import { | |||
// useEffect, | |||
useState | |||
} from "react"; | |||
import { PNSPS_BUTTON_THEME, PNSPS_LONG_BUTTON_THEME } from "../../../themes/buttonConst"; | |||
import { PNSPS_BUTTON_THEME, | |||
// PNSPS_LONG_BUTTON_THEME | |||
} from "../../../themes/buttonConst"; | |||
import { ThemeProvider } from "@emotion/react"; | |||
import { FormattedMessage, useIntl } from "react-intl"; | |||
// ==============================|| DASHBOARD - DEFAULT ||============================== // | |||
@@ -145,11 +147,11 @@ const Index = () => { | |||
<Grid container justifyContent="flex-start" alignItems="center" > | |||
<center> | |||
<Grid item xs={12} md={8} > | |||
<Typography variant="h3" sx={{ textAlign: "left", ml: 4, mr: 4, mt: 4, borderBottom: "1px solid black" }}> | |||
<Typography variant="h4" sx={{ textAlign: "left", ml: 4, mr: 4, mt: 4, borderBottom: "1px solid black" }}> | |||
<FormattedMessage id="proofPaymentHeader_online" /> | |||
</Typography> | |||
<Typography variant="h4" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}> | |||
<Typography variant="h5" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}> | |||
<div dangerouslySetInnerHTML={{ | |||
__html: intl.formatMessage( | |||
{ | |||
@@ -167,7 +169,7 @@ const Index = () => { | |||
id: 'proofPaymentBody_online2' | |||
}, | |||
{ | |||
paymentDeadline: DateUtils.dateStr(record?.closingDate), | |||
paymentDeadline: DateUtils.dateFormat(record?.closingDate, intl.formatMessage({id: "dateStrFormat"})), | |||
} | |||
) | |||
}} /> | |||
@@ -175,10 +177,11 @@ const Index = () => { | |||
</Typography> | |||
<Typography variant="h4" sx={{ ml: 8, textAlign: "left" }}> | |||
<ThemeProvider theme={PNSPS_LONG_BUTTON_THEME}> | |||
<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) }} | |||
> | |||
@@ -238,7 +241,7 @@ const Index = () => { | |||
<DialogContent style={{ display: 'flex', }}> | |||
<Stack direction="column" justifyContent="space-between"> | |||
<Typography variant="h4"> | |||
<FormattedMessage id="totalAmount" /> (HK$): {FormatUtils.currencyFormat(fee)} | |||
<FormattedMessage id="totalAmount" /> ($): {FormatUtils.currencyFormat(fee)} | |||
</Typography> | |||
</Stack> | |||
</DialogContent> | |||
@@ -34,9 +34,11 @@ const ApplicationDetailCard = ({ | |||
const [data, setData] = useState({}); | |||
const [cancelPopUp, setCancelPopUp] = useState(false); | |||
const [onDownload, setOnDownload] = useState(false); | |||
useEffect(() => { | |||
if (formData) { | |||
console.log(formData) | |||
setData(formData); | |||
} | |||
}, [formData]); | |||
@@ -46,26 +48,50 @@ const ApplicationDetailCard = ({ | |||
initialValues: data, | |||
}); | |||
const DisplayField = ({ name, width }) => { | |||
return <TextField | |||
fullWidth | |||
disabled | |||
size="small" | |||
onChange={formik.handleChange} | |||
id={name} | |||
name={name} | |||
value={formik.values[name]} | |||
variant="outlined" | |||
sx={ | |||
{ | |||
"& .MuiInputBase-input.Mui-disabled": { | |||
WebkitTextFillColor: "#000000", | |||
background: "#f8f8f8", | |||
}, | |||
width: width ? width : '100%' | |||
} | |||
const DisplayField = ({ name, width, dummyUser }) => { | |||
return <> | |||
{dummyUser? | |||
<TextField | |||
fullWidth | |||
disabled | |||
size="small" | |||
onChange={formik.handleChange} | |||
id={name} | |||
name={name} | |||
value={"GLD: "+formik.values[name]} | |||
variant="outlined" | |||
sx={ | |||
{ | |||
"& .MuiInputBase-input.Mui-disabled": { | |||
WebkitTextFillColor: "#000000", | |||
background: "#f8f8f8", | |||
}, | |||
width: width ? width : '100%' | |||
} | |||
} | |||
/> | |||
: | |||
<TextField | |||
fullWidth | |||
disabled | |||
size="small" | |||
onChange={formik.handleChange} | |||
id={name} | |||
name={name} | |||
value={formik.values[name]} | |||
variant="outlined" | |||
sx={ | |||
{ | |||
"& .MuiInputBase-input.Mui-disabled": { | |||
WebkitTextFillColor: "#000000", | |||
background: "#f8f8f8", | |||
}, | |||
width: width ? width : '100%' | |||
} | |||
} | |||
/> | |||
} | |||
/>; | |||
</> | |||
} | |||
const confirmCancel = () => { | |||
@@ -83,8 +109,15 @@ const ApplicationDetailCard = ({ | |||
} | |||
const genProof = () => { | |||
setOnDownload(true) | |||
HttpUtils.fileDownload({ | |||
url: UrlUtils.GEN_GAZETTE_PROOF + "/" + params.id | |||
url: UrlUtils.GEN_GAZETTE_PROOF + "/" + params.id, | |||
onResponse:()=>{ | |||
setOnDownload(false) | |||
}, | |||
onError:()=>{ | |||
setOnDownload(false) | |||
} | |||
}); | |||
} | |||
@@ -105,7 +138,7 @@ const ApplicationDetailCard = ({ | |||
component="span" | |||
variant="contained" | |||
size="large" | |||
disabled={!showProofBtn} | |||
disabled={!showProofBtn||onDownload} | |||
onClick={genProof} | |||
> | |||
<Typography variant="h5">Proof Slip</Typography> | |||
@@ -170,10 +203,12 @@ const ApplicationDetailCard = ({ | |||
<Grid item xs={12} md={9} lg={9}> | |||
<FormControl variant="outlined" fullWidth disabled > | |||
{data.orgId === null ? | |||
<DisplayField name="contactPerson" /> | |||
{data?.orgId? | |||
<DisplayField | |||
name="applicant" | |||
dummyUser={data?.enCompanyName == "GLD" ? true : false}/> | |||
: | |||
<DisplayField name="applicant" /> | |||
<DisplayField name="contactPerson" /> | |||
} | |||
</FormControl> | |||
</Grid> | |||
@@ -270,7 +305,7 @@ const ApplicationDetailCard = ({ | |||
</Grid> | |||
<Grid item xs={12} md={12} lg={12} | |||
sx={{ display: 'flex', alignItems: 'center' }}> | |||
<Typography variant="h5">Deadline for confirm proof and payment</Typography> | |||
<Typography variant="h5">Deadline for confirm proof and payment:</Typography> | |||
</Grid> | |||
<Grid item xs={12} md={12} lg={12} sx={{ mb: 4, display: 'flex', alignItems: 'center' }}> | |||
<Typography variant="h5">Before {DateUtils.datetimeStr(data.proofPaymentDeadline)}</Typography> | |||
@@ -76,7 +76,7 @@ const FormPanel = ({ formData, isOverTime }) => { | |||
isOverTime ? | |||
<Grid container direction="column" sx={{ paddingLeft: 4, paddingRight: 4 }} spacing={1}> | |||
<Grid item xs={12} md={12} textAlign="left"> | |||
<Typography variant="h5">The response timed out, please apply again.</Typography> | |||
<Typography variant="h5">Proofing timed out. Please apply again.</Typography> | |||
</Grid> | |||
</Grid> | |||
: | |||
@@ -44,10 +44,10 @@ export default function UploadFileTable({recordList, setRecordList,}) { | |||
...rowModesModel, | |||
[id]: { mode: GridRowModes.View, ignoreModifications: true }, | |||
}); | |||
console.log("Starting Delete") | |||
const editedRow = rows.find((row) => row.id === id); | |||
console.log(editedRow) | |||
console.log(editedRow.isNew) | |||
// console.log("Starting Delete") | |||
// const editedRow = rows.find((row) => row.id === id); | |||
// console.log(editedRow) | |||
// console.log(editedRow.isNew) | |||
setRecordList(rows.filter((row) => row.id !== id)); | |||
setRows(rows.filter((row) => row.id !== id)); | |||
} | |||
@@ -18,6 +18,9 @@ const MainCard = Loadable(React.lazy(() => import('components/MainCard'))); | |||
import * as StatusUtils from "utils/statusUtils/PublicNoteStatusUtils"; | |||
import FileList from "components/FileList" | |||
import { FormattedMessage, useIntl } from "react-intl"; | |||
import { | |||
isORGLoggedIn, | |||
} from "utils/Utils"; | |||
// ==============================|| DASHBOARD - DEFAULT ||============================== // | |||
const ApplicationDetailCard = ({ formData, }) => { | |||
@@ -175,6 +178,32 @@ const ApplicationDetailCard = ({ formData, }) => { | |||
</Grid> | |||
</Grid> | |||
</Grid> | |||
{isORGLoggedIn() ? | |||
<> | |||
<Grid container direction="row" justifyContent="space-between" | |||
alignItems="center"> | |||
<Grid item xs={12} md={6} lg={6} sx={{ mb: 1, }}> | |||
<Grid container alignItems="left"> | |||
<Grid item xs={12} md={3} lg={3} | |||
sx={{ display: 'flex', alignItems: 'center' }}> | |||
<FormLabel><Typography variant="pnspsFormParagraph"> | |||
<FormattedMessage id="careOf" />: | |||
</Typography></FormLabel> | |||
</Grid> | |||
<Grid item xs={12} md={9} lg={9}> | |||
<Stack direction="row"> | |||
<DisplayField name="careOf" /> | |||
</Stack> | |||
</Grid> | |||
</Grid> | |||
</Grid> | |||
</Grid> | |||
</> | |||
: | |||
null | |||
} | |||
<Grid container direction="row" justifyContent="space-between" | |||
alignItems="center"> | |||
<Grid item xs={12} md={6} lg={6} sx={{ mb: 1, }}> | |||
@@ -205,9 +234,11 @@ const ApplicationDetailCard = ({ formData, }) => { | |||
<Grid item xs={12} sm={12} md={6} lg={6} sx={{ mb: 1 }}> | |||
<Grid container alignItems={"center"}> | |||
<Grid item xs={12} sm={12} md={12} lg={12} sx={{ alignItems: 'center', wordBreak: 'break-word' }}> | |||
<Typography><Typography variant="pnspsFormParagraph"> | |||
<FormattedMessage id="pleaseCheckReminder" />: | |||
</Typography></Typography> | |||
<Typography> | |||
<Typography variant="pnspsFormParagraph"> | |||
<FormattedMessage id="pleaseCheckReminder" />: | |||
</Typography> | |||
</Typography> | |||
</Grid> | |||
<Grid item xs={12} sm={12} md={12} lg={12} sx={{ width: '95%', maxWidth: { xs: '70vw', sm: '72vw', md: '75vw', lg: '80vw' } }}> | |||
<FileList | |||
@@ -223,11 +254,14 @@ const ApplicationDetailCard = ({ formData, }) => { | |||
/> | |||
</Grid> | |||
</Grid> | |||
</Grid> | |||
<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"> | |||
@@ -240,7 +274,7 @@ const ApplicationDetailCard = ({ formData, }) => { | |||
{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", "a.m.")?.replace("pm", "p.m.")} ${intl.formatMessage({ id: 'before' })}` | |||
`${DateUtils.dateFormat(data?.reviseDeadline, intl.formatMessage({ id: "paymentMethodDatetimeStrFormat" }))?.replace("am", "上午")?.replace("pm", "下午")}${intl.formatMessage({ id: 'before' })}` | |||
} | |||
</Typography> | |||
</Grid> | |||
@@ -256,15 +290,21 @@ const ApplicationDetailCard = ({ formData, }) => { | |||
{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", "a.m.")?.replace("pm", "p.m.")} ${intl.formatMessage({ id: 'before' })}` | |||
`${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 variant="pnspsFormParagraph"> | |||
<FormattedMessage id="payFeeFor" />: | |||
<Typography> | |||
<Typography variant="pnspsFormParagraph"> | |||
<FormattedMessage id="payFeeFor" />: | |||
</Typography> | |||
</Typography> | |||
</Grid> | |||
<Grid item xs={12} sm={9} md={9} lg={9} sx={{ mb: 1, display: 'flex', alignItems: 'center' }}> | |||
@@ -274,11 +314,16 @@ const ApplicationDetailCard = ({ formData, }) => { | |||
{ | |||
formik.values.groupType === "Private Bill" | |||
? | |||
<Typography variant="pnspsFormParagraph">( {data.noOfPages} {intl.formatMessage({ id: 'page' })} x $6,552 )</Typography> | |||
<Typography> | |||
<Typography variant="pnspsFormParagraph">( {data.noOfPages} {intl.formatMessage({ id: 'page' })} x $6,552 )</Typography> | |||
</Typography> | |||
: | |||
<Typography variant="pnspsFormParagraph">( {data.length} cm x {data.colCount === 2 ? | |||
"$364 " + intl.formatMessage({ id: 'doubleCol' }) : | |||
"$182 " + intl.formatMessage({ id: 'singleCol' })} )</Typography> | |||
<Typography> | |||
<Typography variant="pnspsFormParagraph">( {data.length} cm x {data.colCount === 2 ? | |||
"$364 " + intl.formatMessage({ id: 'doubleCol' }) : | |||
"$182 " + intl.formatMessage({ id: 'singleCol' })} ) | |||
</Typography> | |||
</Typography> | |||
} | |||
</Grid> | |||
</Grid> | |||
@@ -49,6 +49,7 @@ const FormPanel = ({ formData }) => { | |||
const navigate = useNavigate() | |||
const params = useParams(); | |||
const dft = locale === 'en' ? "DD MMMM YYYY" : "YYYY年MM月DD日"; | |||
const tabelStyle = { | |||
border: "2px solid gray", | |||
@@ -120,7 +121,7 @@ const FormPanel = ({ formData }) => { | |||
}, | |||
files: attachments ? attachments : [], | |||
onSuccess: function (responseData) { | |||
console.log(responseData) | |||
// console.log(responseData) | |||
if (responseData.success === false) { | |||
navigate("/publicNotice/" + responseData.id); | |||
} else { | |||
@@ -236,7 +237,7 @@ const FormPanel = ({ formData }) => { | |||
<FormattedMessage id="proofReplyDate" /> : | |||
{ | |||
locale === 'en' ? | |||
DateUtils.dateValue(formik.values.replyDate) | |||
DateUtils.datetimeStr(formik.values.replyDate) | |||
: | |||
DateUtils.datetimeStr_Cht(formik.values.replyDate) | |||
} | |||
@@ -319,138 +320,29 @@ const FormPanel = ({ formData }) => { | |||
isDummyLoggedIn() ? | |||
<Grid item xs={12} sx={{ mb: 1, }}> | |||
<table style={tabelStyle}> | |||
<tr style={tabelStyle}> | |||
<th style={tabelStyle} width="50" align="left"></th> | |||
<th style={tabelStyle} width="300" align="left"><FormattedMessage id="paymentMeans" /></th> | |||
<th style={tabelStyle} width="300" align="left"><FormattedMessage id="confirmingDealine" /></th> | |||
<th style={tabelStyle} width="400" align="left"><FormattedMessage id="PaymentCoonpletDealine" /></th> | |||
</tr> | |||
<tr> | |||
<td style={tabelStyle}> | |||
<Checkbox | |||
checked={paymentMethod == "demandNote"} | |||
onChange={() => { | |||
set_paymentMethod("demandNote") | |||
}} | |||
/> | |||
</td> | |||
<td style={tabelStyle}> | |||
<FormattedMessage id="payDn" /> | |||
<br /><a href="#payOnlineDetails" color='#fff' onClick={() => { | |||
setWarningTitle(intl.formatMessage({ id: "payDn" })) | |||
setWarningText( | |||
<><FormattedMessage id="paymentMethodMeans" /> | |||
<ul> | |||
<li><FormattedMessage id="atm" /></li> | |||
<li><FormattedMessage id="pps" /></li> | |||
<li><FormattedMessage id="eBank" /></li> | |||
<li><FormattedMessage id="phoneBank" /></li> | |||
<li><FormattedMessage id="eCheque" /></li> | |||
<li><FormattedMessage id="fps" /></li> | |||
<li><FormattedMessage id="hkpo" /></li> | |||
<li><FormattedMessage id="store" /></li> | |||
<li><FormattedMessage id="post" /></li> | |||
</ul> | |||
</> | |||
); | |||
setIsWarningPopUp(true); | |||
}}><FormattedMessage id="viewDetail" /></a> | |||
</td> | |||
<td style={tabelStyle}>{DateUtils.dateFormat(formData.closingDateOff, intl.formatMessage({ id: "dateStrFormat" }))} 5:00 p.m.</td> | |||
<td style={tabelStyle}> | |||
<FormattedMessage id="payDnRemark" values={{ | |||
date: DateUtils.dateFormat(formData.closingDate, intl.formatMessage({ id: "dateStrFormat" })) + " 12:00 p.m." | |||
}} /> | |||
</td> | |||
</tr> | |||
<tr> | |||
<td style={tabelStyle}> | |||
<Checkbox | |||
checked={paymentMethod == "office"} | |||
onChange={() => { | |||
set_paymentMethod("office") | |||
}} | |||
/> | |||
</td> | |||
<td style={tabelStyle}> | |||
<FormattedMessage id="payNPGO" /> | |||
<br /><a href="#payOnlineDetails" color='#fff' onClick={() => { | |||
setWarningTitle(intl.formatMessage({ id: "payNPGO" })) | |||
setWarningText( | |||
<><FormattedMessage id="paymentMethodMeans" /> | |||
<ul> | |||
<li><FormattedMessage id="cheque" /></li> | |||
<li><FormattedMessage id="cash" /></li> | |||
</ul> | |||
</> | |||
); | |||
setIsWarningPopUp(true); | |||
}}><FormattedMessage id="viewDetail" /></a> | |||
</td> | |||
<td style={tabelStyle}>{DateUtils.dateFormat(formData.closingDate, intl.formatMessage({ id: "dateStrFormat" }))} 12:00 p.m.</td> | |||
<td style={tabelStyle}> | |||
<FormattedMessage id="payNPGORemark" values={{ | |||
date: DateUtils.dateFormat(formData.closingDate, intl.formatMessage({ id: "dateStrFormat" })) + " 12:30 p.m." | |||
}} /> | |||
</td> | |||
</tr> | |||
</table> | |||
</Grid> : | |||
<> | |||
<Grid item xs={12} sx={{ mb: 1, }}> | |||
<table style={tabelStyle}> | |||
<tbody> | |||
<tr style={tabelStyle}> | |||
<th style={tabelStyle} width="50" align="left"></th> | |||
<th style={tabelStyle} width="300" align="left"><FormattedMessage id="paymentMeans" /></th> | |||
<th style={tabelStyle} width="300" align="left"><FormattedMessage id="commentDeadline" /></th> | |||
<th style={tabelStyle} width="300" align="left"><FormattedMessage id="confirmingDealine" /></th> | |||
<th style={tabelStyle} width="400" align="left"><FormattedMessage id="PaymentCoonpletDealine" /></th> | |||
</tr> | |||
<tr> | |||
<td style={tabelStyle}> | |||
<Checkbox | |||
checked={paymentMethod == "online"} | |||
checked={paymentMethod == "demandNote"} | |||
onChange={() => { | |||
set_paymentMethod("online") | |||
set_paymentMethod("demandNote") | |||
}} | |||
/> | |||
</td> | |||
<td style={tabelStyle}> | |||
<FormattedMessage id="payOnline" /> | |||
<FormattedMessage id="paymentMeans" />: <FormattedMessage id="payDn" /> | |||
<br /><a href="#payOnlineDetails" color='#fff' onClick={() => { | |||
setWarningTitle(intl.formatMessage({ id: "payOnline" })) | |||
setWarningTitle(intl.formatMessage({ id: "paymentMeans" }) + ": " + intl.formatMessage({ id: "payDn" })) | |||
setWarningText( | |||
<><FormattedMessage id="paymentMethodMeans" /> | |||
<ul> | |||
<li><FormattedMessage id="fps" /></li> | |||
<li><FormattedMessage id="card" /></li> | |||
<li><FormattedMessage id="pps" /></li> | |||
</ul> | |||
</> | |||
); | |||
setIsWarningPopUp(true); | |||
}}><FormattedMessage id="viewDetail" /></a> | |||
</td> | |||
<td style={tabelStyle}>{DateUtils.dateFormat(formData.proofPaymentDeadline, intl.formatMessage({ id: "paymentMethodDatetimeStrFormat" }))?.replace("am", "a.m.")?.replace("pm", "p.m.")}</td> | |||
<td style={tabelStyle}>{DateUtils.dateFormat(formData.expiryDate, intl.formatMessage({ id: "paymentMethodDatetimeStrFormat" }))?.replace("am", "a.m.")?.replace("pm", "p.m.")}</td> | |||
</tr> | |||
<tr> | |||
<td style={tabelStyle}> | |||
{isOverDnReviseDeadline() ? | |||
<></> : | |||
<Checkbox | |||
checked={paymentMethod == "demandNote"} | |||
onChange={() => { | |||
set_paymentMethod("demandNote") | |||
}} | |||
/> | |||
} | |||
</td> | |||
<td style={tabelStyle}> | |||
<FormattedMessage id="payDn" /> | |||
<br /><a href="#payOnlineDetails" color='#fff' onClick={() => { | |||
setWarningTitle(intl.formatMessage({ id: "payDn" })) | |||
setWarningText( | |||
<><FormattedMessage id="paymentMethodMeans" /> | |||
<><FormattedMessage id="paymentMethodMeans" />: | |||
<ul> | |||
<li><FormattedMessage id="atm" /></li> | |||
<li><FormattedMessage id="pps" /></li> | |||
@@ -462,64 +354,206 @@ const FormPanel = ({ formData }) => { | |||
<li><FormattedMessage id="store" /></li> | |||
<li><FormattedMessage id="post" /></li> | |||
</ul> | |||
<Typography variant="h6"> | |||
<div style={{ padding: 12 }} dangerouslySetInnerHTML={{ __html: intl.formatMessage({ id: "proofNote" }) }} /> | |||
</Typography> | |||
</> | |||
); | |||
setIsWarningPopUp(true); | |||
}}><FormattedMessage id="viewDetail" /></a> | |||
}}><u><FormattedMessage id="viewDetail" /></u></a> | |||
</td> | |||
<td style={tabelStyle}>{DateUtils.dateFormat(formData.closingDateOff, intl.formatMessage({ id: "dateStrFormat" }))} 5:00 p.m.</td> | |||
<td style={tabelStyle}>{DateUtils.dateFormat(formData.closingDateOff, intl.formatMessage({ id: "dateStrFormat" }))} 5:00 p.m.</td> | |||
<td style={tabelStyle}> | |||
<FormattedMessage id="payDnRemark" values={{ | |||
date: DateUtils.dateFormat(formData.closingDate, intl.formatMessage({ id: "dateStrFormat" })) + " 12:00 p.m." | |||
date: DateUtils.dateFormat(formData.closingDate, intl.formatMessage({ id: "dateStrFormat" })) | |||
}} /> | |||
</td> | |||
</tr> | |||
<tr> | |||
<td style={tabelStyle}> | |||
{ | |||
isOverNpgoReviseDeadline() ? | |||
<></> : | |||
<Checkbox | |||
checked={paymentMethod == "office"} | |||
onChange={() => { | |||
set_paymentMethod("office") | |||
}} | |||
/> | |||
} | |||
<Checkbox | |||
checked={paymentMethod == "office"} | |||
onChange={() => { | |||
set_paymentMethod("office") | |||
}} | |||
/> | |||
</td> | |||
<td style={tabelStyle}> | |||
<FormattedMessage id="payNPGO" /> | |||
<br /><a href="#payOnlineDetails" color='#fff' onClick={() => { | |||
setWarningTitle(intl.formatMessage({ id: "payNPGO" })) | |||
setWarningTitle(intl.formatMessage({ id: "paymentMeans" }) + ": " + intl.formatMessage({ id: "payNPGOPopUpTitle" })) | |||
setWarningText( | |||
<><FormattedMessage id="paymentMethodMeans" /> | |||
<><FormattedMessage id="paymentMethodMeans" />: | |||
<ul> | |||
<li><FormattedMessage id="cheque" /></li> | |||
<li><FormattedMessage id="drafts" /></li> | |||
<li><FormattedMessage id="cashierOrders" /></li> | |||
<li><FormattedMessage id="cash" /></li> | |||
</ul> | |||
</> | |||
); | |||
setIsWarningPopUp(true); | |||
}}><FormattedMessage id="viewDetail" /></a> | |||
}}><u><FormattedMessage id="viewDetail" /></u></a> | |||
</td> | |||
<td style={tabelStyle}>{DateUtils.dateFormat(formData.closingDate, intl.formatMessage({ id: "dateStrFormat" }))} 11:30 a.m.</td> | |||
<td style={tabelStyle}>{DateUtils.dateFormat(formData.closingDate, intl.formatMessage({ id: "dateStrFormat" }))} 12:00 p.m.</td> | |||
<td style={tabelStyle}> | |||
<FormattedMessage id="payNPGORemark" values={{ | |||
date: DateUtils.dateFormat(formData.closingDate, intl.formatMessage({ id: "dateStrFormat" })) + " 12:30 p.m." | |||
date: DateUtils.dateFormat(formData.closingDate, intl.formatMessage({ id: "dateStrFormat" })) | |||
}} /> | |||
</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</Grid> : | |||
<> | |||
<Grid item xs={12} sx={{ mb: 1, }}> | |||
<table style={tabelStyle}> | |||
<tbody> | |||
<tr style={tabelStyle}> | |||
<th style={tabelStyle} width="50" align="left"></th> | |||
<th style={tabelStyle} width="300" align="left"><FormattedMessage id="paymentMeans" /></th> | |||
<th style={tabelStyle} width="300" align="left"><FormattedMessage id="commentDeadline" /></th> | |||
<th style={tabelStyle} width="300" align="left"><FormattedMessage id="confirmingDealine" /></th> | |||
<th style={tabelStyle} width="400" align="left"><FormattedMessage id="PaymentCoonpletDealine" /></th> | |||
</tr> | |||
<tr> | |||
<td style={tabelStyle}> | |||
<Checkbox | |||
checked={paymentMethod == "online"} | |||
onChange={() => { | |||
set_paymentMethod("online") | |||
}} | |||
/> | |||
</td> | |||
<td style={tabelStyle}> | |||
<FormattedMessage id="payOnline" /> | |||
<br /><a href="#payOnlineDetails" color='#fff' onClick={() => { | |||
setWarningTitle(intl.formatMessage({ id: "paymentMeans" }) + ": " + intl.formatMessage({ id: "payOnline" })) | |||
setWarningText( | |||
<><FormattedMessage id="paymentMethodMeans" />: | |||
<ul> | |||
<li><FormattedMessage id="fps" /></li> | |||
<li><FormattedMessage id="card" /></li> | |||
<li><FormattedMessage id="pps" /></li> | |||
</ul> | |||
</> | |||
); | |||
setIsWarningPopUp(true); | |||
}}><u><FormattedMessage id="viewDetail" /></u></a> | |||
</td> | |||
<td style={tabelStyle}>{ | |||
locale === 'en' ? | |||
`${DateUtils.dateFormat(formData.reviseDeadline, intl.formatMessage({ id: "datetimeFormate" }))?.replace("am", "a.m.")?.replace("pm", "p.m.")}` | |||
: | |||
`${DateUtils.dateFormat(formData.reviseDeadline, intl.formatMessage({ id: "datetimeFormate" }))?.replace("am", "上午")?.replace("pm", "下午").replace("00分", "")}` | |||
}</td> | |||
<td style={tabelStyle}>{ | |||
locale === 'en' ? | |||
`${DateUtils.dateFormat(formData.proofPaymentDeadline, intl.formatMessage({ id: "datetimeFormate" }))?.replace("am", "a.m.")?.replace("pm", "p.m.")}` | |||
: | |||
`${DateUtils.dateFormat(formData.proofPaymentDeadline, intl.formatMessage({ id: "datetimeFormate" }))?.replace("am", "上午")?.replace("pm", "下午").replace("00分", "")}` | |||
}</td> | |||
<td style={tabelStyle}> | |||
<FormattedMessage id="payOnlineRemark" values={{ | |||
date: DateUtils.dateFormat(formData.proofPaymentDeadline, dft) | |||
}} /> | |||
</td> | |||
</tr> | |||
<tr> | |||
<td style={tabelStyle}> | |||
{isOverDnReviseDeadline() ? | |||
<></> : | |||
<Checkbox | |||
checked={paymentMethod == "demandNote"} | |||
onChange={() => { | |||
set_paymentMethod("demandNote") | |||
}} | |||
/> | |||
} | |||
</td> | |||
<td style={tabelStyle}> | |||
<FormattedMessage id="payDn" /> | |||
<br /><a href="#payOnlineDetails" color='#fff' onClick={() => { | |||
setWarningTitle(intl.formatMessage({ id: "paymentMeans" }) + ": " + intl.formatMessage({ id: "payDn" })) | |||
setWarningText( | |||
<><FormattedMessage id="paymentMethodMeans" />: | |||
<ul> | |||
<li><FormattedMessage id="atm" /></li> | |||
<li><FormattedMessage id="pps" /></li> | |||
<li><FormattedMessage id="eBank" /></li> | |||
<li><FormattedMessage id="phoneBank" /></li> | |||
<li><FormattedMessage id="eCheque" /></li> | |||
<li><FormattedMessage id="fps" /></li> | |||
<li><FormattedMessage id="hkpo" /></li> | |||
<li><FormattedMessage id="store" /></li> | |||
<li><FormattedMessage id="post" /></li> | |||
</ul> | |||
<Typography variant="h6"> | |||
<div style={{ padding: 12 }} dangerouslySetInnerHTML={{ __html: intl.formatMessage({ id: "proofNote" }) }} /> | |||
</Typography> | |||
</> | |||
); | |||
setIsWarningPopUp(true); | |||
}}><u><FormattedMessage id="viewDetail" /></u></a> | |||
</td> | |||
<td style={tabelStyle}>{DateUtils.dateFormat(formData.closingDateOff, intl.formatMessage({ id: "dateStrFormat" }))} {locale ==='en'?"5:00 p.m.":"下午5時"}</td> | |||
<td style={tabelStyle}>{DateUtils.dateFormat(formData.closingDateOff, intl.formatMessage({ id: "dateStrFormat" }))} {locale ==='en'?"5:00 p.m.":"下午5時"}</td> | |||
<td style={tabelStyle}> | |||
<FormattedMessage id="payDnRemark" values={{ | |||
date: DateUtils.dateFormat(formData.proofPaymentDeadline, intl.formatMessage({ id: "dateStrFormat" })) | |||
}} /> | |||
</td> | |||
</tr> | |||
<tr> | |||
<td style={tabelStyle}> | |||
{ | |||
isOverNpgoReviseDeadline() ? | |||
<></> : | |||
<Checkbox | |||
checked={paymentMethod == "office"} | |||
onChange={() => { | |||
set_paymentMethod("office") | |||
}} | |||
/> | |||
} | |||
</td> | |||
<td style={tabelStyle}> | |||
<FormattedMessage id="payNPGO" /> | |||
<br /><a href="#payOnlineDetails" color='#fff' onClick={() => { | |||
setWarningTitle(intl.formatMessage({ id: "paymentMeans" }) + ": " + intl.formatMessage({ id: "payNPGOPopUpTitle" })) | |||
setWarningText( | |||
<><FormattedMessage id="paymentMethodMeans" />: | |||
<ul> | |||
<li><FormattedMessage id="cheque" /></li> | |||
<li><FormattedMessage id="drafts" /></li> | |||
<li><FormattedMessage id="cashierOrders" /></li> | |||
<li><FormattedMessage id="cash" /></li> | |||
</ul> | |||
</> | |||
); | |||
setIsWarningPopUp(true); | |||
}}><u><FormattedMessage id="viewDetail" /></u></a> | |||
</td> | |||
<td style={tabelStyle}>{DateUtils.dateFormat(formData.closingDate, intl.formatMessage({ id: "dateStrFormat" }))} {locale ==='en'?"11:30 a.m.":"上午11時30分"}</td> | |||
<td style={tabelStyle}>{DateUtils.dateFormat(formData.closingDate, intl.formatMessage({ id: "dateStrFormat" }))} {locale ==='en'?"12:00 p.m.":"下午12時"}</td> | |||
<td style={tabelStyle}> | |||
<FormattedMessage id="payNPGORemark" values={{ | |||
date: DateUtils.dateFormat(formData.closingDate, intl.formatMessage({ id: "dateStrFormat" })) | |||
}} /> | |||
</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</Grid> | |||
<Grid item xs={12}> | |||
{/* <Grid item xs={12}> | |||
<Typography variant="h6" height="100%" > | |||
<div style={{ padding: 12 }} dangerouslySetInnerHTML={{ __html: intl.formatMessage({ id: "proofNote" }) }} /> | |||
</Typography> | |||
</Grid> | |||
</Grid> */} | |||
<Grid item xs={12}> | |||
<Typography variant="h6" height="100%" > | |||
@@ -662,10 +696,10 @@ const FormPanel = ({ formData }) => { | |||
</DialogContent> | |||
<DialogActions> | |||
<Button | |||
aria-label={intl.formatMessage({ id: 'ok' })} | |||
aria-label={intl.formatMessage({ id: 'close' })} | |||
onClick={() => setIsWarningPopUp(false)} | |||
> | |||
OK | |||
<FormattedMessage id="close" /> | |||
</Button> | |||
</DialogActions> | |||
</Dialog> | |||
@@ -46,10 +46,10 @@ export default function UploadFileTable({recordList, setRecordList,}) { | |||
...rowModesModel, | |||
[id]: { mode: GridRowModes.View, ignoreModifications: true }, | |||
}); | |||
console.log("Starting Delete") | |||
const editedRow = rows.find((row) => row.id === id); | |||
console.log(editedRow) | |||
console.log(editedRow.isNew) | |||
// console.log("Starting Delete") | |||
// const editedRow = rows.find((row) => row.id === id); | |||
// console.log(editedRow) | |||
// console.log(editedRow.isNew) | |||
setRecordList(rows.filter((row) => row.id !== id)); | |||
setRows(rows.filter((row) => row.id !== id)); | |||
} | |||
@@ -9,11 +9,11 @@ import { FiDataGrid } from "components/FiDataGrid"; | |||
import { clickableLink } from 'utils/CommonFunction'; | |||
// ==============================|| EVENT TABLE ||============================== // | |||
export default function SearchPublicNoticeTable({searchCriteria}) { | |||
export default function SearchPublicNoticeTable({searchCriteria, applyGridOnReady,applySearch}) { | |||
const navigate = useNavigate() | |||
const [_searchCriteria, set_searchCriteria] = React.useState({}); | |||
const [_searchCriteria, set_searchCriteria] = React.useState({searchCriteria}); | |||
React.useEffect(() => { | |||
set_searchCriteria(searchCriteria); | |||
@@ -83,6 +83,9 @@ export default function SearchPublicNoticeTable({searchCriteria}) { | |||
renderCell: (params) => { | |||
let company = params.row.enCompanyName != null?params.row.enCompanyName: params.row.chCompanyName; | |||
company = company != null ? company : ""; | |||
if (company == "GLD"){ | |||
company = company + ": " + params.row.appCustName | |||
} | |||
return (<> | |||
{params?.value}<br />{company} | |||
</>); | |||
@@ -119,12 +122,18 @@ export default function SearchPublicNoticeTable({searchCriteria}) { | |||
<FiDataGrid | |||
columns={columns} | |||
customPageSize={10} | |||
onRowDoubleClick={handleRowDoubleClick} | |||
getRowHeight={() => 'auto'} | |||
doLoad={{ | |||
onRowDoubleClick={handleRowDoubleClick} | |||
applyGridOnReady={applyGridOnReady} | |||
applySearch = {applySearch} | |||
// doLoad={{ | |||
// url: LIST_PROOF, | |||
// params: _searchCriteria, | |||
// }} | |||
doLoad={React.useMemo(() => ({ | |||
url: LIST_PROOF, | |||
params: _searchCriteria, | |||
}} | |||
}), [_searchCriteria])} | |||
/> | |||
</div> | |||
); | |||
@@ -21,22 +21,34 @@ 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"; | |||
// ==============================|| DASHBOARD - DEFAULT ||============================== // | |||
const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, issueComboData | |||
const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, issueComboData, onGridReady | |||
}) => { | |||
const [type, setType] = React.useState([]); | |||
const [status, setStatus] = React.useState(ComboData.proofStatus[0]); | |||
const [status, setStatus] = React.useState(searchCriteria.statusKey!=undefined?ComboData.proofStatus_GLD[searchCriteria.statusKey]:ComboData.proofStatus_GLD[0]); | |||
const [orgSelected, setOrgSelected] = React.useState({}); | |||
const [orgCombo, setOrgCombo] = React.useState(); | |||
const [issueSelected, setIssueSelected] = React.useState({}); | |||
const [issueCombo, setIssueCombo] = React.useState([]); | |||
const [groupSelected, setGroupSelected] = React.useState({}); | |||
const [groupSelected, setGroupSelected] = React.useState(searchCriteria.gazettGroup!=undefined?ComboData.groupTitle.find(item => item.code === searchCriteria.gazettGroup):{}); | |||
const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom); | |||
const [maxDate, setMaxDate] = React.useState(searchCriteria.dateTo); | |||
const [fromDateValue, setFromDateValue] = React.useState("dd / mm / yyyy"); | |||
const [toDateValue, setToDateValue] = React.useState("dd / mm / yyyy"); | |||
// React.useEffect(() => { | |||
// if(searchCriteria.status!=undefined){ | |||
// if(searchCriteria.status === ""){ | |||
// ComboData.proofStatus_GLD[0] | |||
// }else{ | |||
// setSelectedStatus(ComboData.proofStatus_GLD.find(item => item.type === searchCriteria.status)) | |||
// } | |||
// }else{ | |||
// setSelectedStatus(ComboData.proofStatus_GLD[0]) | |||
// } | |||
// }, [searchCriteria]); | |||
React.useEffect(() => { | |||
setFromDateValue(minDate); | |||
}, [minDate]); | |||
@@ -68,26 +80,56 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss | |||
refNo: data.refNo, | |||
code: data.code, | |||
issueId: issueSelected?.id, | |||
gazettGroup: groupSelected?.type, | |||
gazettGroup: groupSelected?.code, | |||
dateFrom: sentDateFrom, | |||
dateTo: sentDateTo, | |||
contact: data.contact, | |||
replyed: (status?.type && status?.type != 'all') ? status?.type : "", | |||
orgId: (orgSelected?.key && orgSelected?.key > 0) ? orgSelected?.key : "", | |||
statusKey:status?.key, | |||
}; | |||
if(status?.type && status?.type != 'all'){ | |||
if (status?.type == "Confirmed"){ | |||
temp["replyed"] = "T"; | |||
temp["action"] = true; | |||
temp["cancelled"] = false; | |||
}else if(status?.type == "Re-proofing"){ | |||
temp["replyed"] = "T"; | |||
temp["action"] = false; | |||
temp["cancelled"] = false; | |||
}else if(status?.type == "No Reply"){ | |||
temp["replyed"] = "F"; | |||
temp["timeOut"] = "T"; | |||
temp["cancelled"] = false; | |||
}else if(status?.type == "Cancelled"){ | |||
temp["cancelled"] = true; | |||
} else{ | |||
temp["replyed"] = "F"; | |||
temp["timeOut"] = "F"; | |||
temp["cancelled"] = false; | |||
} | |||
} | |||
applySearch(temp); | |||
}; | |||
React.useEffect(() => { | |||
if (orgComboData && orgComboData.length > 0) { | |||
setOrgCombo(orgComboData); | |||
if(searchCriteria.orgId!=undefined){ | |||
setOrgSelected(orgComboData.find(item => item.key === searchCriteria.orgId)) | |||
} | |||
} | |||
}, [orgComboData]); | |||
React.useEffect(() => { | |||
if (issueComboData && issueComboData.length > 0) { | |||
setIssueCombo(issueComboData); | |||
if(searchCriteria.issueId!=undefined){ | |||
setIssueSelected(issueComboData.find(item => item.id === searchCriteria.issueId)) | |||
} | |||
} | |||
}, [issueComboData]); | |||
@@ -99,7 +141,12 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss | |||
setGroupSelected({}); | |||
setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14))) | |||
setMaxDate(DateUtils.dateValue(new Date())) | |||
reset(); | |||
reset({ | |||
refNo:"", | |||
code:"", | |||
contact:"" | |||
}); | |||
localStorage.setItem('searchCriteria',"") | |||
} | |||
function getIssueLabel(data) { | |||
@@ -299,9 +346,10 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss | |||
id="status" | |||
size="small" | |||
filterOptions={(options) => options} | |||
options={ComboData.proofStatus} | |||
options={ComboData.proofStatus_GLD} | |||
value={status} | |||
inputValue={status?.label ? status?.label : ""} | |||
getOptionLabel={(option) => option.type? intl.formatMessage({ id: option.i18nLabel }) : ""} | |||
inputValue={status? intl.formatMessage({id: status.i18nLabel}):""} | |||
onChange={(event, newValue) => { | |||
if (newValue !== null) { | |||
setStatus(newValue); | |||
@@ -323,13 +371,15 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss | |||
<Grid item xs={9} s={6} md={5} lg={3} sx={{ ml: 3, mr: 3, mb: 3 }}> | |||
<Autocomplete | |||
{...register("orgId")} | |||
disablePortal={false} | |||
disablePortal | |||
id="orgId" | |||
size="small" | |||
options={orgCombo} | |||
groupBy={(option) => option.groupType} | |||
size="small" | |||
value={orgSelected} | |||
getOptionLabel={(option) => option.name? option.name : ""} | |||
inputValue={orgSelected ? orgSelected.name : ""} | |||
inputValue={orgSelected ? orgSelected.name!=undefined?orgSelected.name:"" : ""} | |||
onChange={(event, newValue) => { | |||
if (newValue !== null) { | |||
setOrgSelected(newValue); | |||
@@ -345,6 +395,14 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss | |||
}} | |||
/> | |||
)} | |||
renderGroup={(params) => ( | |||
<Grid item key={params.key}> | |||
<Typography fontSize={20} fontStyle="italic" p={1}> | |||
{params.group} | |||
</Typography> | |||
{params.children} | |||
</Grid> | |||
)} | |||
/> | |||
</Grid> | |||
: <></> | |||
@@ -371,7 +429,8 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss | |||
<Button | |||
variant="contained" | |||
type="submit" | |||
> | |||
disabled={onGridReady} | |||
> | |||
Submit | |||
</Button> | |||
</Grid> | |||
@@ -10,6 +10,7 @@ import * as React from "react"; | |||
import * as HttpUtils from "utils/HttpUtils"; | |||
import * as DateUtils from "utils/DateUtils"; | |||
import {GET_ORG_COMBO, GET_ISSUE_COMBO} from "utils/ApiPathConst"; | |||
import { getSearchCriteria } from "auth/utils"; | |||
import Loadable from 'components/Loadable'; | |||
const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | |||
@@ -32,15 +33,22 @@ const BackgroundHead = { | |||
const UserSearchPage_Individual = () => { | |||
const [orgCombo, setOrgCombo] = React.useState([]); | |||
const [issueCombo, setIssueCombo] = React.useState([]); | |||
const [searchCriteria, setSearchCriteria] = React.useState({ | |||
dateTo: DateUtils.dateValue(new Date()), | |||
dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate() - 14)), | |||
}); | |||
const [searchCriteria, setSearchCriteria] = React.useState({}); | |||
const [onReady, setOnReady] = React.useState(false); | |||
const [onGridReady, setGridOnReady] = React.useState(false); | |||
React.useEffect(() => { | |||
React.useEffect(() => { | |||
getOrgCombo(); | |||
getIssueCombo(); | |||
if (Object.keys(getSearchCriteria(window.location.pathname)).length>0){ | |||
setSearchCriteria(getSearchCriteria(window.location.pathname)) | |||
}else{ | |||
localStorage.setItem('searchCriteria',"") | |||
setSearchCriteria({ | |||
dateTo: DateUtils.dateValue(new Date()), | |||
dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)), | |||
}) | |||
} | |||
}, []); | |||
React.useEffect(() => { | |||
@@ -69,7 +77,13 @@ const UserSearchPage_Individual = () => { | |||
} | |||
function applySearch(input) { | |||
setGridOnReady(true) | |||
setSearchCriteria(input); | |||
localStorage.setItem('searchCriteria', JSON.stringify({path:window.location.pathname,data:input})) | |||
} | |||
function applyGridOnReady(input) { | |||
setGridOnReady(input); | |||
} | |||
return ( | |||
@@ -95,6 +109,7 @@ const UserSearchPage_Individual = () => { | |||
orgComboData={orgCombo} | |||
issueComboData={issueCombo} | |||
searchCriteria={searchCriteria} | |||
onGridReady={onGridReady} | |||
/> | |||
</Grid> | |||
{/*row 2*/} | |||
@@ -107,6 +122,8 @@ const UserSearchPage_Individual = () => { | |||
> | |||
<EventTable | |||
searchCriteria={searchCriteria} | |||
applyGridOnReady={applyGridOnReady} | |||
applySearch={applySearch} | |||
/> | |||
</MainCard> | |||
</Grid> | |||
@@ -11,13 +11,14 @@ import { useNavigate } from "react-router-dom"; | |||
import { FiDataGrid } from "components/FiDataGrid"; | |||
import { | |||
isORGLoggedIn, | |||
} from "utils/Utils"; | |||
import {useTheme} from "@emotion/react"; | |||
import {useIntl} from "react-intl"; | |||
isDummyLoggedIn, | |||
} from "utils/Utils"; | |||
import { useTheme } from "@emotion/react"; | |||
import { useIntl } from "react-intl"; | |||
import { clickableLink } from 'utils/CommonFunction'; | |||
// ==============================|| EVENT TABLE ||============================== // | |||
export default function SearchPublicNoticeTable({ searchCriteria }) { | |||
export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnReady, applySearch }) { | |||
const navigate = useNavigate() | |||
const theme = useTheme(); | |||
@@ -44,7 +45,15 @@ export default function SearchPublicNoticeTable({ searchCriteria }) { | |||
'& .MuiDataGrid-footerContainer': { | |||
border: 1, | |||
borderColor: "#EEE" | |||
} | |||
}, | |||
"& .MuiDataGrid-columnHeaderTitle": { | |||
whiteSpace: "normal", | |||
lineHeight: "normal" | |||
}, | |||
"& .MuiDataGrid-columnHeader": { | |||
// Forced to use important since overriding inline styles | |||
height: "unset !important" | |||
}, | |||
} | |||
@@ -66,7 +75,7 @@ export default function SearchPublicNoticeTable({ searchCriteria }) { | |||
} | |||
}*/ | |||
const getIssueLabel=(data) =>{ | |||
const getIssueLabel = (data) => { | |||
let issueYear = data.row.issueYear | |||
let volume = data.row.issueVolume; | |||
let issueNo = data.row.issueNo; | |||
@@ -90,22 +99,22 @@ export default function SearchPublicNoticeTable({ searchCriteria }) { | |||
+ ", " + DateUtils.dateFormat(issueDate, "D MMM YYYY (ddd)"); | |||
} | |||
const columns = [ | |||
{ | |||
field: 'actions', | |||
headerName: intl.formatMessage({id: 'proofId'}), | |||
headerName: intl.formatMessage({ id: 'proofId' }), | |||
width: isMdOrLg ? 'auto' : 200, | |||
flex: isMdOrLg ? 1.5 : undefined, | |||
cellClassName: 'actions', | |||
renderCell: (params) => { | |||
return clickableLink('/proof/reply/' + params.row.id,params.row.refNo); | |||
return clickableLink('/proof/reply/' + params.row.id, params.row.refNo); | |||
}, | |||
}, | |||
{ | |||
id: 'appId', | |||
field: 'appId', | |||
headerName: isORGLoggedIn()?intl.formatMessage({id: 'gazetteCount3'}):intl.formatMessage({id: 'gazetteCount2'}), | |||
headerName: isORGLoggedIn() ? intl.formatMessage({ id: 'gazetteCount3' }) : intl.formatMessage({ id: 'gazetteCount2' }), | |||
width: isMdOrLg ? 'auto' : 330, | |||
flex: isMdOrLg ? 2 : undefined, | |||
renderCell: (params) => { | |||
@@ -114,13 +123,13 @@ export default function SearchPublicNoticeTable({ searchCriteria }) { | |||
let isssue = getIssueLabel(params); | |||
// return <div style={{ margin: 4 }}>{appNo}<br />{isssue}<br />{params.row.appRemarks}</div> | |||
return <div style={{ margin: 4 }}>{isssue}<br />{isORGLoggedIn()?<>{params.row.appCareOf}<br /></>:null}{params.row.appRemarks}</div> | |||
return <div style={{ margin: 4 }}>{isssue}<br />{isORGLoggedIn() ? isDummyLoggedIn()?<><>GLD: {params.row.applicant}<br /></><>{params.row.appCareOf}<br /></></>:<>{params.row.appCareOf}<br /></> : null}{params.row.appRemarks}</div> | |||
}, | |||
}, | |||
{ | |||
id: 'created', | |||
field: 'created', | |||
headerName: intl.formatMessage({id: 'proofDate'}), | |||
field: 'reviseDeadline', | |||
headerName: intl.formatMessage({ id: 'proofDate' }), | |||
width: isMdOrLg ? 'auto' : 200, | |||
flex: isMdOrLg ? 1.5 : undefined, | |||
valueGetter: (params) => { | |||
@@ -130,7 +139,7 @@ export default function SearchPublicNoticeTable({ searchCriteria }) { | |||
{ | |||
id: 'proofPaymentDeadline', | |||
field: 'proofPaymentDeadline', | |||
headerName: intl.formatMessage({id: 'replyBefore'}), | |||
headerName: intl.formatMessage({ id: 'replyBefore' }), | |||
width: isMdOrLg ? 'auto' : 200, | |||
flex: isMdOrLg ? 1.5 : undefined, | |||
valueGetter: (params) => { | |||
@@ -142,7 +151,7 @@ export default function SearchPublicNoticeTable({ searchCriteria }) { | |||
{ | |||
id: 'replyDate', | |||
field: 'replyDate', | |||
headerName: intl.formatMessage({id: 'replyDate'}), | |||
headerName: intl.formatMessage({ id: 'replyDate' }), | |||
width: isMdOrLg ? 'auto' : 200, | |||
flex: isMdOrLg ? 1.5 : undefined, | |||
valueGetter: (params) => { | |||
@@ -151,17 +160,17 @@ export default function SearchPublicNoticeTable({ searchCriteria }) { | |||
}, | |||
{ | |||
id: 'actions', | |||
headerName: intl.formatMessage({id: 'status'}), | |||
headerName: intl.formatMessage({ id: 'status' }), | |||
width: isMdOrLg ? 'auto' : 160, | |||
flex: isMdOrLg ? 1 : undefined, | |||
renderCell: (params) => { | |||
return locale === 'en' ? ProofStatus.getStatus_Eng(params) : ProofStatus.getStatus_Cht(params); | |||
return locale === 'en' ? ProofStatus.getStatus_Eng(params) : locale === 'zh-HK' ? ProofStatus.getStatus_Cht(params) : ProofStatus.getStatus_Cn(params); | |||
}, | |||
}, | |||
{ | |||
id: 'fee', | |||
field: 'fee', | |||
headerName: intl.formatMessage({id: 'fee'}), | |||
headerName: intl.formatMessage({ id: 'fee' }), | |||
width: isMdOrLg ? 'auto' : 160, | |||
flex: isMdOrLg ? 1 : undefined, | |||
valueGetter: (params) => { | |||
@@ -175,7 +184,7 @@ export default function SearchPublicNoticeTable({ searchCriteria }) { | |||
} | |||
return ( | |||
<div style={{ width: '100%', overflowX: 'auto'}}> | |||
<div style={{ width: '100%', overflowX: 'auto' }}> | |||
<FiDataGrid | |||
sx={_sx} | |||
@@ -183,10 +192,12 @@ export default function SearchPublicNoticeTable({ searchCriteria }) { | |||
customPageSize={10} | |||
getRowHeight={() => "auto"} | |||
onRowDoubleClick={handleRowDoubleClick} | |||
doLoad={{ | |||
applyGridOnReady={applyGridOnReady} | |||
applySearch={applySearch} | |||
doLoad={React.useMemo(() => ({ | |||
url: LIST_PROOF, | |||
params: _searchCriteria, | |||
}} | |||
}), [_searchCriteria])} | |||
/> | |||
</div> | |||
); |
@@ -22,16 +22,16 @@ 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"; | |||
// ==============================|| DASHBOARD - DEFAULT ||============================== // | |||
const SearchPublicNoticeForm = ({ applySearch, searchCriteria, issueComboData | |||
const SearchPublicNoticeForm = ({ applySearch, searchCriteria, issueComboData, onGridReady | |||
}) => { | |||
const intl = useIntl(); | |||
const { locale } = intl; | |||
const [type, setType] = React.useState([]); | |||
const [status, setStatus] = React.useState(ComboData.proofStatus[0]); | |||
const [status, setStatus] = React.useState(searchCriteria.statusKey!=undefined?ComboData.proofStatusFull[searchCriteria.statusKey]:ComboData.proofStatusFull[0]); | |||
const [issueSelected, setIssueSelected] = React.useState({}); | |||
const [issueCombo, setIssueCombo] = React.useState([]); | |||
const [groupSelected, setGroupSelected] = React.useState({}); | |||
const [groupSelected, setGroupSelected] = React.useState(searchCriteria.gazettGroup!=undefined?ComboData.groupTitle.find(item => item.code === searchCriteria.gazettGroup):{}); | |||
const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom); | |||
const [maxDate, setMaxDate] = React.useState(searchCriteria.dateTo); | |||
@@ -84,9 +84,24 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, issueComboData | |||
gazettGroup: groupSelected?.type, | |||
dateFrom: sentDateFrom, | |||
dateTo: sentDateTo, | |||
//contact: data.contact, | |||
replyed: (status?.type && status?.type != 'all') ? status?.type : "", | |||
statusKey:status?.key, | |||
}; | |||
if(status?.type && status?.type != 'all'){ | |||
if (status?.type == "Confirmed"){ | |||
temp["replyed"] = "T"; | |||
temp["action"] = true; | |||
}else if(status?.type == "Re-proofing"){ | |||
temp["replyed"] = "T"; | |||
temp["action"] = false; | |||
}else if(status?.type == "No Reply"){ | |||
temp["replyed"] = "F"; | |||
temp["timeOut"] = "T"; | |||
}else{ | |||
temp["replyed"] = "F"; | |||
temp["timeOut"] = "F"; | |||
} | |||
} | |||
applySearch(temp); | |||
}; | |||
@@ -94,17 +109,24 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, issueComboData | |||
React.useEffect(() => { | |||
if (issueComboData && issueComboData.length > 0) { | |||
setIssueCombo(issueComboData); | |||
if(searchCriteria.issueId!=undefined){ | |||
setIssueSelected(issueComboData.find(item => item.id === searchCriteria.issueId)) | |||
} | |||
} | |||
}, [issueComboData]); | |||
function resetForm() { | |||
setType([]); | |||
setStatus(ComboData.proofStatus[0]); | |||
setStatus(ComboData.proofStatusFull[0]); | |||
setIssueSelected({}); | |||
setGroupSelected({}); | |||
setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14))) | |||
setMaxDate(DateUtils.dateValue(new Date())) | |||
reset(); | |||
reset({ | |||
refNo:"", | |||
code:"", | |||
}); | |||
localStorage.setItem('searchCriteria',"") | |||
} | |||
function getIssueLabel(data) { | |||
@@ -300,8 +322,9 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, issueComboData | |||
disablePortal={false} | |||
size="small" | |||
id="status" | |||
disableClearable | |||
filterOptions={(options) => options} | |||
options={ComboData.proofStatus} | |||
options={ComboData.proofStatusFull} | |||
value={status} | |||
getOptionLabel={(option) => option.type? intl.formatMessage({ id: option.i18nLabel }) : ""} | |||
inputValue={status? intl.formatMessage({ id: status.i18nLabel }) : ""} | |||
@@ -345,6 +368,7 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, issueComboData | |||
variant="contained" | |||
type="submit" | |||
aria-label={intl.formatMessage({id: 'submit'})} | |||
disabled={onGridReady} | |||
> | |||
<FormattedMessage id="submit"/> | |||
</Button> | |||
@@ -9,6 +9,7 @@ import * as UrlUtils from "utils/ApiPathConst"; | |||
import * as React from "react"; | |||
import * as HttpUtils from "utils/HttpUtils"; | |||
import * as DateUtils from "utils/DateUtils"; | |||
import { getSearchCriteria } from "auth/utils"; | |||
import Loadable from 'components/Loadable'; | |||
const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | |||
@@ -37,9 +38,15 @@ const UserSearchPage_Individual = () => { | |||
dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)), | |||
}); | |||
const [onReady, setOnReady] = React.useState(false); | |||
const [onGridReady, setGridOnReady] = React.useState(false); | |||
React.useEffect(() => { | |||
getIssueCombo(); | |||
if (Object.keys(getSearchCriteria(window.location.pathname)).length>0){ | |||
setSearchCriteria(getSearchCriteria(window.location.pathname)) | |||
}else{ | |||
localStorage.setItem('searchCriteria',"") | |||
} | |||
}, []); | |||
React.useEffect(() => { | |||
@@ -59,7 +66,13 @@ const UserSearchPage_Individual = () => { | |||
function applySearch(input) { | |||
setGridOnReady(true) | |||
setSearchCriteria(input); | |||
localStorage.setItem('searchCriteria', JSON.stringify({path:window.location.pathname,data:input})) | |||
} | |||
function applyGridOnReady(input) { | |||
setGridOnReady(input); | |||
} | |||
return ( | |||
@@ -83,9 +96,10 @@ const UserSearchPage_Individual = () => { | |||
{/*row 1*/} | |||
<Grid item xs={12} md={12} lg={12}> | |||
<SearchForm | |||
applySearch={applySearch} | |||
issueComboData={issueCombo} | |||
searchCriteria={searchCriteria} | |||
applySearch={applySearch} | |||
issueComboData={issueCombo} | |||
searchCriteria={searchCriteria} | |||
onGridReady={onGridReady} | |||
/> | |||
</Grid> | |||
{/*row 2*/} | |||
@@ -96,7 +110,9 @@ const UserSearchPage_Individual = () => { | |||
sx={{width: "-webkit-fill-available"}} | |||
> | |||
<EventTable | |||
searchCriteria={searchCriteria} | |||
searchCriteria={searchCriteria} | |||
applyGridOnReady={applyGridOnReady} | |||
applySearch={applySearch} | |||
/> | |||
</MainCard> | |||
</Grid> | |||