| @@ -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", | "@testing-library/user-event": "^14.4.3", | ||||
| "@types/react-input-mask": "^3.0.2", | "@types/react-input-mask": "^3.0.2", | ||||
| "apexcharts": "^3.35.5", | "apexcharts": "^3.35.5", | ||||
| "axios": "^1.4.0", | |||||
| "axios": "^1.7.1", | |||||
| "date-fns": "^3.0.6", | "date-fns": "^3.0.6", | ||||
| "dayjs": "^1.11.9", | "dayjs": "^1.11.9", | ||||
| "formik": "^2.2.9", | "formik": "^2.2.9", | ||||
| @@ -2,52 +2,23 @@ | |||||
| <html lang="en"> | <html lang="en"> | ||||
| <head> | <head> | ||||
| <meta charset="utf-8" /> | <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="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="title" content="PNSPS" /> | ||||
| <meta | <meta | ||||
| name="description" | 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 | <meta | ||||
| name="keywords" | 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> | <title>PNSPS</title> | ||||
| <link rel="preconnect" href="https://fonts.gstatic.com" /> | <link rel="preconnect" href="https://fonts.gstatic.com" /> | ||||
| <link | <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> | |||||
| @@ -11,6 +11,10 @@ body, | |||||
| font-family: "Noto Sans HK", "Noto Sans SC"; | font-family: "Noto Sans HK", "Noto Sans SC"; | ||||
| } | } | ||||
| .page-grey { | |||||
| filter: grayscale(100%); | |||||
| } | |||||
| /* Chrome, Safari, Edge, Opera */ | /* Chrome, Safari, Edge, Opera */ | ||||
| input::-webkit-outer-spin-button, | input::-webkit-outer-spin-button, | ||||
| input::-webkit-inner-spin-button { | input::-webkit-inner-spin-button { | ||||
| @@ -32,6 +32,7 @@ export const handleLogin = data => { | |||||
| localStorage.setItem('accessToken', data.accessToken) | localStorage.setItem('accessToken', data.accessToken) | ||||
| localStorage.setItem('refreshToken', data.refreshToken) | localStorage.setItem('refreshToken', data.refreshToken) | ||||
| localStorage.setItem('axiosToken', "Bearer " + data.accessToken) | localStorage.setItem('axiosToken', "Bearer " + data.accessToken) | ||||
| localStorage.setItem('searchCriteria',"") | |||||
| //localStorage.setItem(config.storageUserRoleKeyName, JSON.stringify(data.role).slice(1).slice(0, -1)) | //localStorage.setItem(config.storageUserRoleKeyName, JSON.stringify(data.role).slice(1).slice(0, -1)) | ||||
| localStorage.setItem(refreshIntervalName, "60") | localStorage.setItem(refreshIntervalName, "60") | ||||
| // for demo only | // for demo only | ||||
| @@ -91,6 +92,7 @@ export const handleLogoutFunction = () => { | |||||
| localStorage.removeItem('refreshToken') | localStorage.removeItem('refreshToken') | ||||
| localStorage.removeItem('webtoken') | localStorage.removeItem('webtoken') | ||||
| localStorage.removeItem('transactionid') | localStorage.removeItem('transactionid') | ||||
| localStorage.removeItem('searchCriteria') | |||||
| //localStorage.removeItem(config.storageUserRoleKeyName) | //localStorage.removeItem(config.storageUserRoleKeyName) | ||||
| localStorage.removeItem('expiredAlertShown') | localStorage.removeItem('expiredAlertShown') | ||||
| localStorage.removeItem(refreshIntervalName) | localStorage.removeItem(refreshIntervalName) | ||||
| @@ -14,25 +14,10 @@ export const paymentPath = window.location.href.match("localhost:3000") ? `${hos | |||||
| export const delBugMode = true; | 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 = () => { | export const iAmSmartCallbackPath = () => { | ||||
| let hostname = window.location.hostname; | let hostname = window.location.hostname; | ||||
| if (hostname.match("pnspsuat")) { | if (hostname.match("pnspsuat")) { | ||||
| hostname = "pnspsuat.gld.gov.hk"; | hostname = "pnspsuat.gld.gov.hk"; | ||||
| } else { | |||||
| hostname = "pnspsdev.gld.gov.hk"; | |||||
| } | } | ||||
| return hostname; | return hostname; | ||||
| }; | }; | ||||
| @@ -57,7 +42,10 @@ export const getBowserType = () => { | |||||
| if (navigator.userAgent.match(/Android/i)) return "Android_Chrome" | if (navigator.userAgent.match(/Android/i)) return "Android_Chrome" | ||||
| if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) return "iOS_Chrome" | if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) return "iOS_Chrome" | ||||
| return "PC_Browser" | 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" | if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) return "iOS_Safari" | ||||
| return "PC_Browser" | return "PC_Browser" | ||||
| } else if (navigator.userAgent.indexOf("Firefox") != -1) { | } else if (navigator.userAgent.indexOf("Firefox") != -1) { | ||||
| @@ -89,7 +77,7 @@ export const isGranted = (auth) => { | |||||
| const abilities = getUserData() ? getUserData()["abilities"] : null; | const abilities = getUserData() ? getUserData()["abilities"] : null; | ||||
| if (abilities == null || abilities.length == 0) return false; | if (abilities == null || abilities.length == 0) return false; | ||||
| if (!Array.isArray(auth)) return _checkAuth(abilities, auth); | if (!Array.isArray(auth)) return _checkAuth(abilities, auth); | ||||
| if (auth.length > abilities.length) return false; | if (auth.length > abilities.length) return false; | ||||
| let haveAuth = true; | let haveAuth = true; | ||||
| for (let i = 0; i < auth.length; i++) { | 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 preferpaymentmethods = ['visa', 'mastercard', 'pps', 'creditcard', 'fps']; | ||||
| export const getPaymentMethod = (paymentMethod) => { | 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"; | 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 config from 'config'; | ||||
| import { activeItem } from 'store/reducers/menu'; | import { activeItem } from 'store/reducers/menu'; | ||||
| import { Stack } from '@mui/material'; | import { Stack } from '@mui/material'; | ||||
| import { | |||||
| checkSysEnv | |||||
| } from "utils/Utils"; | |||||
| // ==============================|| MAIN LOGO ||============================== // | // ==============================|| MAIN LOGO ||============================== // | ||||
| @@ -28,7 +31,7 @@ const LogoSection = ({ sx, to }) => { | |||||
| > | > | ||||
| <Logo /> | <Logo /> | ||||
| </ButtonBase> | </ButtonBase> | ||||
| <span id="systemTitle" >PNSPS</span> | |||||
| <span style={{ color: checkSysEnv()!=''?'red':'#0C489E'}} id="systemTitle">PNSPS</span> | |||||
| </Stack> | </Stack> | ||||
| ); | ); | ||||
| @@ -5,7 +5,8 @@ import { handleLogoutFunction } from 'auth/index'; | |||||
| import { useDispatch } from "react-redux"; | import { useDispatch } from "react-redux"; | ||||
| import { | import { | ||||
| isUserLoggedIn, | isUserLoggedIn, | ||||
| isGLDLoggedIn, | |||||
| isGLDLoggedIn, | |||||
| isPasswordExpiry | |||||
| } from "utils/Utils"; | } from "utils/Utils"; | ||||
| const TimerContext = createContext(); | const TimerContext = createContext(); | ||||
| @@ -81,6 +82,9 @@ const AutoLogoutProvider = ({ children }) => { | |||||
| // console.log(logoutInterval) | // console.log(logoutInterval) | ||||
| const interval = setInterval(async () => { | const interval = setInterval(async () => { | ||||
| const currentTime = Date.now(); | const currentTime = Date.now(); | ||||
| if (isPasswordExpiry()){ | |||||
| navigate('/user/changePassword'); | |||||
| } | |||||
| // getRemainingTime(); | // getRemainingTime(); | ||||
| if(state !== "Active" && lastActiveTab){ | if(state !== "Active" && lastActiveTab){ | ||||
| const timeElapsed = currentTime - lastRequestTime; | const timeElapsed = currentTime - lastRequestTime; | ||||
| @@ -1,17 +1,18 @@ | |||||
| // material-ui | // material-ui | ||||
| import {useState, useEffect} from 'react'; | |||||
| import { useState, useEffect } from 'react'; | |||||
| import { | import { | ||||
| DataGrid, GridOverlay, | DataGrid, GridOverlay, | ||||
| } from "@mui/x-data-grid"; | } from "@mui/x-data-grid"; | ||||
| import * as HttpUtils from "utils/HttpUtils"; | 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 ||============================== // | // ==============================|| EVENT TABLE ||============================== // | ||||
| export function FiDataGrid({ rows, columns, sx, autoHeight, | 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 intl = useIntl(); | ||||
| const [_rows, set_rows] = useState([]); | const [_rows, set_rows] = useState([]); | ||||
| const [_doLoad, set_doLoad] = useState({}); | const [_doLoad, set_doLoad] = useState({}); | ||||
| @@ -20,6 +21,7 @@ export function FiDataGrid({ rows, columns, sx, autoHeight, | |||||
| const [_editMode, set_editMode] = useState("row"); | const [_editMode, set_editMode] = useState("row"); | ||||
| const [_pageSizeOptions, set_pageSizeOptions] = useState([10]); | const [_pageSizeOptions, set_pageSizeOptions] = useState([10]); | ||||
| const [_filterItems, set_filterItems] = useState([]); | const [_filterItems, set_filterItems] = useState([]); | ||||
| const [loading, setLoading] = useState(false); | |||||
| const [page, setPage] = useState(0); | const [page, setPage] = useState(0); | ||||
| const [pageSize, setPageSize] = useState(10); | const [pageSize, setPageSize] = useState(10); | ||||
| @@ -27,6 +29,7 @@ export function FiDataGrid({ rows, columns, sx, autoHeight, | |||||
| const [myHideFooterSelectedRowCount, setMyHideFooterSelectedRowCount] = useState(true); | const [myHideFooterSelectedRowCount, setMyHideFooterSelectedRowCount] = useState(true); | ||||
| const [_sx, set_sx] = useState({ | const [_sx, set_sx] = useState({ | ||||
| padding: "4 2 4 2", | padding: "4 2 4 2", | ||||
| lineHeight: "normal", | |||||
| '& .MuiDataGrid-cell': { | '& .MuiDataGrid-cell': { | ||||
| borderTop: 1, | borderTop: 1, | ||||
| borderBottom: 1, | borderBottom: 1, | ||||
| @@ -36,18 +39,41 @@ export function FiDataGrid({ rows, columns, sx, autoHeight, | |||||
| border: 1, | border: 1, | ||||
| borderColor: "#EEE" | 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); | 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) | |||||
| console.log(localStorageSearchCriteria) | |||||
| if(localStorageSearchCriteria.start!=undefined){ | |||||
| console.log(localStorageSearchCriteria) | |||||
| setPage(localStorageSearchCriteria.start/pageSize); | |||||
| } | |||||
| } | |||||
| }else{ | |||||
| setPage(0); | |||||
| setPageSize(parseInt(event.target.value, 10)); | |||||
| } | |||||
| set_doLoad(doLoad); | |||||
| setLoading(true) | |||||
| } | |||||
| }, [doLoad]); | }, [doLoad]); | ||||
| useEffect(()=>{ | |||||
| useEffect(() => { | |||||
| getDataList(); | getDataList(); | ||||
| },[_doLoad, page]); | |||||
| }, [_doLoad, page]); | |||||
| useEffect(() => { | useEffect(() => { | ||||
| @@ -70,18 +96,25 @@ export function FiDataGrid({ rows, columns, sx, autoHeight, | |||||
| if (pageSizeOptions) { | if (pageSizeOptions) { | ||||
| set_pageSizeOptions(pageSizeOptions) | set_pageSizeOptions(pageSizeOptions) | ||||
| } | } | ||||
| if(autoHeight !== undefined){ | |||||
| if (autoHeight !== undefined) { | |||||
| set_autoHeight(autoHeight) | set_autoHeight(autoHeight) | ||||
| } | } | ||||
| if(editMode){ | |||||
| if (editMode) { | |||||
| set_editMode(editMode); | set_editMode(editMode); | ||||
| } | } | ||||
| if(filterItems){ | |||||
| if (filterItems) { | |||||
| set_filterItems(filterItems); | set_filterItems(filterItems); | ||||
| } | } | ||||
| if(customPageSize){ | |||||
| if (customPageSize) { | |||||
| setPageSize(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]); | }, [sx, hideFooterSelectedRowCount, rowModesModel, rows, columns, pageSizeOptions, autoHeight, editMode, filterItems, customPageSize]); | ||||
| const handleChangePage = (event, newPage) => { | const handleChangePage = (event, newPage) => { | ||||
| @@ -103,21 +136,51 @@ export function FiDataGrid({ rows, columns, sx, autoHeight, | |||||
| ); | ); | ||||
| } | } | ||||
| function getDataList() { | 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; | _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({ | HttpUtils.get({ | ||||
| url: _doLoad.url, | url: _doLoad.url, | ||||
| params: _doLoad.params, | params: _doLoad.params, | ||||
| onSuccess: function (responseData) { | onSuccess: function (responseData) { | ||||
| set_rows(responseData?.records); | set_rows(responseData?.records); | ||||
| setRowCount(responseData?.count); | setRowCount(responseData?.count); | ||||
| if(_doLoad.callback != null){ | |||||
| if (_doLoad.callback != null) { | |||||
| _doLoad.callback(responseData); | _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 +190,11 @@ export function FiDataGrid({ rows, columns, sx, autoHeight, | |||||
| <DataGrid | <DataGrid | ||||
| {...props} | {...props} | ||||
| rows={_rows} | rows={_rows} | ||||
| rowCount={rowCount ? rowCount : 0} | |||||
| columns={_columns} | columns={_columns} | ||||
| paginationMode="server" | paginationMode="server" | ||||
| disableColumnMenu | disableColumnMenu | ||||
| shrinkWrap={true} | |||||
| rowModesModel={_rowModesModel} | rowModesModel={_rowModesModel} | ||||
| pageSizeOptions={_pageSizeOptions} | pageSizeOptions={_pageSizeOptions} | ||||
| editMode={_editMode} | editMode={_editMode} | ||||
| @@ -137,16 +202,17 @@ export function FiDataGrid({ rows, columns, sx, autoHeight, | |||||
| hideFooterSelectedRowCount={myHideFooterSelectedRowCount} | hideFooterSelectedRowCount={myHideFooterSelectedRowCount} | ||||
| filterModel={{ items: _filterItems }} | filterModel={{ items: _filterItems }} | ||||
| sx={_sx} | sx={_sx} | ||||
| loading={loading} | |||||
| components={{ | components={{ | ||||
| noRowsOverlay: CustomNoRowsOverlay, | noRowsOverlay: CustomNoRowsOverlay, | ||||
| Pagination: () => ( | Pagination: () => ( | ||||
| <TablePagination | <TablePagination | ||||
| count={rowCount?rowCount:0} | |||||
| count={rowCount ? rowCount : 0} | |||||
| page={page} | page={page} | ||||
| rowsPerPage={pageSize} | rowsPerPage={pageSize} | ||||
| rowsPerPageOptions={_pageSizeOptions} | rowsPerPageOptions={_pageSizeOptions} | ||||
| labelDisplayedRows={() => | 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" }) + ":"} | labelRowsPerPage={intl.formatMessage({ id: "rowsPerPage" }) + ":"} | ||||
| onPageChange={handleChangePage} | onPageChange={handleChangePage} | ||||
| @@ -19,6 +19,7 @@ export default function FileList({ refType, refId, allowDelete, sx, dateHideable | |||||
| const theme = useTheme(); | const theme = useTheme(); | ||||
| const isMdOrLg = useMediaQuery(theme.breakpoints.up('md')); | const isMdOrLg = useMediaQuery(theme.breakpoints.up('md')); | ||||
| const intl = useIntl(); | const intl = useIntl(); | ||||
| const [onDownload, setOnDownload] = React.useState(false); | |||||
| React.useEffect(() => { | React.useEffect(() => { | ||||
| loadData(); | loadData(); | ||||
| @@ -41,10 +42,17 @@ export default function FileList({ refType, refId, allowDelete, sx, dateHideable | |||||
| }; | }; | ||||
| const onDownloadClick = (fileId, skey, filename) => () => { | const onDownloadClick = (fileId, skey, filename) => () => { | ||||
| setOnDownload(true) | |||||
| HttpUtils.fileDownload({ | HttpUtils.fileDownload({ | ||||
| fileId: fileId, | fileId: fileId, | ||||
| skey: skey, | skey: skey, | ||||
| filename: filename, | filename: filename, | ||||
| onResponse:()=>{ | |||||
| setOnDownload(false) | |||||
| }, | |||||
| onError:()=>{ | |||||
| setOnDownload(false) | |||||
| } | |||||
| }); | }); | ||||
| }; | }; | ||||
| @@ -91,6 +99,7 @@ export default function FileList({ refType, refId, allowDelete, sx, dateHideable | |||||
| className="textPrimary" | className="textPrimary" | ||||
| onClick={onDownloadClick(params.id, params.row.skey, params.row.filename)} | onClick={onDownloadClick(params.id, params.row.skey, params.row.filename)} | ||||
| color="primary" | color="primary" | ||||
| disabled={onDownload} | |||||
| />] | />] | ||||
| }, | }, | ||||
| }, | }, | ||||
| @@ -139,6 +148,7 @@ export default function FileList({ refType, refId, allowDelete, sx, dateHideable | |||||
| className="textPrimary" | className="textPrimary" | ||||
| onClick={onDownloadClick(params.id, params.row.skey, params.row.filename)} | onClick={onDownloadClick(params.id, params.row.skey, params.row.filename)} | ||||
| color="primary" | 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" | variant="subtitle2" | ||||
| color="secondary" | color="secondary" | ||||
| component={Link} | component={Link} | ||||
| // href="https://material-ui.com/store/contributors/codedthemes/" | |||||
| href="/importantNotice" | |||||
| target="_blank" | target="_blank" | ||||
| underline="hover" | underline="hover" | ||||
| > | > | ||||
| @@ -36,8 +36,7 @@ const AuthFooter = () => { | |||||
| variant="subtitle2" | variant="subtitle2" | ||||
| color="secondary" | color="secondary" | ||||
| component={Link} | component={Link} | ||||
| href="https://www.gld.gov.hk/zh-hk/privacy-policy/" | |||||
| //href="/testMailPage" | |||||
| href="/privacyPolicy" | |||||
| target="_blank" | target="_blank" | ||||
| underline="hover" | underline="hover" | ||||
| > | > | ||||
| @@ -1,4 +1,4 @@ | |||||
| import { StrictMode } from 'react'; | |||||
| import { StrictMode, useEffect, useContext } from 'react'; | |||||
| import { createRoot } from 'react-dom/client'; | import { createRoot } from 'react-dom/client'; | ||||
| import { BrowserRouter } from 'react-router-dom'; | import { BrowserRouter } from 'react-router-dom'; | ||||
| import "./assets/style/styles.css" | import "./assets/style/styles.css" | ||||
| @@ -16,9 +16,34 @@ import 'assets/third-party/apex-chart.css'; | |||||
| import App from './App'; | import App from './App'; | ||||
| import { store } from 'store'; | import { store } from 'store'; | ||||
| import reportWebVitals from './reportWebVitals'; | 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, SysContext } from 'components/SysSettingProvider'; | |||||
| import { useLocation } from 'react-router-dom'; | |||||
| function GreyWrapper({ children }) { | |||||
| const location = useLocation(); | |||||
| const { sysSetting } = useContext(SysContext); | |||||
| useEffect(() => { | |||||
| const isLoginPage = location.pathname === '/login'; | |||||
| const enableGrey = sysSetting?.greyLogin === true; | |||||
| if (isLoginPage && enableGrey) { | |||||
| document.body.classList.add('page-grey'); | |||||
| } else { | |||||
| document.body.classList.remove('page-grey'); | |||||
| } | |||||
| return () => { | |||||
| document.body.classList.remove('page-grey'); | |||||
| }; | |||||
| }, [location.pathname, sysSetting?.greyLogin]); | |||||
| return children; | |||||
| } | |||||
| // ==============================|| MAIN - REACT DOM RENDER ||============================== // | // ==============================|| MAIN - REACT DOM RENDER ||============================== // | ||||
| @@ -26,18 +51,23 @@ const container = document.getElementById('root'); | |||||
| const root = createRoot(container); // createRoot(container!) if you use TypeScript | const root = createRoot(container); // createRoot(container!) if you use TypeScript | ||||
| //const NotAuthorized = lazy(() => import('../views/NotAuthorized')) | //const NotAuthorized = lazy(() => import('../views/NotAuthorized')) | ||||
| //const Error = lazy(() => import('../views/Error')) | //const Error = lazy(() => import('../views/Error')) | ||||
| root.render( | root.render( | ||||
| <StrictMode> | <StrictMode> | ||||
| <ReduxProvider store={store}> | <ReduxProvider store={store}> | ||||
| <SysSettingProvider> | |||||
| <I18nProvider> | <I18nProvider> | ||||
| <BrowserRouter basename="/"> | <BrowserRouter basename="/"> | ||||
| <RefreshTokenProvider> | <RefreshTokenProvider> | ||||
| <AutoLogoutProvider> | <AutoLogoutProvider> | ||||
| <GreyWrapper> | |||||
| <App /> | <App /> | ||||
| </GreyWrapper> | |||||
| </AutoLogoutProvider> | </AutoLogoutProvider> | ||||
| </RefreshTokenProvider> | </RefreshTokenProvider> | ||||
| </BrowserRouter> | </BrowserRouter> | ||||
| </I18nProvider> | </I18nProvider> | ||||
| </SysSettingProvider> | |||||
| </ReduxProvider> | </ReduxProvider> | ||||
| </StrictMode> | </StrictMode> | ||||
| ); | ); | ||||
| @@ -1,9 +1,10 @@ | |||||
| import PropTypes from 'prop-types'; | import PropTypes from 'prop-types'; | ||||
| import React | import React | ||||
| , { useState } | |||||
| , { useState, useContext } | |||||
| from 'react'; | from 'react'; | ||||
| import { useDispatch } from "react-redux"; | import { useDispatch } from "react-redux"; | ||||
| import { useNavigate } from "react-router-dom"; | import { useNavigate } from "react-router-dom"; | ||||
| import { SysContext } from "components/SysSettingProvider" | |||||
| // material-ui | // material-ui | ||||
| // import { useTheme } from '@mui/material/styles'; | // import { useTheme } from '@mui/material/styles'; | ||||
| @@ -47,7 +48,10 @@ import { | |||||
| isPrimaryLoggedIn, | isPrimaryLoggedIn, | ||||
| isCreditorLoggedIn, | isCreditorLoggedIn, | ||||
| isINDLoggedIn, | isINDLoggedIn, | ||||
| // isORGLoggedIn, | |||||
| isPasswordExpiry, | |||||
| haveOrgPaymentRecord, | |||||
| isORGLoggedIn, | |||||
| checkSysEnv | |||||
| // getUserId | // getUserId | ||||
| } from "utils/Utils"; | } from "utils/Utils"; | ||||
| import { handleLogoutFunction } from 'auth/index'; | import { handleLogoutFunction } from 'auth/index'; | ||||
| @@ -66,6 +70,7 @@ const drawerWidth = 300; | |||||
| // ==============================|| MAIN LAYOUT - HEADER ||============================== // | // ==============================|| MAIN LAYOUT - HEADER ||============================== // | ||||
| function Header(props) { | function Header(props) { | ||||
| const { sysSetting } = useContext(SysContext); | |||||
| const { window } = props; | const { window } = props; | ||||
| const [mobileOpen, setMobileOpen] = useState(false); | const [mobileOpen, setMobileOpen] = useState(false); | ||||
| const dispatch = useDispatch() | const dispatch = useDispatch() | ||||
| @@ -76,346 +81,438 @@ function Header(props) { | |||||
| }; | }; | ||||
| const handleLogout = async () => { | const handleLogout = async () => { | ||||
| dispatch(handleLogoutFunction()); | |||||
| await dispatch(handleLogoutFunction()); | |||||
| //await handleLogoutFunction(); | //await handleLogoutFunction(); | ||||
| navigate('/login'); | |||||
| await navigate('/login'); | |||||
| }; | }; | ||||
| const loginContent = ( | const loginContent = ( | ||||
| isGLDLoggedIn() ? | isGLDLoggedIn() ? | ||||
| <div id="adminContent"> | <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> | <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> | </li> | ||||
| : <></> | |||||
| } | |||||
| { | |||||
| isGrantedAny(["MAINTAIN_PAYMENT", "MAINTAIN_RECON", "VIEW_DEMANDNOTE", "MAINTAIN_DEMANDNOTE"]) ? | |||||
| </div> | |||||
| : | |||||
| <div id="adminContentList"> | |||||
| <li> | <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> | <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> | </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> | <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> | </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> | <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> | </li> | ||||
| : | : | ||||
| <></> | <></> | ||||
| } | } | ||||
| { | { | ||||
| isGrantedAny(["VIEW_GROUP", "MAINTAIN_GROUP"]) ? | |||||
| isGranted("MAINTAIN_SETTING") ? | |||||
| <li> | <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> | </li> | ||||
| : | : | ||||
| <></> | <></> | ||||
| } | } | ||||
| </ul> | </ul> | ||||
| </li> | </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> | <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> | </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> | ||||
| : | : | ||||
| <div id="individualUserContent"> | <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> | </Typography> | ||||
| <KeyboardArrowDownIcon sx={{ fontSize: '1.0rem' }} /> | |||||
| </Link> | </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 }}> | <Link className="manageOrgUser" to='/paymentPage/demandNote'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}> | ||||
| <FormattedMessage id="paymentInfoRecord" /> | <FormattedMessage id="paymentInfoRecord" /> | ||||
| </Typography></Link> | </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> | </Typography> | ||||
| <KeyboardArrowDownIcon sx={{ fontSize: '1.0rem' }} /> | |||||
| </Link> | </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> | </Typography> | ||||
| <KeyboardArrowDownIcon sx={{ fontSize: '1.0rem' }} /> | |||||
| </Link> | </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> | </Typography> | ||||
| <KeyboardArrowDownIcon sx={{ fontSize: '1.0rem' }} /> | |||||
| </Link> | </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' } }}> | <Box sx={{ display: { xs: 'none', sm: 'none', md: 'block' } }}> | ||||
| <li> | <li> | ||||
| <Link className="logout" onClick={handleLogout}><Typography variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}> | <Link className="logout" onClick={handleLogout}><Typography variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}> | ||||
| @@ -429,19 +526,38 @@ function Header(props) { | |||||
| const logoutContent = ( | const logoutContent = ( | ||||
| <div> | <div> | ||||
| <li> | <li> | ||||
| <Link className="login" to='/login'> | |||||
| <Link className="login" to={'/aboutUs'}> | |||||
| <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}> | <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> | </Typography> | ||||
| </Link> | </Link> | ||||
| </li> | </li> | ||||
| <li> | <li> | ||||
| <Link className="register" to='/register'> | |||||
| <Link className="login" to='/login'> | |||||
| <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}> | <Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}> | ||||
| <FormattedMessage id="register" /> | |||||
| <FormattedMessage id="login" /> | |||||
| </Typography> | </Typography> | ||||
| </Link> | </Link> | ||||
| </li> | </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> | </div> | ||||
| ); | ); | ||||
| @@ -453,7 +569,7 @@ function Header(props) { | |||||
| </Typography> */} | </Typography> */} | ||||
| <Box sx={{ mr: 2, mt: 1, display: { md: 'none' } }}> | <Box sx={{ mr: 2, mt: 1, display: { md: 'none' } }}> | ||||
| <MobileLogo /> | <MobileLogo /> | ||||
| <span id="mobileTitle" >PNSPS</span> | |||||
| <span style={{ color: checkSysEnv()!=''?'red':'#0C489E'}} id="mobileTitle" >PNSPS</span> | |||||
| </Box> | </Box> | ||||
| <Divider /> | <Divider /> | ||||
| <ul id="sidebartop"> | <ul id="sidebartop"> | ||||
| @@ -472,7 +588,7 @@ function Header(props) { | |||||
| <Stack id="sidebar" direction="column" justifyContent="center" alignItems="center" onClick={handleDrawerToggle} sx={{ textAlign: 'center' }}> | <Stack id="sidebar" direction="column" justifyContent="center" alignItems="center" onClick={handleDrawerToggle} sx={{ textAlign: 'center' }}> | ||||
| <Box sx={{ mr: 2, mt: 1, display: { md: 'none' } }}> | <Box sx={{ mr: 2, mt: 1, display: { md: 'none' } }}> | ||||
| <MobileLogo /> | <MobileLogo /> | ||||
| <span id="mobileTitle" >PNSPS</span> | |||||
| <span style={{ color: checkSysEnv()!=''?'red':'#0C489E'}} id="mobileTitle" >PNSPS</span> | |||||
| </Box> | </Box> | ||||
| <Divider /> | <Divider /> | ||||
| <ul id="logoutContent"> | <ul id="logoutContent"> | ||||
| @@ -495,8 +611,9 @@ function Header(props) { | |||||
| justifyContent="flex-start" | justifyContent="flex-start" | ||||
| alignItems="center" | alignItems="center" | ||||
| spacing={0} | 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 /> | <AdminLogo /> | ||||
| </Box> | </Box> | ||||
| <IconButton | <IconButton | ||||
| @@ -508,9 +625,16 @@ function Header(props) { | |||||
| > | > | ||||
| <MenuIcon style={{ color: '#0C489E' }} /> | <MenuIcon style={{ color: '#0C489E' }} /> | ||||
| </IconButton> | </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> | </Box> | ||||
| </Stack> : | </Stack> : | ||||
| <Stack | <Stack | ||||
| @@ -520,13 +644,13 @@ function Header(props) { | |||||
| spacing={0} | spacing={0} | ||||
| sx={{ width: { xs: '100%', md: '25%' } }} | 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"> | <Stack direction="row" justifyContent="flex-start" alignItems="center"> | ||||
| <Logo /> | <Logo /> | ||||
| <Stack justifyContent="flex-start" alignItems="center"> | <Stack justifyContent="flex-start" alignItems="center"> | ||||
| {/*<span id="systemTitle">公共啟事提交</span>*/} | {/*<span id="systemTitle">公共啟事提交</span>*/} | ||||
| {/*<span id="systemTitle">及繳費系統</span>*/} | {/*<span id="systemTitle">及繳費系統</span>*/} | ||||
| <span id="systemTitle"> | |||||
| <span style={{ color: checkSysEnv()!=''?'red':'#0C489E'}} id="systemTitle"> | |||||
| <FormattedMessage id="PNSPS" /> | <FormattedMessage id="PNSPS" /> | ||||
| </span> | </span> | ||||
| </Stack> | </Stack> | ||||
| @@ -545,7 +669,7 @@ function Header(props) { | |||||
| <Stack direction="row" justifyContent="space-between" alignItems="center" width="100%"> | <Stack direction="row" justifyContent="space-between" alignItems="center" width="100%"> | ||||
| <MobileLogo /> | <MobileLogo /> | ||||
| <Stack justifyContent="flex-start" alignItems="flex-start" width="100%" ml={2}> | <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" /> | <FormattedMessage id="PNSPS" /> | ||||
| </span> | </span> | ||||
| </Stack> | </Stack> | ||||
| @@ -576,7 +700,9 @@ function Header(props) { | |||||
| > | > | ||||
| { | { | ||||
| isGLDLoggedIn() ? | isGLDLoggedIn() ? | ||||
| <Grid item /> | |||||
| <Grid item > | |||||
| <span style={{color:"#B11B1B",fontWeight:'bold',fontSize:'15px'}}>RESTRICTED</span> | |||||
| </Grid> | |||||
| : | : | ||||
| <Grid item> | <Grid item> | ||||
| <LocaleSelector /> | <LocaleSelector /> | ||||
| @@ -642,7 +768,7 @@ function Header(props) { | |||||
| <Stack direction="row" justifyContent="space-between" alignItems="center" width="100%"> | <Stack direction="row" justifyContent="space-between" alignItems="center" width="100%"> | ||||
| <MobileLogo /> | <MobileLogo /> | ||||
| <Stack justifyContent="flex-start" alignItems="flex-start" width="100%" ml={2}> | <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" /> | <FormattedMessage id="PNSPS" /> | ||||
| </span> | </span> | ||||
| </Stack> | </Stack> | ||||
| @@ -1,6 +1,7 @@ | |||||
| import { useEffect, useState } from 'react'; | import { useEffect, useState } from 'react'; | ||||
| import { Outlet } from 'react-router-dom'; | import { Outlet } from 'react-router-dom'; | ||||
| import { useDispatch, useSelector } from 'react-redux'; | import { useDispatch, useSelector } from 'react-redux'; | ||||
| import { useLocation } from 'react-router-dom'; | |||||
| // material-ui | // material-ui | ||||
| import { useTheme } from '@mui/material/styles'; | import { useTheme } from '@mui/material/styles'; | ||||
| @@ -31,7 +32,8 @@ const MainLayout = () => { | |||||
| const theme = useTheme(); | const theme = useTheme(); | ||||
| const matchDownLG = useMediaQuery(theme.breakpoints.down('lg')); | const matchDownLG = useMediaQuery(theme.breakpoints.down('lg')); | ||||
| const dispatch = useDispatch(); | const dispatch = useDispatch(); | ||||
| const location = useLocation(); | |||||
| const hideNavbarRoutes = ['/databaseHealthCheck'] | |||||
| const { drawerOpen } = useSelector((state) => state.menu); | const { drawerOpen } = useSelector((state) => state.menu); | ||||
| // drawer toggler | // drawer toggler | ||||
| @@ -55,18 +57,26 @@ const MainLayout = () => { | |||||
| }, [drawerOpen]); | }, [drawerOpen]); | ||||
| return ( | 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"; | import {GET_ANNOUNCE_LIST} from "utils/ApiPathConst"; | ||||
| // ==============================|| EVENT TABLE ||============================== // | // ==============================|| EVENT TABLE ||============================== // | ||||
| export default function SearchPublicNoticeTable({ searchCriteria }) { | |||||
| export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnReady, applySearch}) { | |||||
| const navigate = useNavigate() | const navigate = useNavigate() | ||||
| @@ -73,10 +73,16 @@ export default function SearchPublicNoticeTable({ searchCriteria }) { | |||||
| customPageSize={10} | customPageSize={10} | ||||
| getRowHeight={() => 'auto'} | getRowHeight={() => 'auto'} | ||||
| onRowDoubleClick={handleRowDoubleClick} | onRowDoubleClick={handleRowDoubleClick} | ||||
| doLoad={{ | |||||
| applyGridOnReady={applyGridOnReady} | |||||
| applySearch = {applySearch} | |||||
| // doLoad={{ | |||||
| // url: GET_ANNOUNCE_LIST, | |||||
| // params: _searchCriteria, | |||||
| // }} | |||||
| doLoad={React.useMemo(() => ({ | |||||
| url: GET_ANNOUNCE_LIST, | url: GET_ANNOUNCE_LIST, | ||||
| params: _searchCriteria, | params: _searchCriteria, | ||||
| }} | |||||
| }), [_searchCriteria])} | |||||
| /> | /> | ||||
| </div> | </div> | ||||
| ); | ); | ||||
| @@ -17,8 +17,9 @@ import dayjs from "dayjs"; | |||||
| import {DemoItem} from "@mui/x-date-pickers/internals/demo"; | import {DemoItem} from "@mui/x-date-pickers/internals/demo"; | ||||
| import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider"; | import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider"; | ||||
| import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs"; | import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs"; | ||||
| // ==============================|| DASHBOARD - DEFAULT ||============================== // | // ==============================|| DASHBOARD - DEFAULT ||============================== // | ||||
| const SearchPublicNoticeForm = ({ applySearch, searchCriteria}) => { | |||||
| const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady}) => { | |||||
| const navigate = useNavigate() | const navigate = useNavigate() | ||||
| const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom); | const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom); | ||||
| @@ -50,6 +51,8 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria}) => { | |||||
| key: data.key, | key: data.key, | ||||
| dateFrom: sentDateFrom, | dateFrom: sentDateFrom, | ||||
| dateTo: sentDateTo, | dateTo: sentDateTo, | ||||
| start:0, | |||||
| limit:10 | |||||
| }; | }; | ||||
| applySearch(temp); | applySearch(temp); | ||||
| }; | }; | ||||
| @@ -58,7 +61,8 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria}) => { | |||||
| function resetForm() { | function resetForm() { | ||||
| setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14))) | setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14))) | ||||
| setMaxDate(DateUtils.dateValue(new Date())) | setMaxDate(DateUtils.dateValue(new Date())) | ||||
| reset(); | |||||
| reset({key:""}); | |||||
| localStorage.setItem('searchCriteria',"") | |||||
| } | } | ||||
| @@ -180,6 +184,7 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria}) => { | |||||
| <Button | <Button | ||||
| variant="contained" | variant="contained" | ||||
| type="submit" | type="submit" | ||||
| disabled={onGridReady} | |||||
| > | > | ||||
| Submit | Submit | ||||
| </Button> | </Button> | ||||
| @@ -7,6 +7,7 @@ import { | |||||
| import MainCard from "components/MainCard"; | import MainCard from "components/MainCard"; | ||||
| import * as React from "react"; | import * as React from "react"; | ||||
| import * as DateUtils from "utils/DateUtils"; | import * as DateUtils from "utils/DateUtils"; | ||||
| import { getSearchCriteria } from "auth/utils"; | |||||
| import Loadable from 'components/Loadable'; | import Loadable from 'components/Loadable'; | ||||
| const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | ||||
| @@ -28,20 +29,37 @@ const BackgroundHead = { | |||||
| const UserSearchPage_Individual = () => { | 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 [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(() => { | React.useEffect(() => { | ||||
| setOnReady(true); | setOnReady(true); | ||||
| }, [searchCriteria]); | }, [searchCriteria]); | ||||
| function applySearch(input) { | function applySearch(input) { | ||||
| setGridOnReady(true) | |||||
| setSearchCriteria(input); | setSearchCriteria(input); | ||||
| localStorage.setItem('searchCriteria', JSON.stringify({path:window.location.pathname,data:input})) | |||||
| } | |||||
| function applyGridOnReady(input) { | |||||
| setGridOnReady(input); | |||||
| } | } | ||||
| return ( | return ( | ||||
| !onReady ? | !onReady ? | ||||
| <Grid container sx={{ minHeight: '95vh', mb: 3 }} direction="column" justifyContent="center" alignItems="center"> | <Grid container sx={{ minHeight: '95vh', mb: 3 }} direction="column" justifyContent="center" alignItems="center"> | ||||
| @@ -63,6 +81,7 @@ const UserSearchPage_Individual = () => { | |||||
| <SearchForm | <SearchForm | ||||
| applySearch={applySearch} | applySearch={applySearch} | ||||
| searchCriteria={searchCriteria} | searchCriteria={searchCriteria} | ||||
| onGridReady={onGridReady} | |||||
| /> | /> | ||||
| </Grid> | </Grid> | ||||
| {/*row 2*/} | {/*row 2*/} | ||||
| @@ -73,7 +92,9 @@ const UserSearchPage_Individual = () => { | |||||
| sx={{ backgroundColor: '#fff' }} | sx={{ backgroundColor: '#fff' }} | ||||
| > | > | ||||
| <EventTable | <EventTable | ||||
| searchCriteria={searchCriteria} | |||||
| searchCriteria={searchCriteria} | |||||
| applyGridOnReady={applyGridOnReady} | |||||
| applySearch={applySearch} | |||||
| /> | /> | ||||
| </MainCard> | </MainCard> | ||||
| </Grid> | </Grid> | ||||
| @@ -6,7 +6,7 @@ import { FormattedMessage, useIntl } from "react-intl"; | |||||
| import {GET_ANNOUNCE_LIST} from "utils/ApiPathConst"; | import {GET_ANNOUNCE_LIST} from "utils/ApiPathConst"; | ||||
| // ==============================|| EVENT TABLE ||============================== // | // ==============================|| EVENT TABLE ||============================== // | ||||
| export default function SearchPublicNoticeTable({ searchCriteria }) { | |||||
| export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnReady,applySearch }) { | |||||
| const intl = useIntl(); | const intl = useIntl(); | ||||
| const { locale } = intl; | const { locale } = intl; | ||||
| @@ -57,10 +57,16 @@ export default function SearchPublicNoticeTable({ searchCriteria }) { | |||||
| columns={columns} | columns={columns} | ||||
| customPageSize={10} | customPageSize={10} | ||||
| getRowHeight={() => 'auto'} | getRowHeight={() => 'auto'} | ||||
| doLoad={{ | |||||
| applyGridOnReady={applyGridOnReady} | |||||
| applySearch={applySearch} | |||||
| // doLoad={{ | |||||
| // url: GET_ANNOUNCE_LIST, | |||||
| // params: _searchCriteria | |||||
| // }} | |||||
| doLoad={React.useMemo(() => ({ | |||||
| url: GET_ANNOUNCE_LIST, | url: GET_ANNOUNCE_LIST, | ||||
| params: _searchCriteria | |||||
| }} | |||||
| params: _searchCriteria, | |||||
| }), [_searchCriteria])} | |||||
| /> | /> | ||||
| </div> | </div> | ||||
| ); | ); | ||||
| @@ -19,7 +19,7 @@ import {DemoItem} from "@mui/x-date-pickers/internals/demo"; | |||||
| import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider"; | import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider"; | ||||
| import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs"; | import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs"; | ||||
| // ==============================|| DASHBOARD - DEFAULT ||============================== // | // ==============================|| DASHBOARD - DEFAULT ||============================== // | ||||
| const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => { | |||||
| const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady }) => { | |||||
| // const navigate = useNavigate() | // const navigate = useNavigate() | ||||
| const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom); | const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom); | ||||
| @@ -39,6 +39,22 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => { | |||||
| setToDateValue(maxDate); | setToDateValue(maxDate); | ||||
| }, [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 marginBottom = 2.5; | ||||
| const { reset, register, handleSubmit } = useForm() | const { reset, register, handleSubmit } = useForm() | ||||
| const onSubmit = (data) => { | const onSubmit = (data) => { | ||||
| @@ -52,6 +68,8 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => { | |||||
| key: data.key, | key: data.key, | ||||
| dateFrom: sentDateFrom, | dateFrom: sentDateFrom, | ||||
| dateTo: sentDateTo, | dateTo: sentDateTo, | ||||
| start:0, | |||||
| limit:10 | |||||
| }; | }; | ||||
| applySearch(temp); | applySearch(temp); | ||||
| }; | }; | ||||
| @@ -60,7 +78,8 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => { | |||||
| function resetForm() { | function resetForm() { | ||||
| setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14))) | setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14))) | ||||
| setMaxDate(DateUtils.dateValue(new Date())) | setMaxDate(DateUtils.dateValue(new Date())) | ||||
| reset(); | |||||
| reset({key:""}); | |||||
| localStorage.setItem('searchCriteria',"") | |||||
| } | } | ||||
| @@ -68,7 +87,7 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => { | |||||
| <MainCard xs={12} md={12} lg={12} | <MainCard xs={12} md={12} lg={12} | ||||
| border={false} | border={false} | ||||
| content={false} | content={false} | ||||
| sx={{ backgroundColor: '#fff' }} | |||||
| sx={_sx} | |||||
| > | > | ||||
| <form onSubmit={handleSubmit(onSubmit)}> | <form onSubmit={handleSubmit(onSubmit)}> | ||||
| @@ -186,6 +205,8 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => { | |||||
| <Button | <Button | ||||
| variant="contained" | variant="contained" | ||||
| type="submit" | type="submit" | ||||
| disabled={onGridReady} | |||||
| aria-label={intl.formatMessage({id: 'submit'})} | |||||
| > | > | ||||
| <FormattedMessage id="submit"></FormattedMessage> | <FormattedMessage id="submit"></FormattedMessage> | ||||
| </Button> | </Button> | ||||
| @@ -14,6 +14,7 @@ const SearchForm = Loadable(React.lazy(() => import('./SearchForm'))); | |||||
| const EventTable = Loadable(React.lazy(() => import('./DataGrid'))); | const EventTable = Loadable(React.lazy(() => import('./DataGrid'))); | ||||
| import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' | import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' | ||||
| import { FormattedMessage } from "react-intl"; | import { FormattedMessage } from "react-intl"; | ||||
| import { getSearchCriteria } from "auth/utils"; | |||||
| const BackgroundHead = { | const BackgroundHead = { | ||||
| backgroundImage: `url(${titleBackgroundImg})`, | backgroundImage: `url(${titleBackgroundImg})`, | ||||
| @@ -29,19 +30,36 @@ const BackgroundHead = { | |||||
| const UserSearchPage_Individual = () => { | 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 [onReady, setOnReady] = React.useState(false); | ||||
| const [onGridReady, setGridOnReady] = React.useState(false); | |||||
| React.useEffect(() => { | 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]); | }, [searchCriteria]); | ||||
| function applySearch(input) { | function applySearch(input) { | ||||
| setSearchCriteria(input); | setSearchCriteria(input); | ||||
| localStorage.setItem('searchCriteria', JSON.stringify({path:window.location.pathname,data:input})) | |||||
| } | |||||
| function applyGridOnReady(input) { | |||||
| setGridOnReady(input); | |||||
| } | } | ||||
| return ( | return ( | ||||
| @@ -65,6 +83,7 @@ const UserSearchPage_Individual = () => { | |||||
| <SearchForm | <SearchForm | ||||
| applySearch={applySearch} | applySearch={applySearch} | ||||
| searchCriteria={searchCriteria} | searchCriteria={searchCriteria} | ||||
| onGridReady={onGridReady} | |||||
| /> | /> | ||||
| </Grid> | </Grid> | ||||
| {/*row 2*/} | {/*row 2*/} | ||||
| @@ -76,6 +95,8 @@ const UserSearchPage_Individual = () => { | |||||
| > | > | ||||
| <EventTable | <EventTable | ||||
| searchCriteria={searchCriteria} | searchCriteria={searchCriteria} | ||||
| applyGridOnReady={applyGridOnReady} | |||||
| applySearch={applySearch} | |||||
| /> | /> | ||||
| </MainCard> | </MainCard> | ||||
| </Grid> | </Grid> | ||||
| @@ -21,16 +21,18 @@ import {ThemeProvider} from "@emotion/react"; | |||||
| import * as DateUtils from "utils/DateUtils"; | import * as DateUtils from "utils/DateUtils"; | ||||
| import * as UrlUtils from "utils/ApiPathConst"; | import * as UrlUtils from "utils/ApiPathConst"; | ||||
| import * as HttpUtils from "utils/HttpUtils"; | 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 {DatePicker} from "@mui/x-date-pickers/DatePicker"; | ||||
| import dayjs from "dayjs"; | import dayjs from "dayjs"; | ||||
| import {DemoItem} from "@mui/x-date-pickers/internals/demo"; | import {DemoItem} from "@mui/x-date-pickers/internals/demo"; | ||||
| import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider"; | import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider"; | ||||
| import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs"; | import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs"; | ||||
| import { isGranted } from "auth/utils"; | |||||
| // ==============================|| DASHBOARD - DEFAULT ||============================== // | // ==============================|| DASHBOARD - DEFAULT ||============================== // | ||||
| const AuditLogSearchForm = ({ applySearch, searchCriteria}) => { | |||||
| const AuditLogSearchForm = ({ applySearch, searchCriteria, onGridReady}) => { | |||||
| // const navigate = useNavigate(); | // const navigate = useNavigate(); | ||||
| const [minDate, setMinDate] = React.useState(searchCriteria.modifiedFrom); | const [minDate, setMinDate] = React.useState(searchCriteria.modifiedFrom); | ||||
| @@ -64,6 +66,8 @@ const AuditLogSearchForm = ({ applySearch, searchCriteria}) => { | |||||
| username: data.userName, | username: data.userName, | ||||
| modifiedTo: sentDateTo, | modifiedTo: sentDateTo, | ||||
| modifiedFrom: sentDateFrom, | modifiedFrom: sentDateFrom, | ||||
| start:0, | |||||
| limit:10 | |||||
| }; | }; | ||||
| applySearch(temp); | applySearch(temp); | ||||
| }; | }; | ||||
| @@ -77,6 +81,7 @@ const AuditLogSearchForm = ({ applySearch, searchCriteria}) => { | |||||
| setOnDownload(true) | setOnDownload(true) | ||||
| HttpUtils.fileDownload({ | HttpUtils.fileDownload({ | ||||
| url: UrlUtils.AUDIT_LOG_EXPORT, | url: UrlUtils.AUDIT_LOG_EXPORT, | ||||
| params: searchCriteria, | |||||
| onResponse:()=>{ | onResponse:()=>{ | ||||
| setOnDownload(false) | setOnDownload(false) | ||||
| }, | }, | ||||
| @@ -185,18 +190,17 @@ const AuditLogSearchForm = ({ applySearch, searchCriteria}) => { | |||||
| <ThemeProvider theme={PNSPS_BUTTON_THEME}> | <ThemeProvider theme={PNSPS_BUTTON_THEME}> | ||||
| <Grid item xs={12} md={12}> | <Grid item xs={12} md={12}> | ||||
| <Grid container maxWidth justifyContent="flex-end"> | <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 | <Button | ||||
| variant="contained" | variant="contained" | ||||
| onClick={exportExcel} | onClick={exportExcel} | ||||
| disabled={onDownload} | |||||
| > | > | ||||
| Export | Export | ||||
| </Button> | </Button> | ||||
| } | |||||
| </Grid> | |||||
| </Grid> : null | |||||
| } | |||||
| <Grid item sx={{ ml: 3, mr: 3, mb: 3,}}> | <Grid item sx={{ ml: 3, mr: 3, mb: 3,}}> | ||||
| <Button | <Button | ||||
| variant="contained" | variant="contained" | ||||
| @@ -210,6 +214,7 @@ const AuditLogSearchForm = ({ applySearch, searchCriteria}) => { | |||||
| <Button | <Button | ||||
| variant="contained" | variant="contained" | ||||
| type="submit" | type="submit" | ||||
| disabled={onGridReady} | |||||
| > | > | ||||
| Search | Search | ||||
| </Button> | </Button> | ||||
| @@ -12,7 +12,7 @@ import { | |||||
| } from '@mui/material'; | } from '@mui/material'; | ||||
| // ==============================|| EVENT TABLE ||============================== // | // ==============================|| EVENT TABLE ||============================== // | ||||
| export default function AuditLogTable({searchCriteria}) { | |||||
| export default function AuditLogTable({searchCriteria, applyGridOnReady,applySearch}) { | |||||
| const [_searchCriteria, set_searchCriteria] = React.useState(searchCriteria); | const [_searchCriteria, set_searchCriteria] = React.useState(searchCriteria); | ||||
| useEffect(() => { | useEffect(() => { | ||||
| @@ -87,10 +87,16 @@ export default function AuditLogTable({searchCriteria}) { | |||||
| columns={columns} | columns={columns} | ||||
| customPageSize={10} | customPageSize={10} | ||||
| getRowHeight={() => 'auto'} | getRowHeight={() => 'auto'} | ||||
| doLoad={{ | |||||
| applyGridOnReady={applyGridOnReady} | |||||
| applySearch={applySearch} | |||||
| // doLoad={{ | |||||
| // url: GET_AUDIT_LOG_LIST, | |||||
| // params: _searchCriteria | |||||
| // }} | |||||
| doLoad={React.useMemo(() => ({ | |||||
| url: GET_AUDIT_LOG_LIST, | url: GET_AUDIT_LOG_LIST, | ||||
| params: _searchCriteria | |||||
| }} | |||||
| params: _searchCriteria, | |||||
| }), [_searchCriteria])} | |||||
| /> | /> | ||||
| </div> | </div> | ||||
| ); | ); | ||||
| @@ -8,6 +8,7 @@ import { | |||||
| import MainCard from "components/MainCard"; | import MainCard from "components/MainCard"; | ||||
| import { useEffect, useState } from "react"; | import { useEffect, useState } from "react"; | ||||
| import * as DateUtils from "utils/DateUtils"; | import * as DateUtils from "utils/DateUtils"; | ||||
| import * as React from "react"; | |||||
| import Loadable from 'components/Loadable'; | import Loadable from 'components/Loadable'; | ||||
| import { lazy } from 'react'; | import { lazy } from 'react'; | ||||
| @@ -33,15 +34,21 @@ const AuditLogPage = () => { | |||||
| modifiedFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)), | modifiedFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)), | ||||
| }); | }); | ||||
| const [onReady, setOnReady] = useState(false); | const [onReady, setOnReady] = useState(false); | ||||
| const [onGridReady, setGridOnReady] = React.useState(false); | |||||
| useEffect(() => { | useEffect(() => { | ||||
| setOnReady(true); | setOnReady(true); | ||||
| }, [searchCriteria]); | }, [searchCriteria]); | ||||
| function applySearch(input) { | function applySearch(input) { | ||||
| setGridOnReady(true) | |||||
| setSearchCriteria(input); | setSearchCriteria(input); | ||||
| } | } | ||||
| function applyGridOnReady(input) { | |||||
| setGridOnReady(input); | |||||
| } | |||||
| return ( | return ( | ||||
| !onReady ? | !onReady ? | ||||
| <Grid container sx={{ minHeight: '87vh', mb: 3 }} direction="column" justifyContent="center" alignItems="center"> | <Grid container sx={{ minHeight: '87vh', mb: 3 }} direction="column" justifyContent="center" alignItems="center"> | ||||
| @@ -64,7 +71,7 @@ const AuditLogPage = () => { | |||||
| <SearchForm | <SearchForm | ||||
| applySearch={applySearch} | applySearch={applySearch} | ||||
| searchCriteria={searchCriteria} | searchCriteria={searchCriteria} | ||||
| onGridReady={onGridReady} | |||||
| /> | /> | ||||
| </Grid> | </Grid> | ||||
| {/*row 2*/} | {/*row 2*/} | ||||
| @@ -75,6 +82,8 @@ const AuditLogPage = () => { | |||||
| > | > | ||||
| <EventTable | <EventTable | ||||
| searchCriteria={searchCriteria} | searchCriteria={searchCriteria} | ||||
| applyGridOnReady={applyGridOnReady} | |||||
| applySearch={applySearch} | |||||
| /> | /> | ||||
| </MainCard> | </MainCard> | ||||
| </Grid> | </Grid> | ||||
| @@ -136,6 +136,8 @@ const SearchPublicNoticeForm = ({ applySearch, issueComboData, _paymentCount, _p | |||||
| } | } | ||||
| const temp = { | const temp = { | ||||
| issueId: issueSelected.id, | issueId: issueSelected.id, | ||||
| start:0, | |||||
| limit:10 | |||||
| }; | }; | ||||
| applySearch(temp); | applySearch(temp); | ||||
| }; | }; | ||||
| @@ -171,6 +173,11 @@ const SearchPublicNoticeForm = ({ applySearch, issueComboData, _paymentCount, _p | |||||
| setIssueSelected(newValue); | setIssueSelected(newValue); | ||||
| } | } | ||||
| }} | }} | ||||
| sx={{ | |||||
| '& .MuiInputBase-root': { alignItems: 'center' }, | |||||
| '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, | |||||
| '& .MuiOutlinedInput-root': { height: 40 } | |||||
| }} | |||||
| renderInput={(params) => ( | renderInput={(params) => ( | ||||
| <TextField {...params} | <TextField {...params} | ||||
| label="Gazette Issue" | label="Gazette Issue" | ||||
| @@ -143,7 +143,7 @@ const ApplicationDetailCard = ({ data }) => { | |||||
| </Grid> | </Grid> | ||||
| <Grid container direction="row" justifyContent="space-between" | <Grid container direction="row" justifyContent="space-between" | ||||
| alignItems="center"> | 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 container alignItems={"center"}> | ||||
| <Grid item xs={12} md={12} lg={12}> | <Grid item xs={12} md={12} lg={12}> | ||||
| <Grid container direction="row"> | <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.enCompanyName != null ? params.row.enCompanyName : params.row.chCompanyName; | ||||
| let user = params.row.contactPerson; | let user = params.row.contactPerson; | ||||
| // user = user != null ? user : ""; | // 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> | return <div> | ||||
| {user} | {user} | ||||
| </div>; | </div>; | ||||
| @@ -95,7 +95,7 @@ export default function SearchPublicNoticeTable({ searchCriteria,}) { | |||||
| let company = params.row.enCompanyName != null ? params.row.enCompanyName : params.row.chCompanyName; | let company = params.row.enCompanyName != null ? params.row.enCompanyName : params.row.chCompanyName; | ||||
| company = company != null ? company : ""; | company = company != null ? company : ""; | ||||
| if (params.row.sysType != null && params.row.sysType == "dummy"){ | if (params.row.sysType != null && params.row.sysType == "dummy"){ | ||||
| company = params.row.contactPerson | |||||
| company = params.row.custName | |||||
| } | } | ||||
| return <div> | return <div> | ||||
| {company} | {company} | ||||
| @@ -109,7 +109,13 @@ export default function SearchPublicNoticeTable({ searchCriteria,}) { | |||||
| flex: 2, | flex: 2, | ||||
| minWidth: 200, | minWidth: 200, | ||||
| renderCell: (params) => { | 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, | minWidth: 100, | ||||
| valueGetter: (params) => { | valueGetter: (params) => { | ||||
| let length = params.row.length | let length = params.row.length | ||||
| let colCount = params.row.colCount | |||||
| // let colCount = params.row.colCount | |||||
| let noOfPages = params.row.noOfPages | let noOfPages = params.row.noOfPages | ||||
| let dimension = 0 | let dimension = 0 | ||||
| if (noOfPages != null){ | if (noOfPages != null){ | ||||
| dimension = length*colCount*noOfPages | |||||
| dimension = length*noOfPages | |||||
| }else{ | }else{ | ||||
| dimension = length*colCount | |||||
| dimension = length | |||||
| } | } | ||||
| return dimension; | return dimension; | ||||
| } | } | ||||
| @@ -134,7 +140,7 @@ export default function SearchPublicNoticeTable({ searchCriteria,}) { | |||||
| { | { | ||||
| id: 'fee', | id: 'fee', | ||||
| field: 'fee', | field: 'fee', | ||||
| headerName: 'Amount(HK$)', | |||||
| headerName: 'Amount($)', | |||||
| flex: 1, | flex: 1, | ||||
| minWidth: 100, | minWidth: 100, | ||||
| valueGetter: (params) => { | valueGetter: (params) => { | ||||
| @@ -137,6 +137,8 @@ const SearchPublicNoticeForm = ({ applySearch, issueComboData }) => { | |||||
| } | } | ||||
| const temp = { | const temp = { | ||||
| issueId: issueSelected.id, | issueId: issueSelected.id, | ||||
| start:0, | |||||
| limit:10 | |||||
| }; | }; | ||||
| applySearch(temp); | applySearch(temp); | ||||
| }; | }; | ||||
| @@ -172,6 +174,11 @@ const SearchPublicNoticeForm = ({ applySearch, issueComboData }) => { | |||||
| setIssueSelected(newValue); | setIssueSelected(newValue); | ||||
| } | } | ||||
| }} | }} | ||||
| sx={{ | |||||
| '& .MuiInputBase-root': { alignItems: 'center' }, | |||||
| '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, | |||||
| '& .MuiOutlinedInput-root': { height: 40 } | |||||
| }} | |||||
| renderInput={(params) => ( | renderInput={(params) => ( | ||||
| <TextField {...params} | <TextField {...params} | ||||
| label="Gazette Issue" | label="Gazette Issue" | ||||
| @@ -19,7 +19,8 @@ import { | |||||
| DEMAND_NOTE_SEND, | DEMAND_NOTE_SEND, | ||||
| DEMAND_NOTE_ATTACH, | DEMAND_NOTE_ATTACH, | ||||
| DEMAND_NOTE_MARK_PAID, | DEMAND_NOTE_MARK_PAID, | ||||
| DEMAND_NOTE_LIST_ALL | |||||
| DEMAND_NOTE_LIST_ALL, | |||||
| DEMAND_NOTE_REVOKE_PAID | |||||
| } from "utils/ApiPathConst"; | } from "utils/ApiPathConst"; | ||||
| import * as HttpUtils from "utils/HttpUtils"; | import * as HttpUtils from "utils/HttpUtils"; | ||||
| import { PNSPS_BUTTON_THEME } from "themes/buttonConst"; | import { PNSPS_BUTTON_THEME } from "themes/buttonConst"; | ||||
| @@ -27,23 +28,26 @@ import { ThemeProvider } from "@emotion/react"; | |||||
| import { isGrantedAny } from "auth/utils"; | import { isGrantedAny } from "auth/utils"; | ||||
| // ==============================|| EVENT TABLE ||============================== // | // ==============================|| EVENT TABLE ||============================== // | ||||
| export default function SearchDemandNote({ searchCriteria, applySearch }) { | |||||
| export default function SearchDemandNote({ applySearch, searchCriteria, applyGridOnReady }) { | |||||
| const [isConfirmPopUp, setConfirmPopUp] = useState(false); | const [isConfirmPopUp, setConfirmPopUp] = useState(false); | ||||
| const [isRevokePopUp, setRevokePopUp] = useState(false); | |||||
| const [isSendPopUp, setSendPopUp] = useState(false); | const [isSendPopUp, setSendPopUp] = useState(false); | ||||
| const [isErrorPopUp, setIsErrorPopUp] = useState(false); | const [isErrorPopUp, setIsErrorPopUp] = useState(false); | ||||
| const [selectonWarning, setSelectonWarning] = useState(false); | const [selectonWarning, setSelectonWarning] = useState(false); | ||||
| const [wait, setWait] = useState(false); | const [wait, setWait] = useState(false); | ||||
| const [reload, setReload] = useState(new Date()); | |||||
| const [rows, setRows] = useState([]); | const [rows, setRows] = useState([]); | ||||
| const [_searchCriteria, set_searchCriteria] = useState(searchCriteria); | |||||
| const [_searchCriteria, set_searchCriteria] = useState({}); | |||||
| const [selectedRowItems, setSelectedRowItems] = useState([]); | const [selectedRowItems, setSelectedRowItems] = useState([]); | ||||
| const navigate = useNavigate() | const navigate = useNavigate() | ||||
| const [onDownload, setOnDownload] = useState(false); | |||||
| useEffect(() => { | useEffect(() => { | ||||
| set_searchCriteria(searchCriteria); | set_searchCriteria(searchCriteria); | ||||
| }, [searchCriteria]); | }, [searchCriteria]); | ||||
| const handleDnClick = (params) => () => { | const handleDnClick = (params) => () => { | ||||
| navigate('/paymentPage/demandNote/details/' + params.id); | navigate('/paymentPage/demandNote/details/' + params.id); | ||||
| }; | }; | ||||
| @@ -83,10 +87,17 @@ export default function SearchDemandNote({ searchCriteria, applySearch }) { | |||||
| } | } | ||||
| const onDownloadClick = (params) => () => { | const onDownloadClick = (params) => () => { | ||||
| setOnDownload(true) | |||||
| HttpUtils.fileDownload({ | HttpUtils.fileDownload({ | ||||
| fileId: params.row.fileId, | fileId: params.row.fileId, | ||||
| skey: params.row.skey, | skey: params.row.skey, | ||||
| filename: params.row.filename, | filename: params.row.filename, | ||||
| onResponse:()=>{ | |||||
| setOnDownload(false) | |||||
| }, | |||||
| onError:()=>{ | |||||
| setOnDownload(false) | |||||
| } | |||||
| }); | }); | ||||
| }; | }; | ||||
| @@ -109,7 +120,7 @@ export default function SearchDemandNote({ searchCriteria, applySearch }) { | |||||
| dnIdList: idList | dnIdList: idList | ||||
| }, | }, | ||||
| onSuccess: () => { | onSuccess: () => { | ||||
| if (reloadFun) reloadFun(); | |||||
| setReload(new Date()); | |||||
| } | } | ||||
| }); | }); | ||||
| @@ -133,13 +144,36 @@ export default function SearchDemandNote({ searchCriteria, applySearch }) { | |||||
| }, | }, | ||||
| files: [file], | files: [file], | ||||
| onSuccess() { | onSuccess() { | ||||
| setWait(false); | |||||
| if (reloadFun) reloadFun(); | |||||
| setReload(new Date()); | |||||
| }, | }, | ||||
| }); | }); | ||||
| document.getElementById("uploadFileBtn").value = ""; | 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 = () => { | const markPaid = () => { | ||||
| setConfirmPopUp(false); | setConfirmPopUp(false); | ||||
| let idList = []; | let idList = []; | ||||
| @@ -159,7 +193,7 @@ export default function SearchDemandNote({ searchCriteria, applySearch }) { | |||||
| dnIdList: idList | dnIdList: idList | ||||
| }, | }, | ||||
| onSuccess: () => { | onSuccess: () => { | ||||
| if (reloadFun) reloadFun(); | |||||
| setReload(new Date()); | |||||
| } | } | ||||
| }); | }); | ||||
| } | } | ||||
| @@ -240,9 +274,11 @@ export default function SearchDemandNote({ searchCriteria, applySearch }) { | |||||
| width: 300, | width: 300, | ||||
| renderCell: (params) => { | renderCell: (params) => { | ||||
| return (<table> | 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>); | </table>); | ||||
| } | } | ||||
| }, | }, | ||||
| @@ -254,7 +290,7 @@ export default function SearchDemandNote({ searchCriteria, applySearch }) { | |||||
| ), | ), | ||||
| width: 280, | width: 280, | ||||
| renderCell: (params) => { | 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', | headerName: 'Status', | ||||
| width: 175, | width: 175, | ||||
| renderCell: (params) => { | renderCell: (params) => { | ||||
| return [StatusUtils.getStatus_Eng(params)] | |||||
| return StatusUtils.getStatus_Eng(params) | |||||
| }, | }, | ||||
| }, | }, | ||||
| ]; | ]; | ||||
| @@ -300,6 +336,7 @@ export default function SearchDemandNote({ searchCriteria, applySearch }) { | |||||
| </Button> | </Button> | ||||
| </label> | </label> | ||||
| </Grid> | </Grid> | ||||
| <Grid item sx={{ ml: 3, mr: 3, mb: 3, mt: 3 }}> | <Grid item sx={{ ml: 3, mr: 3, mb: 3, mt: 3 }}> | ||||
| <Button | <Button | ||||
| variant="contained" | variant="contained" | ||||
| @@ -334,13 +371,23 @@ export default function SearchDemandNote({ searchCriteria, applySearch }) { | |||||
| Mark as Paid | Mark as Paid | ||||
| </Button> | </Button> | ||||
| </Grid> | </Grid> | ||||
| <Grid item sx={{ ml: 3, mr: 3, mb: 3, mt: 3 }}> | |||||
| <Button | |||||
| variant="contained" | |||||
| onClick={() => setRevokePopUp(true)} | |||||
| > | |||||
| Revoke payment | |||||
| </Button> | |||||
| </Grid> | |||||
| </ThemeProvider> | </ThemeProvider> | ||||
| </Grid> | </Grid> | ||||
| : <></> | : <></> | ||||
| } | } | ||||
| <Box sx={{ backgroundColor: "#fff", ml: 2 }} width="98%"> | <Box sx={{ backgroundColor: "#fff", ml: 2 }} width="98%"> | ||||
| <FiDataGrid | <FiDataGrid | ||||
| checkboxSelection = {isGrantedAny(["MAINTAIN_DEMANDNOTE"])} | |||||
| checkboxSelection={isGrantedAny(["MAINTAIN_DEMANDNOTE"])} | |||||
| disableRowSelectionOnClick | disableRowSelectionOnClick | ||||
| onRowSelectionModelChange={(newSelection) => { | onRowSelectionModelChange={(newSelection) => { | ||||
| setSelectedRowItems(newSelection); | setSelectedRowItems(newSelection); | ||||
| @@ -349,13 +396,15 @@ export default function SearchDemandNote({ searchCriteria, applySearch }) { | |||||
| customPageSize={100} | customPageSize={100} | ||||
| getRowHeight={() => 'auto'} | getRowHeight={() => 'auto'} | ||||
| onRowDoubleClick={handleRowDoubleClick} | onRowDoubleClick={handleRowDoubleClick} | ||||
| applyGridOnReady={applyGridOnReady} | |||||
| applySearch={applySearch} | |||||
| doLoad={useMemo(() => ({ | doLoad={useMemo(() => ({ | ||||
| url: DEMAND_NOTE_LIST_ALL, | url: DEMAND_NOTE_LIST_ALL, | ||||
| params: _searchCriteria, | params: _searchCriteria, | ||||
| callback: function (responseData) { | callback: function (responseData) { | ||||
| setRows(responseData?.records); | setRows(responseData?.records); | ||||
| } | } | ||||
| }), [_searchCriteria])} | |||||
| }), [_searchCriteria, reload])} | |||||
| /> | /> | ||||
| </Box> | </Box> | ||||
| <div> | <div> | ||||
| @@ -422,6 +471,28 @@ export default function SearchDemandNote({ searchCriteria, applySearch }) { | |||||
| </DialogActions> | </DialogActions> | ||||
| </Dialog> | </Dialog> | ||||
| </div> | </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> | <div> | ||||
| <Dialog | <Dialog | ||||
| open={isSendPopUp} | open={isSendPopUp} | ||||
| @@ -21,7 +21,7 @@ import {DemoItem} from "@mui/x-date-pickers/internals/demo"; | |||||
| import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider"; | import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider"; | ||||
| import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs"; | import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs"; | ||||
| // ==============================|| DASHBOARD - DEFAULT ||============================== // | // ==============================|| DASHBOARD - DEFAULT ||============================== // | ||||
| const SearchDemandNoteForm = ({ applySearch, orgComboData, searchCriteria, issueComboData | |||||
| const SearchDemandNoteForm = ({ applySearch, orgComboData, searchCriteria, issueComboData, onGridReady | |||||
| }) => { | }) => { | ||||
| const [type, setType] = React.useState([]); | const [type, setType] = React.useState([]); | ||||
| @@ -44,6 +44,28 @@ const SearchDemandNoteForm = ({ applySearch, orgComboData, searchCriteria, issue | |||||
| const intl = useIntl(); | const intl = useIntl(); | ||||
| const { locale } = intl; | 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(() => { | React.useEffect(() => { | ||||
| setFromDateValue(minDate); | setFromDateValue(minDate); | ||||
| }, [minDate]); | }, [minDate]); | ||||
| @@ -93,6 +115,8 @@ const SearchDemandNoteForm = ({ applySearch, orgComboData, searchCriteria, issue | |||||
| dueDateFrom: sentDueDateFrom, | dueDateFrom: sentDueDateFrom, | ||||
| dueDateTo: sentDueDateTo, | dueDateTo: sentDueDateTo, | ||||
| status: (data?.status === '' || data?.status?.includes("all")) ? "" : data.status, | status: (data?.status === '' || data?.status?.includes("all")) ? "" : data.status, | ||||
| start:0, | |||||
| limit:10 | |||||
| }; | }; | ||||
| applySearch(temp); | applySearch(temp); | ||||
| }; | }; | ||||
| @@ -101,12 +125,18 @@ const SearchDemandNoteForm = ({ applySearch, orgComboData, searchCriteria, issue | |||||
| React.useEffect(() => { | React.useEffect(() => { | ||||
| if (orgComboData && orgComboData.length > 0) { | if (orgComboData && orgComboData.length > 0) { | ||||
| setOrgCombo(orgComboData); | setOrgCombo(orgComboData); | ||||
| if(searchCriteria.orgId!=undefined){ | |||||
| setOrgSelected(orgComboData.find(item => item.key === searchCriteria.orgId)) | |||||
| } | |||||
| } | } | ||||
| }, [orgComboData]); | }, [orgComboData]); | ||||
| React.useEffect(() => { | React.useEffect(() => { | ||||
| if (issueComboData && issueComboData.length > 0) { | if (issueComboData && issueComboData.length > 0) { | ||||
| setIssueCombo(issueComboData); | setIssueCombo(issueComboData); | ||||
| if(searchCriteria.issueId!=undefined){ | |||||
| setIssueSelected(issueComboData.find(item => item.id === searchCriteria.issueId)) | |||||
| } | |||||
| } | } | ||||
| }, [issueComboData]); | }, [issueComboData]); | ||||
| @@ -117,9 +147,13 @@ const SearchDemandNoteForm = ({ applySearch, orgComboData, searchCriteria, issue | |||||
| setSelectedStatus(ComboData.denmandNoteStatus[0]); | setSelectedStatus(ComboData.denmandNoteStatus[0]); | ||||
| setMinDueDate(null); | setMinDueDate(null); | ||||
| setMaxDueDate(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) { | function getIssueLabel(data) { | ||||
| @@ -177,6 +211,11 @@ const SearchDemandNoteForm = ({ applySearch, orgComboData, searchCriteria, issue | |||||
| onChange={(event, newValue) => { | onChange={(event, newValue) => { | ||||
| setIssueSelected(newValue); | setIssueSelected(newValue); | ||||
| }} | }} | ||||
| sx={{ | |||||
| '& .MuiInputBase-root': { alignItems: 'center' }, | |||||
| '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, | |||||
| '& .MuiOutlinedInput-root': { height: 40 } | |||||
| }} | |||||
| renderInput={(params) => ( | renderInput={(params) => ( | ||||
| <TextField {...params} | <TextField {...params} | ||||
| label="Gazette Issue No." | label="Gazette Issue No." | ||||
| @@ -209,10 +248,12 @@ const SearchDemandNoteForm = ({ applySearch, orgComboData, searchCriteria, issue | |||||
| disablePortal | disablePortal | ||||
| id="orgId" | id="orgId" | ||||
| options={orgCombo} | options={orgCombo} | ||||
| groupBy={(option) => option.groupType} | |||||
| size="small" | size="small" | ||||
| value={orgSelected} | value={orgSelected} | ||||
| getOptionLabel={(option) => option.name? option.name : ""} | getOptionLabel={(option) => option.name? option.name : ""} | ||||
| inputValue={orgSelected ? orgSelected.name : ""} | |||||
| inputValue={orgSelected ? orgSelected.name!=undefined?orgSelected.name:"" : ""} | |||||
| onChange={(event, newValue) => { | onChange={(event, newValue) => { | ||||
| if (newValue !== null) { | if (newValue !== null) { | ||||
| setOrgSelected(newValue); | setOrgSelected(newValue); | ||||
| @@ -220,6 +261,11 @@ const SearchDemandNoteForm = ({ applySearch, orgComboData, searchCriteria, issue | |||||
| setOrgSelected({}); | setOrgSelected({}); | ||||
| } | } | ||||
| }} | }} | ||||
| sx={{ | |||||
| '& .MuiInputBase-root': { alignItems: 'center' }, | |||||
| '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, | |||||
| '& .MuiOutlinedInput-root': { height: 40 } | |||||
| }} | |||||
| renderInput={(params) => ( | renderInput={(params) => ( | ||||
| <TextField {...params} | <TextField {...params} | ||||
| label="Organisation" | label="Organisation" | ||||
| @@ -228,12 +274,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> | ||||
| : <></> | : <></> | ||||
| } | } | ||||
| <Grid item xs={9} s={6} md={5} lg={3} sx={{ ml: 3, mr: 3, mb: 3 }}> | <Grid item xs={9} s={6} md={5} lg={3} sx={{ ml: 3, mr: 3, mb: 3 }}> | ||||
| <TextField | <TextField | ||||
| fullWidth | fullWidth | ||||
| @@ -378,6 +431,11 @@ const SearchDemandNoteForm = ({ applySearch, orgComboData, searchCriteria, issue | |||||
| } | } | ||||
| }} | }} | ||||
| getOptionLabel={(option) => option.label} | getOptionLabel={(option) => option.label} | ||||
| sx={{ | |||||
| '& .MuiInputBase-root': { alignItems: 'center' }, | |||||
| '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, | |||||
| '& .MuiOutlinedInput-root': { height: 40 } | |||||
| }} | |||||
| renderInput={(params) => ( | renderInput={(params) => ( | ||||
| <TextField | <TextField | ||||
| {...params} | {...params} | ||||
| @@ -411,6 +469,7 @@ const SearchDemandNoteForm = ({ applySearch, orgComboData, searchCriteria, issue | |||||
| <Button | <Button | ||||
| variant="contained" | variant="contained" | ||||
| type="submit" | type="submit" | ||||
| disabled={onGridReady} | |||||
| > | > | ||||
| Submit | Submit | ||||
| </Button> | </Button> | ||||
| @@ -10,6 +10,7 @@ import * as React from "react"; | |||||
| import * as UrlUtils from "utils/ApiPathConst"; | import * as UrlUtils from "utils/ApiPathConst"; | ||||
| import * as HttpUtils from "utils/HttpUtils"; | import * as HttpUtils from "utils/HttpUtils"; | ||||
| import * as DateUtils from "utils/DateUtils"; | import * as DateUtils from "utils/DateUtils"; | ||||
| import { getSearchCriteria } from "auth/utils"; | |||||
| import Loadable from 'components/Loadable'; | import Loadable from 'components/Loadable'; | ||||
| const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | ||||
| @@ -35,16 +36,26 @@ const UserSearchPage_Individual = () => { | |||||
| const [orgCombo, setOrgCombo] = React.useState([]); | const [orgCombo, setOrgCombo] = React.useState([]); | ||||
| const [issueCombo, setIssueCombo] = React.useState([]); | const [issueCombo, setIssueCombo] = React.useState([]); | ||||
| const [searchCriteria, setSearchCriteria] = 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()), | // dueDateTo: DateUtils.dateValue(new Date()), | ||||
| // dueDateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate() - 14)), | // dueDateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate() - 14)), | ||||
| }); | }); | ||||
| const [onReady, setOnReady] = React.useState(false); | const [onReady, setOnReady] = React.useState(false); | ||||
| const [onGridReady, setGridOnReady] = React.useState(false); | |||||
| React.useEffect(() => { | React.useEffect(() => { | ||||
| getOrgCombo(); | getOrgCombo(); | ||||
| getIssueCombo(); | 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(() => { | React.useEffect(() => { | ||||
| @@ -72,9 +83,14 @@ const UserSearchPage_Individual = () => { | |||||
| }); | }); | ||||
| } | } | ||||
| function applySearch(input) { | function applySearch(input) { | ||||
| setGridOnReady(true) | |||||
| setSearchCriteria(input); | setSearchCriteria(input); | ||||
| localStorage.setItem('searchCriteria', JSON.stringify({path:window.location.pathname,data:input})) | |||||
| } | |||||
| function applyGridOnReady(input) { | |||||
| setGridOnReady(input); | |||||
| } | } | ||||
| return ( | return ( | ||||
| @@ -102,7 +118,7 @@ const UserSearchPage_Individual = () => { | |||||
| orgComboData={orgCombo} | orgComboData={orgCombo} | ||||
| issueComboData={issueCombo} | issueComboData={issueCombo} | ||||
| searchCriteria={searchCriteria} | searchCriteria={searchCriteria} | ||||
| onGridReady={onGridReady} | |||||
| /> | /> | ||||
| </Grid> | </Grid> | ||||
| {/*row 2*/} | {/*row 2*/} | ||||
| @@ -115,6 +131,7 @@ const UserSearchPage_Individual = () => { | |||||
| <EventTable | <EventTable | ||||
| applySearch={applySearch} | applySearch={applySearch} | ||||
| searchCriteria={searchCriteria} | searchCriteria={searchCriteria} | ||||
| applyGridOnReady={applyGridOnReady} | |||||
| /> | /> | ||||
| </MainCard> | </MainCard> | ||||
| </Grid> | </Grid> | ||||
| @@ -15,11 +15,12 @@ import {useIntl} from "react-intl"; | |||||
| import {DEMAND_NOTE_LIST} from "utils/ApiPathConst"; | import {DEMAND_NOTE_LIST} from "utils/ApiPathConst"; | ||||
| // ==============================|| EVENT TABLE ||============================== // | // ==============================|| EVENT TABLE ||============================== // | ||||
| export default function SearchDemandNote({ searchCriteria }) { | |||||
| export default function SearchDemandNote({ searchCriteria, applyGridOnReady,applySearch }) { | |||||
| const intl = useIntl(); | const intl = useIntl(); | ||||
| const theme = useTheme(); | const theme = useTheme(); | ||||
| const isMdOrLg = useMediaQuery(theme.breakpoints.up('md')); | const isMdOrLg = useMediaQuery(theme.breakpoints.up('md')); | ||||
| const { locale } = intl; | |||||
| const [_searchCriteria, set_searchCriteria] = React.useState(searchCriteria); | const [_searchCriteria, set_searchCriteria] = React.useState(searchCriteria); | ||||
| @@ -52,7 +53,7 @@ export default function SearchDemandNote({ searchCriteria }) { | |||||
| { | { | ||||
| id: 'issueDate', | id: 'issueDate', | ||||
| field: 'issueDate', | field: 'issueDate', | ||||
| headerName: intl.formatMessage({id: 'receiptDate'}), | |||||
| headerName: intl.formatMessage({id: 'sendDate'}), | |||||
| width: isMdOrLg ? 'auto' : 175, | width: isMdOrLg ? 'auto' : 175, | ||||
| flex: isMdOrLg ? 1 : undefined, | flex: isMdOrLg ? 1 : undefined, | ||||
| valueGetter: (params) => { | valueGetter: (params) => { | ||||
| @@ -65,12 +66,13 @@ export default function SearchDemandNote({ searchCriteria }) { | |||||
| width: isMdOrLg ? 'auto' : 175, | width: isMdOrLg ? 'auto' : 175, | ||||
| flex: isMdOrLg ? 1 : undefined, | flex: isMdOrLg ? 1 : undefined, | ||||
| renderCell: (params) => { | renderCell: (params) => { | ||||
| return [StatusUtils.getStatus_Cht(params)] | |||||
| return [StatusUtils.getStatus_i18n(params, locale) ] | |||||
| }, | }, | ||||
| }, | }, | ||||
| { | { | ||||
| field: 'sentDate', | field: 'sentDate', | ||||
| headerName: intl.formatMessage({id: 'sendDate'}), | |||||
| headerName: intl.formatMessage({id: 'sendDateTime'}), | |||||
| width: isMdOrLg ? 'auto' : 200, | width: isMdOrLg ? 'auto' : 200, | ||||
| flex: isMdOrLg ? 1 : undefined, | flex: isMdOrLg ? 1 : undefined, | ||||
| valueGetter: (params) => { | valueGetter: (params) => { | ||||
| @@ -95,10 +97,16 @@ export default function SearchDemandNote({ searchCriteria }) { | |||||
| columns={columns} | columns={columns} | ||||
| customPageSize={10} | customPageSize={10} | ||||
| getRowHeight={() => 'auto'} | getRowHeight={() => 'auto'} | ||||
| doLoad={{ | |||||
| applyGridOnReady={applyGridOnReady} | |||||
| applySearch={applySearch} | |||||
| // doLoad={{ | |||||
| // url: DEMAND_NOTE_LIST, | |||||
| // params: _searchCriteria, | |||||
| // }} | |||||
| doLoad={React.useMemo(() => ({ | |||||
| url: DEMAND_NOTE_LIST, | url: DEMAND_NOTE_LIST, | ||||
| params: _searchCriteria, | params: _searchCriteria, | ||||
| }} | |||||
| }), [_searchCriteria])} | |||||
| /> | /> | ||||
| </Box> | </Box> | ||||
| </div> | </div> | ||||
| @@ -22,7 +22,7 @@ import {DemoItem} from "@mui/x-date-pickers/internals/demo"; | |||||
| import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider"; | import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider"; | ||||
| import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs"; | import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs"; | ||||
| // ==============================|| DASHBOARD - DEFAULT ||============================== // | // ==============================|| DASHBOARD - DEFAULT ||============================== // | ||||
| const SearchDemandNoteForm = ({ applySearch, searchCriteria, issueComboData | |||||
| const SearchDemandNoteForm = ({ applySearch, searchCriteria, issueComboData, onGridReady | |||||
| }) => { | }) => { | ||||
| const intl = useIntl(); | const intl = useIntl(); | ||||
| @@ -38,6 +38,18 @@ const SearchDemandNoteForm = ({ applySearch, searchCriteria, issueComboData | |||||
| const [fromDateValue, setFromDateValue] = React.useState("dd / mm / yyyy"); | const [fromDateValue, setFromDateValue] = React.useState("dd / mm / yyyy"); | ||||
| const [toDateValue, setToDateValue] = 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(() => { | React.useEffect(() => { | ||||
| setFromDateValue(minDate); | setFromDateValue(minDate); | ||||
| }, [minDate]); | }, [minDate]); | ||||
| @@ -76,17 +88,23 @@ const SearchDemandNoteForm = ({ applySearch, searchCriteria, issueComboData | |||||
| React.useEffect(() => { | React.useEffect(() => { | ||||
| if (issueComboData && issueComboData.length > 0) { | if (issueComboData && issueComboData.length > 0) { | ||||
| setIssueCombo(issueComboData); | setIssueCombo(issueComboData); | ||||
| if(searchCriteria.issueId!=undefined){ | |||||
| setIssueSelected(issueComboData.find(item => item.id === searchCriteria.issueId)) | |||||
| } | |||||
| } | } | ||||
| }, [issueComboData]); | }, [issueComboData]); | ||||
| function resetForm() { | function resetForm() { | ||||
| setType([]); | setType([]); | ||||
| // setStatus({ key: 0, label: 'All', type: 'all' }); | |||||
| setSelectedStatus(ComboData.denmandNoteStatus_Public[0]); | |||||
| // setOrgSelected({}); | // setOrgSelected({}); | ||||
| setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14))) | setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14))) | ||||
| setMaxDate(DateUtils.dateValue(new Date())) | setMaxDate(DateUtils.dateValue(new Date())) | ||||
| setIssueSelected({}); | setIssueSelected({}); | ||||
| reset(); | |||||
| reset({ | |||||
| appNo:"", | |||||
| dnNo:"", | |||||
| }); | |||||
| } | } | ||||
| function getIssueLabel(data) { | function getIssueLabel(data) { | ||||
| @@ -149,6 +167,11 @@ const SearchDemandNoteForm = ({ applySearch, searchCriteria, issueComboData | |||||
| setIssueSelected(newValue); | setIssueSelected(newValue); | ||||
| } | } | ||||
| }} | }} | ||||
| sx={{ | |||||
| '& .MuiInputBase-root': { alignItems: 'center' }, | |||||
| '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, | |||||
| '& .MuiOutlinedInput-root': { height: 40 } | |||||
| }} | |||||
| renderInput={(params) => ( | renderInput={(params) => ( | ||||
| <TextField {...params} | <TextField {...params} | ||||
| label={intl.formatMessage({ id: 'gazetteCount' })} | label={intl.formatMessage({ id: 'gazetteCount' })} | ||||
| @@ -246,6 +269,7 @@ const SearchDemandNoteForm = ({ applySearch, searchCriteria, issueComboData | |||||
| {...register("status")} | {...register("status")} | ||||
| id="status" | id="status" | ||||
| size="small" | size="small" | ||||
| disableClearable | |||||
| options={ComboData.denmandNoteStatus_Public} | options={ComboData.denmandNoteStatus_Public} | ||||
| getOptionLabel={(option) => option?.i18nLabel ? intl.formatMessage({ id: option.i18nLabel }) : ""} | getOptionLabel={(option) => option?.i18nLabel ? intl.formatMessage({ id: option.i18nLabel }) : ""} | ||||
| inputValue={selectedStatus?.i18nLabel ? intl.formatMessage({ id: selectedStatus.i18nLabel }) : ""} | inputValue={selectedStatus?.i18nLabel ? intl.formatMessage({ id: selectedStatus.i18nLabel }) : ""} | ||||
| @@ -255,6 +279,11 @@ const SearchDemandNoteForm = ({ applySearch, searchCriteria, issueComboData | |||||
| setSelectedStatus(newValue); | setSelectedStatus(newValue); | ||||
| } | } | ||||
| }} | }} | ||||
| sx={{ | |||||
| '& .MuiInputBase-root': { alignItems: 'center' }, | |||||
| '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, | |||||
| '& .MuiOutlinedInput-root': { height: 40 } | |||||
| }} | |||||
| renderInput={(params) => ( | renderInput={(params) => ( | ||||
| <TextField | <TextField | ||||
| {...params} | {...params} | ||||
| @@ -288,6 +317,7 @@ const SearchDemandNoteForm = ({ applySearch, searchCriteria, issueComboData | |||||
| <Button | <Button | ||||
| variant="contained" | variant="contained" | ||||
| type="submit" | type="submit" | ||||
| disabled={onGridReady} | |||||
| > | > | ||||
| <FormattedMessage id="submit" /> | <FormattedMessage id="submit" /> | ||||
| </Button> | </Button> | ||||
| @@ -10,6 +10,7 @@ import * as React from "react"; | |||||
| import {GET_ORG_COMBO, GET_ISSUE_COMBO} from "utils/ApiPathConst"; | import {GET_ORG_COMBO, GET_ISSUE_COMBO} from "utils/ApiPathConst"; | ||||
| import * as HttpUtils from "utils/HttpUtils"; | import * as HttpUtils from "utils/HttpUtils"; | ||||
| import * as DateUtils from "utils/DateUtils"; | import * as DateUtils from "utils/DateUtils"; | ||||
| import { getSearchCriteria } from "auth/utils"; | |||||
| import Loadable from 'components/Loadable'; | import Loadable from 'components/Loadable'; | ||||
| const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | ||||
| @@ -34,15 +35,22 @@ const SearchPage_DemandNote_Pub = () => { | |||||
| const [orgCombo, setOrgCombo] = React.useState([]); | const [orgCombo, setOrgCombo] = React.useState([]); | ||||
| const [issueCombo, setIssueCombo] = 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 [onReady, setOnReady] = React.useState(false); | ||||
| const [onGridReady, setGridOnReady] = React.useState(false); | |||||
| React.useEffect(() => { | React.useEffect(() => { | ||||
| getOrgCombo(); | getOrgCombo(); | ||||
| getIssueCombo(); | 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(() => { | React.useEffect(() => { | ||||
| @@ -72,7 +80,13 @@ const SearchPage_DemandNote_Pub = () => { | |||||
| function applySearch(input) { | function applySearch(input) { | ||||
| setGridOnReady(true) | |||||
| setSearchCriteria(input); | setSearchCriteria(input); | ||||
| localStorage.setItem('searchCriteria', JSON.stringify({path:window.location.pathname,data:input})) | |||||
| } | |||||
| function applyGridOnReady(input) { | |||||
| setGridOnReady(input); | |||||
| } | } | ||||
| return ( | return ( | ||||
| @@ -100,6 +114,7 @@ const SearchPage_DemandNote_Pub = () => { | |||||
| orgComboData={orgCombo} | orgComboData={orgCombo} | ||||
| issueComboData={issueCombo} | issueComboData={issueCombo} | ||||
| searchCriteria={searchCriteria} | searchCriteria={searchCriteria} | ||||
| onGridReady={onGridReady} | |||||
| /> | /> | ||||
| </Grid> | </Grid> | ||||
| {/*row 2*/} | {/*row 2*/} | ||||
| @@ -110,7 +125,9 @@ const SearchPage_DemandNote_Pub = () => { | |||||
| sx={{ backgroundColor: '#fff' }} | sx={{ backgroundColor: '#fff' }} | ||||
| > | > | ||||
| <EventTable | <EventTable | ||||
| searchCriteria={searchCriteria} | |||||
| searchCriteria={searchCriteria} | |||||
| applyGridOnReady={applyGridOnReady} | |||||
| applySearch={applySearch} | |||||
| /> | /> | ||||
| </MainCard> | </MainCard> | ||||
| </Grid> | </Grid> | ||||
| @@ -50,7 +50,7 @@ const Index = () => { | |||||
| axios.get(`${UrlUtils.GET_EMAIL}/${params.id}`) | axios.get(`${UrlUtils.GET_EMAIL}/${params.id}`) | ||||
| .then((response) => { | .then((response) => { | ||||
| if (response.status === 200) { | if (response.status === 200) { | ||||
| console.log(response) | |||||
| // console.log(response) | |||||
| setRecord(response.data.data) | setRecord(response.data.data) | ||||
| } | } | ||||
| }) | }) | ||||
| @@ -95,14 +95,14 @@ const Index = () => { | |||||
| console.log(error); | console.log(error); | ||||
| return false; | return false; | ||||
| }); | }); | ||||
| console.log(data) | |||||
| // console.log(data) | |||||
| } | } | ||||
| const handleDelete = () => { | const handleDelete = () => { | ||||
| axios.delete(`${UrlUtils.DELETE_EMAIL}/${params.id}`, | axios.delete(`${UrlUtils.DELETE_EMAIL}/${params.id}`, | ||||
| ) | ) | ||||
| .then((response) => { | .then((response) => { | ||||
| console.log(response) | |||||
| // console.log(response) | |||||
| if (response.status === 204) { | if (response.status === 204) { | ||||
| // location.reload(); | // location.reload(); | ||||
| navigate('/setting/emailTemplate'); | navigate('/setting/emailTemplate'); | ||||
| @@ -97,10 +97,14 @@ export default function EmailTemplateTable({ responseData }) { | |||||
| customPageSize={10} | customPageSize={10} | ||||
| onRowDoubleClick={handleRowDoubleClick} | onRowDoubleClick={handleRowDoubleClick} | ||||
| getRowHeight={() => 'auto'} | 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> | </div> | ||||
| ); | ); | ||||
| @@ -6,7 +6,7 @@ import { useNavigate } from "react-router-dom"; | |||||
| import { FiDataGrid } from "components/FiDataGrid"; | import { FiDataGrid } from "components/FiDataGrid"; | ||||
| // ==============================|| EVENT TABLE ||============================== // | // ==============================|| EVENT TABLE ||============================== // | ||||
| export default function SearchTable({ searchCriteria }) { | |||||
| export default function SearchTable({ searchCriteria, applyGridOnReady }) { | |||||
| const [_searchCriteria, set_searchCriteria] = React.useState(searchCriteria); | const [_searchCriteria, set_searchCriteria] = React.useState(searchCriteria); | ||||
| const navigate = useNavigate() | const navigate = useNavigate() | ||||
| // const [rows, setRows] = React.useState([]); | // const [rows, setRows] = React.useState([]); | ||||
| @@ -67,6 +67,7 @@ export default function SearchTable({ searchCriteria }) { | |||||
| columns={columns} | columns={columns} | ||||
| customPageSize={10} | customPageSize={10} | ||||
| onRowDoubleClick={handleEditClick} | onRowDoubleClick={handleEditClick} | ||||
| applyGridOnReady={applyGridOnReady} | |||||
| doLoad={React.useMemo(() => ({ | doLoad={React.useMemo(() => ({ | ||||
| url: GFIMIS_LIST, | url: GFIMIS_LIST, | ||||
| params: _searchCriteria, | params: _searchCriteria, | ||||
| @@ -21,7 +21,7 @@ import {DemoItem} from "@mui/x-date-pickers/internals/demo"; | |||||
| import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider"; | import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider"; | ||||
| import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs"; | import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs"; | ||||
| // ==============================|| DASHBOARD - DEFAULT ||============================== // | // ==============================|| 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); | ||||
| const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom); | const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom); | ||||
| @@ -146,6 +146,7 @@ const SearchPublicNoticeForm = ({ applySearch, generateXML, searchCriteria }) => | |||||
| <Button | <Button | ||||
| variant="contained" | variant="contained" | ||||
| type="submit" | type="submit" | ||||
| disabled={onGridReady} | |||||
| > | > | ||||
| Preview | Preview | ||||
| </Button> | </Button> | ||||
| @@ -35,6 +35,7 @@ const Index = () => { | |||||
| // dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)), | // dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)), | ||||
| }); | }); | ||||
| const [onReady, setOnReady] = React.useState(false); | const [onReady, setOnReady] = React.useState(false); | ||||
| const [onGridReady, setGridOnReady] = React.useState(false); | |||||
| React.useEffect(() => { | React.useEffect(() => { | ||||
| setOnReady(true); | setOnReady(true); | ||||
| @@ -50,7 +51,7 @@ const Index = () => { | |||||
| dateFrom: input.dateFrom, | dateFrom: input.dateFrom, | ||||
| }, | }, | ||||
| onSuccess: (responseData) => { | onSuccess: (responseData) => { | ||||
| console.log(responseData) | |||||
| // console.log(responseData) | |||||
| const parser = new DOMParser(); | const parser = new DOMParser(); | ||||
| const xmlDoc = parser.parseFromString(responseData, 'application/xml'); | const xmlDoc = parser.parseFromString(responseData, 'application/xml'); | ||||
| // Get the DCBHeader element | // Get the DCBHeader element | ||||
| @@ -75,7 +76,7 @@ const Index = () => { | |||||
| const updatedXmlString = new XMLSerializer().serializeToString(xmlDoc); | const updatedXmlString = new XMLSerializer().serializeToString(xmlDoc); | ||||
| const filename = xmlDoc.querySelector('FileHeader').getAttribute('H_Filename'); | const filename = xmlDoc.querySelector('FileHeader').getAttribute('H_Filename'); | ||||
| console.log(updatedXmlString) | |||||
| // console.log(updatedXmlString) | |||||
| const blob = new Blob([updatedXmlString], { type: 'application/xml' }); | const blob = new Blob([updatedXmlString], { type: 'application/xml' }); | ||||
| // Create a download link | // Create a download link | ||||
| const link = document.createElement('a'); | const link = document.createElement('a'); | ||||
| @@ -97,9 +98,14 @@ const Index = () => { | |||||
| function applySearch(input) { | function applySearch(input) { | ||||
| setGridOnReady(true) | |||||
| setSearchCriteria(input); | setSearchCriteria(input); | ||||
| } | } | ||||
| function applyGridOnReady(input) { | |||||
| setGridOnReady(input); | |||||
| } | |||||
| function generateXML(input) { | function generateXML(input) { | ||||
| downloadXML(input); | downloadXML(input); | ||||
| } | } | ||||
| @@ -121,9 +127,10 @@ const Index = () => { | |||||
| {/*row 1*/} | {/*row 1*/} | ||||
| <Grid item xs={12} md={12} lg={12} sx={{mb:-1}}> | <Grid item xs={12} md={12} lg={12} sx={{mb:-1}}> | ||||
| <SearchForm | <SearchForm | ||||
| applySearch={applySearch} | |||||
| generateXML={generateXML} | |||||
| searchCriteria={searchCriteria} | |||||
| applySearch={applySearch} | |||||
| generateXML={generateXML} | |||||
| searchCriteria={searchCriteria} | |||||
| onGridReady={onGridReady} | |||||
| /> | /> | ||||
| </Grid> | </Grid> | ||||
| {/*row 2*/} | {/*row 2*/} | ||||
| @@ -135,6 +142,8 @@ const Index = () => { | |||||
| > | > | ||||
| <EventTable | <EventTable | ||||
| searchCriteria={searchCriteria} | searchCriteria={searchCriteria} | ||||
| applyGridOnReady={applyGridOnReady} | |||||
| applySearch={applySearch} | |||||
| /> | /> | ||||
| </MainCard> | </MainCard> | ||||
| </Grid> | </Grid> | ||||
| @@ -7,7 +7,7 @@ import {GET_ISSUE} from "utils/ApiPathConst"; | |||||
| // ==============================|| EVENT TABLE ||============================== // | // ==============================|| EVENT TABLE ||============================== // | ||||
| export default function GazetteIssueTable({ searchCriteria }) { | |||||
| export default function GazetteIssueTable({ searchCriteria, applyGridOnReady }) { | |||||
| const [_searchCriteria, set_searchCriteria] = React.useState(searchCriteria); | const [_searchCriteria, set_searchCriteria] = React.useState(searchCriteria); | ||||
| React.useEffect(() => { | React.useEffect(() => { | ||||
| @@ -100,10 +100,15 @@ export default function GazetteIssueTable({ searchCriteria }) { | |||||
| customPageSize={10} | customPageSize={10} | ||||
| // onRowDoubleClick={handleRowDoubleClick} | // onRowDoubleClick={handleRowDoubleClick} | ||||
| getRowHeight={() => 'auto'} | getRowHeight={() => 'auto'} | ||||
| doLoad={{ | |||||
| applyGridOnReady={applyGridOnReady} | |||||
| // doLoad={{ | |||||
| // url: GET_ISSUE, | |||||
| // params: _searchCriteria, | |||||
| // }} | |||||
| doLoad={React.useMemo(() => ({ | |||||
| url: GET_ISSUE, | url: GET_ISSUE, | ||||
| params: _searchCriteria, | params: _searchCriteria, | ||||
| }} | |||||
| }), [_searchCriteria])} | |||||
| /> | /> | ||||
| </div> | </div> | ||||
| ); | ); | ||||
| @@ -27,9 +27,9 @@ const SearchGazetteIssueForm = ({ applyExport, comboData, waitDownload}) => { | |||||
| handleSubmit } = useForm() | handleSubmit } = useForm() | ||||
| const onSubmit = () => { | const onSubmit = () => { | ||||
| console.log(selectedYear) | |||||
| // console.log(selectedYear) | |||||
| if (selectedYear !=null && Object.keys(selectedYear).length>0){ | if (selectedYear !=null && Object.keys(selectedYear).length>0){ | ||||
| console.log("okkkkkkkkkkkkkkkk") | |||||
| // console.log("okkkkkkkkkkkkkkkk") | |||||
| const temp = { | const temp = { | ||||
| year: selectedYear.label, | year: selectedYear.label, | ||||
| }; | }; | ||||
| @@ -81,9 +81,9 @@ const SearchGazetteIssueForm = ({ applyExport, comboData, waitDownload}) => { | |||||
| setSelectedYear(newValue); | setSelectedYear(newValue); | ||||
| }} | }} | ||||
| sx={{ | sx={{ | ||||
| "& .MuiInputBase-root": { height: "41px" }, | |||||
| "#year-combo": { padding: "0px 0px 0px 0px" }, | |||||
| "& .MuiAutocomplete-endAdornment": { top: "auto" }, | |||||
| '& .MuiInputBase-root': { alignItems: 'center' }, | |||||
| '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, | |||||
| '& .MuiOutlinedInput-root': { height: 40 } | |||||
| }} | }} | ||||
| renderInput={(params) => <TextField {...params} placeholder={""}/>} | renderInput={(params) => <TextField {...params} placeholder={""}/>} | ||||
| /> | /> | ||||
| @@ -16,7 +16,7 @@ import {ThemeProvider} from "@emotion/react"; | |||||
| // ==============================|| DASHBOARD - DEFAULT ||============================== // | // ==============================|| DASHBOARD - DEFAULT ||============================== // | ||||
| const SearchGazetteIssueForm = ({ applySearch, comboData}) => { | |||||
| const SearchGazetteIssueForm = ({ applySearch, comboData, onGridReady}) => { | |||||
| const [selectedYear, setSelectedYear] = React.useState([]); | const [selectedYear, setSelectedYear] = React.useState([]); | ||||
| // const [defaultYear, setDefaultYear] = React.useState(searchCriteria.year); | // const [defaultYear, setDefaultYear] = React.useState(searchCriteria.year); | ||||
| const [comboList, setComboList] = React.useState([]); | const [comboList, setComboList] = React.useState([]); | ||||
| @@ -79,9 +79,9 @@ const SearchGazetteIssueForm = ({ applySearch, comboData}) => { | |||||
| setSelectedYear(newValue); | setSelectedYear(newValue); | ||||
| }} | }} | ||||
| sx={{ | sx={{ | ||||
| "& .MuiInputBase-root": { height: "41px" }, | |||||
| "#year-combo": { padding: "0px 0px 0px 0px" }, | |||||
| "& .MuiAutocomplete-endAdornment": { top: "auto" }, | |||||
| '& .MuiInputBase-root': { alignItems: 'center' }, | |||||
| '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, | |||||
| '& .MuiOutlinedInput-root': { height: 40 } | |||||
| }} | }} | ||||
| renderInput={(params) => <TextField {...params} placeholder={""}/>} | renderInput={(params) => <TextField {...params} placeholder={""}/>} | ||||
| /> | /> | ||||
| @@ -114,6 +114,7 @@ const SearchGazetteIssueForm = ({ applySearch, comboData}) => { | |||||
| <Button | <Button | ||||
| variant="contained" | variant="contained" | ||||
| type="submit" | type="submit" | ||||
| disabled={onGridReady} | |||||
| > | > | ||||
| Search | Search | ||||
| </Button> | </Button> | ||||
| @@ -31,6 +31,7 @@ import {PNSPS_LONG_BUTTON_THEME} from "themes/buttonConst"; | |||||
| import {ThemeProvider} from "@emotion/react"; | import {ThemeProvider} from "@emotion/react"; | ||||
| import { dateStr_Year } from "utils/DateUtils"; | import { dateStr_Year } from "utils/DateUtils"; | ||||
| import { notifySaveSuccess } from 'utils/CommonFunction'; | import { notifySaveSuccess } from 'utils/CommonFunction'; | ||||
| import { isGrantedAny } from "auth/utils"; | |||||
| // ==============================|| DASHBOARD - DEFAULT ||============================== // | // ==============================|| DASHBOARD - DEFAULT ||============================== // | ||||
| @@ -38,6 +39,8 @@ const Index = () => { | |||||
| const [comboData, setComboData] = React.useState([]); | const [comboData, setComboData] = React.useState([]); | ||||
| const [holidayComboData, setHolidayComboData] = React.useState([]); | const [holidayComboData, setHolidayComboData] = React.useState([]); | ||||
| const [onReady, setOnReady] = React.useState(false); | const [onReady, setOnReady] = React.useState(false); | ||||
| const [onGridReady, setGridOnReady] = React.useState(false); | |||||
| const [onSearchReady, setOnSearchReady] = React.useState(false); | const [onSearchReady, setOnSearchReady] = React.useState(false); | ||||
| const [onExportReady, setOnExportReady] = React.useState(false); | const [onExportReady, setOnExportReady] = React.useState(false); | ||||
| const [searchCriteria, setSearchCriteria] = React.useState({ | const [searchCriteria, setSearchCriteria] = React.useState({ | ||||
| @@ -89,6 +92,7 @@ const Index = () => { | |||||
| } | } | ||||
| function applySearch(input) { | function applySearch(input) { | ||||
| setGridOnReady(true) | |||||
| setSearchCriteria(input); | setSearchCriteria(input); | ||||
| } | } | ||||
| @@ -96,6 +100,10 @@ const Index = () => { | |||||
| setExportCriteria(input); | setExportCriteria(input); | ||||
| } | } | ||||
| function applyGridOnReady(input) { | |||||
| setGridOnReady(input); | |||||
| } | |||||
| React.useEffect(() => { | React.useEffect(() => { | ||||
| if (Object.keys(exportCriteria).length > 0) { | if (Object.keys(exportCriteria).length > 0) { | ||||
| // console.log(exportCriteria) | // console.log(exportCriteria) | ||||
| @@ -185,40 +193,39 @@ const Index = () => { | |||||
| /> | /> | ||||
| </Grid> | </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"> | |||||
| {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}> | |||||
| <Button | <Button | ||||
| component="span" | |||||
| component="label" | |||||
| variant="contained" | variant="contained" | ||||
| size="large" | size="large" | ||||
| disabled={waitImport} | disabled={waitImport} | ||||
| > | > | ||||
| <Typography variant="h5">Upload Files</Typography> | <Typography variant="h5">Upload Files</Typography> | ||||
| <input | |||||
| id="uploadFileBtn" | |||||
| name="file" | |||||
| type="file" | |||||
| accept=".xlsx" | |||||
| hidden | |||||
| disabled={waitImport} | |||||
| onChange={readFile} | |||||
| aria-label="Upload Excel file (.xlsx)" | |||||
| /> | |||||
| </Button> | </Button> | ||||
| </label> | |||||
| </ThemeProvider> | |||||
| </Stack> | |||||
| </Grid> | |||||
| </ThemeProvider> | |||||
| </Stack> | |||||
| </Grid> | |||||
| :null | |||||
| } | |||||
| {/*row 1*/} | {/*row 1*/} | ||||
| <Grid item xs={12} md={12} lg={12} width="100%"> | <Grid item xs={12} md={12} lg={12} width="100%"> | ||||
| <SearchForm | <SearchForm | ||||
| applySearch={applySearch} | applySearch={applySearch} | ||||
| comboData={comboData} | comboData={comboData} | ||||
| onGridReady={onGridReady} | |||||
| /> | /> | ||||
| </Grid> | </Grid> | ||||
| {/*row 2*/} | {/*row 2*/} | ||||
| @@ -230,7 +237,8 @@ const Index = () => { | |||||
| content={false} | content={false} | ||||
| > | > | ||||
| <GazetteIssueTable | <GazetteIssueTable | ||||
| searchCriteria={searchCriteria} | |||||
| searchCriteria={searchCriteria} | |||||
| applyGridOnReady={applyGridOnReady} | |||||
| /> | /> | ||||
| </MainCard> | </MainCard> | ||||
| </Grid> | </Grid> | ||||
| @@ -9,13 +9,13 @@ import { dateStr } from "utils/DateUtils"; | |||||
| // ==============================|| EVENT TABLE ||============================== // | // ==============================|| EVENT TABLE ||============================== // | ||||
| export default function HolidayTable({ recordList }) { | |||||
| export default function HolidayTable({ recordList, applyGridOnReady }) { | |||||
| const [rows, setRows] = React.useState(recordList); | const [rows, setRows] = React.useState(recordList); | ||||
| // const navigate = useNavigate() | // const navigate = useNavigate() | ||||
| useEffect(() => { | useEffect(() => { | ||||
| console.log(recordList) | |||||
| // console.log(recordList) | |||||
| setRows(recordList.records); | setRows(recordList.records); | ||||
| }, [recordList]); | }, [recordList]); | ||||
| @@ -48,8 +48,13 @@ export default function HolidayTable({ recordList }) { | |||||
| rows={rows} | rows={rows} | ||||
| columns={columns} | columns={columns} | ||||
| customPageSize={20} | customPageSize={20} | ||||
| applyGridOnReady={applyGridOnReady} | |||||
| // onRowDoubleClick={handleRowDoubleClick} | // onRowDoubleClick={handleRowDoubleClick} | ||||
| getRowHeight={() => 'auto'} | getRowHeight={() => 'auto'} | ||||
| // doLoad={React.useMemo(() => ({ | |||||
| // url: LIST_PROOF, | |||||
| // params: _searchCriteria, | |||||
| // }), [_searchCriteria])} | |||||
| /> | /> | ||||
| </div> | </div> | ||||
| ); | ); | ||||
| @@ -16,7 +16,7 @@ import {ThemeProvider} from "@emotion/react"; | |||||
| // ==============================|| DASHBOARD - DEFAULT ||============================== // | // ==============================|| DASHBOARD - DEFAULT ||============================== // | ||||
| const SearchHolidayForm = ({ applySearch, comboData}) => { | |||||
| const SearchHolidayForm = ({ applySearch, comboData, onGridReady}) => { | |||||
| const [selectedYear, setSelectedYear] = React.useState([]); | const [selectedYear, setSelectedYear] = React.useState([]); | ||||
| // const [defaultYear, setDefaultYear] = React.useState(searchCriteria.year); | // const [defaultYear, setDefaultYear] = React.useState(searchCriteria.year); | ||||
| const [comboList, setComboList] = React.useState([]); | const [comboList, setComboList] = React.useState([]); | ||||
| @@ -79,9 +79,9 @@ const SearchHolidayForm = ({ applySearch, comboData}) => { | |||||
| setSelectedYear(newValue); | setSelectedYear(newValue); | ||||
| }} | }} | ||||
| sx={{ | sx={{ | ||||
| "& .MuiInputBase-root": { height: "41px" }, | |||||
| "#year-combo": { padding: "0px 0px 0px 0px" }, | |||||
| "& .MuiAutocomplete-endAdornment": { top: "auto" }, | |||||
| '& .MuiInputBase-root': { alignItems: 'center' }, | |||||
| '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, | |||||
| '& .MuiOutlinedInput-root': { height: 40 } | |||||
| }} | }} | ||||
| renderInput={(params) => <TextField {...params} placeholder={""}/>} | renderInput={(params) => <TextField {...params} placeholder={""}/>} | ||||
| /> | /> | ||||
| @@ -114,6 +114,7 @@ const SearchHolidayForm = ({ applySearch, comboData}) => { | |||||
| <Button | <Button | ||||
| variant="contained" | variant="contained" | ||||
| type="submit" | type="submit" | ||||
| disabled={onGridReady} | |||||
| > | > | ||||
| Search | Search | ||||
| </Button> | </Button> | ||||
| @@ -32,6 +32,7 @@ import {PNSPS_LONG_BUTTON_THEME} from "themes/buttonConst"; | |||||
| import {ThemeProvider} from "@emotion/react"; | import {ThemeProvider} from "@emotion/react"; | ||||
| import { dateStr_Year } from "utils/DateUtils"; | import { dateStr_Year } from "utils/DateUtils"; | ||||
| import { notifySaveSuccess } from 'utils/CommonFunction'; | import { notifySaveSuccess } from 'utils/CommonFunction'; | ||||
| import { isGrantedAny } from "auth/utils"; | |||||
| // ==============================|| DASHBOARD - DEFAULT ||============================== // | // ==============================|| DASHBOARD - DEFAULT ||============================== // | ||||
| @@ -41,6 +42,8 @@ const Index = () => { | |||||
| const [comboData, setComboData] = React.useState([]); | const [comboData, setComboData] = React.useState([]); | ||||
| const [onReady, setOnReady] = React.useState(false); | const [onReady, setOnReady] = React.useState(false); | ||||
| const [onSearchReady, setOnSearchReady] = React.useState(false); | const [onSearchReady, setOnSearchReady] = React.useState(false); | ||||
| const [onGridReady, setGridOnReady] = React.useState(false); | |||||
| // const navigate = useNavigate() | // const navigate = useNavigate() | ||||
| const [searchCriteria, setSearchCriteria] = React.useState({ | const [searchCriteria, setSearchCriteria] = React.useState({ | ||||
| year: dateStr_Year(new Date()), | year: dateStr_Year(new Date()), | ||||
| @@ -97,9 +100,14 @@ const Index = () => { | |||||
| } | } | ||||
| function applySearch(input) { | function applySearch(input) { | ||||
| setGridOnReady(true) | |||||
| setSearchCriteria(input); | setSearchCriteria(input); | ||||
| } | } | ||||
| function applyGridOnReady(input) { | |||||
| setGridOnReady(input); | |||||
| } | |||||
| React.useEffect(() => { | React.useEffect(() => { | ||||
| if (attachments.length > 0) { | if (attachments.length > 0) { | ||||
| importHoliday(); | importHoliday(); | ||||
| @@ -175,43 +183,39 @@ const Index = () => { | |||||
| <Stack direction="row" justifyContent="flex-start" alignItems="center" spacing={2} sx={{ml:2,mt:1}} > | <Stack direction="row" justifyContent="flex-start" alignItems="center" spacing={2} sx={{ml:2,mt:1}} > | ||||
| <ThemeProvider theme={PNSPS_LONG_BUTTON_THEME}> | <ThemeProvider theme={PNSPS_LONG_BUTTON_THEME}> | ||||
| <label htmlFor="downloadFileBtn"> | |||||
| <Button | |||||
| component="span" | |||||
| variant="contained" | |||||
| size="large" | |||||
| disabled={waitDownload} | |||||
| onClick={doExport} | |||||
| > | |||||
| <Typography variant="h5">Export</Typography> | |||||
| </Button> | |||||
| </label> | |||||
| <Button | |||||
| variant="contained" | |||||
| size="large" | |||||
| disabled={waitDownload} | |||||
| onClick={doExport} | |||||
| aria-label="Export holiday template" | |||||
| > | |||||
| <Typography variant="h5">Export</Typography> | |||||
| </Button> | |||||
| </ThemeProvider> | </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"> | |||||
| {isGrantedAny(["MAINTAIN_GAZETTE_ISSUE"]) ? | |||||
| <ThemeProvider theme={PNSPS_LONG_BUTTON_THEME}> | |||||
| <Button | <Button | ||||
| component="span" | |||||
| component="label" | |||||
| variant="contained" | variant="contained" | ||||
| size="large" | size="large" | ||||
| disabled={waitImport} | disabled={waitImport} | ||||
| > | > | ||||
| <Typography variant="h5">Upload Files</Typography> | <Typography variant="h5">Upload Files</Typography> | ||||
| <input | |||||
| id="uploadFileBtn" | |||||
| name="file" | |||||
| type="file" | |||||
| accept=".xlsx" | |||||
| hidden | |||||
| disabled={waitImport} | |||||
| onChange={readFile} | |||||
| aria-label="Upload Excel file (.xlsx)" | |||||
| /> | |||||
| </Button> | </Button> | ||||
| </label> | |||||
| </ThemeProvider> | |||||
| </ThemeProvider> | |||||
| :null | |||||
| } | |||||
| </Stack> | </Stack> | ||||
| </Grid> | </Grid> | ||||
| @@ -222,6 +226,7 @@ const Index = () => { | |||||
| // generateXML={generateXML} | // generateXML={generateXML} | ||||
| searchCriteria={searchCriteria} | searchCriteria={searchCriteria} | ||||
| comboData={comboData} | comboData={comboData} | ||||
| onGridReady={onGridReady} | |||||
| /> | /> | ||||
| </Grid> | </Grid> | ||||
| {/*row 2*/} | {/*row 2*/} | ||||
| @@ -234,6 +239,7 @@ const Index = () => { | |||||
| > | > | ||||
| <HolidayTable | <HolidayTable | ||||
| recordList={record} | recordList={record} | ||||
| applyGridOnReady={applyGridOnReady} | |||||
| /> | /> | ||||
| </MainCard> | </MainCard> | ||||
| </Grid> | </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 { FiDataGrid } from "components/FiDataGrid"; | ||||
| import {useIntl} from "react-intl"; | import {useIntl} from "react-intl"; | ||||
| import { clickableLink } from 'utils/CommonFunction'; | import { clickableLink } from 'utils/CommonFunction'; | ||||
| import {GET_MSG_LIST} from "utils/ApiPathConst"; | |||||
| // ==============================|| EVENT TABLE ||============================== // | // ==============================|| EVENT TABLE ||============================== // | ||||
| export default function MsgTable({ recordList }) { | |||||
| const [rows, setRows] = React.useState(recordList); | |||||
| export default function MsgTable({ searchCriteria, applyGridOnReady, applySearch}) { | |||||
| const navigate = useNavigate() | const navigate = useNavigate() | ||||
| const intl = useIntl(); | const intl = useIntl(); | ||||
| const [_searchCriteria, set_searchCriteria] = React.useState(searchCriteria); | |||||
| React.useEffect(() => { | |||||
| set_searchCriteria(searchCriteria); | |||||
| }, [searchCriteria]); | |||||
| const _sx = { | const _sx = { | ||||
| padding: "4 2 4 2", | padding: "4 2 4 2", | ||||
| boxShadow: 1, | boxShadow: 1, | ||||
| @@ -25,48 +33,56 @@ export default function MsgTable({ recordList }) { | |||||
| '& .MuiDataGrid-footerContainer': { | '& .MuiDataGrid-footerContainer': { | ||||
| border: 1, | border: 1, | ||||
| borderColor: "#EEE" | 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 = [ | const columns = [ | ||||
| { | { | ||||
| id: 'sentDate', | id: 'sentDate', | ||||
| field: 'sentDate', | field: 'sentDate', | ||||
| headerName: intl.formatMessage({id: 'date'}), | 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 , | flex: 1 , | ||||
| cellClassName: 'actions', | |||||
| cellClassName: 'subject', | |||||
| renderCell: (params) => { | renderCell: (params) => { | ||||
| return clickableLink('/msg/details/' + params.row.id, params.row.subject); | return clickableLink('/msg/details/' + params.row.id, params.row.subject); | ||||
| }, | }, | ||||
| }, | }, | ||||
| ]; | ]; | ||||
| function handleEditClick(params) { | |||||
| navigate('/msg/details/' + params.row.id); | |||||
| } | |||||
| return ( | return ( | ||||
| <div style={{ minHeight: 400, width: '100%' }}> | |||||
| <div style={{ width: '100%', overflowX: 'auto'}}> | |||||
| <FiDataGrid | <FiDataGrid | ||||
| sx={_sx} | sx={_sx} | ||||
| rowHeight={80} | |||||
| rows={rows} | |||||
| columns={columns} | columns={columns} | ||||
| customPageSize={20} | |||||
| customPageSize={10} | |||||
| getRowHeight={() => 'auto'} | |||||
| onRowDoubleClick={handleEditClick} | onRowDoubleClick={handleEditClick} | ||||
| applyGridOnReady={applyGridOnReady} | |||||
| applySearch={applySearch} | |||||
| doLoad={React.useMemo(() => ({ | |||||
| url: GET_MSG_LIST, | |||||
| params: _searchCriteria, | |||||
| }), [_searchCriteria])} | |||||
| /> | /> | ||||
| </div> | </div> | ||||
| ); | ); | ||||
| @@ -21,7 +21,7 @@ import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs"; | |||||
| // ==============================|| DASHBOARD - DEFAULT ||============================== // | // ==============================|| DASHBOARD - DEFAULT ||============================== // | ||||
| const SearchForm = ({ applySearch, searchCriteria }) => { | |||||
| const SearchForm = ({ applySearch, searchCriteria, onGridReady }) => { | |||||
| const intl = useIntl(); | const intl = useIntl(); | ||||
| const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom); | const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom); | ||||
| const [maxDate, setMaxDate] = React.useState(searchCriteria.dateTo); | const [maxDate, setMaxDate] = React.useState(searchCriteria.dateTo); | ||||
| @@ -64,9 +64,11 @@ const SearchForm = ({ applySearch, searchCriteria }) => { | |||||
| sentDateTo = DateUtils.dateValue(toDateValue) | sentDateTo = DateUtils.dateValue(toDateValue) | ||||
| } | } | ||||
| const temp = { | const temp = { | ||||
| keywork: data.keywork, | |||||
| keyword: data.keyword, | |||||
| dateFrom: sentDateFrom, | dateFrom: sentDateFrom, | ||||
| dateTo: sentDateTo, | dateTo: sentDateTo, | ||||
| start:0, | |||||
| limit:10 | |||||
| }; | }; | ||||
| applySearch(temp); | applySearch(temp); | ||||
| }; | }; | ||||
| @@ -75,6 +77,8 @@ const SearchForm = ({ applySearch, searchCriteria }) => { | |||||
| setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14))) | setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14))) | ||||
| setMaxDate(DateUtils.dateValue(new Date())) | setMaxDate(DateUtils.dateValue(new Date())) | ||||
| reset(); | reset(); | ||||
| localStorage.setItem('searchCriteria',"") | |||||
| } | } | ||||
| @@ -196,6 +200,7 @@ const SearchForm = ({ applySearch, searchCriteria }) => { | |||||
| <Button | <Button | ||||
| variant="contained" | variant="contained" | ||||
| type="submit" | type="submit" | ||||
| disabled={onGridReady} | |||||
| aria-label={intl.formatMessage({id: 'submit'})} | aria-label={intl.formatMessage({id: 'submit'})} | ||||
| > | > | ||||
| <FormattedMessage id="submit"/> | <FormattedMessage id="submit"/> | ||||
| @@ -5,9 +5,9 @@ import { | |||||
| Stack | Stack | ||||
| } from '@mui/material'; | } from '@mui/material'; | ||||
| import MainCard from "components/MainCard"; | import MainCard from "components/MainCard"; | ||||
| import * as UrlUtils from "utils/ApiPathConst"; | |||||
| // import * as UrlUtils from "utils/ApiPathConst"; | |||||
| import * as React from "react"; | import * as React from "react"; | ||||
| import * as HttpUtils from "utils/HttpUtils"; | |||||
| // import * as HttpUtils from "utils/HttpUtils"; | |||||
| import * as DateUtils from "utils/DateUtils"; | import * as DateUtils from "utils/DateUtils"; | ||||
| import Loadable from 'components/Loadable'; | import Loadable from 'components/Loadable'; | ||||
| @@ -16,6 +16,7 @@ const SearchForm = Loadable(React.lazy(() => import('./SearchForm'))); | |||||
| const EventTable = Loadable(React.lazy(() => import('./DataGrid'))); | const EventTable = Loadable(React.lazy(() => import('./DataGrid'))); | ||||
| import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' | import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' | ||||
| import {FormattedMessage} from "react-intl"; | import {FormattedMessage} from "react-intl"; | ||||
| import { getSearchCriteria } from "auth/utils"; | |||||
| const BackgroundHead = { | const BackgroundHead = { | ||||
| backgroundImage: `url(${titleBackgroundImg})`, | backgroundImage: `url(${titleBackgroundImg})`, | ||||
| @@ -31,41 +32,58 @@ const BackgroundHead = { | |||||
| const Index = () => { | 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 [onReady, setOnReady] = React.useState(false); | ||||
| const [onGridReady, setGridOnReady] = React.useState(false); | |||||
| React.useEffect(() => { | 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(() => { | React.useEffect(() => { | ||||
| loadGrid(); | |||||
| if(Object.keys(searchCriteria).length>0){ | |||||
| setOnReady(true); | |||||
| } | |||||
| }, [searchCriteria]); | }, [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) { | function applySearch(input) { | ||||
| setGridOnReady(true) | |||||
| setSearchCriteria(input); | setSearchCriteria(input); | ||||
| localStorage.setItem('searchCriteria', JSON.stringify({path:window.location.pathname,data:input})) | |||||
| } | |||||
| function applyGridOnReady(input) { | |||||
| setGridOnReady(input); | |||||
| } | } | ||||
| return ( | return ( | ||||
| !onReady ? | !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}> | <Grid item xs={12}> | ||||
| <div style={BackgroundHead}> | <div style={BackgroundHead}> | ||||
| <Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center"> | <Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center"> | ||||
| @@ -78,8 +96,9 @@ const Index = () => { | |||||
| {/*row 1*/} | {/*row 1*/} | ||||
| <Grid item xs={12} md={12} lg={12}> | <Grid item xs={12} md={12} lg={12}> | ||||
| <SearchForm | <SearchForm | ||||
| applySearch={applySearch} | |||||
| searchCriteria={searchCriteria} | |||||
| applySearch={applySearch} | |||||
| searchCriteria={searchCriteria} | |||||
| onGridReady={onGridReady} | |||||
| /> | /> | ||||
| </Grid> | </Grid> | ||||
| {/*row 2*/} | {/*row 2*/} | ||||
| @@ -90,7 +109,10 @@ const Index = () => { | |||||
| sx={{width: "-webkit-fill-available"}} | sx={{width: "-webkit-fill-available"}} | ||||
| > | > | ||||
| <EventTable | <EventTable | ||||
| recordList={record} | |||||
| // recordList={record} | |||||
| searchCriteria={searchCriteria} | |||||
| applyGridOnReady={applyGridOnReady} | |||||
| applySearch={applySearch} | |||||
| /> | /> | ||||
| </MainCard> | </MainCard> | ||||
| </Grid> | </Grid> | ||||
| @@ -24,18 +24,20 @@ import { PNSPS_BUTTON_THEME } from "themes/buttonConst"; | |||||
| import { ThemeProvider } from "@emotion/react"; | import { ThemeProvider } from "@emotion/react"; | ||||
| import { isGrantedAny } from "auth/utils"; | 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 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 ||============================== // | // ==============================|| DASHBOARD - DEFAULT ||============================== // | ||||
| const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | ||||
| const intl = useIntl(); | const intl = useIntl(); | ||||
| const [creditorConfirmPopUp, setCreditorConfirmPopUp] = React.useState(false); | const [creditorConfirmPopUp, setCreditorConfirmPopUp] = React.useState(false); | ||||
| const [nonCreditorConfirmPopUp, setNonCreditorConfirmPopUp] = React.useState(false); | const [nonCreditorConfirmPopUp, setNonCreditorConfirmPopUp] = React.useState(false); | ||||
| const [afterSendPopUp, setAfterSendPopUp] = React.useState(false); | |||||
| const [currentUserData, setCurrentUserData] = useState({}); | const [currentUserData, setCurrentUserData] = useState({}); | ||||
| const [overduePublicNotice, setOverduePublicNotice] = useState(0); | |||||
| const [editMode, setEditMode] = useState(false); | const [editMode, setEditMode] = useState(false); | ||||
| const [createMode, setCreateMode] = useState(false); | const [createMode, setCreateMode] = useState(false); | ||||
| const [onReady, setOnReady] = useState(false); | const [onReady, setOnReady] = useState(false); | ||||
| @@ -44,7 +46,7 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||||
| const [fromDate, setFromDate] = React.useState(null); | const [fromDate, setFromDate] = React.useState(null); | ||||
| const [currentFromDate, setCurrentFromDate] = React.useState(null); | const [currentFromDate, setCurrentFromDate] = React.useState(null); | ||||
| const [fromDateValue, setFromDateValue] = React.useState(null); | const [fromDateValue, setFromDateValue] = React.useState(null); | ||||
| const {register, handleSubmit, reset} = useForm() | |||||
| const { register, handleSubmit, reset } = useForm() | |||||
| React.useEffect(() => { | React.useEffect(() => { | ||||
| setFromDateValue(fromDate); | setFromDateValue(fromDate); | ||||
| @@ -54,14 +56,14 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||||
| //if state data are ready and assign to different field | //if state data are ready and assign to different field | ||||
| // console.log(currentApplicationDetailData) | // console.log(currentApplicationDetailData) | ||||
| if (Object.keys(currentUserData).length > 0) { | 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); | setFromDate(currentUserData.brExpiryDate); | ||||
| }else{ | |||||
| } else { | |||||
| setCurrentFromDate(currentUserData.brExpiryDate); | setCurrentFromDate(currentUserData.brExpiryDate); | ||||
| // setErrorMsg("Please select a date after today.") | // setErrorMsg("Please select a date after today.") | ||||
| } | } | ||||
| setOnReady(true); | setOnReady(true); | ||||
| } | } | ||||
| }, [currentUserData]); | }, [currentUserData]); | ||||
| @@ -115,7 +117,7 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||||
| let sentDateFrom = ""; | let sentDateFrom = ""; | ||||
| if (fromDateValue == null) { | if (fromDateValue == null) { | ||||
| setErrorMsg(intl.formatMessage({ id: 'pleaseFillInBusinessRegCertValidityDate' })) | setErrorMsg(intl.formatMessage({ id: 'pleaseFillInBusinessRegCertValidityDate' })) | ||||
| }else{ | |||||
| } else { | |||||
| sentDateFrom = DateUtils.dateValue(fromDateValue) | sentDateFrom = DateUtils.dateValue(fromDateValue) | ||||
| HttpUtils.post({ | HttpUtils.post({ | ||||
| url: UrlUtils.POST_ORG_SAVE_PATH, | url: UrlUtils.POST_ORG_SAVE_PATH, | ||||
| @@ -123,7 +125,7 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||||
| id: id > 0 ? id : null, | id: id > 0 ? id : null, | ||||
| enCompanyName: values.enCompanyName, | enCompanyName: values.enCompanyName, | ||||
| chCompanyName: values.chCompanyName, | chCompanyName: values.chCompanyName, | ||||
| orgShortName: values.orgShortName==="N/A"?"":values.orgShortName, | |||||
| orgShortName: values.orgShortName === "N/A" ? "" : values.orgShortName, | |||||
| brNo: values.brNo, | brNo: values.brNo, | ||||
| // brExpiryDate: values.brExpiryDate, | // brExpiryDate: values.brExpiryDate, | ||||
| brExpiryDate: sentDateFrom, | brExpiryDate: sentDateFrom, | ||||
| @@ -188,9 +190,9 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||||
| const onSubmit = (data) => { | const onSubmit = (data) => { | ||||
| let sentOrgShortName = ""; | 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 = { | const temp = { | ||||
| orgShortName: sentOrgShortName, | 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 ( | return ( | ||||
| <MainCard elevation={0} | <MainCard elevation={0} | ||||
| border={false} | border={false} | ||||
| @@ -311,17 +324,32 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||||
| </ThemeProvider> | </ThemeProvider> | ||||
| </Grid> | </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> | <Typography variant="pnspsFormParagraphBold">{FieldUtils.notNullFieldLabel("Expiry Date:")}</Typography> | ||||
| </Grid> | </Grid> | ||||
| <Grid item xs={12} md={6} lg={6}> | <Grid item xs={12} md={6} lg={6}> | ||||
| {(!editMode && !createMode)? | |||||
| {(!editMode && !createMode) ? | |||||
| <TextField | <TextField | ||||
| fullWidth | fullWidth | ||||
| id="currentExDate" | id="currentExDate" | ||||
| // error={(fromDate===null)} | // error={(fromDate===null)} | ||||
| // type="date" | // type="date" | ||||
| name="currentExDate" | name="currentExDate" | ||||
| value={fromDate!=null?DateUtils.dateStr(fromDate):DateUtils.dateStr(currentFromDate)} | |||||
| value={fromDate != null ? DateUtils.dateStr(fromDate) : DateUtils.dateStr(currentFromDate)} | |||||
| disabled={true} | disabled={true} | ||||
| />: | |||||
| /> : | |||||
| <LocalizationProvider dateAdapter={AdapterDayjs}> | <LocalizationProvider dateAdapter={AdapterDayjs}> | ||||
| <DemoItem components={['DatePicker']}> | |||||
| <DemoItem components={['DatePicker']}> | |||||
| <DatePicker | <DatePicker | ||||
| id="brExpiryDate" | id="brExpiryDate" | ||||
| name="brExpiryDate" | name="brExpiryDate" | ||||
| @@ -426,9 +454,9 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||||
| onChange={(newValue) => { | onChange={(newValue) => { | ||||
| // console.log(newValue) | // console.log(newValue) | ||||
| // setErrorMsg("") | // setErrorMsg("") | ||||
| if(DateUtils.dateValue(newValue)>DateUtils.dateValue(new Date())){ | |||||
| if (DateUtils.dateValue(newValue) > DateUtils.dateValue(new Date())) { | |||||
| setFromDate(newValue); | setFromDate(newValue); | ||||
| }else{ | |||||
| } else { | |||||
| // setErrorMsg("Please select a date after today.") | // setErrorMsg("Please select a date after today.") | ||||
| } | } | ||||
| }} | }} | ||||
| @@ -438,19 +466,20 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||||
| } | } | ||||
| </Grid> | </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"> | <FormHelperText error id="helper-text-date"> | ||||
| {intl.formatMessage({ id: 'pleaseFillInBusinessRegCertValidityDate' })} | {intl.formatMessage({ id: 'pleaseFillInBusinessRegCertValidityDate' })} | ||||
| </FormHelperText> | </FormHelperText> | ||||
| : | |||||
| : | |||||
| null | null | ||||
| } | |||||
| } | |||||
| </Grid> | </Grid> | ||||
| </Grid> | </Grid> | ||||
| @@ -488,27 +517,6 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||||
| })} | })} | ||||
| </Grid> | </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 ? | currentUserData.creditor ? | ||||
| <Grid item xs={12} lg={4} > | <Grid item xs={12} lg={4} > | ||||
| @@ -533,6 +541,28 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||||
| })} | })} | ||||
| </Grid> | </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 item lg={12} ></Grid> | ||||
| </Grid> | </Grid> | ||||
| @@ -566,7 +596,7 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||||
| {...register("orgShortName")} | {...register("orgShortName")} | ||||
| id='orgShortName' | id='orgShortName' | ||||
| label="Organisation Short Name" | label="Organisation Short Name" | ||||
| defaultValue={currentUserData.orgShortName!="N/A"?currentUserData.orgShortName:""} | |||||
| defaultValue={currentUserData.orgShortName != "N/A" ? currentUserData.orgShortName : ""} | |||||
| InputLabelProps={{ | InputLabelProps={{ | ||||
| shrink: true | shrink: true | ||||
| }} | }} | ||||
| @@ -605,6 +635,27 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||||
| </DialogActions> | </DialogActions> | ||||
| </Dialog> | </Dialog> | ||||
| </div> | </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> | </MainCard> | ||||
| ); | ); | ||||
| }; | }; | ||||
| @@ -1,6 +1,6 @@ | |||||
| // material-ui | // material-ui | ||||
| import { | import { | ||||
| Grid, Button, | |||||
| Grid, Button, | |||||
| // Checkbox, FormControlLabel, | // Checkbox, FormControlLabel, | ||||
| Typography, | Typography, | ||||
| Dialog, DialogTitle, DialogContent, DialogActions, | Dialog, DialogTitle, DialogContent, DialogActions, | ||||
| @@ -20,9 +20,9 @@ const LoadingComponent = Loadable(lazy(() => import('../../extra-pages/LoadingCo | |||||
| import Loadable from 'components/Loadable'; | import Loadable from 'components/Loadable'; | ||||
| import { lazy } from 'react'; | import { lazy } from 'react'; | ||||
| import { notifySaveSuccess } from 'utils/CommonFunction'; | 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 ||============================== // | // ==============================|| DASHBOARD - DEFAULT ||============================== // | ||||
| @@ -54,19 +54,19 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||||
| enableReinitialize: true, | enableReinitialize: true, | ||||
| initialValues: currentUserData, | initialValues: currentUserData, | ||||
| validationSchema: yup.object().shape({ | 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(), | faxNumber: yup.string().min(8, displayErrorMsg(intl.formatMessage({ id: 'require8Number' }))).nullable(), | ||||
| }), | }), | ||||
| onSubmit: values => { | onSubmit: values => { | ||||
| if (values.country==null){ | |||||
| setErrorMsg(intl.formatMessage({id: 'pleaseFillInCountry'})) | |||||
| if (values.country == null) { | |||||
| setErrorMsg(intl.formatMessage({ id: 'pleaseFillInCountry' })) | |||||
| } else { | } 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 { | } else { | ||||
| HttpUtils.post({ | HttpUtils.post({ | ||||
| url: UrlUtils.POST_PUB_ORG_SAVE_PATH, | url: UrlUtils.POST_PUB_ORG_SAVE_PATH, | ||||
| @@ -100,9 +100,9 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||||
| } | } | ||||
| }); | }); | ||||
| useEffect(()=>{ | |||||
| useEffect(() => { | |||||
| setEditModeFun(editMode); | setEditModeFun(editMode); | ||||
| },[editMode]); | |||||
| }, [editMode]); | |||||
| useEffect(() => { | useEffect(() => { | ||||
| if (Object.keys(userData).length > 0) { | if (Object.keys(userData).length > 0) { | ||||
| @@ -188,7 +188,7 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||||
| onClick={onEditClick} | onClick={onEditClick} | ||||
| color="success" | color="success" | ||||
| > | > | ||||
| < FormattedMessage id="edit" /> | |||||
| < FormattedMessage id="edit" /> | |||||
| </Button> | </Button> | ||||
| </ThemeProvider> | </ThemeProvider> | ||||
| </Grid> | </Grid> | ||||
| @@ -202,11 +202,11 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||||
| <LoadingComponent /> | <LoadingComponent /> | ||||
| : | : | ||||
| <Grid container spacing={1}> | <Grid container spacing={1}> | ||||
| <Grid item xs={12}> | |||||
| {/* <Grid item xs={12}> | |||||
| <Typography variant="h4" sx={{ mb: 2, mr: 3, borderBottom: "1px solid black" }}> | <Typography variant="h4" sx={{ mb: 2, mr: 3, borderBottom: "1px solid black" }}> | ||||
| <FormattedMessage id="organizationDetails" /> | <FormattedMessage id="organizationDetails" /> | ||||
| </Typography> | </Typography> | ||||
| </Grid> | |||||
| </Grid> */} | |||||
| <Grid item xs={12}> | <Grid item xs={12}> | ||||
| <FormHelperText error id="helper-text-address1-signup"> | <FormHelperText error id="helper-text-address1-signup"> | ||||
| <Typography variant="errorMessage1"> | <Typography variant="errorMessage1"> | ||||
| @@ -216,27 +216,27 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||||
| </Grid> | </Grid> | ||||
| <Grid item xs={12} lg={4} > | <Grid item xs={12} lg={4} > | ||||
| {FieldUtils.getTextField({ | {FieldUtils.getTextField({ | ||||
| label: intl.formatMessage({id: 'brNo'}) + ":", | |||||
| label: intl.formatMessage({ id: 'brNo' }) + ":", | |||||
| valueName: "brNo", | valueName: "brNo", | ||||
| disabled: true, | disabled: true, | ||||
| form: formik | form: formik | ||||
| })} | })} | ||||
| </Grid> | </Grid> | ||||
| <Grid item xs={12} lg={4} > | <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> | ||||
| <Grid item xs={12} lg={4} ></Grid> | <Grid item xs={12} lg={4} ></Grid> | ||||
| <Grid item xs={12} lg={4} > | <Grid item xs={12} lg={4} > | ||||
| {FieldUtils.getTextField({ | {FieldUtils.getTextField({ | ||||
| label: FieldUtils.notNullFieldLabel(intl.formatMessage({id: 'nameEng'}) + ":"), | |||||
| label: FieldUtils.notNullFieldLabel(intl.formatMessage({ id: 'nameEng' }) + ":"), | |||||
| valueName: "enCompanyName", | valueName: "enCompanyName", | ||||
| disabled: true, | disabled: true, | ||||
| form: formik | form: formik | ||||
| @@ -245,7 +245,7 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||||
| <Grid item xs={12} lg={4} > | <Grid item xs={12} lg={4} > | ||||
| {FieldUtils.getTextField({ | {FieldUtils.getTextField({ | ||||
| label: intl.formatMessage({id: 'nameChi'}) + ":", | |||||
| label: intl.formatMessage({ id: 'nameChi' }) + ":", | |||||
| valueName: "chCompanyName", | valueName: "chCompanyName", | ||||
| disabled: true, | disabled: true, | ||||
| form: formik | form: formik | ||||
| @@ -253,17 +253,12 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||||
| </Grid> | </Grid> | ||||
| <Grid item xs={12} lg={4} > | <Grid item xs={12} lg={4} > | ||||
| {FieldUtils.getTextField({ | |||||
| label: FieldUtils.notNullFieldLabel(intl.formatMessage({id: 'expiryDate'}) + ":"), | |||||
| valueName: "brExpiryDate", | |||||
| disabled: true, | |||||
| form: formik | |||||
| })} | |||||
| </Grid> | </Grid> | ||||
| <Grid item xs={12} lg={4} > | <Grid item xs={12} lg={4} > | ||||
| {FieldUtils.getTextField({ | {FieldUtils.getTextField({ | ||||
| label: FieldUtils.notNullFieldLabel(intl.formatMessage({id: 'contactPerson'}) + ":"), | |||||
| label: FieldUtils.notNullFieldLabel(intl.formatMessage({ id: 'contactPerson' }) + ":"), | |||||
| valueName: "contactPerson", | valueName: "contactPerson", | ||||
| disabled: (!editMode && !createMode), | disabled: (!editMode && !createMode), | ||||
| form: formik | form: formik | ||||
| @@ -272,7 +267,7 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||||
| <Grid item xs={12} lg={4} > | <Grid item xs={12} lg={4} > | ||||
| {FieldUtils.getPhoneField({ | {FieldUtils.getPhoneField({ | ||||
| label: FieldUtils.notNullFieldLabel(intl.formatMessage({id: 'userContactNumber'}) + ":"), | |||||
| label: FieldUtils.notNullFieldLabel(intl.formatMessage({ id: 'userContactNumber' }) + ":"), | |||||
| valueName: { | valueName: { | ||||
| code: "tel_countryCode", | code: "tel_countryCode", | ||||
| num: "phoneNumber" | num: "phoneNumber" | ||||
| @@ -284,7 +279,7 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||||
| <Grid item xs={12} lg={4} > | <Grid item xs={12} lg={4} > | ||||
| {FieldUtils.getPhoneField({ | {FieldUtils.getPhoneField({ | ||||
| label: intl.formatMessage({id: 'contactFaxNumber'}) + ":", | |||||
| label: intl.formatMessage({ id: 'contactFaxNumber' }) + ":", | |||||
| valueName: { | valueName: { | ||||
| code: "fax_countryCode", | code: "fax_countryCode", | ||||
| num: "faxNumber" | num: "faxNumber" | ||||
| @@ -294,34 +289,35 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => { | |||||
| })} | })} | ||||
| </Grid> | </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), | disabled: (!editMode && !createMode), | ||||
| dataList: ComboData.country, | |||||
| getOptionLabel: (option) => option.type? intl.formatMessage({ id: option.type }) : "", | |||||
| form: formik | form: formik | ||||
| })} | })} | ||||
| </Grid> | </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", | valueName: "district", | ||||
| disabled: (!editMode && !createMode), | disabled: (!editMode && !createMode), | ||||
| dataList: ComboData.district, | dataList: ComboData.district, | ||||
| getOptionLabel: (option) => option.type? intl.formatMessage({ id: option.type }) : "", | |||||
| getOptionLabel: (option) => option.type ? intl.formatMessage({ id: option.type }) : "", | |||||
| form: formik | form: formik | ||||
| })} | })} | ||||
| </Grid> | </Grid> | ||||
| <Grid item xs={12} lg={12} > | <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 | form: formik | ||||
| })} | })} | ||||
| </Grid> | </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> | <Typography variant="h4" style={{ padding: '16px' }}>Are you sure mark as Credit Client?</Typography> | ||||
| </DialogContent> | </DialogContent> | ||||
| <DialogActions> | <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> | <Button onClick={() => markAsCreditor()}><Typography variant="h5">Confirm</Typography></Button> | ||||
| </DialogActions> | </DialogActions> | ||||
| </Dialog> | </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> | <Typography variant="h4" style={{ padding: '16px' }}>Are you sure mark as Non-Credit Client?</Typography> | ||||
| </DialogContent> | </DialogContent> | ||||
| <DialogActions> | <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> | <Button onClick={() => markAsNonCreditor()}><Typography variant="h5">Confirm</Typography></Button> | ||||
| </DialogActions> | </DialogActions> | ||||
| </Dialog> | </Dialog> | ||||
| @@ -310,19 +310,17 @@ const OrganizationCard_loadFromUser = ({ userData, userId }) => { | |||||
| })} | })} | ||||
| </Grid> | </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 | form: formik | ||||
| })} | })} | ||||
| </Grid> | </Grid> | ||||
| <Grid item xs={12} lg={4}> | |||||
| <Grid item xs={12} lg={12}> | |||||
| {FieldUtils.getComboField({ | {FieldUtils.getComboField({ | ||||
| label: FieldUtils.notNullFieldLabel("District:"), | |||||
| label: "", | |||||
| valueName: "district", | valueName: "district", | ||||
| dataList: ComboData.district, | dataList: ComboData.district, | ||||
| getOptionLabel: (option) => option.type ? intl.formatMessage({ id: option.type }) : "", | getOptionLabel: (option) => option.type ? intl.formatMessage({ id: option.type }) : "", | ||||
| @@ -330,13 +328,17 @@ const OrganizationCard_loadFromUser = ({ userData, userId }) => { | |||||
| })} | })} | ||||
| </Grid> | </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 | form: formik | ||||
| })} | })} | ||||
| </Grid> | </Grid> | ||||
| </Grid> | </Grid> | ||||
| } | } | ||||
| </form> | </form> | ||||
| @@ -8,7 +8,7 @@ import { | |||||
| import MainCard from "components/MainCard"; | import MainCard from "components/MainCard"; | ||||
| import { useForm } from "react-hook-form"; | import { useForm } from "react-hook-form"; | ||||
| import { useState } from "react"; | |||||
| import { useState,useEffect } from "react"; | |||||
| import * as React from "react"; | import * as React from "react"; | ||||
| import * as UrlUtils from "utils/ApiPathConst"; | import * as UrlUtils from "utils/ApiPathConst"; | ||||
| @@ -19,11 +19,21 @@ import {ThemeProvider} from "@emotion/react"; | |||||
| // ==============================|| DASHBOARD - DEFAULT ||============================== // | // ==============================|| DASHBOARD - DEFAULT ||============================== // | ||||
| const OrganizationSearchForm = ({ applySearch }) => { | |||||
| const OrganizationSearchForm = ({ applySearch, onGridReady, searchCriteria }) => { | |||||
| const [type, setType] = useState([]); | const [type, setType] = useState([]); | ||||
| const [creditorSelected, setCreditorSelected] = React.useState(ComboData.CreditorStatus[0]); | const [creditorSelected, setCreditorSelected] = React.useState(ComboData.CreditorStatus[0]); | ||||
| const { reset, register, handleSubmit } = useForm() | 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) => { | const onSubmit = (data) => { | ||||
| let typeArray = []; | let typeArray = []; | ||||
| @@ -48,12 +58,23 @@ const OrganizationSearchForm = ({ applySearch }) => { | |||||
| function resetForm() { | function resetForm() { | ||||
| setType([]); | setType([]); | ||||
| setCreditorSelected(ComboData.CreditorStatus[0]); | setCreditorSelected(ComboData.CreditorStatus[0]); | ||||
| reset(); | |||||
| reset({ | |||||
| brNo: "", | |||||
| enCompanyName: "", | |||||
| chCompanyName: "", | |||||
| }); | |||||
| } | } | ||||
| const doExport=()=>{ | const doExport=()=>{ | ||||
| setOnDownload(true) | |||||
| HttpUtils.fileDownload({ | 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")} | {...register("brNo")} | ||||
| id='brNo' | id='brNo' | ||||
| label="BR No." | label="BR No." | ||||
| defaultValue={searchCriteria.brNo} | |||||
| InputLabelProps={{ | InputLabelProps={{ | ||||
| shrink: true | shrink: true | ||||
| }} | }} | ||||
| @@ -92,6 +114,7 @@ const OrganizationSearchForm = ({ applySearch }) => { | |||||
| {...register("enCompanyName")} | {...register("enCompanyName")} | ||||
| id="enCompanyName" | id="enCompanyName" | ||||
| label="Name (English)" | label="Name (English)" | ||||
| defaultValue={searchCriteria.enCompanyName} | |||||
| InputLabelProps={{ | InputLabelProps={{ | ||||
| shrink: true | shrink: true | ||||
| }} | }} | ||||
| @@ -104,6 +127,7 @@ const OrganizationSearchForm = ({ applySearch }) => { | |||||
| {...register("chCompanyName")} | {...register("chCompanyName")} | ||||
| id="chCompanyName" | id="chCompanyName" | ||||
| label="Name (Chinese)" | label="Name (Chinese)" | ||||
| defaultValue={searchCriteria.chCompanyName} | |||||
| InputLabelProps={{ | InputLabelProps={{ | ||||
| shrink: true | shrink: true | ||||
| }} | }} | ||||
| @@ -126,6 +150,11 @@ const OrganizationSearchForm = ({ applySearch }) => { | |||||
| }} | }} | ||||
| getOptionLabel={(option) => option.label} | getOptionLabel={(option) => option.label} | ||||
| sx={{ | |||||
| '& .MuiInputBase-root': { alignItems: 'center' }, | |||||
| '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, | |||||
| '& .MuiOutlinedInput-root': { height: 40 } | |||||
| }} | |||||
| renderInput={(params) => ( | renderInput={(params) => ( | ||||
| <TextField | <TextField | ||||
| {...params} | {...params} | ||||
| @@ -148,6 +177,7 @@ const OrganizationSearchForm = ({ applySearch }) => { | |||||
| <Button | <Button | ||||
| variant="contained" | variant="contained" | ||||
| onClick={doExport} | onClick={doExport} | ||||
| disabled={onDownload} | |||||
| > | > | ||||
| Export | Export | ||||
| </Button> | </Button> | ||||
| @@ -167,6 +197,7 @@ const OrganizationSearchForm = ({ applySearch }) => { | |||||
| <Button | <Button | ||||
| variant="contained" | variant="contained" | ||||
| type="submit" | type="submit" | ||||
| disabled={onGridReady} | |||||
| > | > | ||||
| Submit | Submit | ||||
| </Button> | </Button> | ||||
| @@ -11,7 +11,7 @@ import { clickableLink} from 'utils/CommonFunction'; | |||||
| import {GET_ORG_PATH} from "utils/ApiPathConst"; | import {GET_ORG_PATH} from "utils/ApiPathConst"; | ||||
| // ==============================|| EVENT TABLE ||============================== // | // ==============================|| EVENT TABLE ||============================== // | ||||
| export default function OrganizationTable({ searchCriteria }) { | |||||
| export default function OrganizationTable({ searchCriteria, applyGridOnReady, applySearch}) { | |||||
| const [_searchCriteria, set_searchCriteria] = React.useState(searchCriteria); | const [_searchCriteria, set_searchCriteria] = React.useState(searchCriteria); | ||||
| const navigate = useNavigate() | const navigate = useNavigate() | ||||
| @@ -111,12 +111,18 @@ export default function OrganizationTable({ searchCriteria }) { | |||||
| <div style={{ height: "fit-content", width: '100%' }}> | <div style={{ height: "fit-content", width: '100%' }}> | ||||
| <FiDataGrid | <FiDataGrid | ||||
| columns={columns} | columns={columns} | ||||
| customPageSize={5} | |||||
| customPageSize={10} | |||||
| onRowDoubleClick={handleRowDoubleClick} | onRowDoubleClick={handleRowDoubleClick} | ||||
| doLoad={{ | |||||
| applyGridOnReady={applyGridOnReady} | |||||
| applySearch={applySearch} | |||||
| // doLoad={{ | |||||
| // url: GET_ORG_PATH, | |||||
| // params: _searchCriteria, | |||||
| // }} | |||||
| doLoad={React.useMemo(() => ({ | |||||
| url: GET_ORG_PATH, | url: GET_ORG_PATH, | ||||
| params: _searchCriteria, | params: _searchCriteria, | ||||
| }} | |||||
| }), [_searchCriteria])} | |||||
| /> | /> | ||||
| </div> | </div> | ||||
| ); | ); | ||||
| @@ -5,7 +5,7 @@ import { | |||||
| import MainCard from "components/MainCard"; | import MainCard from "components/MainCard"; | ||||
| import { useEffect, useState } from "react"; | import { useEffect, useState } from "react"; | ||||
| import * as React from "react"; | import * as React from "react"; | ||||
| import { getSearchCriteria } from "auth/utils"; | |||||
| // import LoadingComponent from "../extra-pages/LoadingComponent"; | // import LoadingComponent from "../extra-pages/LoadingComponent"; | ||||
| // import SearchForm from "./OrganizationSearchForm"; | // import SearchForm from "./OrganizationSearchForm"; | ||||
| @@ -32,13 +32,29 @@ const OrganizationSearchPage = () => { | |||||
| const [searchCriteria, setSearchCriteria] = useState({}); | const [searchCriteria, setSearchCriteria] = useState({}); | ||||
| const [onReady, setOnReady] = useState(false); | 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(() => { | useEffect(() => { | ||||
| setOnReady(true); | setOnReady(true); | ||||
| }, [searchCriteria]); | }, [searchCriteria]); | ||||
| function applySearch(input) { | function applySearch(input) { | ||||
| setGridOnReady(true) | |||||
| setSearchCriteria(input); | setSearchCriteria(input); | ||||
| localStorage.setItem('searchCriteria', JSON.stringify({path:window.location.pathname,data:input})) | |||||
| } | |||||
| function applyGridOnReady(input) { | |||||
| setGridOnReady(input); | |||||
| } | } | ||||
| return ( | return ( | ||||
| @@ -59,7 +75,11 @@ const OrganizationSearchPage = () => { | |||||
| </Grid> | </Grid> | ||||
| {/*row 1*/} | {/*row 1*/} | ||||
| <Grid item xs={12} md={12} lg={12} sx={{ mb: -1 }}> | <Grid item xs={12} md={12} lg={12} sx={{ mb: -1 }}> | ||||
| <SearchForm applySearch={applySearch} /> | |||||
| <SearchForm | |||||
| applySearch={applySearch} | |||||
| onGridReady={onGridReady} | |||||
| searchCriteria={searchCriteria} | |||||
| /> | |||||
| </Grid> | </Grid> | ||||
| {/*row 2*/} | {/*row 2*/} | ||||
| <Grid item xs={12} md={12} lg={12}> | <Grid item xs={12} md={12} lg={12}> | ||||
| @@ -69,6 +89,8 @@ const OrganizationSearchPage = () => { | |||||
| > | > | ||||
| <EventTable | <EventTable | ||||
| searchCriteria={searchCriteria} | searchCriteria={searchCriteria} | ||||
| applyGridOnReady={applyGridOnReady} | |||||
| applySearch={applySearch} | |||||
| /> | /> | ||||
| </MainCard> | </MainCard> | ||||
| </Grid> | </Grid> | ||||
| @@ -43,7 +43,7 @@ export default function SearchPublicNoticeTable({ recordList }) { | |||||
| flex: 1, | flex: 1, | ||||
| renderCell: (params) => { | renderCell: (params) => { | ||||
| let appNo = params.row.appNo; | 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/> | 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} | {isORGLoggedIn()&¶ms.row.careOf!=null&¶ms.row.careOf!=""?<>{params.row.careOf}<br /></>:null} | ||||
| App No: {appNo}<br/> | App No: {appNo}<br/> | ||||
| @@ -9,15 +9,19 @@ import { | |||||
| import * as React from "react"; | import * as React from "react"; | ||||
| import * as FormatUtils from "utils/FormatUtils"; | import * as FormatUtils from "utils/FormatUtils"; | ||||
| import * as PaymentStatus from "utils/statusUtils/PaymentStatus"; | import * as PaymentStatus from "utils/statusUtils/PaymentStatus"; | ||||
| import * as DateUtils from "utils/DateUtils"; | |||||
| import Loadable from 'components/Loadable'; | import Loadable from 'components/Loadable'; | ||||
| const MainCard = Loadable(React.lazy(() => import('components/MainCard'))); | const MainCard = Loadable(React.lazy(() => import('components/MainCard'))); | ||||
| const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | ||||
| import DownloadIcon from '@mui/icons-material/Download'; | import DownloadIcon from '@mui/icons-material/Download'; | ||||
| import {useIntl} from "react-intl"; | |||||
| // ==============================|| DASHBOARD - DEFAULT ||============================== // | // ==============================|| DASHBOARD - DEFAULT ||============================== // | ||||
| const PaymentDetails = ({ formData,doPrint,onDownload }) => { | const PaymentDetails = ({ formData,doPrint,onDownload }) => { | ||||
| const intl = useIntl(); | |||||
| const [data, setData] = React.useState({}); | const [data, setData] = React.useState({}); | ||||
| const [onReady, setOnReady] = React.useState(false); | const [onReady, setOnReady] = React.useState(false); | ||||
| // const { locale } = intl; | |||||
| React.useEffect(() => { | React.useEffect(() => { | ||||
| if (formData != null && formData != undefined && Object.keys(formData).length > 0) { | if (formData != null && formData != undefined && Object.keys(formData).length > 0) { | ||||
| @@ -89,7 +93,7 @@ const PaymentDetails = ({ formData,doPrint,onDownload }) => { | |||||
| </Grid> | </Grid> | ||||
| <Grid item xs={6} md={5} sx={{ml:5, textAlign: "left" }}> | <Grid item xs={6} md={5} sx={{ml:5, textAlign: "left" }}> | ||||
| <FormLabel sx={{ color: "#000000" }}> | <FormLabel sx={{ color: "#000000" }}> | ||||
| {data.transDateStr + " (DD/MM/YYYY)"} | |||||
| {DateUtils.dateFormat(data.transDateStr, intl.formatMessage({id: "dateStrFormat"})) +" ("+intl.formatMessage({id: "dateStrFormat"})+")"} | |||||
| </FormLabel> | </FormLabel> | ||||
| </Grid> | </Grid> | ||||
| </Grid> | </Grid> | ||||
| @@ -131,7 +135,7 @@ const PaymentDetails = ({ formData,doPrint,onDownload }) => { | |||||
| </Grid> | </Grid> | ||||
| <Grid item xs={6} md={5} sx={{ml:5, textAlign: "left" }}> | <Grid item xs={6} md={5} sx={{ml:5, textAlign: "left" }}> | ||||
| <FormLabel sx={{ color: "#000000" }}> | <FormLabel sx={{ color: "#000000" }}> | ||||
| {"HK$ " + FormatUtils.currencyFormat(data.payload?.amount)} | |||||
| {"$ " + FormatUtils.currencyFormat(data.payload?.amount)} | |||||
| </FormLabel> | </FormLabel> | ||||
| </Grid> | </Grid> | ||||
| </Grid> | </Grid> | ||||
| @@ -161,14 +165,10 @@ const PaymentDetails = ({ formData,doPrint,onDownload }) => { | |||||
| </FormLabel> | </FormLabel> | ||||
| </Grid> | </Grid> | ||||
| <Grid xs={6} md={5} sx={{ml:5,textAlign: "left" }}> | <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> | </Grid> | ||||
| </Grid> | </Grid> | ||||
| @@ -77,7 +77,7 @@ const Index = () => { | |||||
| if (!responseData.data?.id) { | if (!responseData.data?.id) { | ||||
| navigate("/paymentPage/search"); | 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"); | responseData.data["transTimeStr"] = DateUtils.dateFormat(responseData.data.transDateTime, "HH:mm:ss"); | ||||
| setItemList(responseData.paymentItemList) | setItemList(responseData.paymentItemList) | ||||
| setRecord(responseData.data); | setRecord(responseData.data); | ||||
| @@ -81,7 +81,7 @@ export default function SearchPublicNoticeTable({ recordList }) { | |||||
| { | { | ||||
| id: 'fee', | id: 'fee', | ||||
| field: 'fee', | field: 'fee', | ||||
| headerName: intl.formatMessage({id: 'currencyAmount'}) + ' ($)', | |||||
| headerName: intl.formatMessage({id: 'currencyAmount'}), | |||||
| width: 200, | width: 200, | ||||
| valueGetter: (params) => { | valueGetter: (params) => { | ||||
| return (params?.value) ? "$ " + FormatUtils.currencyFormat(params?.value) : ""; | return (params?.value) ? "$ " + FormatUtils.currencyFormat(params?.value) : ""; | ||||
| @@ -9,6 +9,7 @@ import { | |||||
| import * as React from "react"; | import * as React from "react"; | ||||
| import * as FormatUtils from "utils/FormatUtils"; | import * as FormatUtils from "utils/FormatUtils"; | ||||
| import * as PaymentStatus from "utils/statusUtils/PaymentStatus"; | import * as PaymentStatus from "utils/statusUtils/PaymentStatus"; | ||||
| import * as DateUtils from "utils/DateUtils"; | |||||
| import Loadable from 'components/Loadable'; | import Loadable from 'components/Loadable'; | ||||
| const MainCard = Loadable(React.lazy(() => import('components/MainCard'))); | const MainCard = Loadable(React.lazy(() => import('components/MainCard'))); | ||||
| const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | ||||
| @@ -24,30 +25,56 @@ const PaymentDetails = ({ formData,doPrint,onDownload }) => { | |||||
| React.useEffect(() => { | React.useEffect(() => { | ||||
| if (formData != null && formData != undefined && Object.keys(formData).length > 0) { | if (formData != null && formData != undefined && Object.keys(formData).length > 0) { | ||||
| console.log(formData) | |||||
| // console.log(formData) | |||||
| setData(formData); | setData(formData); | ||||
| } | } | ||||
| }, [formData]); | }, [formData]); | ||||
| React.useEffect(() => { | React.useEffect(() => { | ||||
| if (data != null && data != undefined && Object.keys(data).length > 0) { | if (data != null && data != undefined && Object.keys(data).length > 0) { | ||||
| console.log(data) | |||||
| // console.log(data) | |||||
| setOnReady(data != {}); | setOnReady(data != {}); | ||||
| } | } | ||||
| }, [data]); | }, [data]); | ||||
| const getPaymentMethod=()=>{ | const getPaymentMethod=()=>{ | ||||
| let paymentmethod = "" | let paymentmethod = "" | ||||
| // console.log(locale) | |||||
| if (data?.payload!=null) { | if (data?.payload!=null) { | ||||
| paymentmethod = data.payload?.paymentdetail.paymentmethod; | 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 { | } else { | ||||
| paymentmethod = data.payMethod; | 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; | return paymentmethod; | ||||
| } | } | ||||
| @@ -109,7 +136,7 @@ const PaymentDetails = ({ formData,doPrint,onDownload }) => { | |||||
| </Grid> | </Grid> | ||||
| <Grid item xs={6} md={6} sx={{textAlign: "left" }}> | <Grid item xs={6} md={6} sx={{textAlign: "left" }}> | ||||
| <FormLabel sx={{ fontSize: "16px", color: "#000000" }}> | <FormLabel sx={{ fontSize: "16px", color: "#000000" }}> | ||||
| {data.transDateStr + " (DD/MM/YYYY)"} | |||||
| {DateUtils.dateFormat(data.transDateStr, intl.formatMessage({id: "dateStrFormat"})) +" ("+intl.formatMessage({id: "dateStrFormat"})+")"} | |||||
| </FormLabel> | </FormLabel> | ||||
| </Grid> | </Grid> | ||||
| </Grid> | </Grid> | ||||
| @@ -151,7 +178,7 @@ const PaymentDetails = ({ formData,doPrint,onDownload }) => { | |||||
| </Grid> | </Grid> | ||||
| <Grid item xs={6} md={6} sx={{textAlign: "left" }}> | <Grid item xs={6} md={6} sx={{textAlign: "left" }}> | ||||
| <FormLabel sx={{ fontSize: "16px", color: "#000000" }}> | <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> | </FormLabel> | ||||
| </Grid> | </Grid> | ||||
| </Grid> | </Grid> | ||||
| @@ -181,16 +208,12 @@ const PaymentDetails = ({ formData,doPrint,onDownload }) => { | |||||
| </FormLabel> | </FormLabel> | ||||
| </Grid> | </Grid> | ||||
| <Grid item xs={6} md={5} sx={{textAlign: "left" }}> | <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> | </Grid> | ||||
| </Grid> | </Grid> | ||||
| @@ -59,9 +59,9 @@ const Index = () => { | |||||
| React.useEffect(() => { | React.useEffect(() => { | ||||
| if (Object.keys(transactionData).length > 0) { | 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); | setOnReady(true); | ||||
| } | } | ||||
| }, [transactionData]); | }, [transactionData]); | ||||
| @@ -102,21 +102,21 @@ const Index = () => { | |||||
| "paymentId": params.id | "paymentId": params.id | ||||
| }, | }, | ||||
| onSuccess: function(responseData2){ | 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"); | responseData2.data["transTimeStr"] = DateUtils.dateFormat(responseData2.data.transDateTime, "HH:mm:ss"); | ||||
| setResponeData(responseData2.transactionData) | setResponeData(responseData2.transactionData) | ||||
| setItemList(responseData2.paymentItemList) | setItemList(responseData2.paymentItemList) | ||||
| setRecord(responseData2.data); | setRecord(responseData2.data); | ||||
| }, | }, | ||||
| onError: function(){ | 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"); | responseData.data["transTimeStr"] = DateUtils.dateFormat(responseData.data.transDateTime, "HH:mm:ss"); | ||||
| setResponeData(responseData) | setResponeData(responseData) | ||||
| } | } | ||||
| }); | }); | ||||
| }else{ | }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"); | responseData.data["transTimeStr"] = DateUtils.dateFormat(responseData.data.transDateTime, "HH:mm:ss"); | ||||
| setResponeData(responseData) | setResponeData(responseData) | ||||
| setItemList(responseData.paymentItemList) | setItemList(responseData.paymentItemList) | ||||
| @@ -104,7 +104,7 @@ const AckPage = () => { | |||||
| onSuccess: function(responseData){ | onSuccess: function(responseData){ | ||||
| localStorage.removeItem("webtoken"); | localStorage.removeItem("webtoken"); | ||||
| localStorage.removeItem("transactionid"); | 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"); | responseData.data["transTimeStr"] = DateUtils.dateFormat(responseData.data.transDateTime, "HH:mm:ss"); | ||||
| setResponeDataData(responseData.transactionData) | setResponeDataData(responseData.transactionData) | ||||
| setItemList(responseData.paymentItemList) | setItemList(responseData.paymentItemList) | ||||
| @@ -202,7 +202,8 @@ const AckPage = () => { | |||||
| {/*row 1*/} | {/*row 1*/} | ||||
| <Grid item xs={12} md={12} spacing={2} sx={{ textAlign: "center" }}> | <Grid item xs={12} md={12} spacing={2} sx={{ textAlign: "center" }}> | ||||
| <Typography variant="h3" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "center" }}> | <Typography variant="h3" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "center" }}> | ||||
| 您的申請和付款已收到 | |||||
| {/* 您的申請和付款已收到 */} | |||||
| <FormattedMessage id="MSG.paymentMsg"/> | |||||
| </Typography> | </Typography> | ||||
| <Grid container justifyContent="center" direction="column" spacing={2} sx={{ p: 2 }} alignitems="stretch" > | <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 }}> | <Grid item className="printOrder" xs={12} md={12} sx={{ pt: 2 }} style={{ height: '100%', order: 1 }}> | ||||
| @@ -253,21 +254,22 @@ const AckPage = () => { | |||||
| <center> | <center> | ||||
| <Grid item xs={12} md={8} > | <Grid item xs={12} md={8} > | ||||
| <Typography variant="h5" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}> | <Typography variant="h5" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}> | ||||
| 付款取消訊息: | |||||
| {/* 付款取消訊息: */} | |||||
| <FormattedMessage id="MSG.paymentCancelMsg1"/> | |||||
| <br /><br /> | <br /><br /> | ||||
| 您的付款已被取消。我們收到了您的付款請求,但由於某些原因,付款無法完成。請注意以下事項: | |||||
| <FormattedMessage id="MSG.paymentCancelMsg2"/> | |||||
| <br /><br /> | <br /><br /> | ||||
| 如果您主動取消了支付,請確認並確保取消是您的意願。 | |||||
| <FormattedMessage id="MSG.paymentCancelMsg3"/> | |||||
| <br /> | <br /> | ||||
| 如果付款被取消是由於系統問題或其他原因,請您嘗試以下解決方法: | |||||
| <FormattedMessage id="MSG.paymentCancelMsg4"/> | |||||
| <br /><br /> | <br /><br /> | ||||
| 檢查您的支付帳戶是否有任何異常或限制。 | |||||
| <FormattedMessage id="MSG.paymentCancelMsg5"/> | |||||
| <br /> | <br /> | ||||
| 確保您的付款資訊準確無誤。 | |||||
| <FormattedMessage id="MSG.paymentCancelMsg6"/> | |||||
| <br /> | <br /> | ||||
| 檢查您的網路連線是否正常。 | |||||
| <FormattedMessage id="MSG.paymentCancelMsg7"/> | |||||
| <br /><br /> | <br /><br /> | ||||
| 如果您需要進一步的協助或有任何疑問,請隨時與我們聯繫,我們將盡快解決您的付款問題。謝謝! | |||||
| <FormattedMessage id="MSG.paymentCancelMsg8"/> | |||||
| </Typography> | </Typography> | ||||
| </Grid> | </Grid> | ||||
| </center> | </center> | ||||
| @@ -296,29 +298,39 @@ const AckPage = () => { | |||||
| <Grid container justifyContent="flex-start" alignItems="center" > | <Grid container justifyContent="flex-start" alignItems="center" > | ||||
| <center> | <center> | ||||
| <Grid item xs={12} md={8} > | <Grid item xs={12} md={8} > | ||||
| <Typography variant="h5" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}> | <Typography variant="h5" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}> | ||||
| 付款失敗訊息: | |||||
| <FormattedMessage id="MSG.paymentFailMsg1"/> | |||||
| <br /><br /> | <br /><br /> | ||||
| 親愛的用戶,很遺憾地告訴您,您的付款操作未成功。我們在處理您的付款時遇到了問題。請您仔細檢查以下事項: | |||||
| <FormattedMessage id="MSG.paymentFailMsg2"/> | |||||
| <br /><br /> | <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 /> | <br /><br /> | ||||
| 如果您已確認以上問題無誤,但付款失敗,請您嘗試以下解決方法: | |||||
| <FormattedMessage id="MSG.paymentFailMsg6"/> | |||||
| <br /><br /> | <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 /> | <br /><br /> | ||||
| 如果您需要進一步的協助或有任何疑問,請隨時與我們聯繫。非常抱歉給您帶來不便,我們將盡快解決您的付款問題。謝謝! | |||||
| <FormattedMessage id="MSG.paymentFailMsg10"/> | |||||
| </Typography> | </Typography> | ||||
| </Grid> | </Grid> | ||||
| </center> | </center> | ||||
| </Grid> | </Grid> | ||||
| @@ -10,6 +10,9 @@ import * as HttpUtils from "utils/HttpUtils"; | |||||
| import * as UrlUtils from "utils/ApiPathConst"; | import * as UrlUtils from "utils/ApiPathConst"; | ||||
| import { useNavigate } from "react-router-dom"; | import { useNavigate } from "react-router-dom"; | ||||
| import FpsIcon from "assets/images/icons/fps.svg"; | 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 { useLocation } from 'react-router-dom'; | ||||
| // import {paymentPath} from "auth/utils"; | // import {paymentPath} from "auth/utils"; | ||||
| import {currencyFormat} from "utils/FormatUtils"; | import {currencyFormat} from "utils/FormatUtils"; | ||||
| @@ -19,7 +22,7 @@ import Loadable from 'components/Loadable'; | |||||
| const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | ||||
| import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' | import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' | ||||
| import {FormattedMessage} from "react-intl"; | |||||
| import {FormattedMessage, useIntl} from "react-intl"; | |||||
| const BackgroundHead = { | const BackgroundHead = { | ||||
| backgroundImage: `url(${titleBackgroundImg})`, | backgroundImage: `url(${titleBackgroundImg})`, | ||||
| width: '100%', | width: '100%', | ||||
| @@ -30,15 +33,21 @@ const BackgroundHead = { | |||||
| backgroundPosition: 'right' | backgroundPosition: 'right' | ||||
| } | } | ||||
| // ==============================|| DASHBOARD - DEFAULT ||============================== // | // ==============================|| DASHBOARD - DEFAULT ||============================== // | ||||
| const Index = () => { | const Index = () => { | ||||
| const navigate = useNavigate() | const navigate = useNavigate() | ||||
| const location = useLocation(); | const location = useLocation(); | ||||
| const intl = useIntl(); | |||||
| const { locale } = intl; | |||||
| const [locationData, setLocationData] = React.useState({}); | const [locationData, setLocationData] = React.useState({}); | ||||
| const [paymentData, setPaymentData] = React.useState({}); | const [paymentData, setPaymentData] = React.useState({}); | ||||
| const [onReady, setOnReady] = React.useState(false); | 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 [responeData, setResponeDataData] = React.useState({}); | ||||
| const [fpsTransctionData, setFpsTransctionData] = React.useState({}); | const [fpsTransctionData, setFpsTransctionData] = React.useState({}); | ||||
| @@ -49,6 +58,7 @@ const Index = () => { | |||||
| const [fpsqrcodeurlPrd, setFpsqrcodeurlPrd] = React.useState(""); | const [fpsqrcodeurlPrd, setFpsqrcodeurlPrd] = React.useState(""); | ||||
| const [fpsqrcodeurlFps, setFpsqrcodeurlFps] = React.useState(""); | const [fpsqrcodeurlFps, setFpsqrcodeurlFps] = React.useState(""); | ||||
| const [browserType, setBrowserType] = React.useState(""); | const [browserType, setBrowserType] = React.useState(""); | ||||
| const [sysEnv, setSysEnv] = React.useState(""); | |||||
| const mobileBrowser = "Mobile"; | const mobileBrowser = "Mobile"; | ||||
| const desktopBrowser = "Desktop"; | const desktopBrowser = "Desktop"; | ||||
| @@ -69,12 +79,14 @@ const Index = () => { | |||||
| if(Object.keys(location.state).length > 0){ | if(Object.keys(location.state).length > 0){ | ||||
| // console.log (location.state) | // console.log (location.state) | ||||
| setLocationData(location.state) | setLocationData(location.state) | ||||
| setBrowserType(desktopBrowser) | |||||
| if (/Android|webOS|iPhone|iPad|iPod|Opera Mini/i.test(navigator.userAgent)) { | if (/Android|webOS|iPhone|iPad|iPod|Opera Mini/i.test(navigator.userAgent)) { | ||||
| console.log('Mobile web browser'); | |||||
| // console.log('Mobile web browser'); | |||||
| setBrowserType(mobileBrowser) | setBrowserType(mobileBrowser) | ||||
| // setFpsqrcodeurl(openPASGUrl) | // setFpsqrcodeurl(openPASGUrl) | ||||
| } else { | } else { | ||||
| console.log('Desktop web browser'); | |||||
| // console.log('Desktop web browser'); | |||||
| setBrowserType(desktopBrowser) | setBrowserType(desktopBrowser) | ||||
| } | } | ||||
| } | } | ||||
| @@ -88,6 +100,17 @@ const Index = () => { | |||||
| } | } | ||||
| }, [locationData]); | }, [locationData]); | ||||
| React.useEffect(() => { | |||||
| // console.log (locationData) | |||||
| if (locale === 'zh-HK'){ | |||||
| setExpiredQrcode(expiredQrcodeZH) | |||||
| } else if (locale === 'en'){ | |||||
| setExpiredQrcode(expiredQrcodeEN) | |||||
| } else { | |||||
| setExpiredQrcode(expiredQrcodeCN) | |||||
| } | |||||
| }, [locale]); | |||||
| React.useEffect(() => { | React.useEffect(() => { | ||||
| // console.log (paymentData) | // console.log (paymentData) | ||||
| if (Object.keys(paymentData).length > 0){ | if (Object.keys(paymentData).length > 0){ | ||||
| @@ -159,6 +182,7 @@ const Index = () => { | |||||
| */ | */ | ||||
| setResponeDataData(responseData) | setResponeDataData(responseData) | ||||
| const timeoutdatetime = responseData.fpsmerchanttimeoutdatetime | const timeoutdatetime = responseData.fpsmerchanttimeoutdatetime | ||||
| setSysEnv(responseData.sysEnv) | |||||
| const searchString = "[UTC]"; | const searchString = "[UTC]"; | ||||
| let convertedDateString = ""; | let convertedDateString = ""; | ||||
| if ( timeoutdatetime.toString().includes(searchString) ){ | if ( timeoutdatetime.toString().includes(searchString) ){ | ||||
| @@ -175,12 +199,18 @@ const Index = () => { | |||||
| console.log(fpsqrcodeurl) | console.log(fpsqrcodeurl) | ||||
| console.log(fpsqrcodeurlwithFps) | 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=' | 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) | setFpsqrcodeurl(openPASGUrl) | ||||
| setFpsqrcodeurlPrd(openPASGUrlPrd) | setFpsqrcodeurlPrd(openPASGUrlPrd) | ||||
| setFpsqrcodeurlFps(openPASGUrlPrdFps) | setFpsqrcodeurlFps(openPASGUrlPrdFps) | ||||
| @@ -188,7 +218,7 @@ const Index = () => { | |||||
| }); | }); | ||||
| //testing | //testing | ||||
| // const timeoutdatetime = "2024-05-06T11:10:30Z[UTC]" | |||||
| // const timeoutdatetime = "2024-11-18T07:04:35Z[UTC]" | |||||
| // const convertedDateString = timeoutdatetime.replace("[UTC]", ""); | // const convertedDateString = timeoutdatetime.replace("[UTC]", ""); | ||||
| // setFpsmerchanttimeoutdatetime(convertedDateString) | // setFpsmerchanttimeoutdatetime(convertedDateString) | ||||
| // setPaymentId("C202310268000681") | // setPaymentId("C202310268000681") | ||||
| @@ -196,7 +226,7 @@ const Index = () => { | |||||
| // { | // { | ||||
| // "paymentid": "C202310268000681", | // "paymentid": "C202310268000681", | ||||
| // "paymentstatus": "INPR", | // "paymentstatus": "INPR", | ||||
| // "fpsmerchanttimeoutdatetime": "2024-05-06T11:10:30Z[UTC]", | |||||
| // "fpsmerchanttimeoutdatetime": "2024-11-18T07:04:35Z[UTC]", | |||||
| // "fpsqrcodeimgbase64": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAYAAAB5fY51AAAuyklEQVR4Xu3dfcy/d1nff2IAAAAASUVORK5CYII=", | // "fpsqrcodeimgbase64": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAYAAAB5fY51AAAuyklEQVR4Xu3dfcy/d1nff2IAAAAASUVORK5CYII=", | ||||
| // "fpsqrcodeurl": "http://127.0.0.1:8080/api/payment/wallet/fps/enquiryfpspayload/vm.JKDDlTOavR3ASviSwUnS1Lw4-" | // "fpsqrcodeurl": "http://127.0.0.1:8080/api/payment/wallet/fps/enquiryfpspayload/vm.JKDDlTOavR3ASviSwUnS1Lw4-" | ||||
| // } | // } | ||||
| @@ -231,6 +261,7 @@ const Index = () => { | |||||
| }, | }, | ||||
| onSuccess: function(responseData){ | onSuccess: function(responseData){ | ||||
| const paymentstatuscode = responseData.paymentdetail.result.paymentstatuscode; | const paymentstatuscode = responseData.paymentdetail.result.paymentstatuscode; | ||||
| setPaymentStatusCode(paymentstatuscode) | |||||
| if (paymentstatuscode != "" && paymentstatuscode != "INPR" ){ | if (paymentstatuscode != "" && paymentstatuscode != "INPR" ){ | ||||
| if (paymentstatuscode === 'APPR') { | if (paymentstatuscode === 'APPR') { | ||||
| // const timestamp = Date.now(); | // const timestamp = Date.now(); | ||||
| @@ -249,7 +280,8 @@ const Index = () => { | |||||
| } | } | ||||
| }, | }, | ||||
| onError: function(){ | onError: function(){ | ||||
| cancelPayment() | |||||
| alert("ERROR") | |||||
| // cancelPayment() | |||||
| // clearInterval(currentTimer.current); | // clearInterval(currentTimer.current); | ||||
| } | } | ||||
| }); | }); | ||||
| @@ -260,35 +292,43 @@ const Index = () => { | |||||
| const timeOutDate = new Date(fpsmerchanttimeoutdatetime); | const timeOutDate = new Date(fpsmerchanttimeoutdatetime); | ||||
| const currentTime = new Date; | const currentTime = new Date; | ||||
| const timedowncount = Math.round((timeOutDate.getTime() - currentTime.getTime()) / 1000); | const timedowncount = Math.round((timeOutDate.getTime() - currentTime.getTime()) / 1000); | ||||
| setTimeDownCount(timedowncount); | |||||
| // console.log(time) | // console.log(time) | ||||
| // console.log(timeOutDate) | // console.log(timeOutDate) | ||||
| // console.log(currentTime) | // console.log(currentTime) | ||||
| // console.log(timeOutDate.getTime()-currentTime.getTime()) | // 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]) | },[time]) | ||||
| const cancelPayment = ()=>{ | const cancelPayment = ()=>{ | ||||
| if (Object.keys(paymentData).length>0){ | 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} > | <Grid item xs={12} md={12} > | ||||
| <Typography variant="h3" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "center" }}> | <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> | <img src={FpsIcon} width="80" height="80" alt="FPS"></img> | ||||
| <br /> | <br /> | ||||
| <FormattedMessage id="payTotalDeatail"/> | <FormattedMessage id="payTotalDeatail"/> | ||||
| @@ -338,50 +380,69 @@ const Index = () => { | |||||
| </Typography> | </Typography> | ||||
| {browserType==mobileBrowser? | {browserType==mobileBrowser? | ||||
| <Typography variant="h3" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "center" }}> | <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> | ||||
| : | : | ||||
| <Typography variant="h3" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "center" }}> | <Typography variant="h3" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "center" }}> | ||||
| 請掃描以下二維碼 | |||||
| <FormattedMessage id="fpsQrcodeTitle1"/> | |||||
| <br /> | <br /> | ||||
| <img src={fpsTransctionData.fpsqrcodeimgbase64} alt="QR Code"/> | |||||
| { | |||||
| !qrCodeTimeout? | |||||
| <img src={fpsTransctionData.fpsqrcodeimgbase64} alt="QR Code"/> | |||||
| :<img src={expiredQrcode} alt="Expired QR Code"/> | |||||
| } | |||||
| <br /> | <br /> | ||||
| {"["+paymentId+"]"} | {"["+paymentId+"]"} | ||||
| <br/> | <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> | ||||
| } | } | ||||
| <Typography variant="h3" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "center" }}> | <Typography variant="h3" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "center" }}> | ||||
| @@ -312,7 +312,7 @@ const Index = () => { | |||||
| <br/> | <br/> | ||||
| 二維碼有效期限3分鐘 | 二維碼有效期限3分鐘 | ||||
| <br /> | <br /> | ||||
| 請在規定時間內完成付款流程 | |||||
| 請在限規定時間內完成付款流程 | |||||
| <br /> | <br /> | ||||
| {"剩餘時間:"+timeDownCount} | {"剩餘時間:"+timeDownCount} | ||||
| </Typography> | </Typography> | ||||
| @@ -76,22 +76,22 @@ const Fpscallback = () => { | |||||
| const loadForm = () => { | const loadForm = () => { | ||||
| const params = new URLSearchParams(window.location.search); | 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") | let paymentId = params.get("PAYMENT_ID") | ||||
| paymentId = paymentId.split('?is_successful')[0]; | paymentId = paymentId.split('?is_successful')[0]; | ||||
| console.log(transactionid) | |||||
| console.log(webtoken) | |||||
| // console.log(transactionid) | |||||
| // console.log(webtoken) | |||||
| console.log(paymentId) | console.log(paymentId) | ||||
| HttpUtils.post({ | HttpUtils.post({ | ||||
| url: UrlUtils.PAYMENT_CALLBACK_STATUS_API, | url: UrlUtils.PAYMENT_CALLBACK_STATUS_API, | ||||
| params:{ | params:{ | ||||
| "apprefid": transactionid, | |||||
| "webtoken": webtoken, | |||||
| // "apprefid": transactionid, | |||||
| // "webtoken": webtoken, | |||||
| "paymentId": paymentId, | "paymentId": paymentId, | ||||
| "transactionid":Number(transactionid) | |||||
| // "transactionid":Number(transactionid) | |||||
| }, | }, | ||||
| onSuccess: function(responseData){ | onSuccess: function(responseData){ | ||||
| setResponeDataData(responseData) | setResponeDataData(responseData) | ||||
| @@ -99,7 +99,7 @@ const Fpscallback = () => { | |||||
| localStorage.removeItem("webtoken"); | localStorage.removeItem("webtoken"); | ||||
| localStorage.removeItem("transactionid"); | 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"); | responseData.data["transTimeStr"] = DateUtils.dateFormat(responseData.data.transDateTime, "HH:mm:ss"); | ||||
| setResponeDataData(responseData.transactionData) | setResponeDataData(responseData.transactionData) | ||||
| setItemList(responseData.paymentItemList) | setItemList(responseData.paymentItemList) | ||||
| @@ -191,7 +191,7 @@ const Fpscallback = () => { | |||||
| {/*row 1*/} | {/*row 1*/} | ||||
| <Grid item xs={12} md={12} spacing={2} sx={{ textAlign: "center" }}> | <Grid item xs={12} md={12} spacing={2} sx={{ textAlign: "center" }}> | ||||
| <Typography variant="h3" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "center" }}> | <Typography variant="h3" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "center" }}> | ||||
| 您的申請和付款已收到 | |||||
| <FormattedMessage id="MSG.paymentMsg"/> | |||||
| </Typography> | </Typography> | ||||
| <Grid container justifyContent="center" direction="column" spacing={2} sx={{ p: 2 }} alignitems="stretch" > | <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 }}> | <Grid item className="printOrder" xs={12} md={12} sx={{ pt: 2 }} style={{ height: '100%', order: 1 }}> | ||||
| @@ -242,21 +242,21 @@ const Fpscallback = () => { | |||||
| <center> | <center> | ||||
| <Grid item xs={12} md={8} > | <Grid item xs={12} md={8} > | ||||
| <Typography variant="h5" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}> | <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> | </Typography> | ||||
| </Grid> | </Grid> | ||||
| </center> | </center> | ||||
| @@ -285,29 +285,39 @@ const Fpscallback = () => { | |||||
| <Grid container justifyContent="flex-start" alignItems="center" > | <Grid container justifyContent="flex-start" alignItems="center" > | ||||
| <center> | <center> | ||||
| <Grid item xs={12} md={8} > | <Grid item xs={12} md={8} > | ||||
| <Typography variant="h5" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}> | <Typography variant="h5" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}> | ||||
| 付款失敗訊息: | |||||
| <FormattedMessage id="MSG.paymentFailMsg1"/> | |||||
| <br /><br /> | <br /><br /> | ||||
| 親愛的用戶,很遺憾地告訴您,您的付款操作未成功。我們在處理您的付款時遇到了問題。請您仔細檢查以下事項: | |||||
| <FormattedMessage id="MSG.paymentFailMsg2"/> | |||||
| <br /><br /> | <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 /> | <br /><br /> | ||||
| 如果您已確認以上問題無誤,但付款失敗,請您嘗試以下解決方法: | |||||
| <FormattedMessage id="MSG.paymentFailMsg6"/> | |||||
| <br /><br /> | <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 /> | <br /><br /> | ||||
| 如果您需要進一步的協助或有任何疑問,請隨時與我們聯繫。非常抱歉給您帶來不便,我們將盡快解決您的付款問題。謝謝! | |||||
| <FormattedMessage id="MSG.paymentFailMsg10"/> | |||||
| </Typography> | </Typography> | ||||
| </Grid> | </Grid> | ||||
| </center> | </center> | ||||
| </Grid> | </Grid> | ||||
| @@ -64,7 +64,7 @@ const MultiPaymentWindow = (props) => { | |||||
| // console.log(props.transactionData) | // console.log(props.transactionData) | ||||
| if(Object.keys(props.transactionData).length > 0){ | if(Object.keys(props.transactionData).length > 0){ | ||||
| setLoadtTransactionData(props.transactionData) | setLoadtTransactionData(props.transactionData) | ||||
| console.log(props.browserType) | |||||
| // console.log(props.browserType) | |||||
| } | } | ||||
| }, [props.transactionData]); | }, [props.transactionData]); | ||||
| @@ -292,7 +292,7 @@ const MultiPaymentWindow = (props) => { | |||||
| <DialogContent> | <DialogContent> | ||||
| <DialogContentText> | <DialogContentText> | ||||
| <FormLabel sx={{ fontSize: "20px", color: "#000000", textAlign: "left", ml:1}}> | <FormLabel sx={{ fontSize: "20px", color: "#000000", textAlign: "left", ml:1}}> | ||||
| <FormattedMessage id="paymentProcessLimited"/>。 | |||||
| <FormattedMessage id="paymentProcessLimited"/> | |||||
| </FormLabel> | </FormLabel> | ||||
| <Grid item xs={12} md={12} sx={{ pt: 2 }} style={{ height: '100%' }} width="100%"> | <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' }} > | <Box xs={12} md={12} sx={{ p: 4, border: '3px solid #eee', borderRadius: '10px' }} > | ||||
| @@ -304,7 +304,7 @@ const MultiPaymentWindow = (props) => { | |||||
| </Typography> | </Typography> | ||||
| {/* <Typography variant="h5" sx={{ textAlign: "left" }}> | {/* <Typography variant="h5" sx={{ textAlign: "left" }}> | ||||
| 支付金額: HK$ {FormatUtils.currencyFormat(props.totalAmount)} | |||||
| 付款金額: HK$ {FormatUtils.currencyFormat(props.totalAmount)} | |||||
| </Typography> */} | </Typography> */} | ||||
| {!props.onReady ? | {!props.onReady ? | ||||
| <LoadingComponent /> | <LoadingComponent /> | ||||
| @@ -373,7 +373,7 @@ const MultiPaymentWindow = (props) => { | |||||
| </Grid>: | </Grid>: | ||||
| <Grid container direction="row" justifyContent="center" alignItems="center"> | <Grid container direction="row" justifyContent="center" alignItems="center"> | ||||
| <FormLabel sx={{ fontSize: "20px", color: "#000000", textAlign: "center"}}> | <FormLabel sx={{ fontSize: "20px", color: "#000000", textAlign: "center"}}> | ||||
| <FormattedMessage id="paymentMethodNotAvailable"/>。 | |||||
| <FormattedMessage id="paymentMethodNotAvailable"/> | |||||
| </FormLabel> | </FormLabel> | ||||
| </Grid> | </Grid> | ||||
| } | } | ||||
| @@ -381,12 +381,12 @@ const MultiPaymentWindow = (props) => { | |||||
| <Grid item xs={12} md={12}> | <Grid item xs={12} md={12}> | ||||
| <Grid container > | <Grid container > | ||||
| <Grid item> | <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> | </Typography> | ||||
| </Grid> | </Grid> | ||||
| <Grid item> | <Grid item> | ||||
| <Typography variant="pnspsFormParagraphBold" sx={{color: "#000000", textAlign: "left" }}> | |||||
| <Typography variant="h5" sx={{color: "#000000", textAlign: "left" }}> | |||||
| {" HK$ " + FormatUtils.currencyFormat(props.totalAmount)} | {" HK$ " + FormatUtils.currencyFormat(props.totalAmount)} | ||||
| </Typography> | </Typography> | ||||
| </Grid> | </Grid> | ||||
| @@ -123,7 +123,7 @@ const Index = () => { | |||||
| localStorage.removeItem("webtoken"); | localStorage.removeItem("webtoken"); | ||||
| localStorage.removeItem("transactionid"); | 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"); | responseData.data["transTimeStr"] = DateUtils.dateFormat(responseData.data.transDateTime, "HH:mm:ss"); | ||||
| setResponeDataData(responseData.transactionData) | setResponeDataData(responseData.transactionData) | ||||
| setItemList(responseData.paymentItemList) | setItemList(responseData.paymentItemList) | ||||
| @@ -294,29 +294,39 @@ const Index = () => { | |||||
| <Grid container justifyContent="flex-start" alignItems="center" > | <Grid container justifyContent="flex-start" alignItems="center" > | ||||
| <center> | <center> | ||||
| <Grid item xs={12} md={8} > | <Grid item xs={12} md={8} > | ||||
| <Typography variant="h5" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}> | <Typography variant="h5" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}> | ||||
| <FormattedMessage id="MSG.paymentFailMsg1"/> | <FormattedMessage id="MSG.paymentFailMsg1"/> | ||||
| <br /><br /> | <br /><br /> | ||||
| <FormattedMessage id="MSG.paymentFailMsg2"/> | <FormattedMessage id="MSG.paymentFailMsg2"/> | ||||
| <br /><br /> | <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 /> | <br /><br /> | ||||
| <FormattedMessage id="MSG.paymentFailMsg6"/> | <FormattedMessage id="MSG.paymentFailMsg6"/> | ||||
| <br /><br /> | <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 /> | <br /><br /> | ||||
| <FormattedMessage id="MSG.paymentFailMsg10"/> | <FormattedMessage id="MSG.paymentFailMsg10"/> | ||||
| </Typography> | |||||
| </Typography> | |||||
| </Grid> | </Grid> | ||||
| </center> | </center> | ||||
| </Grid> | </Grid> | ||||
| @@ -9,7 +9,7 @@ import { FiDataGrid } from "components/FiDataGrid"; | |||||
| import { clickableLink } from 'utils/CommonFunction'; | import { clickableLink } from 'utils/CommonFunction'; | ||||
| // ==============================|| EVENT TABLE ||============================== // | // ==============================|| EVENT TABLE ||============================== // | ||||
| export default function SearchPaymentTable({ searchCriteria }) { | |||||
| export default function SearchPaymentTable({ searchCriteria, applyGridOnReady, applySearch}) { | |||||
| const [_searchCriteria, set_searchCriteria] = React.useState(searchCriteria); | const [_searchCriteria, set_searchCriteria] = React.useState(searchCriteria); | ||||
| const navigate = useNavigate() | const navigate = useNavigate() | ||||
| @@ -96,10 +96,16 @@ export default function SearchPaymentTable({ searchCriteria }) { | |||||
| columns={columns} | columns={columns} | ||||
| customPageSize={10} | customPageSize={10} | ||||
| onRowDoubleClick={handleEditClick} | 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> | </div> | ||||
| ); | ); | ||||
| @@ -19,7 +19,7 @@ import {DemoItem} from "@mui/x-date-pickers/internals/demo"; | |||||
| import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider"; | import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider"; | ||||
| import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs"; | import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs"; | ||||
| // ==============================|| DASHBOARD - DEFAULT ||============================== // | // ==============================|| DASHBOARD - DEFAULT ||============================== // | ||||
| const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => { | |||||
| const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady }) => { | |||||
| const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom); | const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom); | ||||
| const [maxDate, setMaxDate] = React.useState(searchCriteria.dateTo); | const [maxDate, setMaxDate] = React.useState(searchCriteria.dateTo); | ||||
| @@ -31,6 +31,18 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => { | |||||
| const [fromDateValue, setFromDateValue] = React.useState("dd / mm / yyyy"); | const [fromDateValue, setFromDateValue] = React.useState("dd / mm / yyyy"); | ||||
| const [toDateValue, setToDateValue] = 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(() => { | React.useEffect(() => { | ||||
| setFromDateValue(minDate); | setFromDateValue(minDate); | ||||
| }, [minDate]); | }, [minDate]); | ||||
| @@ -54,6 +66,8 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => { | |||||
| dateFrom: sentDateFrom, | dateFrom: sentDateFrom, | ||||
| dateTo: sentDateTo, | dateTo: sentDateTo, | ||||
| status : (status?.type && status?.type != 'all') ? status?.type : "", | status : (status?.type && status?.type != 'all') ? status?.type : "", | ||||
| start:0, | |||||
| limit:10 | |||||
| }; | }; | ||||
| applySearch(temp); | applySearch(temp); | ||||
| }; | }; | ||||
| @@ -62,7 +76,11 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => { | |||||
| setStatus(ComboData.paymentStatus[0]); | setStatus(ComboData.paymentStatus[0]); | ||||
| setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14))) | setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14))) | ||||
| setMaxDate(DateUtils.dateValue(new Date())) | setMaxDate(DateUtils.dateValue(new Date())) | ||||
| reset(); | |||||
| reset({ | |||||
| code:"", | |||||
| transNo:"" | |||||
| }); | |||||
| localStorage.setItem('searchCriteria',"") | |||||
| } | } | ||||
| @@ -184,6 +202,11 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => { | |||||
| setStatus(newValue); | setStatus(newValue); | ||||
| } | } | ||||
| }} | }} | ||||
| sx={{ | |||||
| '& .MuiInputBase-root': { alignItems: 'center' }, | |||||
| '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, | |||||
| '& .MuiOutlinedInput-root': { height: 40 } | |||||
| }} | |||||
| renderInput={(params) => ( | renderInput={(params) => ( | ||||
| <TextField {...params} | <TextField {...params} | ||||
| label="Status" | label="Status" | ||||
| @@ -215,6 +238,7 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => { | |||||
| <Button | <Button | ||||
| variant="contained" | variant="contained" | ||||
| type="submit" | type="submit" | ||||
| disabled={onGridReady} | |||||
| > | > | ||||
| Submit | Submit | ||||
| </Button> | </Button> | ||||
| @@ -7,6 +7,7 @@ import { | |||||
| import MainCard from "components/MainCard"; | import MainCard from "components/MainCard"; | ||||
| import * as React from "react"; | import * as React from "react"; | ||||
| import * as DateUtils from "utils/DateUtils"; | import * as DateUtils from "utils/DateUtils"; | ||||
| import { getSearchCriteria } from "auth/utils"; | |||||
| import Loadable from 'components/Loadable'; | import Loadable from 'components/Loadable'; | ||||
| const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | ||||
| @@ -28,18 +29,34 @@ const BackgroundHead = { | |||||
| const Index = () => { | 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 [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(() => { | React.useEffect(() => { | ||||
| setOnReady(true); | setOnReady(true); | ||||
| }, [searchCriteria]); | }, [searchCriteria]); | ||||
| function applySearch(input) { | function applySearch(input) { | ||||
| setGridOnReady(true) | |||||
| setSearchCriteria(input); | setSearchCriteria(input); | ||||
| localStorage.setItem('searchCriteria', JSON.stringify({path:window.location.pathname,data:input})) | |||||
| } | |||||
| function applyGridOnReady(input) { | |||||
| setGridOnReady(input); | |||||
| } | } | ||||
| return ( | return ( | ||||
| @@ -63,8 +80,9 @@ const Index = () => { | |||||
| {/*row 1*/} | {/*row 1*/} | ||||
| <Grid item xs={12} md={12} lg={12} sx={{mb:-1}}> | <Grid item xs={12} md={12} lg={12} sx={{mb:-1}}> | ||||
| <SearchForm | <SearchForm | ||||
| applySearch={applySearch} | |||||
| searchCriteria={searchCriteria} | |||||
| applySearch={applySearch} | |||||
| searchCriteria={searchCriteria} | |||||
| onGridReady={onGridReady} | |||||
| /> | /> | ||||
| </Grid> | </Grid> | ||||
| {/*row 2*/} | {/*row 2*/} | ||||
| @@ -76,6 +94,8 @@ const Index = () => { | |||||
| > | > | ||||
| <EventTable | <EventTable | ||||
| searchCriteria={searchCriteria} | searchCriteria={searchCriteria} | ||||
| applyGridOnReady={applyGridOnReady} | |||||
| applySearch={applySearch} | |||||
| /> | /> | ||||
| </MainCard> | </MainCard> | ||||
| </Grid> | </Grid> | ||||
| @@ -14,7 +14,7 @@ import { clickableLink } from 'utils/CommonFunction'; | |||||
| import {PAYMENT_LIST} from "utils/ApiPathConst"; | import {PAYMENT_LIST} from "utils/ApiPathConst"; | ||||
| // ==============================|| EVENT TABLE ||============================== // | // ==============================|| EVENT TABLE ||============================== // | ||||
| export default function SearchPublicNoticeTable({ searchCriteria }) { | |||||
| export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnReady, applySearch }) { | |||||
| const navigate = useNavigate() | const navigate = useNavigate() | ||||
| const theme = useTheme(); | const theme = useTheme(); | ||||
| const isMdOrLg = useMediaQuery(theme.breakpoints.up('md')); | const isMdOrLg = useMediaQuery(theme.breakpoints.up('md')); | ||||
| @@ -94,7 +94,7 @@ export default function SearchPublicNoticeTable({ searchCriteria }) { | |||||
| { | { | ||||
| id: 'payAmount', | id: 'payAmount', | ||||
| field: 'payAmount', | field: 'payAmount', | ||||
| headerName: intl.formatMessage({id: 'currencyAmount'}) + ' ($)', | |||||
| headerName: intl.formatMessage({id: 'currencyAmount'}), | |||||
| width: 150, | width: 150, | ||||
| valueGetter: (params) => { | valueGetter: (params) => { | ||||
| return (params?.value) ? "$ " + FormatUtils.currencyFormat(params?.value) : ""; | return (params?.value) ? "$ " + FormatUtils.currencyFormat(params?.value) : ""; | ||||
| @@ -110,10 +110,16 @@ export default function SearchPublicNoticeTable({ searchCriteria }) { | |||||
| columns={columns} | columns={columns} | ||||
| customPageSize={10} | customPageSize={10} | ||||
| onRowDoubleClick={handleEditDoubleClick} | onRowDoubleClick={handleEditDoubleClick} | ||||
| doLoad={{ | |||||
| applyGridOnReady={applyGridOnReady} | |||||
| applySearch={applySearch} | |||||
| // doLoad={{ | |||||
| // url: PAYMENT_LIST, | |||||
| // params: _searchCriteria, | |||||
| // }} | |||||
| doLoad={React.useMemo(() => ({ | |||||
| url: PAYMENT_LIST, | url: PAYMENT_LIST, | ||||
| params: _searchCriteria, | params: _searchCriteria, | ||||
| }} | |||||
| }), [_searchCriteria])} | |||||
| /> | /> | ||||
| </div> | </div> | ||||
| ); | ); | ||||
| @@ -21,11 +21,11 @@ import {DemoItem} from "@mui/x-date-pickers/internals/demo"; | |||||
| import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider"; | import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider"; | ||||
| import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs"; | import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs"; | ||||
| // ==============================|| DASHBOARD - DEFAULT ||============================== // | // ==============================|| DASHBOARD - DEFAULT ||============================== // | ||||
| const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => { | |||||
| const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady }) => { | |||||
| const intl = useIntl(); | const intl = useIntl(); | ||||
| const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom); | const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom); | ||||
| const [maxDate, setMaxDate] = React.useState(searchCriteria.dateTo); | 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 [fromDateValue, setFromDateValue] = React.useState("dd / mm / yyyy"); | ||||
| const [toDateValue, setToDateValue] = React.useState("dd / mm / yyyy"); | const [toDateValue, setToDateValue] = React.useState("dd / mm / yyyy"); | ||||
| @@ -70,6 +70,8 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => { | |||||
| dateFrom: sentDateFrom, | dateFrom: sentDateFrom, | ||||
| dateTo: sentDateTo, | dateTo: sentDateTo, | ||||
| status : (status?.type && status?.type != 'all') ? status?.type : "", | status : (status?.type && status?.type != 'all') ? status?.type : "", | ||||
| start:0, | |||||
| limit:10 | |||||
| }; | }; | ||||
| applySearch(temp); | applySearch(temp); | ||||
| }; | }; | ||||
| @@ -78,7 +80,11 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => { | |||||
| setStatus(ComboData.paymentStatus[0]); | setStatus(ComboData.paymentStatus[0]); | ||||
| setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14))) | setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14))) | ||||
| setMaxDate(DateUtils.dateValue(new Date())) | setMaxDate(DateUtils.dateValue(new Date())) | ||||
| reset(); | |||||
| reset({ | |||||
| code:"", | |||||
| transNo:"" | |||||
| }); | |||||
| localStorage.setItem('searchCriteria',"") | |||||
| } | } | ||||
| @@ -181,6 +187,7 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => { | |||||
| disablePortal={false} | disablePortal={false} | ||||
| id="status" | id="status" | ||||
| size="small" | size="small" | ||||
| disableClearable | |||||
| filterOptions={(options) => options} | filterOptions={(options) => options} | ||||
| options={ComboData.paymentStatus} | options={ComboData.paymentStatus} | ||||
| value={status} | value={status} | ||||
| @@ -193,6 +200,11 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => { | |||||
| setStatus(ComboData.paymentStatus[0]); | setStatus(ComboData.paymentStatus[0]); | ||||
| } | } | ||||
| }} | }} | ||||
| sx={{ | |||||
| '& .MuiInputBase-root': { alignItems: 'center' }, | |||||
| '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, | |||||
| '& .MuiOutlinedInput-root': { height: 40 } | |||||
| }} | |||||
| renderInput={(params) => ( | renderInput={(params) => ( | ||||
| <TextField {...params} | <TextField {...params} | ||||
| label={intl.formatMessage({id: 'status'})} | label={intl.formatMessage({id: 'status'})} | ||||
| @@ -239,6 +251,7 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => { | |||||
| variant="contained" | variant="contained" | ||||
| type="submit" | type="submit" | ||||
| aria-label={intl.formatMessage({id: 'submit'})} | aria-label={intl.formatMessage({id: 'submit'})} | ||||
| disabled={onGridReady} | |||||
| > | > | ||||
| <FormattedMessage id="submit"/> | <FormattedMessage id="submit"/> | ||||
| </Button> | </Button> | ||||
| @@ -14,6 +14,7 @@ const SearchForm = Loadable(React.lazy(() => import('./SearchForm'))); | |||||
| const EventTable = Loadable(React.lazy(() => import('./DataGrid'))); | const EventTable = Loadable(React.lazy(() => import('./DataGrid'))); | ||||
| import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' | import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' | ||||
| import {FormattedMessage} from "react-intl"; | import {FormattedMessage} from "react-intl"; | ||||
| import { getSearchCriteria } from "auth/utils"; | |||||
| const BackgroundHead = { | const BackgroundHead = { | ||||
| backgroundImage: `url(${titleBackgroundImg})`, | backgroundImage: `url(${titleBackgroundImg})`, | ||||
| @@ -33,13 +34,34 @@ const Index = () => { | |||||
| dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)), | dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)), | ||||
| }); | }); | ||||
| const [onReady, setOnReady] = React.useState(false); | const [onReady, setOnReady] = React.useState(false); | ||||
| const [onGridReady, setGridOnReady] = React.useState(false); | |||||
| React.useEffect(() => { | 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]); | }, [searchCriteria]); | ||||
| function applySearch(input) { | function applySearch(input) { | ||||
| setGridOnReady(true) | |||||
| setSearchCriteria(input); | setSearchCriteria(input); | ||||
| localStorage.setItem('searchCriteria', JSON.stringify({path:window.location.pathname,data:input})) | |||||
| } | |||||
| function applyGridOnReady(input) { | |||||
| setGridOnReady(input); | |||||
| } | } | ||||
| return ( | return ( | ||||
| @@ -63,8 +85,9 @@ const Index = () => { | |||||
| {/*row 1*/} | {/*row 1*/} | ||||
| <Grid item xs={12} md={12} lg={12}> | <Grid item xs={12} md={12} lg={12}> | ||||
| <SearchForm | <SearchForm | ||||
| applySearch={applySearch} | |||||
| searchCriteria={searchCriteria} | |||||
| applySearch={applySearch} | |||||
| searchCriteria={searchCriteria} | |||||
| onGridReady={onGridReady} | |||||
| /> | /> | ||||
| </Grid> | </Grid> | ||||
| {/*row 2*/} | {/*row 2*/} | ||||
| @@ -76,6 +99,8 @@ const Index = () => { | |||||
| > | > | ||||
| <EventTable | <EventTable | ||||
| searchCriteria={searchCriteria} | searchCriteria={searchCriteria} | ||||
| applyGridOnReady={applyGridOnReady} | |||||
| applySearch={applySearch} | |||||
| /> | /> | ||||
| </MainCard> | </MainCard> | ||||
| </Grid> | </Grid> | ||||
| @@ -520,7 +520,9 @@ const Index = () => { | |||||
| }} | }} | ||||
| > | > | ||||
| <DialogTitle></DialogTitle> | <DialogTitle></DialogTitle> | ||||
| <Typography variant="h2" style={{ padding: '16px' }}>行動失敗</Typography> | |||||
| <Typography variant="h2" style={{ padding: '16px' }}> | |||||
| <FormattedMessage id ="MSG.actionFail"/> | |||||
| </Typography> | |||||
| <DialogContent style={{ display: 'flex', }}> | <DialogContent style={{ display: 'flex', }}> | ||||
| <Stack direction="column" justifyContent="space-between"> | <Stack direction="column" justifyContent="space-between"> | ||||
| { | { | ||||
| @@ -27,26 +27,50 @@ const SearchPublicNoticeForm = ({ formData }) => { | |||||
| initialValues: data, | 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> | ||||
| <Grid item xs={12} md={8} lg={8}> | <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> | </Grid> | ||||
| </Grid> | </Grid> | ||||
| @@ -131,6 +131,21 @@ const FormPanel = ({ formData }) => { | |||||
| setSaving(false); | setSaving(false); | ||||
| return; | 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); | // console.log(values); | ||||
| HttpUtils.postWithFiles({ | HttpUtils.postWithFiles({ | ||||
| url: UrlUtils.CREATE_PROOF, | url: UrlUtils.CREATE_PROOF, | ||||
| @@ -208,7 +223,7 @@ const FormPanel = ({ formData }) => { | |||||
| <Grid item xs={12} md={12}> | <Grid item xs={12} md={12}> | ||||
| <Stack direction="row" sx={{ display: 'flex', alignItems: 'center' }}> | <Stack direction="row" sx={{ display: 'flex', alignItems: 'center' }}> | ||||
| <FormLabel sx={{ paddingRight: 2, textAlign: "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> | </FormLabel> | ||||
| <TextField | <TextField | ||||
| fullWidth | fullWidth | ||||
| @@ -258,32 +273,26 @@ const FormPanel = ({ formData }) => { | |||||
| /> | /> | ||||
| </Stack> | </Stack> | ||||
| </Grid> | </Grid> | ||||
| <Grid item xs={12} md={12}> | <Grid item xs={12} md={12}> | ||||
| <Button | |||||
| component="label" | |||||
| variant="contained" | |||||
| size="large" | |||||
| disabled={attachments.length >= (formik.values.groupType == "Private Bill" ? 2 : 1)} | |||||
| > | |||||
| <Typography variant="h5">Upload Files</Typography> | |||||
| <input | <input | ||||
| id="uploadFileBtn" | id="uploadFileBtn" | ||||
| name="file" | name="file" | ||||
| type="file" | type="file" | ||||
| accept=".pdf" | accept=".pdf" | ||||
| style={{ display: 'none' }} | |||||
| hidden | |||||
| disabled={attachments.length >= (formik.values.groupType == "Private Bill" ? 2 : 1)} | disabled={attachments.length >= (formik.values.groupType == "Private Bill" ? 2 : 1)} | ||||
| onChange={(event) => { | |||||
| readFile(event) | |||||
| }} | |||||
| onChange={readFile} | |||||
| aria-label="Upload PDF file" | |||||
| /> | /> | ||||
| <label htmlFor="uploadFileBtn"> | |||||
| <Button | |||||
| component="span" | |||||
| variant="contained" | |||||
| size="large" | |||||
| disabled={attachments.length >= (formik.values.groupType == "Private Bill" ? 2 : 1)} | |||||
| > | |||||
| <Typography variant="h5">Upload Files</Typography> | |||||
| </Button> | |||||
| </label> | |||||
| </Button> | |||||
| </Grid> | </Grid> | ||||
| <Grid item xs={12} md={12}> | <Grid item xs={12} md={12}> | ||||
| <UploadFileTable | <UploadFileTable | ||||
| key="uploadTable" | key="uploadTable" | ||||
| @@ -388,7 +397,10 @@ const FormPanel = ({ formData }) => { | |||||
| <Autocomplete | <Autocomplete | ||||
| sx={{ | sx={{ | ||||
| width: "15%" | |||||
| width: "15%", | |||||
| '& .MuiInputBase-root': { alignItems: 'center' }, | |||||
| '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, | |||||
| '& .MuiOutlinedInput-root': { height: 40 } | |||||
| }} | }} | ||||
| disablePortal | disablePortal | ||||
| id="price" | id="price" | ||||
| @@ -400,6 +412,7 @@ const FormPanel = ({ formData }) => { | |||||
| setColumnPrice(newValue) | setColumnPrice(newValue) | ||||
| formik.values["fee"] = newValue.value * formik.values.length; | formik.values["fee"] = newValue.value * formik.values.length; | ||||
| }} | }} | ||||
| renderInput={(params) => ( | renderInput={(params) => ( | ||||
| <TextField {...params} | <TextField {...params} | ||||
| InputLabelProps={{ | InputLabelProps={{ | ||||
| @@ -59,10 +59,10 @@ export default function UploadFileTable({ recordList, setRecordList, showPageCol | |||||
| ...rowModesModel, | ...rowModesModel, | ||||
| [id]: { mode: GridRowModes.View, ignoreModifications: true }, | [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)); | setRecordList(rows.filter((row) => row.id !== id)); | ||||
| setRows(rows.filter((row) => row.id !== id)); | setRows(rows.filter((row) => row.id !== id)); | ||||
| } | } | ||||
| @@ -181,7 +181,7 @@ const Index = ({ record }) => { | |||||
| <DialogContent style={{ display: 'flex', }}> | <DialogContent style={{ display: 'flex', }}> | ||||
| <Stack direction="column" justifyContent="space-between"> | <Stack direction="column" justifyContent="space-between"> | ||||
| <Typography variant="h4"> | <Typography variant="h4"> | ||||
| <FormattedMessage id="totalAmount" /> (HK$): {FormatUtils.currencyFormat(record.fee)} | |||||
| <FormattedMessage id="totalAmount" /> ($): {FormatUtils.currencyFormat(record.fee)} | |||||
| </Typography> | </Typography> | ||||
| </Stack> | </Stack> | ||||
| </DialogContent> | </DialogContent> | ||||
| @@ -70,6 +70,7 @@ const Index = ({ record }) => { | |||||
| navigate("/publicNotice"); | navigate("/publicNotice"); | ||||
| }} | }} | ||||
| > | > | ||||
| <FormattedMessage id="backToNoticePage" /> | |||||
| </Button> | </Button> | ||||
| </Typography> | </Typography> | ||||
| </Grid> | </Grid> | ||||
| @@ -44,12 +44,12 @@ const Index = ({ record }) => { | |||||
| <Grid container justifyContent="flex-start" alignItems="center" > | <Grid container justifyContent="flex-start" alignItems="center" > | ||||
| <center> | <center> | ||||
| <Grid item xs={12} md={8} > | <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" /> | <FormattedMessage id="proofPaymentHeader_demandNote" /> | ||||
| </Typography> | </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={{ | <div dangerouslySetInnerHTML={{ | ||||
| __html: intl.formatMessage( | __html: intl.formatMessage( | ||||
| { | { | ||||
| @@ -67,7 +67,7 @@ const Index = ({ record }) => { | |||||
| id: 'proofPaymentBody_demandNote2' | id: 'proofPaymentBody_demandNote2' | ||||
| }, | }, | ||||
| { | { | ||||
| closingDateOff: DateUtils.dateStr(record.closingDateOff), | |||||
| closingDateOff: DateUtils.dateFormat(record?.closingDateOff, intl.formatMessage({id: "dateStrFormat"})), | |||||
| email: record?.mail, | email: record?.mail, | ||||
| } | } | ||||
| ) | ) | ||||
| @@ -79,7 +79,7 @@ const Index = ({ record }) => { | |||||
| id: 'proofPaymentBody_demandNote3' | 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"); | navigate("/publicNotice"); | ||||
| }} | }} | ||||
| > | > | ||||
| <FormattedMessage id="backToNoticePage" /> | |||||
| </Button> | </Button> | ||||
| </Typography> | </Typography> | ||||
| </Grid> | </Grid> | ||||
| @@ -44,12 +44,12 @@ const Index = ({ record }) => { | |||||
| <Grid container justifyContent="flex-start" alignItems="center" > | <Grid container justifyContent="flex-start" alignItems="center" > | ||||
| <center> | <center> | ||||
| <Grid item xs={12} md={8} > | <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" /> | <FormattedMessage id="proofPaymentHeader_office" /> | ||||
| </Typography> | </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={{ | <div dangerouslySetInnerHTML={{ | ||||
| __html: intl.formatMessage( | __html: intl.formatMessage( | ||||
| { | { | ||||
| @@ -91,7 +91,7 @@ const Index = ({ record }) => { | |||||
| id: 'proofPaymentBody_office5' | 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"); | navigate("/publicNotice"); | ||||
| }} | }} | ||||
| > | > | ||||
| <FormattedMessage id="backToNoticePage" /> | |||||
| </Button> | </Button> | ||||
| </Typography> | </Typography> | ||||
| </Grid> | </Grid> | ||||
| @@ -32,7 +32,9 @@ import { | |||||
| // useEffect, | // useEffect, | ||||
| useState | useState | ||||
| } from "react"; | } 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 { ThemeProvider } from "@emotion/react"; | ||||
| import { FormattedMessage, useIntl } from "react-intl"; | import { FormattedMessage, useIntl } from "react-intl"; | ||||
| // ==============================|| DASHBOARD - DEFAULT ||============================== // | // ==============================|| DASHBOARD - DEFAULT ||============================== // | ||||
| @@ -145,11 +147,11 @@ const Index = () => { | |||||
| <Grid container justifyContent="flex-start" alignItems="center" > | <Grid container justifyContent="flex-start" alignItems="center" > | ||||
| <center> | <center> | ||||
| <Grid item xs={12} md={8} > | <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" /> | <FormattedMessage id="proofPaymentHeader_online" /> | ||||
| </Typography> | </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={{ | <div dangerouslySetInnerHTML={{ | ||||
| __html: intl.formatMessage( | __html: intl.formatMessage( | ||||
| { | { | ||||
| @@ -167,7 +169,7 @@ const Index = () => { | |||||
| id: 'proofPaymentBody_online2' | 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> | ||||
| <Typography variant="h4" sx={{ ml: 8, textAlign: "left" }}> | <Typography variant="h4" sx={{ ml: 8, textAlign: "left" }}> | ||||
| <ThemeProvider theme={PNSPS_LONG_BUTTON_THEME}> | |||||
| <ThemeProvider theme={PNSPS_BUTTON_THEME}> | |||||
| <Button | <Button | ||||
| component="span" | component="span" | ||||
| variant="contained" | 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 }} | sx={{mr: 4 }} | ||||
| onClick={() => { setIsPopUp(true) }} | onClick={() => { setIsPopUp(true) }} | ||||
| > | > | ||||
| @@ -238,7 +241,7 @@ const Index = () => { | |||||
| <DialogContent style={{ display: 'flex', }}> | <DialogContent style={{ display: 'flex', }}> | ||||
| <Stack direction="column" justifyContent="space-between"> | <Stack direction="column" justifyContent="space-between"> | ||||
| <Typography variant="h4"> | <Typography variant="h4"> | ||||
| <FormattedMessage id="totalAmount" /> (HK$): {FormatUtils.currencyFormat(fee)} | |||||
| <FormattedMessage id="totalAmount" /> ($): {FormatUtils.currencyFormat(fee)} | |||||
| </Typography> | </Typography> | ||||
| </Stack> | </Stack> | ||||
| </DialogContent> | </DialogContent> | ||||
| @@ -34,9 +34,11 @@ const ApplicationDetailCard = ({ | |||||
| const [data, setData] = useState({}); | const [data, setData] = useState({}); | ||||
| const [cancelPopUp, setCancelPopUp] = useState(false); | const [cancelPopUp, setCancelPopUp] = useState(false); | ||||
| const [onDownload, setOnDownload] = useState(false); | |||||
| useEffect(() => { | useEffect(() => { | ||||
| if (formData) { | if (formData) { | ||||
| console.log(formData) | |||||
| setData(formData); | setData(formData); | ||||
| } | } | ||||
| }, [formData]); | }, [formData]); | ||||
| @@ -46,26 +48,50 @@ const ApplicationDetailCard = ({ | |||||
| initialValues: data, | 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 = () => { | const confirmCancel = () => { | ||||
| @@ -83,8 +109,15 @@ const ApplicationDetailCard = ({ | |||||
| } | } | ||||
| const genProof = () => { | const genProof = () => { | ||||
| setOnDownload(true) | |||||
| HttpUtils.fileDownload({ | 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" | component="span" | ||||
| variant="contained" | variant="contained" | ||||
| size="large" | size="large" | ||||
| disabled={!showProofBtn} | |||||
| disabled={!showProofBtn||onDownload} | |||||
| onClick={genProof} | onClick={genProof} | ||||
| > | > | ||||
| <Typography variant="h5">Proof Slip</Typography> | <Typography variant="h5">Proof Slip</Typography> | ||||
| @@ -170,10 +203,12 @@ const ApplicationDetailCard = ({ | |||||
| <Grid item xs={12} md={9} lg={9}> | <Grid item xs={12} md={9} lg={9}> | ||||
| <FormControl variant="outlined" fullWidth disabled > | <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> | </FormControl> | ||||
| </Grid> | </Grid> | ||||
| @@ -270,7 +305,7 @@ const ApplicationDetailCard = ({ | |||||
| </Grid> | </Grid> | ||||
| <Grid item xs={12} md={12} lg={12} | <Grid item xs={12} md={12} lg={12} | ||||
| sx={{ display: 'flex', alignItems: 'center' }}> | 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> | ||||
| <Grid item xs={12} md={12} lg={12} sx={{ mb: 4, display: 'flex', alignItems: 'center' }}> | <Grid item xs={12} md={12} lg={12} sx={{ mb: 4, display: 'flex', alignItems: 'center' }}> | ||||
| <Typography variant="h5">Before {DateUtils.datetimeStr(data.proofPaymentDeadline)}</Typography> | <Typography variant="h5">Before {DateUtils.datetimeStr(data.proofPaymentDeadline)}</Typography> | ||||
| @@ -76,7 +76,7 @@ const FormPanel = ({ formData, isOverTime }) => { | |||||
| isOverTime ? | isOverTime ? | ||||
| <Grid container direction="column" sx={{ paddingLeft: 4, paddingRight: 4 }} spacing={1}> | <Grid container direction="column" sx={{ paddingLeft: 4, paddingRight: 4 }} spacing={1}> | ||||
| <Grid item xs={12} md={12} textAlign="left"> | <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> | ||||
| </Grid> | </Grid> | ||||
| : | : | ||||
| @@ -44,10 +44,10 @@ export default function UploadFileTable({recordList, setRecordList,}) { | |||||
| ...rowModesModel, | ...rowModesModel, | ||||
| [id]: { mode: GridRowModes.View, ignoreModifications: true }, | [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)); | setRecordList(rows.filter((row) => row.id !== id)); | ||||
| setRows(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 * as StatusUtils from "utils/statusUtils/PublicNoteStatusUtils"; | ||||
| import FileList from "components/FileList" | import FileList from "components/FileList" | ||||
| import { FormattedMessage, useIntl } from "react-intl"; | import { FormattedMessage, useIntl } from "react-intl"; | ||||
| import { | |||||
| isORGLoggedIn, | |||||
| } from "utils/Utils"; | |||||
| // ==============================|| DASHBOARD - DEFAULT ||============================== // | // ==============================|| DASHBOARD - DEFAULT ||============================== // | ||||
| const ApplicationDetailCard = ({ formData, }) => { | const ApplicationDetailCard = ({ formData, }) => { | ||||
| @@ -175,6 +178,32 @@ const ApplicationDetailCard = ({ formData, }) => { | |||||
| </Grid> | </Grid> | ||||
| </Grid> | </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" | <Grid container direction="row" justifyContent="space-between" | ||||
| alignItems="center"> | alignItems="center"> | ||||
| <Grid item xs={12} md={6} lg={6} sx={{ mb: 1, }}> | <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 item xs={12} sm={12} md={6} lg={6} sx={{ mb: 1 }}> | ||||
| <Grid container alignItems={"center"}> | <Grid container alignItems={"center"}> | ||||
| <Grid item xs={12} sm={12} md={12} lg={12} sx={{ alignItems: 'center', wordBreak: 'break-word' }}> | <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> | ||||
| <Grid item xs={12} sm={12} md={12} lg={12} sx={{ width: '95%', maxWidth: { xs: '70vw', sm: '72vw', md: '75vw', lg: '80vw' } }}> | <Grid item xs={12} sm={12} md={12} lg={12} sx={{ width: '95%', maxWidth: { xs: '70vw', sm: '72vw', md: '75vw', lg: '80vw' } }}> | ||||
| <FileList | <FileList | ||||
| @@ -223,11 +254,14 @@ const ApplicationDetailCard = ({ formData, }) => { | |||||
| /> | /> | ||||
| </Grid> | </Grid> | ||||
| </Grid> | </Grid> | ||||
| </Grid> | </Grid> | ||||
| <Grid item xs={12} md={5} lg={5} sx={{ mb: 1, }}> | <Grid item xs={12} md={5} lg={5} sx={{ mb: 1, }}> | ||||
| <Grid container alignItems={"center"}> | <Grid container alignItems={"center"}> | ||||
| { | |||||
| data.creditor == true ? | |||||
| <> | |||||
| <Grid item xs={12} md={12} lg={12} | <Grid item xs={12} md={12} lg={12} | ||||
| sx={{ display: 'flex', alignItems: 'center' }}> | sx={{ display: 'flex', alignItems: 'center' }}> | ||||
| <Typography variant="h5" display="inline"> | <Typography variant="h5" display="inline"> | ||||
| @@ -240,7 +274,7 @@ const ApplicationDetailCard = ({ formData, }) => { | |||||
| {locale === 'en' ? | {locale === 'en' ? | ||||
| `${intl.formatMessage({ id: 'before' })} ${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", "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> | </Typography> | ||||
| </Grid> | </Grid> | ||||
| @@ -256,15 +290,21 @@ const ApplicationDetailCard = ({ formData, }) => { | |||||
| {locale === 'en' ? | {locale === 'en' ? | ||||
| `${intl.formatMessage({ id: 'before' })} ${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", "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> | </Typography> | ||||
| </Grid> | </Grid> | ||||
| </> | |||||
| : | |||||
| <></> | |||||
| } | |||||
| <Grid item xs={12} sm={3} md={3} lg={3} | <Grid item xs={12} sm={3} md={3} lg={3} | ||||
| sx={{ mb: 1, display: 'flex', alignItems: 'center' }}> | sx={{ mb: 1, display: 'flex', alignItems: 'center' }}> | ||||
| <Typography variant="pnspsFormParagraph"> | |||||
| <FormattedMessage id="payFeeFor" />: | |||||
| <Typography> | |||||
| <Typography variant="pnspsFormParagraph"> | |||||
| <FormattedMessage id="payFeeFor" />: | |||||
| </Typography> | |||||
| </Typography> | </Typography> | ||||
| </Grid> | </Grid> | ||||
| <Grid item xs={12} sm={9} md={9} lg={9} sx={{ mb: 1, display: 'flex', alignItems: 'center' }}> | <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" | 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> | ||||
| </Grid> | </Grid> | ||||
| @@ -49,6 +49,7 @@ const FormPanel = ({ formData }) => { | |||||
| const navigate = useNavigate() | const navigate = useNavigate() | ||||
| const params = useParams(); | const params = useParams(); | ||||
| const dft = locale === 'en' ? "DD MMMM YYYY" : "YYYY年MM月DD日"; | |||||
| const tabelStyle = { | const tabelStyle = { | ||||
| border: "2px solid gray", | border: "2px solid gray", | ||||
| @@ -120,7 +121,7 @@ const FormPanel = ({ formData }) => { | |||||
| }, | }, | ||||
| files: attachments ? attachments : [], | files: attachments ? attachments : [], | ||||
| onSuccess: function (responseData) { | onSuccess: function (responseData) { | ||||
| console.log(responseData) | |||||
| // console.log(responseData) | |||||
| if (responseData.success === false) { | if (responseData.success === false) { | ||||
| navigate("/publicNotice/" + responseData.id); | navigate("/publicNotice/" + responseData.id); | ||||
| } else { | } else { | ||||
| @@ -236,7 +237,7 @@ const FormPanel = ({ formData }) => { | |||||
| <FormattedMessage id="proofReplyDate" /> : | <FormattedMessage id="proofReplyDate" /> : | ||||
| { | { | ||||
| locale === 'en' ? | locale === 'en' ? | ||||
| DateUtils.dateValue(formik.values.replyDate) | |||||
| DateUtils.datetimeStr(formik.values.replyDate) | |||||
| : | : | ||||
| DateUtils.datetimeStr_Cht(formik.values.replyDate) | DateUtils.datetimeStr_Cht(formik.values.replyDate) | ||||
| } | } | ||||
| @@ -319,138 +320,29 @@ const FormPanel = ({ formData }) => { | |||||
| isDummyLoggedIn() ? | isDummyLoggedIn() ? | ||||
| <Grid item xs={12} sx={{ mb: 1, }}> | <Grid item xs={12} sx={{ mb: 1, }}> | ||||
| <table style={tabelStyle}> | <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}> | <tr style={tabelStyle}> | ||||
| <th style={tabelStyle} width="50" align="left"></th> | <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="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="300" align="left"><FormattedMessage id="confirmingDealine" /></th> | ||||
| <th style={tabelStyle} width="400" align="left"><FormattedMessage id="PaymentCoonpletDealine" /></th> | <th style={tabelStyle} width="400" align="left"><FormattedMessage id="PaymentCoonpletDealine" /></th> | ||||
| </tr> | </tr> | ||||
| <tr> | <tr> | ||||
| <td style={tabelStyle}> | <td style={tabelStyle}> | ||||
| <Checkbox | <Checkbox | ||||
| checked={paymentMethod == "online"} | |||||
| checked={paymentMethod == "demandNote"} | |||||
| onChange={() => { | onChange={() => { | ||||
| set_paymentMethod("online") | |||||
| set_paymentMethod("demandNote") | |||||
| }} | }} | ||||
| /> | /> | ||||
| </td> | </td> | ||||
| <td style={tabelStyle}> | <td style={tabelStyle}> | ||||
| <FormattedMessage id="payOnline" /> | |||||
| <FormattedMessage id="paymentMeans" />: <FormattedMessage id="payDn" /> | |||||
| <br /><a href="#payOnlineDetails" color='#fff' onClick={() => { | <br /><a href="#payOnlineDetails" color='#fff' onClick={() => { | ||||
| setWarningTitle(intl.formatMessage({ id: "payOnline" })) | |||||
| setWarningTitle(intl.formatMessage({ id: "paymentMeans" }) + ": " + intl.formatMessage({ id: "payDn" })) | |||||
| setWarningText( | 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> | <ul> | ||||
| <li><FormattedMessage id="atm" /></li> | <li><FormattedMessage id="atm" /></li> | ||||
| <li><FormattedMessage id="pps" /></li> | <li><FormattedMessage id="pps" /></li> | ||||
| @@ -462,64 +354,206 @@ const FormPanel = ({ formData }) => { | |||||
| <li><FormattedMessage id="store" /></li> | <li><FormattedMessage id="store" /></li> | ||||
| <li><FormattedMessage id="post" /></li> | <li><FormattedMessage id="post" /></li> | ||||
| </ul> | </ul> | ||||
| <Typography variant="h6"> | |||||
| <div style={{ padding: 12 }} dangerouslySetInnerHTML={{ __html: intl.formatMessage({ id: "proofNote" }) }} /> | |||||
| </Typography> | |||||
| </> | </> | ||||
| ); | ); | ||||
| setIsWarningPopUp(true); | setIsWarningPopUp(true); | ||||
| }}><FormattedMessage id="viewDetail" /></a> | |||||
| }}><u><FormattedMessage id="viewDetail" /></u></a> | |||||
| </td> | </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}>{DateUtils.dateFormat(formData.closingDateOff, intl.formatMessage({ id: "dateStrFormat" }))} 5:00 p.m.</td> | ||||
| <td style={tabelStyle}> | <td style={tabelStyle}> | ||||
| <FormattedMessage id="payDnRemark" values={{ | <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> | </td> | ||||
| </tr> | </tr> | ||||
| <tr> | <tr> | ||||
| <td style={tabelStyle}> | <td style={tabelStyle}> | ||||
| { | |||||
| isOverNpgoReviseDeadline() ? | |||||
| <></> : | |||||
| <Checkbox | |||||
| checked={paymentMethod == "office"} | |||||
| onChange={() => { | |||||
| set_paymentMethod("office") | |||||
| }} | |||||
| /> | |||||
| } | |||||
| <Checkbox | |||||
| checked={paymentMethod == "office"} | |||||
| onChange={() => { | |||||
| set_paymentMethod("office") | |||||
| }} | |||||
| /> | |||||
| </td> | </td> | ||||
| <td style={tabelStyle}> | <td style={tabelStyle}> | ||||
| <FormattedMessage id="payNPGO" /> | <FormattedMessage id="payNPGO" /> | ||||
| <br /><a href="#payOnlineDetails" color='#fff' onClick={() => { | <br /><a href="#payOnlineDetails" color='#fff' onClick={() => { | ||||
| setWarningTitle(intl.formatMessage({ id: "payNPGO" })) | |||||
| setWarningTitle(intl.formatMessage({ id: "paymentMeans" }) + ": " + intl.formatMessage({ id: "payNPGOPopUpTitle" })) | |||||
| setWarningText( | setWarningText( | ||||
| <><FormattedMessage id="paymentMethodMeans" /> | |||||
| <><FormattedMessage id="paymentMethodMeans" />: | |||||
| <ul> | <ul> | ||||
| <li><FormattedMessage id="cheque" /></li> | <li><FormattedMessage id="cheque" /></li> | ||||
| <li><FormattedMessage id="drafts" /></li> | |||||
| <li><FormattedMessage id="cashierOrders" /></li> | |||||
| <li><FormattedMessage id="cash" /></li> | <li><FormattedMessage id="cash" /></li> | ||||
| </ul> | </ul> | ||||
| </> | </> | ||||
| ); | ); | ||||
| setIsWarningPopUp(true); | setIsWarningPopUp(true); | ||||
| }}><FormattedMessage id="viewDetail" /></a> | |||||
| }}><u><FormattedMessage id="viewDetail" /></u></a> | |||||
| </td> | </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}>{DateUtils.dateFormat(formData.closingDate, intl.formatMessage({ id: "dateStrFormat" }))} 12:00 p.m.</td> | ||||
| <td style={tabelStyle}> | <td style={tabelStyle}> | ||||
| <FormattedMessage id="payNPGORemark" values={{ | <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> | </td> | ||||
| </tr> | </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> | </table> | ||||
| </Grid> | </Grid> | ||||
| <Grid item xs={12}> | |||||
| {/* <Grid item xs={12}> | |||||
| <Typography variant="h6" height="100%" > | <Typography variant="h6" height="100%" > | ||||
| <div style={{ padding: 12 }} dangerouslySetInnerHTML={{ __html: intl.formatMessage({ id: "proofNote" }) }} /> | <div style={{ padding: 12 }} dangerouslySetInnerHTML={{ __html: intl.formatMessage({ id: "proofNote" }) }} /> | ||||
| </Typography> | </Typography> | ||||
| </Grid> | |||||
| </Grid> */} | |||||
| <Grid item xs={12}> | <Grid item xs={12}> | ||||
| <Typography variant="h6" height="100%" > | <Typography variant="h6" height="100%" > | ||||
| @@ -662,10 +696,10 @@ const FormPanel = ({ formData }) => { | |||||
| </DialogContent> | </DialogContent> | ||||
| <DialogActions> | <DialogActions> | ||||
| <Button | <Button | ||||
| aria-label={intl.formatMessage({ id: 'ok' })} | |||||
| aria-label={intl.formatMessage({ id: 'close' })} | |||||
| onClick={() => setIsWarningPopUp(false)} | onClick={() => setIsWarningPopUp(false)} | ||||
| > | > | ||||
| OK | |||||
| <FormattedMessage id="close" /> | |||||
| </Button> | </Button> | ||||
| </DialogActions> | </DialogActions> | ||||
| </Dialog> | </Dialog> | ||||
| @@ -46,10 +46,10 @@ export default function UploadFileTable({recordList, setRecordList,}) { | |||||
| ...rowModesModel, | ...rowModesModel, | ||||
| [id]: { mode: GridRowModes.View, ignoreModifications: true }, | [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)); | setRecordList(rows.filter((row) => row.id !== id)); | ||||
| setRows(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'; | import { clickableLink } from 'utils/CommonFunction'; | ||||
| // ==============================|| EVENT TABLE ||============================== // | // ==============================|| EVENT TABLE ||============================== // | ||||
| export default function SearchPublicNoticeTable({searchCriteria}) { | |||||
| export default function SearchPublicNoticeTable({searchCriteria, applyGridOnReady,applySearch}) { | |||||
| const navigate = useNavigate() | const navigate = useNavigate() | ||||
| const [_searchCriteria, set_searchCriteria] = React.useState({}); | |||||
| const [_searchCriteria, set_searchCriteria] = React.useState({searchCriteria}); | |||||
| React.useEffect(() => { | React.useEffect(() => { | ||||
| set_searchCriteria(searchCriteria); | set_searchCriteria(searchCriteria); | ||||
| @@ -83,6 +83,9 @@ export default function SearchPublicNoticeTable({searchCriteria}) { | |||||
| renderCell: (params) => { | renderCell: (params) => { | ||||
| let company = params.row.enCompanyName != null?params.row.enCompanyName: params.row.chCompanyName; | let company = params.row.enCompanyName != null?params.row.enCompanyName: params.row.chCompanyName; | ||||
| company = company != null ? company : ""; | company = company != null ? company : ""; | ||||
| if (company == "GLD"){ | |||||
| company = company + ": " + params.row.appCustName | |||||
| } | |||||
| return (<> | return (<> | ||||
| {params?.value}<br />{company} | {params?.value}<br />{company} | ||||
| </>); | </>); | ||||
| @@ -119,12 +122,18 @@ export default function SearchPublicNoticeTable({searchCriteria}) { | |||||
| <FiDataGrid | <FiDataGrid | ||||
| columns={columns} | columns={columns} | ||||
| customPageSize={10} | customPageSize={10} | ||||
| onRowDoubleClick={handleRowDoubleClick} | |||||
| getRowHeight={() => 'auto'} | getRowHeight={() => 'auto'} | ||||
| doLoad={{ | |||||
| onRowDoubleClick={handleRowDoubleClick} | |||||
| applyGridOnReady={applyGridOnReady} | |||||
| applySearch = {applySearch} | |||||
| // doLoad={{ | |||||
| // url: LIST_PROOF, | |||||
| // params: _searchCriteria, | |||||
| // }} | |||||
| doLoad={React.useMemo(() => ({ | |||||
| url: LIST_PROOF, | url: LIST_PROOF, | ||||
| params: _searchCriteria, | params: _searchCriteria, | ||||
| }} | |||||
| }), [_searchCriteria])} | |||||
| /> | /> | ||||
| </div> | </div> | ||||
| ); | ); | ||||
| @@ -21,22 +21,34 @@ import {DemoItem} from "@mui/x-date-pickers/internals/demo"; | |||||
| import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider"; | import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider"; | ||||
| import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs"; | import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs"; | ||||
| // ==============================|| DASHBOARD - DEFAULT ||============================== // | // ==============================|| DASHBOARD - DEFAULT ||============================== // | ||||
| const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, issueComboData | |||||
| const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, issueComboData, onGridReady | |||||
| }) => { | }) => { | ||||
| const [type, setType] = React.useState([]); | 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 [orgSelected, setOrgSelected] = React.useState({}); | ||||
| const [orgCombo, setOrgCombo] = React.useState(); | const [orgCombo, setOrgCombo] = React.useState(); | ||||
| const [issueSelected, setIssueSelected] = React.useState({}); | const [issueSelected, setIssueSelected] = React.useState({}); | ||||
| const [issueCombo, setIssueCombo] = 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 [minDate, setMinDate] = React.useState(searchCriteria.dateFrom); | ||||
| const [maxDate, setMaxDate] = React.useState(searchCriteria.dateTo); | const [maxDate, setMaxDate] = React.useState(searchCriteria.dateTo); | ||||
| const [fromDateValue, setFromDateValue] = React.useState("dd / mm / yyyy"); | const [fromDateValue, setFromDateValue] = React.useState("dd / mm / yyyy"); | ||||
| const [toDateValue, setToDateValue] = 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(() => { | React.useEffect(() => { | ||||
| setFromDateValue(minDate); | setFromDateValue(minDate); | ||||
| }, [minDate]); | }, [minDate]); | ||||
| @@ -68,26 +80,56 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss | |||||
| refNo: data.refNo, | refNo: data.refNo, | ||||
| code: data.code, | code: data.code, | ||||
| issueId: issueSelected?.id, | issueId: issueSelected?.id, | ||||
| gazettGroup: groupSelected?.type, | |||||
| gazettGroup: groupSelected?.code, | |||||
| dateFrom: sentDateFrom, | dateFrom: sentDateFrom, | ||||
| dateTo: sentDateTo, | dateTo: sentDateTo, | ||||
| contact: data.contact, | contact: data.contact, | ||||
| replyed: (status?.type && status?.type != 'all') ? status?.type : "", | |||||
| orgId: (orgSelected?.key && orgSelected?.key > 0) ? orgSelected?.key : "", | 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); | applySearch(temp); | ||||
| }; | }; | ||||
| React.useEffect(() => { | React.useEffect(() => { | ||||
| if (orgComboData && orgComboData.length > 0) { | if (orgComboData && orgComboData.length > 0) { | ||||
| setOrgCombo(orgComboData); | setOrgCombo(orgComboData); | ||||
| if(searchCriteria.orgId!=undefined){ | |||||
| setOrgSelected(orgComboData.find(item => item.key === searchCriteria.orgId)) | |||||
| } | |||||
| } | } | ||||
| }, [orgComboData]); | }, [orgComboData]); | ||||
| React.useEffect(() => { | React.useEffect(() => { | ||||
| if (issueComboData && issueComboData.length > 0) { | if (issueComboData && issueComboData.length > 0) { | ||||
| setIssueCombo(issueComboData); | setIssueCombo(issueComboData); | ||||
| if(searchCriteria.issueId!=undefined){ | |||||
| setIssueSelected(issueComboData.find(item => item.id === searchCriteria.issueId)) | |||||
| } | |||||
| } | } | ||||
| }, [issueComboData]); | }, [issueComboData]); | ||||
| @@ -99,7 +141,12 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss | |||||
| setGroupSelected({}); | setGroupSelected({}); | ||||
| setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14))) | setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14))) | ||||
| setMaxDate(DateUtils.dateValue(new Date())) | setMaxDate(DateUtils.dateValue(new Date())) | ||||
| reset(); | |||||
| reset({ | |||||
| refNo:"", | |||||
| code:"", | |||||
| contact:"" | |||||
| }); | |||||
| localStorage.setItem('searchCriteria',"") | |||||
| } | } | ||||
| function getIssueLabel(data) { | function getIssueLabel(data) { | ||||
| @@ -185,6 +232,11 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss | |||||
| onChange={(event, newValue) => { | onChange={(event, newValue) => { | ||||
| setIssueSelected(newValue); | setIssueSelected(newValue); | ||||
| }} | }} | ||||
| sx={{ | |||||
| '& .MuiInputBase-root': { alignItems: 'center' }, | |||||
| '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, | |||||
| '& .MuiOutlinedInput-root': { height: 40 } | |||||
| }} | |||||
| renderInput={(params) => ( | renderInput={(params) => ( | ||||
| <TextField {...params} | <TextField {...params} | ||||
| label="Gazette Issue No." | label="Gazette Issue No." | ||||
| @@ -209,6 +261,11 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss | |||||
| onChange={(event, newValue) => { | onChange={(event, newValue) => { | ||||
| setGroupSelected(newValue); | setGroupSelected(newValue); | ||||
| }} | }} | ||||
| sx={{ | |||||
| '& .MuiInputBase-root': { alignItems: 'center' }, | |||||
| '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, | |||||
| '& .MuiOutlinedInput-root': { height: 40 } | |||||
| }} | |||||
| renderInput={(params) => ( | renderInput={(params) => ( | ||||
| <TextField {...params} | <TextField {...params} | ||||
| label="Gazette Group" | label="Gazette Group" | ||||
| @@ -299,14 +356,20 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss | |||||
| id="status" | id="status" | ||||
| size="small" | size="small" | ||||
| filterOptions={(options) => options} | filterOptions={(options) => options} | ||||
| options={ComboData.proofStatus} | |||||
| options={ComboData.proofStatus_GLD} | |||||
| value={status} | 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) => { | onChange={(event, newValue) => { | ||||
| if (newValue !== null) { | if (newValue !== null) { | ||||
| setStatus(newValue); | setStatus(newValue); | ||||
| } | } | ||||
| }} | }} | ||||
| sx={{ | |||||
| '& .MuiInputBase-root': { alignItems: 'center' }, | |||||
| '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, | |||||
| '& .MuiOutlinedInput-root': { height: 40 } | |||||
| }} | |||||
| renderInput={(params) => ( | renderInput={(params) => ( | ||||
| <TextField {...params} | <TextField {...params} | ||||
| label="Status" | label="Status" | ||||
| @@ -323,13 +386,15 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss | |||||
| <Grid item xs={9} s={6} md={5} lg={3} sx={{ ml: 3, mr: 3, mb: 3 }}> | <Grid item xs={9} s={6} md={5} lg={3} sx={{ ml: 3, mr: 3, mb: 3 }}> | ||||
| <Autocomplete | <Autocomplete | ||||
| {...register("orgId")} | {...register("orgId")} | ||||
| disablePortal={false} | |||||
| disablePortal | |||||
| id="orgId" | id="orgId" | ||||
| size="small" | |||||
| options={orgCombo} | options={orgCombo} | ||||
| groupBy={(option) => option.groupType} | |||||
| size="small" | |||||
| value={orgSelected} | value={orgSelected} | ||||
| getOptionLabel={(option) => option.name? option.name : ""} | getOptionLabel={(option) => option.name? option.name : ""} | ||||
| inputValue={orgSelected ? orgSelected.name : ""} | |||||
| inputValue={orgSelected ? orgSelected.name!=undefined?orgSelected.name:"" : ""} | |||||
| onChange={(event, newValue) => { | onChange={(event, newValue) => { | ||||
| if (newValue !== null) { | if (newValue !== null) { | ||||
| setOrgSelected(newValue); | setOrgSelected(newValue); | ||||
| @@ -337,6 +402,11 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss | |||||
| setOrgSelected({}); | setOrgSelected({}); | ||||
| } | } | ||||
| }} | }} | ||||
| sx={{ | |||||
| '& .MuiInputBase-root': { alignItems: 'center' }, | |||||
| '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, | |||||
| '& .MuiOutlinedInput-root': { height: 40 } | |||||
| }} | |||||
| renderInput={(params) => ( | renderInput={(params) => ( | ||||
| <TextField {...params} | <TextField {...params} | ||||
| label="Organisation" | label="Organisation" | ||||
| @@ -345,6 +415,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> | </Grid> | ||||
| : <></> | : <></> | ||||
| @@ -371,7 +449,8 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss | |||||
| <Button | <Button | ||||
| variant="contained" | variant="contained" | ||||
| type="submit" | type="submit" | ||||
| > | |||||
| disabled={onGridReady} | |||||
| > | |||||
| Submit | Submit | ||||
| </Button> | </Button> | ||||
| </Grid> | </Grid> | ||||