Сравнить коммиты

...

26 коммитов
master ... uat

Автор SHA1 Сообщение Дата
  Jason Chuang cd5f649833 font update 4 часов назад
  Jason Chuang 91a381eefc Merge branch 'cr022024' into uat 11 часов назад
  Jason Chuang c1d73566e4 Merge branch 'web-access-fix-2' into uat 11 часов назад
  Jason Chuang 991959003a change blue color 12 часов назад
  Jason Chuang 6202ecb2fc update style 3 дней назад
  Jason Chuang 7bb16a64f4 update span 3 дней назад
  Jason Chuang c9a33ef0d8 update header as span 3 дней назад
  Jason Chuang c8d3708c91 update FPS refresh error message 5 дней назад
  Jason Chuang a684f4cb6f payment description in receipt 5 дней назад
  Jason Chuang c118bfbde9 fix to payment desc for private bill 5 дней назад
  Jason Chuang 02f6c6222f fix to address length check 5 дней назад
  Jason Chuang 55178dffe1 various changes 5 дней назад
  Jason Chuang d9ce1032d5 Merge branch 'web-access-fix-2' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into web-access-fix-2 5 дней назад
  Jason Chuang 7f222cf577 various changes 5 дней назад
  Jason Chuang ce05043496 fix label 6 дней назад
  Jason Chuang 4f2cc3469b various update 6 дней назад
  Jason Chuang 1376d65ad4 register form - upload file and tabindex fix 6 дней назад
  Jason Chuang ad367709fd CR-024 Item 3 2 недель назад
  Jason Chuang d1d844b633 CR-024 Item 1 2 недель назад
  Jason Chuang b0ee1b0714 CR-022 Item 7 2 недель назад
  Jason Chuang f447cb1dae CR-022 Item 5 2 недель назад
  Jason Chuang 7b7a913398 CR-022 Item 3 2 недель назад
  Jason Chuang c5a1153aa7 CR-022 Item 2 2 недель назад
  Jason Chuang cdb9062c90 CR-022 Item 2 2 недель назад
  Jason Chuang 4214676dcf CR-022 Item 1 2 недель назад
  Jason Chuang b7b7a9c246 header h4 to h3 2 недель назад
100 измененных файлов: 1382 добавлений и 870 удалений
  1. +1
    -1
      public/favicon.svg
  2. +41
    -0
      public/index.html
  3. Двоичные данные
      public/public-sans-latin-400-normal.woff2
  4. Двоичные данные
      public/public-sans-latin-500-normal.woff2
  5. Двоичные данные
      public/public-sans-latin-600-normal.woff2
  6. Двоичные данные
      public/public-sans-latin-700-normal.woff2
  7. +14
    -13
      src/assets/fonts.css
  8. +9
    -9
      src/assets/style/navbarStyles.css
  9. +4
    -4
      src/assets/style/styles.css
  10. +2
    -2
      src/components/AdminLogo/index.js
  11. +27
    -0
      src/components/FileDeleteButton.js
  12. +8
    -22
      src/components/FileList.js
  13. +1
    -1
      src/components/MobileLogo/index.js
  14. +55
    -0
      src/components/RegisterStepIcon.js
  15. +1
    -1
      src/components/iAmSmartButton.js
  16. +4
    -1
      src/index.js
  17. +3
    -1
      src/layout/MainLayout/Header/HeaderContent/LocaleSelector.js
  18. +1
    -1
      src/layout/MainLayout/Header/HeaderContent/Notification.js
  19. +23
    -9
      src/layout/MainLayout/Header/index.js
  20. +1
    -1
      src/layout/MainLayout/index.js
  21. +1
    -1
      src/pages/Announcement/Search/index.js
  22. +1
    -1
      src/pages/Announcement/Search_Public/index.js
  23. +1
    -1
      src/pages/AuditLog/index.js
  24. +1
    -1
      src/pages/DemandNote/Create/index.js
  25. +1
    -1
      src/pages/DemandNote/Export/index.js
  26. +2
    -0
      src/pages/DemandNote/Search/DataGrid.js
  27. +1
    -1
      src/pages/DemandNote/Search/index.js
  28. +1
    -1
      src/pages/GFMIS/index.js
  29. +1
    -1
      src/pages/JVM/index.js
  30. +4
    -3
      src/pages/Message/Details/index.js
  31. +1
    -1
      src/pages/Organization/SearchPage/index.js
  32. +2
    -1
      src/pages/Payment/Details_GLD/DataGrid.js
  33. +67
    -7
      src/pages/Payment/Details_GLD/PaymentDetails.js
  34. +42
    -7
      src/pages/Payment/Details_GLD/index.js
  35. +2
    -1
      src/pages/Payment/Details_Public/DataGrid.js
  36. +2
    -3
      src/pages/Payment/Details_Public/index.js
  37. +2
    -3
      src/pages/Payment/FPS/AckPage.js
  38. +8
    -2
      src/pages/Payment/FPS/FPS.js
  39. +2
    -2
      src/pages/Payment/FPS/fpscallback.js
  40. +3
    -2
      src/pages/Payment/MultiPaymentWindow.js
  41. +2
    -4
      src/pages/Payment/PaymentCallback.js
  42. +8
    -2
      src/pages/Payment/Search_GLD/DataGrid.js
  43. +1
    -1
      src/pages/Payment/Search_GLD/index.js
  44. +14
    -0
      src/pages/Payment/Search_Public/DataGrid.js
  45. +4
    -3
      src/pages/Payment/index.js
  46. +5
    -41
      src/pages/Proof/Create_FromApp/UploadFileTable.js
  47. +1
    -1
      src/pages/Proof/Create_FromApp/index.js
  48. +56
    -31
      src/pages/Proof/Payment/Pay_Online.js
  49. +1
    -1
      src/pages/Proof/Reply_GLD/ApplicationDetails.js
  50. +4
    -23
      src/pages/Proof/Reply_GLD/UploadFileTable.js
  51. +7
    -7
      src/pages/Proof/Reply_Public/ApplicationDetails.js
  52. +17
    -16
      src/pages/Proof/Reply_Public/ProofForm.js
  53. +4
    -23
      src/pages/Proof/Reply_Public/UploadFileTable.js
  54. +1
    -1
      src/pages/Proof/Search_GLD/index.js
  55. +7
    -5
      src/pages/PublicNotice/ApplyForm/PublicNoticeApplyForm.js
  56. +2
    -2
      src/pages/PublicNotice/Details_GLD/ApplicationDetailCard.js
  57. +17
    -12
      src/pages/PublicNotice/Details_Public/ApplicationDetailCard.js
  58. +2
    -1
      src/pages/PublicNotice/Details_Public/index.js
  59. +2
    -1
      src/pages/PublicNotice/ListPanel/BaseGrid.js
  60. +6
    -5
      src/pages/PublicNotice/ListPanel/PendingPaymentTab.js
  61. +2
    -0
      src/pages/PublicNotice/ListPanel/SearchPublicNoticeTable.js
  62. +1
    -1
      src/pages/PublicNotice/Search_GLD/index.js
  63. +1
    -1
      src/pages/PublicNotice/Search_Mark_As_Paid_GLD/index.js
  64. +1
    -1
      src/pages/Recon/index.js
  65. +1
    -1
      src/pages/Report/FullList/index.js
  66. +1
    -1
      src/pages/Report/Summary/index.js
  67. +3
    -0
      src/pages/Setting/DrImport/index.js
  68. +101
    -0
      src/pages/Setting/HkidKeyMigration/index.js
  69. +133
    -0
      src/pages/Setting/UserPiiEncryption/index.js
  70. +10
    -10
      src/pages/User/ChangePasswordPage/index.js
  71. +1
    -1
      src/pages/User/DetailPage/index.js
  72. +23
    -6
      src/pages/User/DetailsPage_Individual/UserInformationCard_Individual.js
  73. +5
    -86
      src/pages/User/DetailsPage_Individual/UserInformationCard_Individual_Pub.js
  74. +21
    -14
      src/pages/User/ManagePage_OrgPublic/index.js
  75. +1
    -1
      src/pages/User/SearchPage/index.js
  76. +1
    -1
      src/pages/User/SearchPage_Individual/index.js
  77. +1
    -1
      src/pages/User/SearchPage_Organization/index.js
  78. +30
    -72
      src/pages/authentication/BusRegister.js
  79. +4
    -4
      src/pages/authentication/ForgotPassword/ForgotPasswordApplyForm.js
  80. +4
    -4
      src/pages/authentication/ForgotUsername/ForgotUsernameApplyForm.js
  81. +29
    -55
      src/pages/authentication/IAmSmartRegister.js
  82. +29
    -71
      src/pages/authentication/Register.js
  83. +11
    -11
      src/pages/authentication/RegisterCustom.js
  84. +2
    -2
      src/pages/authentication/auth-forms/AuthLoginCustom.js
  85. +64
    -29
      src/pages/authentication/auth-forms/BusCustomFormWizard.js
  86. +64
    -26
      src/pages/authentication/auth-forms/CustomFormWizard.js
  87. +98
    -66
      src/pages/authentication/auth-forms/IAmSmartFormWizard.js
  88. +56
    -84
      src/pages/authentication/auth-forms/UploadFileTable.js
  89. +1
    -1
      src/pages/components-overview/Color.js
  90. +1
    -1
      src/pages/dashboard/GLD/index.js
  91. +9
    -3
      src/pages/dashboard/Public/Notice.js
  92. +24
    -11
      src/pages/dashboard/Public/index.js
  93. +1
    -1
      src/pages/extra-pages/UserMenuPub1/index.js
  94. +1
    -1
      src/pages/pnspsUserGroupDetailPage/index.js
  95. +1
    -1
      src/pages/pnspsUserGroupSearchPage/index.js
  96. +14
    -0
      src/routes/GLDUserRoutes.js
  97. +48
    -7
      src/themes/buttonConst.js
  98. +48
    -3
      src/themes/colorConst.js
  99. +18
    -6
      src/themes/overrides/Button.js
  100. +17
    -0
      src/themes/overrides/Checkbox.js

+ 1
- 1
public/favicon.svg Просмотреть файл

@@ -2,7 +2,7 @@
<path d="M1.63954 13.3644L3.95187 11.052L3.95428 11.0496H8.30453L6.5736 12.7806L6.12669 13.2275L4.35415 15L4.57368 15.2201L14.5039 25.1498L24.6537 15L22.8805 13.2275L22.7557 13.102L20.7033 11.0496H25.0535L25.0559 11.052L26.8683 12.8644L29.0039 15L14.5039 29.5L0.00390625 15L1.63954 13.3644ZM14.5039 0.5L22.8823 8.87842H18.5321L14.5039 4.85024L10.4757 8.87842H6.12548L14.5039 0.5Z" fill="#096DD9"/>
<path d="M4.35477 15.0002L6.12731 13.2276L6.57422 12.7807L4.84389 11.0498H3.9549L3.95249 11.0522L1.64016 13.3645L3.85961 15.5731L4.35477 15.0002Z" fill="url(#paint0_linear_112102_1824)"/>
<path d="M22.8814 13.2276L24.6545 15.0002L24.479 15.1757L24.4796 15.1763L26.8691 12.8646L25.0568 11.0522L25.0544 11.0498H24.8783L22.7565 13.1022L22.8814 13.2276Z" fill="url(#paint1_linear_112102_1824)"/>
<path d="M3.9497 11.0498L3.95211 11.0522L6.12693 13.2276L14.5041 21.6043L25.0586 11.0498H3.9497Z" fill="#1890FF"/>
<path d="M3.9497 11.0498L3.95211 11.0522L6.12693 13.2276L14.5041 21.6043L25.0586 11.0498H3.9497Z" fill="#0C489E"/>
<defs>
<linearGradient id="paint0_linear_112102_1824" x1="5.62978" y1="11.5889" x2="2.57161" y2="14.6471" gradientUnits="userSpaceOnUse">
<stop stop-color="#023B95"/>


+ 41
- 0
public/index.html Просмотреть файл

@@ -2,6 +2,47 @@
<html lang="en">
<head>
<meta charset="utf-8" />
<!-- Preload critical Public Sans webfont files and declare @font-face so the browser
uses the custom font immediately on page render, eliminating the flash of the
default/fallback font (FOIT/FOUT). -->
<link rel="preload" as="font" href="%PUBLIC_URL%/public-sans-latin-400-normal.woff2" type="font/woff2" crossorigin="anonymous" />
<link rel="preload" as="font" href="%PUBLIC_URL%/public-sans-latin-500-normal.woff2" type="font/woff2" crossorigin="anonymous" />
<link rel="preload" as="font" href="%PUBLIC_URL%/public-sans-latin-600-normal.woff2" type="font/woff2" crossorigin="anonymous" />
<link rel="preload" as="font" href="%PUBLIC_URL%/public-sans-latin-700-normal.woff2" type="font/woff2" crossorigin="anonymous" />
<style>
@font-face {
font-family: 'Public Sans';
font-style: normal;
font-display: swap;
font-weight: 400;
src: url(%PUBLIC_URL%/public-sans-latin-400-normal.woff2) format('woff2');
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
font-family: 'Public Sans';
font-style: normal;
font-display: swap;
font-weight: 500;
src: url(%PUBLIC_URL%/public-sans-latin-500-normal.woff2) format('woff2');
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
font-family: 'Public Sans';
font-style: normal;
font-display: swap;
font-weight: 600;
src: url(%PUBLIC_URL%/public-sans-latin-600-normal.woff2) format('woff2');
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
font-family: 'Public Sans';
font-style: normal;
font-display: swap;
font-weight: 700;
src: url(%PUBLIC_URL%/public-sans-latin-700-normal.woff2) format('woff2');
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
</style>
<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">


Двоичные данные
public/public-sans-latin-400-normal.woff2 Просмотреть файл


Двоичные данные
public/public-sans-latin-500-normal.woff2 Просмотреть файл


Двоичные данные
public/public-sans-latin-600-normal.woff2 Просмотреть файл


Двоичные данные
public/public-sans-latin-700-normal.woff2 Просмотреть файл


+ 14
- 13
src/assets/fonts.css Просмотреть файл

@@ -1,19 +1,20 @@
/* Self-hosted fonts (bundled via @fontsource; no Google Fonts CDN — CSP-friendly). */
/* All @fontsource v5 packages already use font-display: swap by default. */

/* Public Sans — MUI theme (`themeConst.js`), charts, config */
@import "@fontsource/public-sans/400.css";
@import "@fontsource/public-sans/500.css";
@import "@fontsource/public-sans/600.css";
@import "@fontsource/public-sans/700.css";
@import url("@fontsource/public-sans/400.css");
@import url("@fontsource/public-sans/500.css");
@import url("@fontsource/public-sans/600.css");
@import url("@fontsource/public-sans/700.css");

/* Noto Sans HK — `styles.css` / navbar (Latin + Hong Kong glyphs) */
@import "@fontsource/noto-sans-hk/latin-400.css";
@import "@fontsource/noto-sans-hk/chinese-hongkong-400.css";
@import "@fontsource/noto-sans-hk/latin-600.css";
@import "@fontsource/noto-sans-hk/chinese-hongkong-600.css";
/* Noto Sans HK — navbar (Latin + Hong Kong glyphs) */
@import url("@fontsource/noto-sans-hk/latin-400.css");
@import url("@fontsource/noto-sans-hk/chinese-hongkong-400.css");
@import url("@fontsource/noto-sans-hk/latin-600.css");
@import url("@fontsource/noto-sans-hk/chinese-hongkong-600.css");

/* Noto Sans SC — fallback for simplified Chinese */
@import "@fontsource/noto-sans-sc/latin-400.css";
@import "@fontsource/noto-sans-sc/chinese-simplified-400.css";
@import "@fontsource/noto-sans-sc/latin-600.css";
@import "@fontsource/noto-sans-sc/chinese-simplified-600.css";
@import url("@fontsource/noto-sans-sc/latin-400.css");
@import url("@fontsource/noto-sans-sc/chinese-simplified-400.css");
@import url("@fontsource/noto-sans-sc/latin-600.css");
@import url("@fontsource/noto-sans-sc/chinese-simplified-600.css");

+ 9
- 9
src/assets/style/navbarStyles.css Просмотреть файл

@@ -11,7 +11,7 @@
top: 0px;
width: 100%;
z-index: 9999;
border-bottom: 3px solid #0C489E;
border-bottom: 3px solid #0c489e;
min-height: 77px;
}

@@ -112,7 +112,7 @@

#navbar div li a:hover,
#navbar div li button.navTrigger:hover{
color: #0C489E;
color: #1565C0;
}

#navbar div li a:hover::after,
@@ -122,7 +122,7 @@
content: "";
width: 80%;
height: 3px;
background:#0C489E;
background:#1565C0;
position: absolute;
bottom: -5px;
left: 20px;
@@ -166,7 +166,7 @@

#navbar a:focus-visible,
#navbar button.navTrigger:focus-visible{
outline: 3px solid #0C489E;
outline: 3px solid #0c489e;
outline-offset: 2px;
border-radius: 10px;
}
@@ -234,7 +234,7 @@
text-decoration: none;
font-size: 1.1rem;
font-weight: 600;
color: #0C489E;
color: #0c489e;
transition: 0.3s ease-in-out;
text-align: center;
}
@@ -242,7 +242,7 @@
text-decoration: none;
font-size: 1.1rem;
font-weight: 600;
color: #0C489E;
color: #0c489e;
transition: 0.3s ease-in-out;
text-align: center;
}
@@ -284,7 +284,7 @@
transition: 0.3s ease-in-out;
}
#sidebar li a:hover{
color: #0C489E;
color: #0c489e;
}
#sidebar div li ul{
background: white;
@@ -344,12 +344,12 @@
/* Hover / focus */
#sidebar li > a:hover,
#sidebar li > button.navTrigger:hover{
color: #0C489E;
color: #0c489e;
}

#sidebar li > a:focus-visible,
#sidebar li > button.navTrigger:focus-visible{
outline: 3px solid #0C489E;
outline: 3px solid #0c489e;
outline-offset: 2px;
border-radius: 10px;
}


+ 4
- 4
src/assets/style/styles.css Просмотреть файл

@@ -72,7 +72,7 @@ a:active {
[role="link"],
[tabindex]:not([tabindex="-1"])
):focus-visible {
outline: 3px solid #0C489E;
outline: 3px solid #0c489e;
outline-offset: 2px;
border-radius: 4px;
}
@@ -95,9 +95,9 @@ a:active {
/* ===== MUI DataGrid keyboard focus (WCAG 2.4.7 / 2.4.11) ===== */
.MuiDataGrid-columnHeader:focus-visible,
.MuiDataGrid-cell:focus-visible {
outline: 3px solid #0C489E;
outline: 3px solid #0c489e;
outline-offset: -2px;
box-shadow: 0 0 0 3px rgba(12, 72, 158, 0.25);
box-shadow: 0 0 0 3px rgba(25, 118, 210, 0.25);
}

/* Contained buttons only */
@@ -122,7 +122,7 @@ a:active {

/* ===== Outlined button focus ===== */
.MuiButton-outlined:focus-visible {
outline: 3px solid #0C489E;
outline: 3px solid #0c489e;
outline-offset: 2px;
}



+ 2
- 2
src/components/AdminLogo/index.js Просмотреть файл

@@ -34,7 +34,7 @@ const LogoSection = ({ sx, to }) => {
...sx,
/* ✅ WCAG 2.4.7 focus indicator */
'&:focus-visible': {
outline: '3px solid #0C489E',
outline: '3px solid #0c489e',
outlineOffset: '2px',
borderRadius: '6px'
}
@@ -42,7 +42,7 @@ const LogoSection = ({ sx, to }) => {
>
<Stack direction="column" justifyContent="center" alignItems="center" >
<Logo />
<span style={{ color: checkSysEnv()!=''?'red':'#0C489E'}} id="systemTitle">PNSPS</span>
<span style={{ color: checkSysEnv()!=''?'red':'#0c489e'}} id="systemTitle">PNSPS</span>
</Stack>
</ButtonBase>



+ 27
- 0
src/components/FileDeleteButton.js Просмотреть файл

@@ -0,0 +1,27 @@
import RemoveCircleOutlineIcon from '@mui/icons-material/RemoveCircleOutline';
import { IconButton } from '@mui/material';
import { useIntl } from 'react-intl';
import { handleActionKeyDown } from 'utils/CommonFunction';

export default function FileDeleteButton({ onDelete, icon: IconComponent = RemoveCircleOutlineIcon, color = 'error' }) {
const intl = useIntl();
const label = intl.formatMessage({ id: 'ariaDeleteFile' });

const handleDelete = (event) => {
onDelete(event);
};

return (
<IconButton
size="small"
color={color}
tabIndex={0}
aria-label={label}
title={label}
onClick={handleDelete}
onKeyDown={(event) => handleActionKeyDown(event, handleDelete)}
>
<IconComponent fontSize="small" />
</IconButton>
);
}

+ 8
- 22
src/components/FileList.js Просмотреть файл

@@ -11,6 +11,8 @@ import { FiDataGrid } from './FiDataGrid';
import {useTheme} from "@emotion/react";
import {useMediaQuery} from "@mui/material";
import {useIntl} from "react-intl";
import { createDeleteFileColumn } from 'utils/fileListColumns';
import { CONTAINED_PRIMARY_BLUE } from "themes/colorConst";
// ==============================|| EVENT TABLE ||============================== //

export default function FileList({ refType, refId, allowDelete, sx, dateHideable,lang, ...props }) {
@@ -94,11 +96,10 @@ export default function FileList({ refType, refId, allowDelete, sx, dateHideable
return [
<GridActionsCellItem
key="OutSave"
icon={<Icon.Download />}
icon={<Icon.Download sx={{ color: CONTAINED_PRIMARY_BLUE }} />}
label="Download"
className="textPrimary"
onClick={onDownloadClick(params.id, params.row.skey, params.row.filename)}
color="primary"
disabled={onDownload}
/>]
},
@@ -143,11 +144,10 @@ export default function FileList({ refType, refId, allowDelete, sx, dateHideable
return [
<GridActionsCellItem
key="OutSave"
icon={<Icon.Download />}
icon={<Icon.Download sx={{ color: CONTAINED_PRIMARY_BLUE }} />}
label="Download"
className="textPrimary"
onClick={onDownloadClick(params.id, params.row.skey, params.row.filename)}
color="primary"
disabled={onDownload}
/>]
},
@@ -175,24 +175,10 @@ export default function FileList({ refType, refId, allowDelete, sx, dateHideable


if (allowDelete) {
columns.push({
field: 'actions',
type: 'actions',
headerName: 'Delete',
width: 100,
cellClassName: 'actions',
getActions: (params) => {
return [
<GridActionsCellItem
key="OutSave"
icon={<Icon.Delete />}
label="Delete"
className="textPrimary"
onClick={onDeleteClick(params.id, params.row.skey, params.row.filename)}
color="primary"
/>]
},
});
columns.push(createDeleteFileColumn(
(id, row) => onDeleteClick(id, row.skey, row.filename),
{ icon: Icon.Delete, color: 'primary', width: 100 }
));
}

return (


+ 1
- 1
src/components/MobileLogo/index.js Просмотреть файл

@@ -30,7 +30,7 @@ const LogoSection = ({ sx, to }) => {

/* WCAG 2.4.7 – visible keyboard focus */
'&:focus-visible': {
outline: '3px solid #0C489E',
outline: '3px solid #0c489e',
outlineOffset: '2px',
borderRadius: '6px'
}


+ 55
- 0
src/components/RegisterStepIcon.js Просмотреть файл

@@ -0,0 +1,55 @@
import { Box, useTheme } from '@mui/material';

/** Darker green for completed register steps (matches PAY button hover). */
export const REGISTER_STEP_COMPLETED_COLOR = '#488F52';

export const registerStepStyle = {
width: { lg: '40%', md: '70%', xs: '100%' },
boxShadow: 1,
backgroundColor: '#FFFFFF',
padding: 2,
'& .MuiStepLabel-label': { color: '#424242' },
'& .MuiStepConnector-line': { borderColor: '#9E9E9E' },
'& .MuiStepConnector-root.Mui-completed .MuiStepConnector-line': {
borderColor: REGISTER_STEP_COMPLETED_COLOR,
},
'& .MuiStepConnector-root.Mui-active .MuiStepConnector-line': {
borderColor: 'warning.main',
},
};

const RegisterStepIcon = ({ active, completed, className, icon }) => {
const theme = useTheme();
let circleColor = '#757575';
let textColor = '#FFFFFF';

if (completed) {
circleColor = REGISTER_STEP_COMPLETED_COLOR;
} else if (active) {
circleColor = theme.palette.warning.main;
textColor = '#1A1A1A';
}

return (
<Box
className={className}
sx={{
width: '2rem',
height: '2rem',
borderRadius: '50%',
backgroundColor: circleColor,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
color: textColor,
fontSize: '1rem',
fontWeight: 600,
lineHeight: 1,
}}
>
{icon}
</Box>
);
};

export default RegisterStepIcon;

+ 1
- 1
src/components/iAmSmartButton.js Просмотреть файл

@@ -25,7 +25,7 @@ export function IAmSmartButton({ label, onClickFun, fullWidth }) {

return (
<Button onClick={()=>doOnClick()} sx={{textTransform: 'none'}} color="iAmSmart" fullWidth={fullWidth} size="large" variant="outlined" startIcon={<img src={iAmSmartICon} alt={intl.formatMessage({ id: 'iAmSmartAlt' })} width="30" />}>
<Typography variant="h5">
<Typography component="span" variant="h5">
{_label}
</Typography>
</Button>


+ 4
- 1
src/index.js Просмотреть файл

@@ -58,7 +58,10 @@ root.render(
<ReduxProvider store={store}>
<SysSettingProvider>
<I18nProvider>
<BrowserRouter basename="/">
<BrowserRouter
basename="/"
future={{ v7_startTransition: true, v7_relativeSplatPath: true }}
>
<RefreshTokenProvider>
<AutoLogoutProvider>
<GreyWrapper>


+ 3
- 1
src/layout/MainLayout/Header/HeaderContent/LocaleSelector.js Просмотреть файл

@@ -64,7 +64,8 @@ const LocaleSelector = () => {
}}
aria-label={intl.formatMessage({id: 'openLanguage'})}
ref={anchorRef}
aria-controls={open ? 'profile-grow' : undefined}
aria-controls={open ? 'locale-selector-menu' : undefined}
aria-expanded={open}
aria-haspopup="true"
onClick={handleToggle}
>
@@ -103,6 +104,7 @@ const LocaleSelector = () => {
>
<ClickAwayListener onClickAway={handleClose}>
<List
id="locale-selector-menu"
component="nav"
>
<ListItem disablePadding>


+ 1
- 1
src/layout/MainLayout/Header/HeaderContent/Notification.js Просмотреть файл

@@ -77,7 +77,7 @@ const Notification = () => {

/* ✅ WCAG 2.4.7 focus indicator */
'&:focus-visible': {
outline: '3px solid #0C489E',
outline: '3px solid #0c489e',
outlineOffset: '2px',
borderRadius: '6px'
}


+ 23
- 9
src/layout/MainLayout/Header/index.js Просмотреть файл

@@ -516,6 +516,20 @@ function Header(props) {

{isGranted("MAINTAIN_SETTING") ? (
<>
<li>
<Link className="systemSetting" to="/setting/hkidKeyMigration">
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>
HKID Key Migration
</Typography>
</Link>
</li>
<li>
<Link className="systemSetting" to="/setting/userPiiEncryption">
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>
User PII Encryption
</Typography>
</Link>
</li>
<li>
<Link className="systemSetting" to="/setting/sys">
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>
@@ -775,7 +789,7 @@ function Header(props) {
<Stack id="sidebar" direction="column" justifyContent="center" alignItems="center" sx={{ textAlign: "center", width: "300px" }}>
<Box sx={{ mr: 2, mt: 1, display: { md: "none" } }}>
<MobileLogo />
<span style={{ color: checkSysEnv() !== "" ? "red" : "#0C489E" }} id="mobileTitle">
<span style={{ color: checkSysEnv() !== "" ? "red" : "#0c489e" }} id="mobileTitle">
PNSPS
</span>
</Box>
@@ -794,7 +808,7 @@ function Header(props) {
<Stack id="sidebar" direction="column" justifyContent="center" alignItems="center" onClick={handleDrawerToggle} sx={{ textAlign: "center" }}>
<Box sx={{ mr: 2, mt: 1, display: { md: "none" } }}>
<MobileLogo />
<span style={{ color: checkSysEnv() !== "" ? "red" : "#0C489E" }} id="mobileTitle">
<span style={{ color: checkSysEnv() !== "" ? "red" : "#0c489e" }} id="mobileTitle">
PNSPS
</span>
</Box>
@@ -826,13 +840,13 @@ function Header(props) {
onClick={handleDrawerToggle}
sx={{ mr: 2, display: { md: "none" } }}
>
<MenuIcon style={{ color: "#0C489E" }} />
<MenuIcon style={{ color: "#0c489e" }} />
</IconButton>
<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">
<span style={{ color: checkSysEnv() !== "" ? "red" : "#0c489e" }} id="mobileTitle">
PNSPS
</span>
</Stack>
@@ -848,7 +862,7 @@ function Header(props) {
<Stack direction="row" justifyContent="flex-start" alignItems="center">
<Logo />
<Stack justifyContent="flex-start" alignItems="center">
<span style={{ color: checkSysEnv() !== "" ? "#B00020" : "#0C489E" }} id="systemTitle">
<span style={{ color: checkSysEnv() !== "" ? "#B00020" : "#0c489e" }} id="systemTitle">
<FormattedMessage id="PNSPS" />
</span>
</Stack>
@@ -863,14 +877,14 @@ function Header(props) {
onClick={handleDrawerToggle}
sx={{ mr: 2, display: { md: "none" } }}
>
<MenuIcon style={{ color: "#0C489E" }} />
<MenuIcon style={{ color: "#0c489e" }} />
</IconButton>

<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">
<span style={{ color: checkSysEnv() !== "" ? "red" : "#000" }} id="mobileTitle">
<FormattedMessage id="PNSPS" />
</span>
</Stack>
@@ -946,14 +960,14 @@ function Header(props) {
onClick={handleDrawerToggle}
sx={{ mr: 2, display: { md: "none" } }}
>
<MenuIcon style={{ color: "#0C489E" }} />
<MenuIcon style={{ color: "#0c489e" }} />
</IconButton>

<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">
<span style={{ color: checkSysEnv() !== "" ? "red" : "#0c489e" }} id="mobileTitle">
<FormattedMessage id="PNSPS" />
</span>
</Stack>


+ 1
- 1
src/layout/MainLayout/index.js Просмотреть файл

@@ -67,7 +67,7 @@ const MainLayout = () => {
{/* <Breadcrumbs navigation={navigation} title /> */}
<Outlet />
</Box>
<Box sx={{borderTop: "3px solid #0C489E"}}>
<Box sx={{borderTop: "3px solid #0c489e"}}>
<Footer/>
</Box>
</Box>


+ 1
- 1
src/pages/Announcement/Search/index.js Просмотреть файл

@@ -72,7 +72,7 @@ const UserSearchPage_Individual = () => {
<Grid item xs={12}>
<div style={BackgroundHead}>
<Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center">
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0C489E" }}>Announcement</Typography>
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0c489e" }}>Announcement</Typography>
</Stack>
</div>
</Grid>


+ 1
- 1
src/pages/Announcement/Search_Public/index.js Просмотреть файл

@@ -75,7 +75,7 @@ const UserSearchPage_Individual = () => {
<Grid item xs={12}>
<div style={BackgroundHead}>
<Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center">
<Typography component="h1" ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0C489E" }}><FormattedMessage id="announcement" /></Typography>
<Typography component="h1" ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0c489e" }}><FormattedMessage id="announcement" /></Typography>
</Stack>
</div>
</Grid>


+ 1
- 1
src/pages/AuditLog/index.js Просмотреть файл

@@ -61,7 +61,7 @@ const AuditLogPage = () => {
<Grid item xs={12}>
<div style={BackgroundHead}>
<Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center">
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0C489E" }}>Audit Log</Typography>
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0c489e" }}>Audit Log</Typography>
</Stack>
</div>
</Grid>


+ 1
- 1
src/pages/DemandNote/Create/index.js Просмотреть файл

@@ -68,7 +68,7 @@ const Index = () => {
<Grid item xs={12}>
<div style={BackgroundHead}>
<Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center">
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0C489E" }}>
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0c489e" }}>
Create Demand Note
</Typography>
</Stack>


+ 1
- 1
src/pages/DemandNote/Export/index.js Просмотреть файл

@@ -68,7 +68,7 @@ const Index = () => {
<Grid item xs={12}>
<div style={BackgroundHead}>
<Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center">
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0C489E" }}>
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0c489e" }}>
Export for GDN (Non Creditor)
</Typography>
</Stack>


+ 2
- 0
src/pages/DemandNote/Search/DataGrid.js Просмотреть файл

@@ -27,6 +27,7 @@ import { PNSPS_BUTTON_THEME } from "themes/buttonConst";
import { ThemeProvider } from "@emotion/react";
import { isGrantedAny } from "auth/utils";
import { useIntl } from "react-intl";
import { PRIMARY_CONTAINED_BUTTON_SX } from "themes/colorConst";
// ==============================|| EVENT TABLE ||============================== //

export default function SearchDemandNote({ applySearch, searchCriteria, applyGridOnReady }) {
@@ -334,6 +335,7 @@ export default function SearchDemandNote({ applySearch, searchCriteria, applyGri
<Button
component="span"
variant="contained"
sx={PRIMARY_CONTAINED_BUTTON_SX}
>
Attach DN
</Button>


+ 1
- 1
src/pages/DemandNote/Search/index.js Просмотреть файл

@@ -93,7 +93,7 @@ const UserSearchPage_Individual = () => {
<Grid item xs={12}>
<div style={BackgroundHead}>
<Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center">
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0C489E" }}>
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0c489e" }}>
Demand Note
</Typography>
</Stack>


+ 1
- 1
src/pages/GFMIS/index.js Просмотреть файл

@@ -208,7 +208,7 @@ const Index = () => {
<Grid item xs={12}>
<div style={BackgroundHead}>
<Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center">
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0C489E" }}>
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0c489e" }}>
GFMIS Generate XML
</Typography>
</Stack>


+ 1
- 1
src/pages/JVM/index.js Просмотреть файл

@@ -87,7 +87,7 @@ const JVMDefault = () => {
<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" }}>
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0c489e" }}>
System Background Status
</Typography>
</Stack>


+ 4
- 3
src/pages/Message/Details/index.js Просмотреть файл

@@ -18,6 +18,7 @@ const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/Loa
import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png'
import { FormattedMessage } from "react-intl";
import usePageTitle from 'components/usePageTitle';
import { PRIMARY_CONTAINED_BUTTON_SX } from 'themes/colorConst';

const BackgroundHead = {
backgroundImage: `url(${titleBackgroundImg})`,
@@ -91,8 +92,8 @@ const Index = () => {
{record?.subject}
</Typography>
<Typography sx={{p:1}} align="justify">{DateUtils.datetimeStr(record?.sentDate)}</Typography>
<Typography variant="body1" sx={{ p:4, textAlign: "left" }} align="justify" backgroundColor="#f8f8f8">
<div dangerouslySetInnerHTML={{__html: record?.content}}></div>
<Typography component="div" variant="body1" sx={{ p: 4, textAlign: "left", bgcolor: "#f8f8f8" }} align="justify">
<div dangerouslySetInnerHTML={{ __html: record?.content }} />
</Typography>

<Typography component="h3" variant="h4" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "center" }}>
@@ -100,7 +101,7 @@ const Index = () => {
component="span"
variant="contained"
size="large"
sx={{ m: 4 }}
sx={{ m: 4, ...PRIMARY_CONTAINED_BUTTON_SX }}
onClick={() => {
navigate(-1);
}}


+ 1
- 1
src/pages/Organization/SearchPage/index.js Просмотреть файл

@@ -72,7 +72,7 @@ const OrganizationSearchPage = () => {
<Grid item xs={12}>
<div style={BackgroundHead}>
<Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center">
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0C489E" }}>View Organisation</Typography>
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0c489e" }}>View Organisation</Typography>
</Stack>
</div>
</Grid>


+ 2
- 1
src/pages/Payment/Details_GLD/DataGrid.js Просмотреть файл

@@ -4,6 +4,7 @@ import {
} from '@mui/material';
import {
isORGLoggedIn,
formatPaymentParticularsLength,
} from "utils/Utils";
import * as React from 'react';
import * as FormatUtils from "utils/FormatUtils"
@@ -48,7 +49,7 @@ export default function SearchPublicNoticeTable({ recordList }) {
{isORGLoggedIn()&&params.row.careOf!=null&&params.row.careOf!=""?<>{params.row.careOf}<br /></>:null}
App No: {appNo}<br/>
Issue Date: {DateUtils.dateValue(params.row.issueDate)}<br/>
Length: {params.row.length+ " cm"}</div>
Length: {formatPaymentParticularsLength(params.row)}</div>
},
},
{


+ 67
- 7
src/pages/Payment/Details_GLD/PaymentDetails.js Просмотреть файл

@@ -3,24 +3,33 @@ import {
Grid,
Typography,
FormLabel,
Button
Button,
Dialog,
DialogTitle,
DialogContent,
DialogActions,
Box
} from '@mui/material';

import * as React from "react";
import * as FormatUtils from "utils/FormatUtils";
import * as PaymentStatus from "utils/statusUtils/PaymentStatus";
import * as DateUtils from "utils/DateUtils";
import * as HttpUtils from "utils/HttpUtils";
import { PAYMENT_MARK_AS_PAID } from "utils/ApiPathConst";
import Loadable from 'components/Loadable';
const MainCard = Loadable(React.lazy(() => import('components/MainCard')));
const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent')));
import DownloadIcon from '@mui/icons-material/Download';
import {useIntl} from "react-intl";
// ==============================|| DASHBOARD - DEFAULT ||============================== //
const PaymentDetails = ({ formData,doPrint,onDownload }) => {
const PaymentDetails = ({ formData, doPrint, onDownload, onRefresh }) => {

const intl = useIntl();
const [data, setData] = React.useState({});
const [onReady, setOnReady] = React.useState(false);
const [confirmOpen, setConfirmOpen] = React.useState(false);
const [markingPaid, setMarkingPaid] = React.useState(false);
// const { locale } = intl;

React.useEffect(() => {
@@ -40,9 +49,29 @@ const PaymentDetails = ({ formData,doPrint,onDownload }) => {
if("01" == paymentmethod) return "PPS";
if("02" == paymentmethod || "03" == paymentmethod) return "Credit Card";
if("04" == paymentmethod) return "FPS";
if (data.payMethod === "04,BCFP,FPS") return "FPS";
return paymentmethod;
}

const showMarkAsPaid = data.status === "REJT" && getPaymentMethod() === "FPS";

const handleMarkAsPaid = () => {
setMarkingPaid(true);
HttpUtils.post({
url: PAYMENT_MARK_AS_PAID + "/" + data.id,
onSuccess: () => {
setConfirmOpen(false);
setMarkingPaid(false);
if (onRefresh) {
onRefresh();
}
},
onError: () => {
setMarkingPaid(false);
}
});
};

return (
!onReady ?
<LoadingComponent />
@@ -51,9 +80,21 @@ const PaymentDetails = ({ formData,doPrint,onDownload }) => {
border={false}
content={false}
>
<Typography variant="h5" sx={{ textAlign: "left", mb: 2, borderBottom: "1px solid black" }}>
Payment Details
</Typography>
<Box sx={{ display: "flex", alignItems: "center", justifyContent: "space-between", mb: 2, borderBottom: "1px solid black" }}>
<Typography variant="h5" sx={{ textAlign: "left" }}>
Payment Details
</Typography>
{showMarkAsPaid && (
<Button
className="printHidden"
variant="contained"
color="primary"
onClick={() => setConfirmOpen(true)}
>
Mark as Paid
</Button>
)}
</Box>
<form>
<Grid container>
<Grid item xs={12} md={12} >
@@ -116,7 +157,7 @@ const PaymentDetails = ({ formData,doPrint,onDownload }) => {
<Grid container >
<Grid item xs={6} md={6} sx={{ml:-5, textAlign: "right" }}>
<FormLabel sx={{ color: "#000000" }}>
EGIS Reference No.:
Payment Reference No.:
</FormLabel>
</Grid>
<Grid item xs={6} md={5} sx={{ml:5, textAlign: "left" }}>
@@ -164,7 +205,7 @@ const PaymentDetails = ({ formData,doPrint,onDownload }) => {
Payment Receipt:
</FormLabel>
</Grid>
<Grid xs={6} md={5} sx={{ml:5,textAlign: "left" }}>
<Grid item xs={6} md={5} sx={{ml:5,textAlign: "left" }}>
<Button className="printHidden" variant="contained" disabled={onDownload} sx={{ mt:2 }} onClick={doPrint}>
<DownloadIcon/>
<Typography sx={{fontSize: "16px"}}>Download</Typography>
@@ -176,6 +217,25 @@ const PaymentDetails = ({ formData,doPrint,onDownload }) => {
}
</Grid>
</form>
<Dialog
open={confirmOpen}
onClose={() => !markingPaid && setConfirmOpen(false)}
>
<DialogTitle>Confirm</DialogTitle>
<DialogContent>
<Typography variant="h5" sx={{ padding: '16px' }}>
{`Are you sure to mark as paid for Payment No. ${data.transNo || data.payload?.transactionid} ?`}
</Typography>
</DialogContent>
<DialogActions>
<Button onClick={() => setConfirmOpen(false)} disabled={markingPaid}>
<Typography variant="h5">Cancel</Typography>
</Button>
<Button onClick={handleMarkAsPaid} disabled={markingPaid}>
<Typography variant="h5">Confirm</Typography>
</Button>
</DialogActions>
</Dialog>
</MainCard>
);
};


+ 42
- 7
src/pages/Payment/Details_GLD/index.js Просмотреть файл

@@ -35,6 +35,9 @@ const Index = () => {
const params = useParams();
const navigate = useNavigate()

const [responeData, setResponeData] = React.useState({});
const [transactionData, setTransactionData] = React.useState({});

const [record, setRecord] = React.useState();
const [itemList, setItemList] = React.useState([]);
const [onReady, setOnReady] = React.useState(false);
@@ -47,8 +50,16 @@ const Index = () => {
}, []);

React.useEffect(() => {
setOnReady(true);
}, [record]);
if (Object.keys(responeData).length > 0) {
setTransactionData(responeData);
}
}, [responeData]);

React.useEffect(() => {
if (Object.keys(transactionData).length > 0) {
setOnReady(true);
}
}, [transactionData]);

// const handleResize = () => {
// setDetailsOrder(window.innerWidth > 1023 ? 2 : -1);
@@ -70,17 +81,40 @@ const Index = () => {

const loadForm = () => {
if (params.id > 0) {

HttpUtils.get({
url: UrlUtils.PAYMENT_LOAD + "/" + params.id,
onSuccess: (responseData) => {
if (!responseData.data?.id) {
navigate("/paymentPage/search");
}
responseData.data["transDateStr"] = responseData.data.transDateTime;
responseData.data["transTimeStr"] = DateUtils.dateFormat(responseData.data.transDateTime, "HH:mm:ss");
setItemList(responseData.paymentItemList)
setRecord(responseData.data);
if (responseData.data.status == null || responseData.data.status == "INPR") {
HttpUtils.post({
url: UrlUtils.PAYMENT_RETRY_STATUS_API,
params: {
"paymentId": params.id
},
onSuccess: function (responseData2) {
responseData2.data["transDateStr"] = responseData2.data.transDateTime;
responseData2.data["transTimeStr"] = DateUtils.dateFormat(responseData2.data.transDateTime, "HH:mm:ss");
setResponeData(responseData2.transactionData);
setItemList(responseData2.paymentItemList);
setRecord(responseData2.data);
},
onError: function () {
responseData.data["transDateStr"] = responseData.data.transDateTime;
responseData.data["transTimeStr"] = DateUtils.dateFormat(responseData.data.transDateTime, "HH:mm:ss");
setResponeData(responseData);
setItemList(responseData.paymentItemList);
setRecord(responseData.data);
}
});
} else {
responseData.data["transDateStr"] = responseData.data.transDateTime;
responseData.data["transTimeStr"] = DateUtils.dateFormat(responseData.data.transDateTime, "HH:mm:ss");
setResponeData(responseData);
setItemList(responseData.paymentItemList);
setRecord(responseData.data);
}
}
});
}
@@ -125,6 +159,7 @@ const Index = () => {
formData={record}
doPrint={doPrint}
onDownload={onDownload}
onRefresh={loadForm}
style={{
display: "flex",
height: "100%",


+ 2
- 1
src/pages/Payment/Details_Public/DataGrid.js Просмотреть файл

@@ -4,6 +4,7 @@ import {
} from '@mui/material';
import {
isORGLoggedIn,
formatPaymentParticularsLength,
} from "utils/Utils";
import * as React from 'react';
import * as FormatUtils from "utils/FormatUtils"
@@ -75,7 +76,7 @@ export default function SearchPublicNoticeTable({ recordList }) {
{isORGLoggedIn()&&params.row.careOf!=null&&params.row.careOf!=""?<>{params.row.careOf}<br /></>:null}
<FormattedMessage id="applicationId"/>: {appNo}<br/>
<FormattedMessage id="gazetteDate"/>: {locale === 'en' ? DateUtils.dateValue(params.row.issueDate) : DateUtils.dateStr_Cht(params.row.issueDate)}<br/>
<FormattedMessage id="gazetteLength"/>: {params.row.length+ " cm"}</div>
<FormattedMessage id="gazetteLength"/>: {formatPaymentParticularsLength(params.row, intl)}</div>
},
},
{


+ 2
- 3
src/pages/Payment/Details_Public/index.js Просмотреть файл

@@ -21,6 +21,7 @@ import ForwardIcon from '@mui/icons-material/Forward';
import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png'
import {FormattedMessage,useIntl} from "react-intl";
import usePageTitle from "components/usePageTitle";
import { toReceiptLanguage } from "utils/Utils";
const BackgroundHead = {
backgroundImage: `url(${titleBackgroundImg})`,
width: '100%',
@@ -76,10 +77,8 @@ const Index = () => {
const doPrint = () => {
// window.print();
setOnDownload(true)
const local = locale
// console.log(local)
HttpUtils.fileDownload({
url: UrlUtils.GEN_PAYMENT_RECEIPT+"/"+params.id+"/"+local,
url: UrlUtils.GEN_PAYMENT_RECEIPT+"/"+params.id+"/"+toReceiptLanguage(locale),
onResponse:()=>{
setOnDownload(false)
},


+ 2
- 3
src/pages/Payment/FPS/AckPage.js Просмотреть файл

@@ -24,6 +24,7 @@ const DataGrid = Loadable(React.lazy(() => import('../Details_Public/DataGrid'))

import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png'
import {FormattedMessage,useIntl} from "react-intl";
import { toReceiptLanguage } from "utils/Utils";
const BackgroundHead = {
backgroundImage: `url(${titleBackgroundImg})`,
width: '100%',
@@ -162,10 +163,8 @@ const AckPage = () => {
const doPrint = () => {
// window.print();
setOnDownload(true)
const local = locale
HttpUtils.fileDownload({
// url: UrlUtils.GEN_PAYMENT_RECEIPT+"/"+localStorage.getItem("paymentId")+"/"+local,
url: UrlUtils.GEN_PAYMENT_RECEIPT+"/"+paymentData.id+"/"+local,
url: UrlUtils.GEN_PAYMENT_RECEIPT+"/"+paymentData.id+"/"+toReceiptLanguage(locale),
onResponse:()=>{
setOnDownload(false)
},


+ 8
- 2
src/pages/Payment/FPS/FPS.js Просмотреть файл

@@ -485,11 +485,17 @@ const Index = () => {
component="span"
variant="contained"
size="large"
color="error"
onClick={()=>{
cancelPayment();
}}
sx={{ m: 4 }}
sx={{
m: 4,
backgroundColor: (theme) => theme.palette.error.darker,
color: (theme) => theme.palette.error.contrastText,
'&:hover': {
backgroundColor: (theme) => theme.palette.error.dark,
},
}}
>
<FormattedMessage id="payCancel"/>
</Button>


+ 2
- 2
src/pages/Payment/FPS/fpscallback.js Просмотреть файл

@@ -24,6 +24,7 @@ const DataGrid = Loadable(React.lazy(() => import('../Details_Public/DataGrid'))

import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png'
import {FormattedMessage,useIntl} from "react-intl";
import { toReceiptLanguage } from "utils/Utils";
const BackgroundHead = {
backgroundImage: `url(${titleBackgroundImg})`,
width: '100%',
@@ -152,9 +153,8 @@ const Fpscallback = () => {
const params = new URLSearchParams(window.location.search);
// window.print();
setOnDownload(true)
const local = locale
HttpUtils.fileDownload({
url: UrlUtils.GEN_PAYMENT_RECEIPT+"/"+params.get("PAYMENT_ID")+"/"+local,
url: UrlUtils.GEN_PAYMENT_RECEIPT+"/"+params.get("PAYMENT_ID")+"/"+toReceiptLanguage(locale),
onResponse:()=>{
setOnDownload(false)
},


+ 3
- 2
src/pages/Payment/MultiPaymentWindow.js Просмотреть файл

@@ -32,6 +32,7 @@ import UnionPayIcon from "assets/images/icons/unionpay.svg";
import PpsIcon from "assets/images/icons/ppshk.svg";
import FpsIcon from "assets/images/icons/fps.svg";
import {FormattedMessage, useIntl} from "react-intl";
import { PRIMARY_CONTAINED_BUTTON_SX, PAY_CONTAINED_BUTTON_SX } from "themes/colorConst";
import * as HttpUtils from "utils/HttpUtils"
import * as UrlUtils from "utils/ApiPathConst"

@@ -442,7 +443,7 @@ const MultiPaymentWindow = (props) => {
</FormikProvider>
<Stack direction="row" justifyContent="space-around">
<DialogActions>
<Button variant="contained" onClick={closeHandle()} autoFocus >
<Button variant="contained" onClick={closeHandle()} autoFocus sx={PRIMARY_CONTAINED_BUTTON_SX}>
<FormattedMessage id="cancel"/>
</Button>
</DialogActions>
@@ -451,7 +452,7 @@ const MultiPaymentWindow = (props) => {
props.onPayment?
<LoadingComponent disableText={true} alignItems="flex-start"/>
:
<Button variant="contained" color="success" onClick={confirmPaymentHandle()} disabled={paymentMethod === "" || isLimit || isPPSLimit}>
<Button variant="contained" onClick={confirmPaymentHandle()} disabled={paymentMethod === "" || isLimit || isPPSLimit} sx={PAY_CONTAINED_BUTTON_SX}>
<FormattedMessage id="pay"/>
</Button>
}


+ 2
- 4
src/pages/Payment/PaymentCallback.js Просмотреть файл

@@ -21,6 +21,7 @@ const DataGrid = Loadable(React.lazy(() => import('./Details_Public/DataGrid')))

import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png'
import {FormattedMessage,useIntl} from "react-intl";
import { toReceiptLanguage } from "utils/Utils";
const BackgroundHead = {
backgroundImage: `url(${titleBackgroundImg})`,
width: '100%',
@@ -159,11 +160,8 @@ const Index = () => {
const doPrint = () => {
// window.print();
setOnDownload(true)
const local = locale
console.log(local)
HttpUtils.fileDownload({
// url: UrlUtils.GEN_PAYMENT_RECEIPT+"/"+localStorage.getItem("paymentId")+"/"+local,
url: UrlUtils.GEN_PAYMENT_RECEIPT+"/"+paymentData.id+"/"+local,
url: UrlUtils.GEN_PAYMENT_RECEIPT+"/"+paymentData.id+"/"+toReceiptLanguage(locale),
onResponse:()=>{
setOnDownload(false)
},


+ 8
- 2
src/pages/Payment/Search_GLD/DataGrid.js Просмотреть файл

@@ -87,7 +87,7 @@ export default function SearchPaymentTable({ searchCriteria, applyGridOnReady, a
},
{
field: 'actions',
headerName: 'Transaction No.',
headerName: 'Payment No.',
flex: 1,
minWidth: 200,
cellClassName: 'actions',
@@ -95,6 +95,12 @@ export default function SearchPaymentTable({ searchCriteria, applyGridOnReady, a
return clickableLink('/paymentPage/details/' + params.row.id, params.row.transNo);
},
},
{
field: 'egisRefNo',
headerName: 'Payment Reference No.',
flex: 1,
minWidth: 200,
},
{
field: 'payMethod',
headerName: 'Payment Method',
@@ -107,7 +113,7 @@ export default function SearchPaymentTable({ searchCriteria, applyGridOnReady, a
{
id: 'transDateTime',
field: 'transDateTime',
headerName: 'Transaction Date',
headerName: 'Payment Date',
flex: 1,
minWidth: 150,



+ 1
- 1
src/pages/Payment/Search_GLD/index.js Просмотреть файл

@@ -71,7 +71,7 @@ const Index = () => {
<Grid item xs={12}>
<div style={BackgroundHead}>
<Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center">
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0C489E" }}>
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0c489e" }}>
Online Payment Record
</Typography>
</Stack>


+ 14
- 0
src/pages/Payment/Search_Public/DataGrid.js Просмотреть файл

@@ -11,6 +11,7 @@ import { FiDataGrid } from "components/FiDataGrid";
import {useTheme} from "@emotion/react";
import {useIntl} from "react-intl";
import { clickableLink } from 'utils/CommonFunction';
import { getPaymentMethodByCode } from "auth/utils";
import {PAYMENT_LIST} from "utils/ApiPathConst";
// ==============================|| EVENT TABLE ||============================== //

@@ -58,6 +59,12 @@ export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnRea
return clickableLink('/paymentPage/details/' + params.row.id, params.row.transNo);
},
},
{
field: 'egisRefNo',
headerName: intl.formatMessage({id: 'paymentRefCode'}),
width: isMdOrLg ? 'auto' : 160,
flex: isMdOrLg ? 1 : undefined,
},
{
id: 'appNos',
field: 'appNos',
@@ -69,6 +76,13 @@ export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnRea
return <div style={{ margin: 4 }}>{appNo}</div>
},
},
{
field: 'payMethod',
headerName: intl.formatMessage({id: 'paymentMethod'}),
width: isMdOrLg ? 'auto' : 160,
flex: isMdOrLg ? 1 : undefined,
renderCell: (params) => getPaymentMethodByCode(params?.value),
},
{
id: 'transDateTime',
field: 'transDateTime',


+ 4
- 3
src/pages/Payment/index.js Просмотреть файл

@@ -23,6 +23,7 @@ import {
import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png'
import {ThemeProvider} from "@emotion/react";
import {PNSPS_BUTTON_THEME} from "../../themes/buttonConst";
import { PRIMARY_CONTAINED_BUTTON_SX, PAY_CONTAINED_BUTTON_SX } from "themes/colorConst";
import {
FormattedMessage,
useIntl
@@ -490,16 +491,16 @@ const Index = () => {
variant="contained"
// color="error"
onClick={() => paymentClick()}
sx={{ mt: 4 }}
sx={{ mt: 4, ...PAY_CONTAINED_BUTTON_SX }}
>
<FormattedMessage id="pay"/>
<FormattedMessage id="selectPaymentMethodBtn"/>
</Button>
<Button
component="span"
variant="contained"
// color="error"
onClick={() => { navigate("/publicNotice") }}
sx={{ mt: 4 }}
sx={{ mt: 4, ...PRIMARY_CONTAINED_BUTTON_SX }}
>
<FormattedMessage id="cancel"/>
</Button>


+ 5
- 41
src/pages/Proof/Create_FromApp/UploadFileTable.js Просмотреть файл

@@ -2,11 +2,10 @@
import * as React from 'react';
import {
DataGrid,
GridActionsCellItem,
GridRowModes
} from "@mui/x-data-grid";
import RemoveCircleOutlineIcon from '@mui/icons-material/RemoveCircleOutline';
import { useEffect } from "react";
import { createDeleteFileColumn } from 'utils/fileListColumns';
// import {useNavigate} from "react-router-dom";
// import { useTheme } from '@mui/material/styles';
import {
@@ -17,7 +16,6 @@ import {
// ==============================|| EVENT TABLE ||============================== //

export default function UploadFileTable({ recordList, setRecordList, showPageColumn, _checkCode, _expectedCode }) {

const [rows, setRows] = React.useState(recordList);
const [rowModesModel, setRowModesModel] = React.useState({});
const [showPage, setShowPage] = React.useState(false);
@@ -67,6 +65,8 @@ export default function UploadFileTable({ recordList, setRecordList, showPageCol
setRows(rows.filter((row) => row.id !== id));
}

const deleteColumn = createDeleteFileColumn((id) => handleCancelClick(id));

const handlePreviewClick = (param) => () => {
var reader = new FileReader();
reader.onload = function () {
@@ -87,25 +87,7 @@ export default function UploadFileTable({ recordList, setRecordList, showPageCol


const columns = showPage?[
{
field: 'actions',
type: 'actions',
headerName: '',
width: 30,
cellClassName: 'actions',
// hide:true,
getActions: ({ id }) => {
return [
<GridActionsCellItem
key="OutSave"
icon={<RemoveCircleOutlineIcon />}
label="delete"
className="textPrimary"
onClick={handleCancelClick(id)}
color="error"
/>]
},
},
deleteColumn,
{
field: 'name',
headerName: 'File Name',
@@ -132,25 +114,7 @@ export default function UploadFileTable({ recordList, setRecordList, showPageCol
hide: true
},
]:[
{
field: 'actions',
type: 'actions',
headerName: '',
width: 30,
cellClassName: 'actions',
// hide:true,
getActions: ({ id }) => {
return [
<GridActionsCellItem
key="OutSave"
icon={<RemoveCircleOutlineIcon />}
label="delete"
className="textPrimary"
onClick={handleCancelClick(id)}
color="error"
/>]
},
},
deleteColumn,
{
field: 'name',
headerName: 'File Name',


+ 1
- 1
src/pages/Proof/Create_FromApp/index.js Просмотреть файл

@@ -79,7 +79,7 @@ const Index = () => {
<Grid item xs={12}>
<div style={BackgroundHead}>
<Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center">
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0C489E" }}>Create Proof</Typography>
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0c489e" }}>Create Proof</Typography>
</Stack>
</div>
</Grid>


+ 56
- 31
src/pages/Proof/Payment/Pay_Online.js Просмотреть файл

@@ -32,6 +32,37 @@ const BackgroundHead = {
backgroundPosition: 'right'
}

const contentBoxSx = {
px: { xs: 2, sm: 3, md: 5, lg: 6 },
maxWidth: 1500,
width: '100%',
};

const headerSx = {
textAlign: 'left',
mt: 4,
fontSize: { xs: '1.15rem', sm: '1.35rem', md: '1.5rem' },
textDecoration: 'underline',
textDecorationThickness: '2px',
textUnderlineOffset: '4px',
};

const bodySx = {
mt: 4,
textAlign: 'left',
fontSize: { xs: '1rem', sm: '1.1rem', md: '1.25rem' },
lineHeight: 1.6,
};

const payButtonSx = {
minWidth: 'unset',
px: { xs: 2, sm: 3 },
py: 1.25,
whiteSpace: 'nowrap',
width: { xs: '100%', sm: 'auto' },
fontSize: { xs: '1rem', sm: '1.2rem' },
};

import {
// useEffect,
useState
@@ -151,37 +182,19 @@ const Index = () => {
</Grid>
{/*row 1*/}
<Grid item xs={12} md={12} >
<Grid container justifyContent="flex-start" alignItems="center" >
<center>
<Grid item xs={12} md={8} >
<Grid container justifyContent="center" alignItems="center" >
<Grid item xs={12} md={11} lg={10} sx={contentBoxSx}>
{isAfter ? (
<Typography
variant="h4"
sx={{ textAlign: "left", ml: 8, mr: 4, mt: 4,
textDecoration: "underline",
textDecorationThickness: "2px",
textUnderlineOffset: "4px" }}
>
<Typography variant="h4" sx={headerSx}>
<FormattedMessage id="proofPaymentHeader_online2" />
</Typography>
) : (
<Typography
variant="h4"
sx={{
textAlign: "left",
ml: 4,
mr: 4,
mt: 4,
textDecoration: "underline",
textDecorationThickness: "2px",
textUnderlineOffset: "4px"
}}
>
<Typography variant="h4" sx={headerSx}>
<FormattedMessage id="proofPaymentHeader_online" />
</Typography>
)}

<Typography variant="h5" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}>
<Typography variant="h5" sx={bodySx}>
<div dangerouslySetInnerHTML={{
__html: intl.formatMessage(
{
@@ -215,26 +228,39 @@ const Index = () => {
</Typography>

{!checkPaymentSuspension()?
<Typography variant="h4" sx={{ ml: 8, textAlign: "left" }}>
<Stack
direction={{ xs: 'column', sm: 'row' }}
alignItems={{ xs: 'stretch', sm: 'center' }}
sx={{ mt: 4, gap: { xs: 1.5, sm: 2 } }}
>
<ThemeProvider theme={PNSPS_BUTTON_THEME}>
<Button
component="span"
variant="contained"
// sx={{ ml: { sm: 4, md: 4, lg: 4 }, mr: 4, mt: { xs: 2, sm: 2 }, mb: { xs: 2, sm: 2 } }}
sx={{mr: 4 }}
sx={payButtonSx}
onClick={() => { setIsPopUp(true) }}
>
<FormattedMessage id="payInstantly" />
</Button>
</ThemeProvider>

<FormattedMessage id="or" />
<Typography
component="span"
variant="h4"
sx={{
textAlign: { xs: 'center', sm: 'left' },
fontSize: { xs: '1rem', sm: '1.25rem' },
my: { xs: 0.5, sm: 0 },
}}
>
<FormattedMessage id="or" />
</Typography>

<ThemeProvider theme={PNSPS_BUTTON_THEME}>
<Button
component="span"
variant="contained"
sx={{ ml: { sm: 4, md: 4, lg: 4 }, mr: 4, mt: { xs: 2, sm: 2 }, mb: { xs: 2, sm: 2 } }}
sx={payButtonSx}
onClick={() => {
navigate("/publicNotice");
}}
@@ -242,10 +268,10 @@ const Index = () => {
<FormattedMessage id="payLater" />
</Button>
</ThemeProvider>
</Typography>:null
</Stack>:null
}

<Typography variant="h4" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}>
<Typography variant="h4" sx={bodySx}>
<div dangerouslySetInnerHTML={{
__html: intl.formatMessage(
{
@@ -258,7 +284,6 @@ const Index = () => {


</Grid>
</center>
</Grid>
</Grid>
<div>


+ 1
- 1
src/pages/Proof/Reply_GLD/ApplicationDetails.js Просмотреть файл

@@ -350,7 +350,7 @@ const ApplicationDetailCard = ({
{
formik.values.groupType == "Private Bill"
?
<Typography variant="h5">( {data.noOfPages} page x $6,552 )</Typography>
<Typography variant="h5">( {data.noOfPages} {data.noOfPages === 1 ? 'page' : 'pages'} x $6,552 )</Typography>
:
<Typography variant="h5">( {data.length} cm x {data.colCount == 2 ? "$364 Double Column" : "$182 Single Column"} )</Typography>
}


+ 4
- 23
src/pages/Proof/Reply_GLD/UploadFileTable.js Просмотреть файл

@@ -1,19 +1,16 @@
// material-ui
import RemoveCircleOutlineIcon from '@mui/icons-material/RemoveCircleOutline';
import {
DataGrid,
GridActionsCellItem,
GridRowModes
} from "@mui/x-data-grid";
import * as React from 'react';
import { useEffect } from "react";
// import {useNavigate} from "react-router-dom";
// import { useTheme } from '@mui/material/styles';
import {
Box,
Stack
} from '@mui/material';
import {useIntl} from "react-intl";
import { createDeleteFileColumn } from 'utils/fileListColumns';
// ==============================|| EVENT TABLE ||============================== //

export default function UploadFileTable({recordList, setRecordList,}) {
@@ -52,26 +49,10 @@ export default function UploadFileTable({recordList, setRecordList,}) {
setRows(rows.filter((row) => row.id !== id));
}

const deleteColumn = createDeleteFileColumn((id) => handleCancelClick(id));

const columns = [
{
field: 'actions',
type: 'actions',
headerName: '',
width: 30,
cellClassName: 'actions',
// hide:true,
getActions: ({id}) => {
return [
<GridActionsCellItem
key="OutSave"
icon={<RemoveCircleOutlineIcon/>}
label="delete"
className="textPrimary"
onClick={handleCancelClick(id)}
color="error"
/>]
},
},
deleteColumn,
{
id: 'name',
field: 'name',


+ 7
- 7
src/pages/Proof/Reply_Public/ApplicationDetails.js Просмотреть файл

@@ -70,7 +70,7 @@ const ApplicationDetailCard = ({ formData, }) => {
border={false}
content={false}
>
<Typography variant="h4" sx={{ textAlign: "left", mb: 2, borderBottom: "1px solid black" }}>
<Typography variant="h4" component="h2" sx={{ textAlign: "left", mb: 2, borderBottom: "1px solid black" }}>
<FormattedMessage id="publicNoticePaymentProofInfo" />
</Typography>
<form>
@@ -262,12 +262,12 @@ const ApplicationDetailCard = ({ formData, }) => {
<>
<Grid item xs={12} md={12} lg={12}
sx={{ display: 'flex', alignItems: 'center' }}>
<Typography variant="h5" display="inline">
<Typography variant="h5" component="span" display="inline">
<FormattedMessage id="commentDeadline" />:
</Typography>
</Grid>
<Grid item xs={12} md={12} lg={12} sx={{ mb: 4, display: 'flex', alignItems: 'center' }}>
<Typography variant="h5">&emsp;
<Typography variant="h5" component="span">&emsp;
{locale === 'en' ?
`${intl.formatMessage({ id: 'before' })} ${DateUtils.dateFormat(data?.reviseDeadline, intl.formatMessage({ id: "paymentMethodDatetimeStrFormat" }))?.replace("am", "a.m.")?.replace("pm", "p.m.")} `
:
@@ -278,12 +278,12 @@ const ApplicationDetailCard = ({ formData, }) => {

<Grid item xs={12} md={12} lg={12}
sx={{ display: 'flex', alignItems: 'center' }}>
<Typography variant="h5" display="inline">
<Typography variant="h5" component="span" display="inline">
<FormattedMessage id="paymentDeadline" />:
</Typography>
</Grid>
<Grid item xs={12} md={12} lg={12} sx={{ mb: 4, display: 'flex', alignItems: 'center' }}>
<Typography variant="h5">&emsp;
<Typography variant="h5" component="span">&emsp;
{locale === 'en' ?
`${intl.formatMessage({ id: 'before' })} ${DateUtils.dateFormat(data?.expiryDate, intl.formatMessage({ id: "paymentMethodDatetimeStrFormat" }))?.replace("am", "a.m.")?.replace("pm", "p.m.")} `
:
@@ -304,14 +304,14 @@ const ApplicationDetailCard = ({ formData, }) => {
</Typography>
</Grid>
<Grid item xs={12} sm={9} md={9} lg={9} sx={{ mb: 1, display: 'flex', alignItems: 'center' }}>
<Typography variant="h4" style={{ color: "#0049B8", fontWeight: "bold", }}>{FormatUtils.currencyFormat(data.fee)}</Typography>
<Typography variant="h4" component="span" style={{ color: "#0049B8", fontWeight: "bold", }}>{FormatUtils.currencyFormat(data.fee)}</Typography>
</Grid>
<Grid item xs={12} md={9} lg={9} sx={{ mb: 4, display: 'flex', alignItems: 'center' }}>
{
formik.values.groupType === "Private Bill"
?
<Typography>
<Typography variant="pnspsFormParagraph">( {data.noOfPages} {intl.formatMessage({ id: 'page' })} x $6,552 )</Typography>
<Typography variant="pnspsFormParagraph">( {data.noOfPages} {intl.formatMessage({ id: data.noOfPages === 1 ? 'page' : 'pages' })} x $6,552 )</Typography>
</Typography>
:
<Typography>


+ 17
- 16
src/pages/Proof/Reply_Public/ProofForm.js Просмотреть файл

@@ -24,6 +24,7 @@ import * as DateUtils from "utils/DateUtils"
import Loadable from 'components/Loadable';
import { notifyActionSuccess } from 'utils/CommonFunction';
import { PNSPS_BUTTON_THEME } from "themes/buttonConst";
import { PRIMARY_CONTAINED_BUTTON_SX } from "themes/colorConst";
import { ThemeProvider } from "@emotion/react";
import { FormattedMessage, useIntl } from "react-intl";
import {
@@ -251,7 +252,7 @@ const FormPanel = ({ formData }) => {
border={false}
content={false}>

<Typography variant="h4" sx={{ textAlign: "left", mb: 2, borderBottom: "1px solid black" }}>
<Typography variant="h4" component="h2" sx={{ textAlign: "left", mb: 2, borderBottom: "1px solid black" }}>
<FormattedMessage id="publicNoticePaymentProofComment" />
</Typography>

@@ -261,7 +262,7 @@ const FormPanel = ({ formData }) => {
formik.values.replyDate ?
<Grid container direction="column" sx={{ paddingLeft: 0, paddingRight: 0 }}>
<Grid item xs={12} sm={12} md={12} lg={8} textAlign="left">
<Typography variant="h5">
<Typography variant="h5" component="span">
<FormattedMessage id="proofReplyDate" /> :&nbsp;
{
locale === 'en' ?
@@ -272,7 +273,7 @@ const FormPanel = ({ formData }) => {
</Typography>
</Grid>
<Grid item xs={12} md={12} textAlign="left">
<Typography variant="h5">
<Typography variant="h5" component="span">
<FormattedMessage id="proofReply" /> : {formik.values.action ?
(<span style={{ color: 'green' }}>
<FormattedMessage id="proofErrorFree" />
@@ -284,7 +285,7 @@ const FormPanel = ({ formData }) => {
</Typography>
</Grid>
{/* <Grid item xs={12} md={12} textAlign="left">
<Typography variant="h5">
<Typography variant="h5" component="span">
<FormattedMessage id="proofReply" /> :&nbsp;
<span style={{ color: 'green' }}>
{
@@ -321,7 +322,7 @@ const FormPanel = ({ formData }) => {
isOverTime() ?
<Grid container direction="column" sx={{ paddingLeft: 0, paddingRight: 0 }} spacing={1}>
<Grid item xs={12} md={12} textAlign="left">
<Typography variant="h5"><FormattedMessage id="MSG.proofOutOfTime" /></Typography>
<Typography variant="h5" component="span"><FormattedMessage id="MSG.proofOutOfTime" /></Typography>
</Grid>
</Grid>
:
@@ -380,7 +381,7 @@ const FormPanel = ({ formData }) => {
<li><FormattedMessage id="store" /></li>
<li><FormattedMessage id="post" /></li>
</ul>
<Typography variant="h6">
<Typography variant="h6" component="span">
<div style={{ padding: 12 }} dangerouslySetInnerHTML={{ __html: intl.formatMessage({ id: "proofNote" }) }} />
</Typography>
</>
@@ -534,7 +535,7 @@ const FormPanel = ({ formData }) => {
<li><FormattedMessage id="store" /></li>
<li><FormattedMessage id="post" /></li>
</ul>
<Typography variant="h6">
<Typography variant="h6" component="span">
<div style={{ padding: 12 }} dangerouslySetInnerHTML={{ __html: intl.formatMessage({ id: "proofNote" }) }} />
</Typography>
</>
@@ -597,13 +598,13 @@ const FormPanel = ({ formData }) => {
</Grid>
}
{/* <Grid item xs={12}>
<Typography variant="h6" height="100%" >
<Typography variant="h6" component="span" height="100%" >
<div style={{ padding: 12 }} dangerouslySetInnerHTML={{ __html: intl.formatMessage({ id: "proofNote" }) }} />
</Typography>
</Grid> */}
{!isOnlyOnlinePayment?
<Grid item xs={12}>
<Typography variant="h6" height="100%" >
<Typography variant="h6" component="span" height="100%" >
<div style={{ padding: 12 }} dangerouslySetInnerHTML={{ __html: intl.formatMessage({ id: "proofImportant" }) }} />
</Typography>
</Grid>:null
@@ -617,14 +618,14 @@ const FormPanel = ({ formData }) => {
{
isOverReviseDeadline() ?
<Grid item xs={12} md={12} textAlign="left">
<Typography variant="h5" style={{ color: "red" }}>
<Typography variant="h5" component="span" style={{ color: "red" }}>
<FormattedMessage id="MSG.overReviseDeadline" />
</Typography>
</Grid>
:
<>
<Grid item xs={12} md={12} textAlign="left">
<Typography variant="h5">
<Typography variant="h5" component="span">
<FormattedMessage id="requiredUploadFix" />:
</Typography>
</Grid>
@@ -632,10 +633,10 @@ const FormPanel = ({ formData }) => {
<Grid item xs={12} md={12} textAlign="left">
<ThemeProvider theme={PNSPS_BUTTON_THEME}>
<Button
color="save"
variant="contained"
type="button"
aria-label={intl.formatMessage({ id: 'upload' })}
sx={PRIMARY_CONTAINED_BUTTON_SX}
disabled={attachments.length >= (formik.values.groupType === "Private Bill" ? 2 : 1)}
onClick={() => {
if (fileInputRef.current) {
@@ -683,7 +684,7 @@ const FormPanel = ({ formData }) => {
<Grid item xs={12} sm={12} md={12} lg={12}>
<Stack direction="row" alignItems="center">
<FormLabel sx={{ paddingRight: 2, paddingBottom: 3, textAlign: "center" }}>
<Typography variant="h5">
<Typography variant="h5" component="span">
<FormattedMessage id="sign" />:
</Typography>
</FormLabel>
@@ -718,9 +719,9 @@ const FormPanel = ({ formData }) => {
disabled={(actionValue == false && isOverReviseDeadline()) || isSubmitting}
aria-label={intl.formatMessage({ id: 'submitReply' })}
sx={{
backgroundColor: '#0C489E',
backgroundColor: '#0c489e',
color: '#FFFFFF',
'&:hover': { backgroundColor: '#093A7A' },
'&:hover': { backgroundColor: '#1565c0' },
}}
>
{isSubmitting ? <FormattedMessage id="loading" /> : <FormattedMessage id="submitReply" />}
@@ -753,7 +754,7 @@ const FormPanel = ({ formData }) => {
{warningTitle}
</DialogTitle>
<DialogContent style={{ display: 'flex', }}>
<Typography variant="h5" style={{ padding: '16px' }}>{warningText}</Typography>
<Typography variant="h5" component="span" style={{ padding: '16px' }}>{warningText}</Typography>
</DialogContent>
<DialogActions>
<Button


+ 4
- 23
src/pages/Proof/Reply_Public/UploadFileTable.js Просмотреть файл

@@ -2,18 +2,15 @@
import * as React from 'react';
import {
DataGrid,
GridActionsCellItem,
GridRowModes
} from "@mui/x-data-grid";
import RemoveCircleOutlineIcon from '@mui/icons-material/RemoveCircleOutline';
import {useEffect} from "react";
// import {useNavigate} from "react-router-dom";
// import { useTheme } from '@mui/material/styles';
import {
Stack, useMediaQuery
} from '@mui/material';
import {useTheme} from "@emotion/react";
import {useIntl} from "react-intl";
import { createDeleteFileColumn } from 'utils/fileListColumns';
// ==============================|| EVENT TABLE ||============================== //

export default function UploadFileTable({recordList, setRecordList,}) {
@@ -54,26 +51,10 @@ export default function UploadFileTable({recordList, setRecordList,}) {
setRows(rows.filter((row) => row.id !== id));
}

const deleteColumn = createDeleteFileColumn((id) => handleCancelClick(id));

const columns = [
{
field: 'actions',
type: 'actions',
headerName: '',
width: 30,
cellClassName: 'actions',
// hide:true,
getActions: ({id}) => {
return [
<GridActionsCellItem
key="OutSave"
icon={<RemoveCircleOutlineIcon/>}
label="delete"
className="textPrimary"
onClick={handleCancelClick(id)}
color="error"
/>]
},
},
deleteColumn,
{
id: 'name',
field: 'name',


+ 1
- 1
src/pages/Proof/Search_GLD/index.js Просмотреть файл

@@ -86,7 +86,7 @@ const UserSearchPage_Individual = () => {
<Grid item xs={12}>
<div style={BackgroundHead}>
<Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center">
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0C489E" }}>Proof</Typography>
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0c489e" }}>Proof</Typography>
</Stack>
</div>
</Grid>


+ 7
- 5
src/pages/PublicNotice/ApplyForm/PublicNoticeApplyForm.js Просмотреть файл

@@ -33,6 +33,7 @@ import { ThemeProvider } from "@emotion/react";
import { FormattedMessage, useIntl } from "react-intl";
import { useState, useEffect, useRef } from 'react';
import { checkPaymentSuspension } from "utils/Utils";
import { PRIMARY_CONTAINED_BUTTON_SX } from "themes/colorConst";

// ==============================|| DASHBOARD - DEFAULT ||============================== //

@@ -457,7 +458,7 @@ const PublicNoticeApplyForm = ({ loadedData, _selections, gazetteIssueList }) =>
<li><FormattedMessage id="store" /></li>
<li><FormattedMessage id="post" /></li>
</ul>
<Typography variant="h6">
<Typography variant="h6" component="span">
<div style={{ padding: 12 }} dangerouslySetInnerHTML={{ __html: intl.formatMessage({ id: "proofNote" }) }} />
</Typography>
</>
@@ -545,8 +546,9 @@ const PublicNoticeApplyForm = ({ loadedData, _selections, gazetteIssueList }) =>
<Button
aria-label={intl.formatMessage({ id: 'uploadFileBtn' })}
component="span"
variant="outlined"
variant="contained"
size="large"
sx={PRIMARY_CONTAINED_BUTTON_SX}
>{attachment ? intl.formatMessage({ id: 'uploadFileBtn' }) : intl.formatMessage({ id: 'reUpload' })}</Button>
</label>
</Grid>
@@ -627,7 +629,7 @@ const PublicNoticeApplyForm = ({ loadedData, _selections, gazetteIssueList }) =>
"aria-label": intl.formatMessage({ id: "applyTickStr" })
}}
/>
<Typography variant="h6" height="100%" >
<Typography variant="h6" component="span" height="100%" >
<div style={{ padding: 12, textAlign: 'justify' }} dangerouslySetInnerHTML={{ __html: intl.formatMessage({ id: "applyTickStr" }) }} />
</Typography>
</Stack>
@@ -650,7 +652,7 @@ const PublicNoticeApplyForm = ({ loadedData, _selections, gazetteIssueList }) =>
</Grid>

<Grid item xs={12}>
<Typography variant="h6" height="100%" >
<Typography variant="h6" component="span" height="100%" >
<div style={{ padding: 12 }} dangerouslySetInnerHTML={{ __html: intl.formatMessage({ id: "applyPublicNoticeText" }) }} />
</Typography>
</Grid>
@@ -676,7 +678,7 @@ const PublicNoticeApplyForm = ({ loadedData, _selections, gazetteIssueList }) =>
{warningTitle}
</DialogTitle>
<DialogContent style={{ display: 'flex', }}>
<Typography variant="h5" style={{ padding: '16px' }}>
<Typography variant="h5" component="span" style={{ padding: '16px' }}>
{warningText}
</Typography>
</DialogContent>


+ 2
- 2
src/pages/PublicNotice/Details_GLD/ApplicationDetailCard.js Просмотреть файл

@@ -749,9 +749,9 @@ const ApplicationDetailCard = (
sx={{
textTransform: 'capitalize',
alignItems: 'end',
backgroundColor: '#0C489E',
backgroundColor: '#0c489e',
color: '#FFFFFF',
'&:hover': { backgroundColor: '#093A7A' },
'&:hover': { backgroundColor: '#1565c0' },
}}
>
<DownloadIcon />


+ 17
- 12
src/pages/PublicNotice/Details_Public/ApplicationDetailCard.js Просмотреть файл

@@ -40,6 +40,7 @@ import CloseIcon from '@mui/icons-material/Close';
import EditNoteIcon from '@mui/icons-material/EditNote';
import DownloadIcon from '@mui/icons-material/Download';
import { PNSPS_BUTTON_THEME } from "../../../themes/buttonConst";
import { PRIMARY_CONTAINED_BUTTON_SX } from "themes/colorConst";
import { ThemeProvider } from "@emotion/react";
import { FormattedMessage, useIntl } from "react-intl";
// ==============================|| DASHBOARD - DEFAULT ||============================== //
@@ -239,9 +240,9 @@ const ApplicationDetailCard = (
startIcon={<CloseIcon />}
aria-label={intl.formatMessage({ id: 'cancelApp' })}
sx={{
backgroundColor: '#0C489E',
backgroundColor: '#0c489e',
color: '#FFFFFF',
'&:hover': { backgroundColor: '#093A7A' },
'&:hover': { backgroundColor: '#1565c0' },
}}
>
<FormattedMessage id="cancelApp" />
@@ -253,7 +254,7 @@ const ApplicationDetailCard = (
</div>
:null
}
<Typography variant="h4" sx={{ mb: 2, borderBottom: "1px solid black" }}>
<Typography variant="h4" component="h3" sx={{ mb: 2, borderBottom: "1px solid black" }}>
<FormattedMessage id="publicNoticeDetailTitle" />
</Typography>
<form>
@@ -665,9 +666,9 @@ const ApplicationDetailCard = (
<Button
sx={{
ml: 3,
backgroundColor: '#0C489E',
backgroundColor: '#0c489e',
color: '#FFFFFF',
'&:hover': { backgroundColor: '#093A7A' },
'&:hover': { backgroundColor: '#1565c0' },
}}
variant="contained"
onClick={onDownloadClick()}
@@ -752,30 +753,34 @@ const ApplicationDetailCard = (
}}
>
<DialogTitle>
<Typography variant="h3" >
<Typography variant="h3" component="span">
<FormattedMessage id="payConfirm" />
</Typography>
</DialogTitle>
<DialogContent style={{ display: 'flex', }}>
<Stack direction="column" justifyContent="space-between">
<Typography variant="h4">
<Typography variant="h4" component="span">
<FormattedMessage id="totalAmount" /> ($): {FormatUtils.currencyFormat(fee)}
</Typography>
</Stack>
</DialogContent>
<DialogActions>
<Button
variant="contained"
onClick={() => setIsPopUp(false)}
aria-label={intl.formatMessage({ id: 'close' })}
sx={PRIMARY_CONTAINED_BUTTON_SX}
>
<Typography variant="pnspsFormParagraph">
<Typography variant="pnspsFormParagraph" sx={{ color: 'inherit' }}>
<FormattedMessage id="close" />
</Typography></Button>
<Button
variant="contained"
onClick={() => doPayment()}
aria-label={intl.formatMessage({ id: 'confirm' })}
sx={PRIMARY_CONTAINED_BUTTON_SX}
>
<Typography variant="pnspsFormParagraph">
<Typography variant="pnspsFormParagraph" sx={{ color: 'inherit' }}>
<FormattedMessage id="confirm" />
</Typography></Button>
</DialogActions>
@@ -794,7 +799,7 @@ const ApplicationDetailCard = (
}}
>
<DialogTitle></DialogTitle>
<Typography variant="h2" style={{ padding: '16px' }}><FormattedMessage id="MSG.actionFail" /></Typography>
<Typography variant="h2" component="span" style={{ padding: '16px' }}><FormattedMessage id="MSG.actionFail" /></Typography>
<DialogContent style={{ display: 'flex', }}>
<Stack direction="column" justifyContent="space-between">
{
@@ -826,7 +831,7 @@ const ApplicationDetailCard = (
}}
>
<DialogTitle></DialogTitle>
<Typography variant="h4" style={{ paddingLeft: '24px' }}><FormattedMessage id="MSG.actionFail" /></Typography>
<Typography variant="h4" component="span" style={{ paddingLeft: '24px' }}><FormattedMessage id="MSG.actionFail" /></Typography>
<DialogContent style={{ display: 'flex', }}>
<Stack direction="column" justifyContent="space-between">
<div dangerouslySetInnerHTML={{ __html: intl.formatMessage({ id: 'MSG.paymentHolded' }, { appNo: paymentHoldedErrText }) }} />
@@ -834,7 +839,7 @@ const ApplicationDetailCard = (
</DialogContent>
<DialogActions>
<Button onClick={() => setPaymentHoldedErr(false)} aria-label={intl.formatMessage({ id: 'close' })}>
<Typography variant="h5">
<Typography variant="h5" component="span">
<FormattedMessage id="close" />
</Typography></Button>
</DialogActions>


+ 2
- 1
src/pages/PublicNotice/Details_Public/index.js Просмотреть файл

@@ -34,6 +34,7 @@ import ForwardIcon from '@mui/icons-material/Forward';
import { notifyActionSuccess } from "utils/CommonFunction";
import { FormattedMessage, useIntl } from "react-intl";
import usePageTitle from "components/usePageTitle";
import { PRIMARY_OUTLINED_BUTTON_SX } from "themes/colorConst";
// ==============================|| Body - DEFAULT ||============================== //

const DashboardDefault = () => {
@@ -190,7 +191,7 @@ const DashboardDefault = () => {
<Button
aria-label={intl.formatMessage({ id: 'back' })}
title={intl.formatMessage({ id: 'back' })}
sx={{ ml: 0, mt: 2.5 }} style={{ border: '2px solid' }}
sx={{ ml: 0, mt: 2.5, borderWidth: '2px', ...PRIMARY_OUTLINED_BUTTON_SX }}
variant="outlined" onClick={() => { navigate("/publicNotice") }}
>
<ForwardIcon style={{ height: 30, width: 50, transform: "rotate(180deg)" }} />


+ 2
- 1
src/pages/PublicNotice/ListPanel/BaseGrid.js Просмотреть файл

@@ -15,6 +15,7 @@ import {
import {useTheme} from "@emotion/react";
import {getStatusIntl,getModeIntl } from "utils/statusUtils/PublicNoteStatusUtils";
import {FormattedMessage, useIntl} from "react-intl";
import { PRIMARY_TEXT_BUTTON_SX } from "themes/colorConst";

// ==============================|| EVENT TABLE ||============================== //

@@ -106,7 +107,7 @@ export default function BaseGrid({setCount, url}) {
renderHeader: renderHeaderWithAria,
cellClassName: 'actions',
renderCell: (params) => {
return <Button aria-label={intl.formatMessage({id: 'viewDetail'})} onClick={handleDetailClick(params)}>
return <Button aria-label={intl.formatMessage({id: 'viewDetail'})} onClick={handleDetailClick(params)} sx={PRIMARY_TEXT_BUTTON_SX}>
<FormattedMessage id="viewDetail"/>
</Button>;
},


+ 6
- 5
src/pages/PublicNotice/ListPanel/PendingPaymentTab.js Просмотреть файл

@@ -29,6 +29,7 @@ import {
import { ThemeProvider, useTheme } from "@emotion/react";
import { PNSPS_BUTTON_THEME } from "../../../themes/buttonConst";
import { FormattedMessage, useIntl } from "react-intl";
import { PRIMARY_TEXT_BUTTON_SX, PRIMARY_CONTAINED_BUTTON_SX } from "themes/colorConst";
// ==============================|| EVENT TABLE ||============================== //

export default function SubmittedTab({ setCount, url }) {
@@ -309,7 +310,7 @@ export default function SubmittedTab({ setCount, url }) {
renderHeader: renderHeaderWithAria,
cellClassName: 'actions',
renderCell: (params) => {
return <Button aria-label={intl.formatMessage({ id: 'viewDetail' })} onClick={handleDetailClick(params)}>
return <Button aria-label={intl.formatMessage({ id: 'viewDetail' })} onClick={handleDetailClick(params)} sx={PRIMARY_TEXT_BUTTON_SX}>
<FormattedMessage id="viewDetail" />
</Button>;
},
@@ -484,13 +485,13 @@ export default function SubmittedTab({ setCount, url }) {
</Stack>
</DialogContent>
<DialogActions>
<Button onClick={() => setIsPopUp(false)} aria-label={intl.formatMessage({ id: 'close' })}>
<Typography variant="h5">
<Button variant="contained" onClick={() => setIsPopUp(false)} aria-label={intl.formatMessage({ id: 'close' })} sx={PRIMARY_CONTAINED_BUTTON_SX}>
<Typography variant="h5" sx={{ color: 'inherit' }}>
<FormattedMessage id="close" />
</Typography></Button>

<Button onClick={() => doPayment()} aria-label={intl.formatMessage({ id: 'confirm' })}>
<Typography variant="h5">
<Button variant="contained" onClick={() => doPayment()} aria-label={intl.formatMessage({ id: 'confirm' })} sx={PRIMARY_CONTAINED_BUTTON_SX}>
<Typography variant="h5" sx={{ color: 'inherit' }}>
<FormattedMessage id="confirm" />
</Typography></Button>
</DialogActions>


+ 2
- 0
src/pages/PublicNotice/ListPanel/SearchPublicNoticeTable.js Просмотреть файл

@@ -17,6 +17,7 @@ import {getModeIntl } from "utils/statusUtils/PublicNoteStatusUtils";
import { useTheme } from "@emotion/react";
import { FormattedMessage, useIntl } from "react-intl";
import * as React from 'react';
import { PRIMARY_TEXT_BUTTON_SX } from "themes/colorConst";
// ==============================|| EVENT TABLE ||============================== //

export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnReady, applySearch }) {
@@ -139,6 +140,7 @@ export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnRea
renderCell: (params) => {
return <Button onClick={handleDetailClick(params)}
aria-label={intl.formatMessage({ id: 'viewDetail' })}
sx={PRIMARY_TEXT_BUTTON_SX}
>
<FormattedMessage id="viewDetail" />
</Button>;


+ 1
- 1
src/pages/PublicNotice/Search_GLD/index.js Просмотреть файл

@@ -84,7 +84,7 @@ const UserSearchPage_Individual = () => {
<Grid item xs={12}>
<div style={BackgroundHead}>
<Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center">
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0C489E" }}>Application</Typography>
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0c489e" }}>Application</Typography>
</Stack>
</div>
</Grid>


+ 1
- 1
src/pages/PublicNotice/Search_Mark_As_Paid_GLD/index.js Просмотреть файл

@@ -84,7 +84,7 @@ const UserSearchPage_Individual = () => {
<Grid item xs={12}>
<div style={BackgroundHead}>
<Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center">
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0C489E" }}>Mark Payment</Typography>
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0c489e" }}>Mark Payment</Typography>
</Stack>
</div>
</Grid>


+ 1
- 1
src/pages/Recon/index.js Просмотреть файл

@@ -125,7 +125,7 @@ const Index = () => {
<Grid item xs={12}>
<div style={BackgroundHead}>
<Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center">
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0C489E" }}>
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0c489e" }}>
Recon Report
</Typography>
</Stack>


+ 1
- 1
src/pages/Report/FullList/index.js Просмотреть файл

@@ -74,7 +74,7 @@ const ReportSearchPage = () => {
<Grid item xs={12} mb={2}>
<div style={BackgroundHead}>
<Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center">
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0C489E" }}>Gazette Notice Full List</Typography>
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0c489e" }}>Gazette Notice Full List</Typography>
</Stack>
</div>
</Grid>


+ 1
- 1
src/pages/Report/Summary/index.js Просмотреть файл

@@ -74,7 +74,7 @@ const ReportSearchPage = () => {
<Grid item xs={12} mb={2}>
<div style={BackgroundHead}>
<Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center">
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0C489E" }}>Summary of Gazette Notice</Typography>
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0c489e" }}>Summary of Gazette Notice</Typography>
</Stack>
</div>
</Grid>


+ 3
- 0
src/pages/Setting/DrImport/index.js Просмотреть файл

@@ -14,6 +14,7 @@ import { notifyActionError } from 'utils/CommonFunction';
import { FormattedMessage, useIntl } from "react-intl";

import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png'
import { PRIMARY_OUTLINED_BUTTON_SX } from 'themes/colorConst';

// ==============================|| DASHBOARD - DEFAULT ||============================== //

@@ -168,6 +169,7 @@ const Index = () => {
component="span"
variant="outlined"
size="large"
sx={PRIMARY_OUTLINED_BUTTON_SX}
>Import DR Excel</Button>
</label>
</Grid>
@@ -199,6 +201,7 @@ const Index = () => {
component="span"
variant="outlined"
size="large"
sx={PRIMARY_OUTLINED_BUTTON_SX}
>Import Offline Mode Application</Button>
</label>
</Grid>


+ 101
- 0
src/pages/Setting/HkidKeyMigration/index.js Просмотреть файл

@@ -0,0 +1,101 @@
import * as React from "react";
import * as HttpUtils from "utils/HttpUtils";
import * as DateUtils from "utils/DateUtils";
import * as UrlUtils from "utils/ApiPathConst";

import {
Grid, Typography, Button,
Stack, Box, CircularProgress,
} from '@mui/material';
import { notifyActionError } from 'utils/CommonFunction';

import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png'

const formatLog = (responData) => {
if (responData?.msg && !responData?.log) {
return <>{DateUtils.datetimeStr(new Date())}<br/><span style={{ color: "red" }}>Error</span><br/>{responData.msg}</>;
}
const statusColor = responData?.success ? "green" : "red";
const statusText = responData?.success ? "Success" : "Completed with errors";
const logText = (responData?.log || []).join("\n");
return (
<>
{DateUtils.datetimeStr(new Date())}<br/>
<span style={{ color: statusColor }}>{responData?.dryRun ? "Dry-run " : ""}{statusText}</span><br/>
Total: {responData?.total ?? 0}, OK: {responData?.successCount ?? 0}, Skipped: {responData?.skipped ?? 0}, Failed: {responData?.failed ?? 0}<br/>
<span style={{ whiteSpace: "pre-line" }}>{logText}</span>
</>
);
};

const HkidKeyMigration = () => {
const [resultStr, setResultStr] = React.useState("");
const [wait, setWait] = React.useState(false);

const BackgroundHead = {
backgroundImage: `url(${titleBackgroundImg})`,
width: 'auto',
height: 'auto',
backgroundSize: 'contain',
backgroundRepeat: 'no-repeat',
backgroundColor: '#0C489E',
backgroundPosition: 'right'
};

const runMigration = (dryRun) => {
setWait(true);
HttpUtils.post({
url: `${UrlUtils.HKID_REKEY_MIGRATION}?dryRun=${dryRun}&batchSize=100`,
params: {},
onSuccess: function (responData) {
setWait(false);
setResultStr(formatLog(responData));
},
onError: function () {
setWait(false);
notifyActionError("HKID re-key migration failed");
}
});
};

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" }}>
HKID Key Migration
</Typography>
</Stack>
</div>
</Grid>

<Grid item xs={12} sx={{ backgroundColor: '#ffffff', ml: 2, mt: 1 }} width="98%">
<Box sx={{ borderRadius: '10px', backgroundColor: '#fff', p: 4 }}>
<Typography variant="body1" sx={{ mb: 2 }}>
Re-encrypt identification and checkDigit from the legacy key to the new key.
Ensure Tomcat has both <code>security.hkid-secret</code> and <code>security.hkid-secret-legacy</code> configured before running.
</Typography>
<Stack direction="row" spacing={2}>
<Button variant="outlined" size="large" disabled={wait} onClick={() => runMigration(true)}>
Dry Run
</Button>
<Button variant="contained" size="large" disabled={wait} onClick={() => runMigration(false)}>
Run Migration
</Button>
{wait ? <CircularProgress size={32} /> : null}
</Stack>
</Box>
</Grid>

<Grid item xs={12} sx={{ backgroundColor: '#ffffff', ml: 2, mt: 1, mb: 2 }} width="98%">
<Box sx={{ borderRadius: '10px', backgroundColor: '#fff', p: 4 }}>
<Typography variant="h4">Result:</Typography>
<Box sx={{ pl: 2, pt: 2 }}>{resultStr}</Box>
</Box>
</Grid>
</Grid>
);
};

export default HkidKeyMigration;

+ 133
- 0
src/pages/Setting/UserPiiEncryption/index.js Просмотреть файл

@@ -0,0 +1,133 @@
import * as React from "react";
import * as HttpUtils from "utils/HttpUtils";
import * as DateUtils from "utils/DateUtils";
import * as UrlUtils from "utils/ApiPathConst";

import {
Grid, Typography, Button,
Stack, Box, CircularProgress,
} from '@mui/material';
import { notifyActionError } from 'utils/CommonFunction';

import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png'

const formatEncryptLog = (responData) => {
if (responData?.msg && !responData?.log) {
return <>{DateUtils.datetimeStr(new Date())}<br/><span style={{ color: "red" }}>Error</span><br/>{responData.msg}</>;
}
const statusColor = responData?.success ? "green" : "red";
const statusText = responData?.success ? "Success" : "Completed with errors";
const logText = (responData?.log || []).join("\n");
return (
<>
{DateUtils.datetimeStr(new Date())}<br/>
<span style={{ color: statusColor }}>{responData?.dryRun ? "Dry-run " : ""}{statusText}</span><br/>
Total: {responData?.total ?? 0}, OK: {responData?.successCount ?? 0}, Skipped: {responData?.skipped ?? 0}, Failed: {responData?.failed ?? 0}<br/>
<span style={{ whiteSpace: "pre-line" }}>{logText}</span>
</>
);
};

const formatVerifyLog = (responData) => {
const tests = responData?.tests || [];
const logText = tests.map(t => `${t.passed ? "PASS" : "FAIL"} - ${t.name}: ${t.message}`).join("\n");
const statusColor = responData?.success ? "green" : "red";
return (
<>
{DateUtils.datetimeStr(new Date())}<br/>
<span style={{ color: statusColor }}>{responData?.success ? "All tests passed" : "Some tests failed"}</span><br/>
Passed: {responData?.passed ?? 0}, Failed: {responData?.failed ?? 0}<br/>
<span style={{ whiteSpace: "pre-line" }}>{logText}</span>
</>
);
};

const UserPiiEncryption = () => {
const [resultStr, setResultStr] = React.useState("");
const [wait, setWait] = React.useState(false);

const BackgroundHead = {
backgroundImage: `url(${titleBackgroundImg})`,
width: 'auto',
height: 'auto',
backgroundSize: 'contain',
backgroundRepeat: 'no-repeat',
backgroundColor: '#0C489E',
backgroundPosition: 'right'
};

const runEncrypt = (dryRun) => {
setWait(true);
HttpUtils.post({
url: `${UrlUtils.USER_PII_ENCRYPT_MIGRATION}?dryRun=${dryRun}&batchSize=100`,
params: {},
onSuccess: function (responData) {
setWait(false);
setResultStr(formatEncryptLog(responData));
},
onError: function () {
setWait(false);
notifyActionError("User PII encryption failed");
}
});
};

const runVerify = () => {
setWait(true);
HttpUtils.post({
url: UrlUtils.USER_PII_VERIFY_MIGRATION,
params: {},
onSuccess: function (responData) {
setWait(false);
setResultStr(formatVerifyLog(responData));
},
onError: function () {
setWait(false);
notifyActionError("User PII verification failed");
}
});
};

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" }}>
User PII Encryption
</Typography>
</Stack>
</div>
</Grid>

<Grid item xs={12} sx={{ backgroundColor: '#ffffff', ml: 2, mt: 1 }} width="98%">
<Box sx={{ borderRadius: '10px', backgroundColor: '#fff', p: 4 }}>
<Typography variant="body1" sx={{ mb: 2 }}>
Encrypt enName, chName, mobileNumber, and address for existing user records, then verify data retrieval.
</Typography>
<Stack direction="row" spacing={2} flexWrap="wrap">
<Button variant="outlined" size="large" disabled={wait} onClick={() => runEncrypt(true)}>
Dry Run Encrypt
</Button>
<Button variant="contained" size="large" disabled={wait} onClick={() => runEncrypt(false)}>
Run Encrypt
</Button>
<Button variant="contained" color="secondary" size="large" disabled={wait} onClick={runVerify}>
Verify Retrieval
</Button>
{wait ? <CircularProgress size={32} /> : null}
</Stack>
</Box>
</Grid>

<Grid item xs={12} sx={{ backgroundColor: '#ffffff', ml: 2, mt: 1, mb: 2 }} width="98%">
<Box sx={{ borderRadius: '10px', backgroundColor: '#fff', p: 4 }}>
<Typography variant="h4">Result:</Typography>
<Box sx={{ pl: 2, pt: 2 }}>{resultStr}</Box>
</Box>
</Grid>
</Grid>
);
};

export default UserPiiEncryption;

+ 10
- 10
src/pages/User/ChangePasswordPage/index.js Просмотреть файл

@@ -215,13 +215,13 @@ const Index = () => {
<Grid container spacing={4} sx={{ minHeight: {xs:"80vh", sm:"50vh", md: "50vh", lg:"70vh", xl:"50vh"} }} direction="column" justifyContent="flex-start" alignItems="center">
{isPasswordExpiry()?
<Grid item width="70%" xs={12} md={12} lg={12} sx={{ mb: 1, mt:2 }}>
<Typography variant="h5">
<Typography variant="h5" component="span">
<FormattedMessage id="passwordExpired"/>
</Typography>
</Grid>
:
<Grid item xs={12} md={12} lg={12} sx={{ mb: 1, mt:2 }}>
<Typography variant="h5" >
<Typography variant="h5" component="span">
<FormattedMessage id="setNewPassword"/>
</Typography>
</Grid>
@@ -433,14 +433,14 @@ const Index = () => {
<DialogTitle></DialogTitle>
<DialogContent style={{ display: 'flex', }}>
<Stack direction="column" justifyContent="space-between">
<Typography variant="h5" style={{ padding: '10px' }}>
<Typography variant="h5" component="span" style={{ padding: '10px' }}>
<FormattedMessage id ="changePasswordConfirm"/>
</Typography>
</Stack>
</DialogContent>
<DialogActions>
<Button disabled={isChangingPassword} onClick={() => setComfirmChangeMessage(false)}>
<Typography variant="h5">
<Typography variant="h5" component="span">
<FormattedMessage id="close"/>
</Typography>
</Button>
@@ -449,7 +449,7 @@ const Index = () => {
onClick={() => goLogin(changePasswordValues)}
startIcon={isChangingPassword ? <CircularProgress color="inherit" size={18} /> : null}
>
<Typography variant="h5">
<Typography variant="h5" component="span">
<FormattedMessage id="confirm"/>
</Typography>
</Button>
@@ -468,13 +468,13 @@ const Index = () => {
}}
>
<DialogTitle>
<Typography variant="h5" style={{ padding: '10px' }}>
<Typography variant="h5" component="span" style={{ padding: '10px' }}>
<FormattedMessage id ="MSG.actionFail"/>
</Typography>
</DialogTitle>
<DialogContent style={{ display: 'flex', }}>
<Stack direction="column" justifyContent="space-between">
<Typography variant="h5">
<Typography variant="h5" component="span">
{
expiryErrText
}
@@ -483,7 +483,7 @@ const Index = () => {
</DialogContent>
<DialogActions>
<Button onClick={() => setExpiryErr(false)}>
<Typography variant="h5">
<Typography variant="h5" component="span">
<FormattedMessage id="close"/>
</Typography>
</Button>
@@ -498,13 +498,13 @@ const Index = () => {
<CheckCircleOutlineIcon color="success" sx={{ width: "200px", height: "200px" }} />
</Grid>
<Grid item xs={12} md={12} lg={12} sx={{ mb: 1, mt:5,}}>
<Typography display="inline" variant="h4">
<Typography display="inline" variant="h4" component="span">
<FormattedMessage id="resetPasswordSuccess"/>
</Typography>
</Grid>
<Grid item xs={12} md={12} lg={12} sx={{ mb: 1, mt:5,}}>
<Button color="success" variant="outlined" onClick={()=>logout()}>
<Typography variant="h5">
<Typography variant="h5" component="span">
<FormattedMessage id="backToLogin"/>
</Typography>
</Button>


+ 1
- 1
src/pages/User/DetailPage/index.js Просмотреть файл

@@ -242,7 +242,7 @@ const UserMaintainPage = () => {
<Grid item xs={12}>
<div style={BackgroundHead}>
<Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center">
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0C489E" }}>{isNewRecord ? "Create GLD User" : "Maintain GLD User"}</Typography>
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0c489e" }}>{isNewRecord ? "Create GLD User" : "Maintain GLD User"}</Typography>
</Stack>
</div>
</Grid>


+ 23
- 6
src/pages/User/DetailsPage_Individual/UserInformationCard_Individual.js Просмотреть файл

@@ -17,6 +17,7 @@ import * as ComboData from "utils/ComboData";
const LoadingComponent = Loadable(lazy(() => import('../../extra-pages/LoadingComponent')));
import Loadable from 'components/Loadable';
import { notifyActiveSuccess, notifyLockSuccess, notifySaveSuccess, notifyVerifySuccess } from 'utils/CommonFunction';
import { PRIMARY_CONTAINED_BUTTON_SX } from 'themes/colorConst';
import { useIntl } from "react-intl";
import { PNSPS_BUTTON_THEME } from "themes/buttonConst";
import { ThemeProvider } from "@emotion/react";
@@ -80,7 +81,10 @@ const UserInformationCard_Individual = ({ formData, loadDataFun }) => {
addressLine3: yup.string().max(40, getMaxErrStr(40)).nullable(),
emailAddress: yup.string().email(intl.formatMessage({ id: 'validEmailFormat' })).max(255).required(intl.formatMessage({ id: 'requireEmail' })),
idDocType: yup.string().max(255, getMaxErrStr(255)).required(intl.formatMessage({ id: 'requireIdDocType' })),
identification: yup.string().required(getRequiredErrStr('number'))
identification: yup.string().when('verifiedBy', {
is: (verifiedBy) => verifiedBy != null,
then: (schema) => schema.notRequired(),
otherwise: (schema) => schema.required(getRequiredErrStr('number'))
.matches(/^[aA-zZ0-9\s]+$/, { message: displayErrorMsg(`${selectedIdDocInputType}${intl.formatMessage({ id: 'noSpecialCharacter' })}`) })
.matches(/^\S*$/, { message: displayErrorMsg(`${selectedIdDocInputType}${intl.formatMessage({ id: 'noSpace' })}`) })
.test('checkIDCardFormat', displayErrorMsg(`${intl.formatMessage({ id: 'requiredValid' })}${selectedIdDocInputType}${intl.formatMessage({ id: 'number' })}`), function (value) {
@@ -132,8 +136,12 @@ const UserInformationCard_Individual = ({ formData, loadDataFun }) => {
break;
}
}
})
}),
checkDigit: yup.string().max(1, getMaxErrStr(1)).nullable()
checkDigit: yup.string().when('verifiedBy', {
is: (verifiedBy) => verifiedBy != null,
then: (schema) => schema.notRequired(),
otherwise: (schema) => schema.max(1, getMaxErrStr(1)).nullable()
.matches(/^[A-Z0-9\s]+$/, { message: displayErrorMsg(`${selectedIdDocInputType}${intl.formatMessage({ id: 'noSpecialCharacter' })}`) })
.test('checkIDCardFormat', displayErrorMsg(`${intl.formatMessage({ id: 'requiredNumberInQuote' })}`), function (value) {
// console.log(selectedIdDocInputType)
@@ -161,7 +169,8 @@ const UserInformationCard_Individual = ({ formData, loadDataFun }) => {
return false
}
}
}),
})
}),
tel_countryCode: yup.string().min(3, intl.formatMessage({ id: 'require3Number' })).required(intl.formatMessage({ id: 'requireDialingCode' })),
fax_countryCode: yup.string().min(3, intl.formatMessage({ id: 'require3Number' })),
phoneNumber: yup.string().min(8, intl.formatMessage({ id: 'require8Number' })).required(intl.formatMessage({ id: 'requireContactNumber' })),
@@ -185,8 +194,10 @@ const UserInformationCard_Individual = ({ formData, loadDataFun }) => {
countryCode: values.tel_countryCode,
phoneNumber: values.phoneNumber
},
identification: values.identification,
checkDigit: values.checkDigit,
...(values.verifiedBy == null ? {
identification: values.identification,
checkDigit: values.checkDigit,
} : {}),
faxNo: {
countryCode: values.fax_countryCode,
faxNumber: values.faxNumber
@@ -288,7 +299,7 @@ const UserInformationCard_Individual = ({ formData, loadDataFun }) => {
<Button
variant="contained"
type="submit"
color="success"
sx={PRIMARY_CONTAINED_BUTTON_SX}
>
Save
</Button>
@@ -470,6 +481,11 @@ const UserInformationCard_Individual = ({ formData, loadDataFun }) => {
</Grid>

<Grid item xs={12} sm={12} md={9} lg={6}>
{currentUserData.verifiedBy ?
<Typography variant="h5" mt={1}>
Hidden for security purpose
</Typography>
:
<Grid container>
{formik.values.idDocType === "HKID" ?
editMode ?
@@ -548,6 +564,7 @@ const UserInformationCard_Individual = ({ formData, loadDataFun }) => {
</Stack>
}
</Grid>
}
</Grid>
</Grid>
</Grid>


+ 5
- 86
src/pages/User/DetailsPage_Individual/UserInformationCard_Individual_Pub.js Просмотреть файл

@@ -2,8 +2,6 @@
import {
Grid, Button, Typography,
FormHelperText,
Stack,
IconButton
} from '@mui/material';
import MainCard from "components/MainCard";
import * as React from "react";
@@ -19,10 +17,10 @@ const LoadingComponent = Loadable(lazy(() => import('../../extra-pages/LoadingCo
import Loadable from 'components/Loadable';
import { lazy } from 'react';
import {notifySaveSuccess,} from 'utils/CommonFunction';
import { PRIMARY_CONTAINED_BUTTON_SX } from 'themes/colorConst';
import {FormattedMessage, useIntl} from "react-intl";
import {PNSPS_BUTTON_THEME} from "../../../themes/buttonConst";
import {ThemeProvider} from "@emotion/react";
import { EyeInvisibleOutlined, EyeOutlined } from '@ant-design/icons';
// ==============================|| DASHBOARD - DEFAULT ||============================== //


@@ -33,15 +31,6 @@ const UserInformationCard_Individual_Pub = ({ formData, loadDataFun }) => {
const [editMode, setEditMode] = useState(false);
const [onReady, setOnReady] = useState(false);
const [errorMsg, setErrorMsg] = useState("");
const [showId, setshowId] = useState(false);

const handleClickShowId = () => {
setshowId(!showId);
};

const handleMouseDownId = (event) => {
event.preventDefault();
};

useEffect(() => {
if (Object.keys(formData).length > 0) {
@@ -166,7 +155,7 @@ const UserInformationCard_Individual_Pub = ({ formData, loadDataFun }) => {
aria-label={intl.formatMessage({id: 'save'})}
variant="contained"
type="submit"
color="success"
sx={PRIMARY_CONTAINED_BUTTON_SX}
disabled={formik.isSubmitting}
>
<FormattedMessage id="save" />
@@ -251,79 +240,9 @@ const UserInformationCard_Individual_Pub = ({ formData, loadDataFun }) => {
</Grid>

<Grid item xs={12} sm={12} md={9} lg={6}>
<Grid container>
{formik.values.idDocType === "HKID" ?
// <>
// <Grid item xs={6} sm={6} md={6} lg={7.5} sx={{mr:1}}>
// {FieldUtils.initField({
// valueName: "identification",
// disabled: true,
// form: formik,
// placeholder: intl.formatMessage({id: 'idDocNumber'}),
// inputProps: {
// maxLength: 7,
// onKeyDown: (e) => {
// if (e.key === 'Enter') {
// e.preventDefault();
// }
// },
// }
// })}

// </Grid>
// <Grid item xs={2} sm={2} md={2} lg={2} style={{minWidth:40}}>
// {FieldUtils.initField({
// valueName: "checkDigit",
// disabled: true,
// form: formik,
// })}
// </Grid>
// </>
<Stack direction="row">
<Typography variant="h5" mt={1}>
{formik.values.identification?.slice(0, 4)}
</Typography>
<Typography variant="h5"mt={1}>
{/* {showId ?formik.values.identification.slice(4):"****"}{showId ? '(' + formik.values.checkDigit + ')' :null} */}
{showId ? formik.values.identification?.slice(4) : "****"}{showId ? formik.values.checkDigit?'(' +formik.values.checkDigit+ ')': "()" : ""}
</Typography>
<IconButton
aria-label={intl.formatMessage({ id: 'ariaToggleIdVisibility' })}
onClick={handleClickShowId}
onMouseDown={handleMouseDownId}
edge="end"
size="large"
>
{showId ? <EyeOutlined /> : <EyeInvisibleOutlined />}
</IconButton>
</Stack>
:
// <Grid item xs={10} sm={4} md={4} lg={10}>
// {FieldUtils.initField({
// valueName: "identification",
// disabled: true,
// form: formik
// })}
// </Grid>
<Stack direction="row">
<Typography variant="h5" mt={1}>
{formik.values.identification?.slice(0, 4)}
</Typography>
<Typography variant="h5"mt={1}>
{showId ?formik.values.identification?.slice(4):"****"}
</Typography>
<IconButton
aria-label={intl.formatMessage({ id: 'ariaToggleIdVisibility' })}
onClick={handleClickShowId}
onMouseDown={handleMouseDownId}
edge="end"
size="large"
>
{showId ? <EyeOutlined /> : <EyeInvisibleOutlined />}
</IconButton>
</Stack>
}
</Grid>
<Typography variant="h5" mt={1}>
{formik.values.identification?.slice(0, 4)}
</Typography>
</Grid>
</Grid>
</Grid>


+ 21
- 14
src/pages/User/ManagePage_OrgPublic/index.js Просмотреть файл

@@ -53,7 +53,14 @@ const ManageOrgUserPage = () => {
'& .MuiDataGrid-footerContainer': {
border: 1,
borderColor: "#EEE"
}
},
"& .MuiDataGrid-columnHeaderTitle": {
whiteSpace: "normal",
lineHeight: "normal"
},
"& .MuiDataGrid-columnHeader": {
height: "unset !important"
},
}

const [_searchCriteria, set_searchCriteria] = React.useState({});
@@ -78,9 +85,9 @@ const ManageOrgUserPage = () => {
});
}

/** DataGrid `headerName` must be a string; use `renderHeader` for styled markup. */
const renderStyledHeader = (params) => (
<Typography variant="h5">{params.colDef.headerName}</Typography>
/** Match /proof/search grid column header styling (inherits MuiDataGrid columnHeader color). */
const renderHeaderWithAria = (params) => (
<span aria-label={params.colDef.headerName}>{params.colDef.headerName}</span>
);

function getStatus(params) {
@@ -127,7 +134,7 @@ const ManageOrgUserPage = () => {
id: 'username',
field: 'username',
headerName: intl.formatMessage({ id: 'loginName' }),
renderHeader: renderStyledHeader,
renderHeader: renderHeaderWithAria,
width: isMdOrLg ? 'auto' : 160,
flex: isMdOrLg ? 1 : undefined,

@@ -135,8 +142,8 @@ const ManageOrgUserPage = () => {
{
id: 'contactPerson',
field: 'contactPerson',
headerName: intl.formatMessage({ id: 'userName' }),
renderHeader: renderStyledHeader,
headerName: intl.formatMessage({ id: 'contactPerson' }),
renderHeader: renderHeaderWithAria,
width: isMdOrLg ? 'auto' : 160,
flex: isMdOrLg ? 1 : undefined,

@@ -145,7 +152,7 @@ const ManageOrgUserPage = () => {
id: 'contactTel',
field: 'contactTel',
headerName: intl.formatMessage({ id: 'userContactNumber' }),
renderHeader: renderStyledHeader,
renderHeader: renderHeaderWithAria,
width: isMdOrLg ? 'auto' : 160,
flex: isMdOrLg ? 1 : undefined,
valueGetter: (params) => {
@@ -157,7 +164,7 @@ const ManageOrgUserPage = () => {
id: 'emailBus',
field: 'emailBus',
headerName: intl.formatMessage({ id: 'userContactEmail' }),
renderHeader: renderStyledHeader,
renderHeader: renderHeaderWithAria,
width: isMdOrLg ? 'auto' : 160,
flex: isMdOrLg ? 1 : undefined,
},
@@ -165,7 +172,7 @@ const ManageOrgUserPage = () => {
id: 'lastLogin',
field: 'lastLogin',
headerName: intl.formatMessage({ id: 'lastLoginDate' }),
renderHeader: renderStyledHeader,
renderHeader: renderHeaderWithAria,
width: isMdOrLg ? 'auto' : 160,
flex: isMdOrLg ? 1 : undefined,
valueGetter: (params) => {
@@ -176,7 +183,7 @@ const ManageOrgUserPage = () => {
id: 'lastApply',
field: 'lastApply',
headerName: intl.formatMessage({ id: 'lastSubmissionDate' }),
renderHeader: renderStyledHeader,
renderHeader: renderHeaderWithAria,
width: isMdOrLg ? 'auto' : 160,
flex: isMdOrLg ? 1 : undefined,
valueGetter: () => {
@@ -186,7 +193,7 @@ const ManageOrgUserPage = () => {
{
field: 'actions',
headerName: intl.formatMessage({ id: 'status' }),
renderHeader: renderStyledHeader,
renderHeader: renderHeaderWithAria,
width: isMdOrLg ? 'auto' : 160,
flex: isMdOrLg ? 1 : undefined,
cellClassName: 'actions',
@@ -199,7 +206,7 @@ const ManageOrgUserPage = () => {
field: 'primaryUser',
type: 'bool',
headerName: intl.formatMessage({ id: 'primary' }),
renderHeader: renderStyledHeader,
renderHeader: renderHeaderWithAria,
width: isMdOrLg ? 'auto' : 160,
flex: isMdOrLg ? 1 : undefined,
renderCell: (params) => {
@@ -272,7 +279,7 @@ const ManageOrgUserPage = () => {
<FormattedMessage id="confirm" />
</DialogTitle>
<DialogContent style={{ display: 'flex', }}>
<Typography variant="h5" style={{ padding: '16px' }}>{warningText}</Typography>
<Typography variant="h5" component="span" style={{ padding: '16px' }}>{warningText}</Typography>
</DialogContent>
<DialogActions>
<Button onClick={() => {


+ 1
- 1
src/pages/User/SearchPage/index.js Просмотреть файл

@@ -92,7 +92,7 @@ const UserSettingPage = () => {
<Grid item xs={12}>
<div style={BackgroundHead}>
<Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center">
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0C489E" }}>View GLD User</Typography>
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0c489e" }}>View GLD User</Typography>
</Stack>
</div>
</Grid>


+ 1
- 1
src/pages/User/SearchPage_Individual/index.js Просмотреть файл

@@ -64,7 +64,7 @@ const UserSearchPage_Individual = () => {
<Grid item xs={12}>
<div style={BackgroundHead}>
<Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center">
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0C489E" }}>
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0c489e" }}>
View Individual User
</Typography>
</Stack>


+ 1
- 1
src/pages/User/SearchPage_Organization/index.js Просмотреть файл

@@ -68,7 +68,7 @@ const UserSearchPage_Organization = () => {
<Grid item xs={12}>
<div style={BackgroundHead}>
<Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center">
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0C489E" }}>View Organisation User</Typography>
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0c489e" }}>View Organisation User</Typography>
</Stack>
</div>
</Grid>


+ 30
- 72
src/pages/authentication/BusRegister.js Просмотреть файл

@@ -12,7 +12,8 @@ import {
Button, StepLabel,
CircularProgress,
} from '@mui/material';
import VisibilityIcon from '@mui/icons-material/Visibility';
import { POST_USERNAME, POST_VERIFY_CAPTCHA } from "utils/ApiPathConst";
import RegisterStepIcon, { registerStepStyle } from 'components/RegisterStepIcon';

// project import
import Loadable from 'components/Loadable';
@@ -21,8 +22,8 @@ import { notifyActionError } from 'utils/CommonFunction';
const CustomFormWizard = Loadable(lazy(() => import('./auth-forms/BusCustomFormWizard')));
const AuthWrapper = Loadable(lazy(() => import('./AuthWrapperCustom')));
import axios from "axios";
import { POST_USERNAME, POST_VERIFY_CAPTCHA } from "utils/ApiPathConst";
import {FormattedMessage, useIntl} from "react-intl";
import { PRIMARY_CONTAINED_BUTTON_SX } from "themes/colorConst";
// import CustomFormWizard from './auth-forms/BusCustomFormWizard';
// import AuthWrapper from './AuthWrapperCustom';

@@ -37,6 +38,7 @@ const BusRegister = () => {
const [base64Url, setBase64Url] = useState("")
const [checkCode, setCheckCode] = useState("")
const [isNextBusy, setIsNextBusy] = useState(false);
const [registrationComplete, setRegistrationComplete] = useState(false);
const intl = useIntl();
const steps = [
intl.formatMessage({id: 'personalInformation'}),
@@ -44,30 +46,6 @@ const BusRegister = () => {
intl.formatMessage({id: 'finishSubmission'})
];

const stepStyle = {
width: { lg: "40%", md: "70%", xs: "100%" },
boxShadow: 1,
backgroundColor: "#FFFFFF",
padding: 2,

/* Inactive (default) */
"& .MuiStepIcon-root": { color: "#757575", fontSize: "2rem" }, // darker grey
"& .MuiStepLabel-label": { color: "#424242" }, // label darker
"& .MuiStepConnector-line": { borderColor: "#9E9E9E" }, // connector darker

/* Active */
"& .Mui-active": {
"&.MuiStepIcon-root": { color: "warning.main", fontSize: "2rem" },
"& .MuiStepConnector-line": { borderColor: "warning.main" }
},

/* Completed */
"& .Mui-completed": {
"&.MuiStepIcon-root": { color: "#0C489E", fontSize: "2rem" }, // use your strong blue
"& .MuiStepConnector-line": { borderColor: "#0C489E" }
}
};

const totalSteps = () => {
return steps.length;
};
@@ -147,51 +125,30 @@ const BusRegister = () => {
const handleReset = () => {
setActiveStep(0);
setCompleted({});
setRegistrationComplete(false);
};

const isStepCompleted = (index) => index < activeStep || registrationComplete;

return (
// <AuthWrapper>
<Stack sx={{ width: '100%', fontSize: '2rem', paddingTop: '35px', bgcolor: 'backgroundColor.default' }} alignItems="center">
<Stepper activeStep={activeStep} sx={stepStyle}>
<Stepper activeStep={activeStep} sx={registerStepStyle}>
{steps.map((label, index) => (
<Step key={label} completed={completed[index]} readOnly={true}>
{index < 2 ? (
<StepButton
aria-current={activeStep === index ? "step" : undefined}
// onClick={handleStep(index)}
>
<StepLabel
sx={{
flexDirection: "column",
"& .MuiStepLabel-iconContainer": { paddingRight: 0 },
}}
>
<Typography variant="step1">{label}</Typography>
</StepLabel>
</StepButton>
) : (
<StepButton
aria-current={activeStep === index ? "step" : undefined}
sx={
activeStep === 2
? { "& .MuiSvgIcon-root": { color: "warning.main", fontSize: "2rem" } }
: allStepsCompleted()
? { "& .MuiSvgIcon-root": { color: "#0C489E", fontSize: "2rem" } }
: { color: "rgba(0,0,0,0.6)" }
}
icon={<VisibilityIcon />}
// onClick={handleStep(index)}
<Step key={label} completed={isStepCompleted(index)} readOnly={true}>
<StepButton
aria-current={activeStep === index ? "step" : undefined}
>
<StepLabel
StepIconComponent={RegisterStepIcon}
sx={{
flexDirection: "column",
"& .MuiStepLabel-iconContainer": { paddingRight: 0 },
}}
>
<StepLabel
sx={{
flexDirection: "column",
"& .MuiStepLabel-iconContainer": { paddingRight: 0 },
}}
>
<Typography variant="step1">{label}</Typography>
</StepLabel>
</StepButton>
)}
<Typography variant="step1">{label}</Typography>
</StepLabel>
</StepButton>
</Step>
))}
</Stepper>
@@ -215,6 +172,7 @@ const BusRegister = () => {
setUsername={setUsername}
setBase64Url={setBase64Url}
setCheckCode={setCheckCode}
onRegistrationComplete={() => setRegistrationComplete(true)}
/>
{/* <CustomFormWizard step={activeStep} /> */}
</AuthWrapper>
@@ -249,33 +207,33 @@ const BusRegister = () => {
{activeStep === totalSteps() - 2 ?
(
<Button
variant="outlined"
variant="contained"
disabled={isNextBusy}
onClick={handleNext}
aria-busy={isNextBusy}
sx={{ mr: 1, minWidth: 120 }}
sx={{ mr: 1, minWidth: 120, ...PRIMARY_CONTAINED_BUTTON_SX }}
>
{isNextBusy ? (
<CircularProgress size={22} color="inherit" aria-hidden />
) : (
<Typography variant="h5">
<Typography variant="h5" sx={{ color: 'inherit' }}>
<FormattedMessage id="submit"/>
</Typography>
)}
</Button>
) : (activeStep === totalSteps() - 1 ?
(
<Button variant="outlined" color="inherit"
disabled={true} sx={{ mr: 1 }}>
<Typography variant="h5">
<Button variant="contained" color="inherit"
disabled={true} sx={{ mr: 1, ...PRIMARY_CONTAINED_BUTTON_SX }}>
<Typography variant="h5" sx={{ color: 'inherit' }}>
<FormattedMessage id="submit"/>
</Typography>
</Button>
) :
(
// <Button disabled={updateValid} variant="outlined" onClick={handleNext} sx={{ mr: 1 }}>
<Button disabled={!updateValid || isNextBusy} variant="outlined" onClick={handleNext} sx={{ mr: 1 }}>
<Typography variant="h5">
<Button disabled={!updateValid || isNextBusy} variant="contained" onClick={handleNext} sx={{ mr: 1, ...PRIMARY_CONTAINED_BUTTON_SX }}>
<Typography variant="h5" sx={{ color: 'inherit' }}>
<FormattedMessage id="continue"/>
</Typography>
</Button>


+ 4
- 4
src/pages/authentication/ForgotPassword/ForgotPasswordApplyForm.js Просмотреть файл

@@ -128,17 +128,17 @@ const ForgotPasswordApplyForm = () => {
<Grid container spacing={2} sx={{ minHeight: '40vh' }} direction="column" justifyContent="flex-start" alignItems="center">
<Grid item xs={12} md={12} lg={12} sx={{ mb: 1, mt:5, display: { xs: 'none', sm: 'none', md: 'block' } }}>
<InputLabel htmlFor="email-login-title">
<Typography variant="h5" >
<Typography variant="h5" component="span">
<FormattedMessage id="forgotPasswordSubTitle"/>
</Typography>
</InputLabel>
</Grid>
<Grid item xs={12} md={12} lg={12} sx={{ mb: 1, mt:5, display: { md: 'none', xl: 'none', lg: 'none' } }}>
<InputLabel htmlFor="email-login-subtitle">
<Typography variant="h6" >
<Typography variant="h6" component="span">
<FormattedMessage id="forgotPasswordSubTitle1"/>
</Typography>
<Typography variant="h6" >
<Typography variant="h6" component="span">
<FormattedMessage id="forgotPasswordSubTitle2"/>
</Typography>
</InputLabel>
@@ -212,7 +212,7 @@ const ForgotPasswordApplyForm = () => {
<FormattedMessage id="attention"/>
</DialogTitle>
<DialogContent style={{ display: 'flex', }}>
{/* <Typography variant="h5" style={{ padding: '16px' }}>{warningText}</Typography> */}
{/* <Typography variant="h5" component="span" style={{ padding: '16px' }}>{warningText}</Typography> */}
</DialogContent>
<DialogActions>
<Button


+ 4
- 4
src/pages/authentication/ForgotUsername/ForgotUsernameApplyForm.js Просмотреть файл

@@ -127,17 +127,17 @@ const ForgotUsernameApplyForm = () => {
<Grid container spacing={2} sx={{ minHeight: '40vh' }} direction="column" justifyContent="flex-start" alignItems="center">
<Grid item xs={12} md={12} lg={12} sx={{ mb: 1, mt:5, display: { xs: 'none', sm: 'none', md: 'block' } }}>
<InputLabel htmlFor="email-login-title">
<Typography variant="h5" >
<Typography variant="h5" component="span">
<FormattedMessage id="forgotUsernameSubTitle"/>
</Typography>
</InputLabel>
</Grid>
<Grid item xs={12} md={12} lg={12} sx={{ mb: 1, mt:5, display: { md: 'none', xl: 'none', lg: 'none' } }}>
<InputLabel htmlFor="email-login-subtitle">
<Typography variant="h6" >
<Typography variant="h6" component="span">
<FormattedMessage id="forgotUsernameSubTitle1"/>
</Typography>
<Typography variant="h6" >
<Typography variant="h6" component="span">
<FormattedMessage id="forgotPasswordSubTitle2"/>
</Typography>
</InputLabel>
@@ -211,7 +211,7 @@ const ForgotUsernameApplyForm = () => {
<FormattedMessage id="attention"/>
</DialogTitle>
<DialogContent style={{ display: 'flex', }}>
{/* <Typography variant="h5" style={{ padding: '16px' }}>{warningText}</Typography> */}
{/* <Typography variant="h5"component="span" style={{ padding: '16px' }}>{warningText}</Typography> */}
</DialogContent>
<DialogActions>
<Button


+ 29
- 55
src/pages/authentication/IAmSmartRegister.js Просмотреть файл

@@ -13,10 +13,11 @@ import {
Stack,
Typography,
Button,
StepLabel,
CircularProgress,
} from '@mui/material';
import VisibilityIcon from '@mui/icons-material/Visibility';
import { GET_ID, POST_VERIFY_CAPTCHA } from "utils/ApiPathConst";
import RegisterStepIcon, { registerStepStyle } from 'components/RegisterStepIcon';

// project import
import Loadable from 'components/Loadable';
@@ -24,32 +25,10 @@ import { lazy } from 'react';
import { notifyActionError } from 'utils/CommonFunction';
import axios from "axios";
import {FormattedMessage, useIntl} from "react-intl";
import { PRIMARY_CONTAINED_BUTTON_SX } from "themes/colorConst";
const CustomFormWizard = Loadable(lazy(() => import('./auth-forms/IAmSmartFormWizard')));
const AuthWrapper = Loadable(lazy(() => import('./AuthWrapperCustom')));
// ================================|| REGISTER ||================================ //
const stepStyle = {
width: { lg: "40%", md: "70%", xs: "100%" },
boxShadow: 1,
backgroundColor: "#FFFFFF",
padding: 2,

/* Inactive (default) */
"& .MuiStepIcon-root": { color: "#757575", fontSize: "2rem" }, // darker grey
"& .MuiStepLabel-label": { color: "#424242" }, // label darker
"& .MuiStepConnector-line": { borderColor: "#9E9E9E" }, // connector darker

/* Active */
"& .Mui-active": {
"&.MuiStepIcon-root": { color: "warning.main", fontSize: "2rem" },
"& .MuiStepConnector-line": { borderColor: "warning.main" }
},

/* Completed */
"& .Mui-completed": {
"&.MuiStepIcon-root": { color: "#0C489E", fontSize: "2rem" }, // use your strong blue
"& .MuiStepConnector-line": { borderColor: "#0C489E" }
}
};

const Register = () => {
const [activeStep, setActiveStep] = useState(0);
@@ -61,6 +40,7 @@ const Register = () => {
const [checkCode, setCheckCode] = useState("")
const [idNo, setIdNo] = useState("");
const [isNextBusy, setIsNextBusy] = useState(false);
const [registrationComplete, setRegistrationComplete] = useState(false);
const intl = useIntl();
const steps = [
intl.formatMessage({id: 'personalInformation'}),
@@ -152,37 +132,30 @@ const Register = () => {
const handleReset = () => {
setActiveStep(0);
setCompleted({});
setRegistrationComplete(false);
};

const isStepCompleted = (index) => index < activeStep || registrationComplete;

return (
// <AuthWrapper>
<Stack sx={{ width: '100%', fontSize: '2rem', paddingTop: '65px', bgcolor: 'backgroundColor.default' }} alignItems="center">
<Stepper activeStep={activeStep} sx={stepStyle}>
<Stepper activeStep={activeStep} sx={registerStepStyle}>
{steps.map((label, index) => (
<Step key={label} completed={completed[index]} readOnly={true}>
{index < 2 ? (
<StepButton
aria-current={activeStep === index ? "step" : undefined}
// onClick={handleStep(index)}
>
<Typography variant="step1">{label}</Typography>
</StepButton>
) : (
<StepButton
aria-current={activeStep === index ? "step" : undefined}
sx={
activeStep === 2
? { "& .MuiSvgIcon-root": { color: "warning.main", fontSize: "2rem" } }
: allStepsCompleted()
? { "& .MuiSvgIcon-root": { color: "#0C489E", fontSize: "2rem" } }
: { color: "rgba(0,0,0,0.6)" }
}
icon={<VisibilityIcon />}
// onClick={handleStep(index)}
<Step key={label} completed={isStepCompleted(index)} readOnly={true}>
<StepButton
aria-current={activeStep === index ? "step" : undefined}
>
<StepLabel
StepIconComponent={RegisterStepIcon}
sx={{
flexDirection: "column",
"& .MuiStepLabel-iconContainer": { paddingRight: 0 },
}}
>
<Typography variant="step1">{label}</Typography>
</StepButton>
)}
</StepLabel>
</StepButton>
</Step>
))}
</Stepper>
@@ -207,6 +180,7 @@ const Register = () => {
setIdNo={setIdNo}
setBase64Url={setBase64Url}
setCheckCode={setCheckCode}
onRegistrationComplete={() => setRegistrationComplete(true)}
/>
{/* <CustomFormWizard step={activeStep} /> */}
</AuthWrapper>
@@ -239,33 +213,33 @@ const Register = () => {
{activeStep === totalSteps() - 2 ?
(
<Button
variant="outlined"
variant="contained"
disabled={isNextBusy}
onClick={handleNext}
aria-busy={isNextBusy}
sx={{ mr: 1, minWidth: 120 }}
sx={{ mr: 1, minWidth: 120, ...PRIMARY_CONTAINED_BUTTON_SX }}
>
{isNextBusy ? (
<CircularProgress size={22} color="inherit" aria-hidden />
) : (
<Typography variant="h5">
<Typography variant="h5" sx={{ color: 'inherit' }}>
<FormattedMessage id="submit"/>
</Typography>
)}
</Button>
) : (activeStep === totalSteps() - 1 ?
(
<Button variant="outlined" color="inherit"
disabled={true} sx={{ mr: 1 }}>
<Typography variant="h5">
<Button variant="contained" color="inherit"
disabled={true} sx={{ mr: 1, ...PRIMARY_CONTAINED_BUTTON_SX }}>
<Typography variant="h5" sx={{ color: 'inherit' }}>
<FormattedMessage id="submit"/>
</Typography>
</Button>
) :
(
// <Button disabled={updateValid} variant="outlined" onClick={handleNext} sx={{ mr: 1 }}>
<Button disabled={!updateValid || isNextBusy} variant="outlined" onClick={handleNext} sx={{ mr: 1 }}>
<Typography variant="h5">
<Button disabled={!updateValid || isNextBusy} variant="contained" onClick={handleNext} sx={{ mr: 1, ...PRIMARY_CONTAINED_BUTTON_SX }}>
<Typography variant="h5" sx={{ color: 'inherit' }}>
<FormattedMessage id="continue"/>
</Typography>
</Button>


+ 29
- 71
src/pages/authentication/Register.js Просмотреть файл

@@ -15,8 +15,8 @@ import {
Button, StepLabel,
CircularProgress,
} from '@mui/material';
import VisibilityIcon from '@mui/icons-material/Visibility';
import { POST_USERNAME, POST_VERIFY_CAPTCHA } from "utils/ApiPathConst";
import RegisterStepIcon, { registerStepStyle } from 'components/RegisterStepIcon';

// project import
import Loadable from 'components/Loadable';
@@ -25,6 +25,7 @@ import { notifyActionError } from 'utils/CommonFunction';
import axios from "axios";
import {FormattedMessage, useIntl} from "react-intl";
import usePageTitle from "components/usePageTitle";
import { PRIMARY_CONTAINED_BUTTON_SX } from "themes/colorConst";
const CustomFormWizard = Loadable(lazy(() => import('./auth-forms/CustomFormWizard')));
const AuthWrapper = Loadable(lazy(() => import('./AuthWrapperCustom')));
// ================================|| REGISTER ||================================ //
@@ -38,6 +39,7 @@ const Register = () => {
const [base64Url, setBase64Url] = useState("")
const [checkCode, setCheckCode] = useState("")
const [isNextBusy, setIsNextBusy] = useState(false);
const [registrationComplete, setRegistrationComplete] = useState(false);
const nextBusyRef = useRef(false);
const intl = useIntl();
// Localized document title/meta for register flow
@@ -48,30 +50,6 @@ const Register = () => {
intl.formatMessage({id: 'finishSubmission'})
];

const stepStyle = {
width: { lg: "40%", md: "70%", xs: "100%" },
boxShadow: 1,
backgroundColor: "#FFFFFF",
padding: 2,

/* Inactive (default) */
"& .MuiStepIcon-root": { color: "#757575", fontSize: "2rem" }, // darker grey
"& .MuiStepLabel-label": { color: "#424242" }, // label darker
"& .MuiStepConnector-line": { borderColor: "#9E9E9E" }, // connector darker

/* Active */
"& .Mui-active": {
"&.MuiStepIcon-root": { color: "warning.main", fontSize: "2rem" },
"& .MuiStepConnector-line": { borderColor: "warning.main" }
},

/* Completed */
"& .Mui-completed": {
"&.MuiStepIcon-root": { color: "#0C489E", fontSize: "2rem" }, // use your strong blue
"& .MuiStepConnector-line": { borderColor: "#0C489E" }
}
};

const totalSteps = () => {
return steps.length;
};
@@ -153,51 +131,30 @@ const Register = () => {
const handleReset = () => {
setActiveStep(0);
setCompleted({});
setRegistrationComplete(false);
};

const isStepCompleted = (index) => index < activeStep || registrationComplete;

return (
// <AuthWrapper>
<Stack sx={{ width: '100%', fontSize: '2rem', paddingTop: '35px', bgcolor: 'backgroundColor.default' }} alignItems="center">
<Stepper activeStep={activeStep} sx={stepStyle}>
<Stepper activeStep={activeStep} sx={registerStepStyle}>
{steps.map((label, index) => (
<Step key={label} completed={completed[index]} readOnly={true}>
{index < 2 ? (
<StepButton
aria-current={activeStep === index ? 'step' : undefined}
// onClick={handleStep(index)}
<Step key={label} completed={isStepCompleted(index)} readOnly={true}>
<StepButton
aria-current={activeStep === index ? 'step' : undefined}
>
<StepLabel
StepIconComponent={RegisterStepIcon}
sx={{
flexDirection: 'column',
"& .MuiStepLabel-iconContainer": { paddingRight: 0 }
}}
>
<StepLabel
sx={{
flexDirection: 'column',
"& .MuiStepLabel-iconContainer": { paddingRight: 0 }
}}
>
<Typography variant="step1">{label}</Typography>
</StepLabel>
</StepButton>
) : (
<StepButton
aria-current={activeStep === index ? 'step' : undefined}
sx={
activeStep === 2
? { "& .MuiSvgIcon-root": { color: "warning.main", fontSize: "2rem" } }
: allStepsCompleted()
? { "& .MuiSvgIcon-root": { color: "#0C489E", fontSize: "2rem" } }
: { color: "rgba(0,0,0,0.6)" }
}
icon={<VisibilityIcon />}
// onClick={handleStep(index)}
>
<StepLabel
sx={{
flexDirection: 'column',
"& .MuiStepLabel-iconContainer": { paddingRight: 0 }
}}
>
<Typography variant="step1">{label}</Typography>
</StepLabel>
</StepButton>
)}
<Typography variant="step1">{label}</Typography>
</StepLabel>
</StepButton>
</Step>
))}
</Stepper>
@@ -221,6 +178,7 @@ const Register = () => {
setUsername={setUsername}
setBase64Url={setBase64Url}
setCheckCode={setCheckCode}
onRegistrationComplete={() => setRegistrationComplete(true)}
/>
{/* <CustomFormWizard step={activeStep} /> */}
</AuthWrapper>
@@ -255,33 +213,33 @@ const Register = () => {
{activeStep === totalSteps() - 2 ?
(
<Button
variant="outlined"
variant="contained"
disabled={isNextBusy}
onClick={handleNext}
aria-busy={isNextBusy}
sx={{ mr: 1, minWidth: 120 }}
sx={{ mr: 1, minWidth: 120, ...PRIMARY_CONTAINED_BUTTON_SX }}
>
{isNextBusy ? (
<CircularProgress size={22} color="inherit" aria-hidden />
) : (
<Typography variant="h5">
<Typography variant="h5" sx={{ color: 'inherit' }}>
<FormattedMessage id="submit"/>
</Typography>
)}
</Button>
) : (activeStep === totalSteps() - 1 ?
(
<Button variant="outlined" color="inherit"
disabled={true} sx={{ mr: 1 }}>
<Typography variant="h5">
<Button variant="contained" color="inherit"
disabled={true} sx={{ mr: 1, ...PRIMARY_CONTAINED_BUTTON_SX }}>
<Typography variant="h5" sx={{ color: 'inherit' }}>
<FormattedMessage id="submit"/>
</Typography>
</Button>
) :
(
// <Button disabled={updateValid} variant="outlined" onClick={handleNext} sx={{ mr: 1 }}>
<Button disabled={!updateValid || isNextBusy} variant="outlined" onClick={handleNext} sx={{ mr: 1 }}>
<Typography variant="h5">
<Button disabled={!updateValid || isNextBusy} variant="contained" onClick={handleNext} sx={{ mr: 1, ...PRIMARY_CONTAINED_BUTTON_SX }}>
<Typography variant="h5" sx={{ color: 'inherit' }}>
<FormattedMessage id="continue"/>
</Typography>
</Button>


+ 11
- 11
src/pages/authentication/RegisterCustom.js Просмотреть файл

@@ -142,19 +142,19 @@ const RegisterCustom = () => {
href="/registerFrom"
variant="contained"
sx={{
backgroundColor: '#0C489E',
backgroundColor: '#0c489e',
color: '#FFFFFF',
border: '1px solid #0C489E',
border: '1px solid #0c489e',
boxShadow: 'none',
'&:hover': {
backgroundColor: '#093A7A',
backgroundColor: '#1565c0',
color: '#FFFFFF',
border: '1px solid #093A7A',
border: '1px solid #1565c0',
boxShadow: 'none',
},
}}
>
<Typography variant="h5" sx={{ color: 'inherit' }}>
<Typography component="span" variant="h5" sx={{ color: 'inherit' }}>
<FormattedMessage id="registerNewPersonalUser" />
</Typography>
</Button>
@@ -164,7 +164,7 @@ const RegisterCustom = () => {
</Typography>
</Grid>
<Grid item xs={12} md={6} sx={{ borderLeft: 1, borderColor: 'grey.500' }}>
<Typography mb={4} variant="h3">
<Typography component="h2" mb={4} variant="h3">
<FormattedMessage id="businessUser" />
</Typography>
<Button
@@ -172,19 +172,19 @@ const RegisterCustom = () => {
variant="contained"
sx={{
mt: 0.5,
backgroundColor: '#0C489E',
backgroundColor: '#0c489e',
color: '#FFFFFF',
border: '1px solid #0C489E',
border: '1px solid #0c489e',
boxShadow: 'none',
'&:hover': {
backgroundColor: '#093A7A',
backgroundColor: '#1565c0',
color: '#FFFFFF',
border: '1px solid #093A7A',
border: '1px solid #1565c0',
boxShadow: 'none',
},
}}
>
<Typography component="h2" variant="h5" sx={{ color: 'inherit' }}>
<Typography component="span" variant="h5" sx={{ color: 'inherit' }}>
<FormattedMessage id="registerNewBusinessUser" />
</Typography>
</Button>


+ 2
- 2
src/pages/authentication/auth-forms/AuthLoginCustom.js Просмотреть файл

@@ -369,9 +369,9 @@ const AuthLoginCustom = () => {
<Button disableElevation disabled={isButtonDisabled}
fullWidth size="large" type="submit" variant="contained" color="primary"
sx={{
backgroundColor: "#0C489E",
backgroundColor: "#0c489e",
color: "#FFFFFF",
"&:hover": { backgroundColor: "#093A7A" },
"&:hover": { backgroundColor: "#1565c0" },
"&.Mui-disabled": {
background: "#bbdefb",
color: "#fff",


+ 64
- 29
src/pages/authentication/auth-forms/BusCustomFormWizard.js Просмотреть файл

@@ -55,7 +55,8 @@ import {PNSPS_LONG_BUTTON_THEME} from "../../../themes/buttonConst";
import {ThemeProvider} from "@emotion/react";
import {FormattedMessage, useIntl} from "react-intl";
//import { Invaild } from 'utils/IconUtils';
import { notifyActionError } from 'utils/CommonFunction';
import { handleActionKeyDown, notifyActionError } from 'utils/CommonFunction';
import { ADDRESS_LINE_MAX_LENGTH, isAddressLineWithinLimit, isRegisterAddressValid } from 'utils/registerValidation';

// ============================|| FIREBASE - REGISTER ||============================ //

@@ -286,7 +287,7 @@ const BusCustomFormWizard = (props) => {
(data.chCompanyName !== "" || data.enCompanyName !== "") &&
data.enName !== "" &&
data.chName !== "" &&
data.address1 !== "" &&
isRegisterAddressValid(data) &&
data.email !== "" &&
data.emailConfirm !== "" &&
data.email === data.emailConfirm &&
@@ -343,6 +344,10 @@ const BusCustomFormWizard = (props) => {

}

if (fileInputRef.current) {
fileInputRef.current.value = '';
}

}, [updateRows]);

const handleBrNo = (brNo) => {
@@ -396,6 +401,8 @@ const BusCustomFormWizard = (props) => {

setFileListData(saveFileList)
setFileList(updatedFileList);
setUpdateRows(saveFileList);
event.target.value = '';
};

useEffect(() => {
@@ -494,6 +501,7 @@ const BusCustomFormWizard = (props) => {
) => {
// console.log(response)
setCheckUpload(true)
props.onRegistrationComplete?.();
setLoding(false);
})
.catch(error => {
@@ -669,7 +677,17 @@ const BusCustomFormWizard = (props) => {
const syncOk = computeStep0ValidSync(values);
if (!syncOk) {
setisValid(false);
if (!isDistrictSelectionValid()) {
if (!isRegisterAddressValid(values)) {
if (values.address1 === '') {
notifyActionError(intl.formatMessage({ id: 'validateAddressLine1' }));
} else if (!isAddressLineWithinLimit(values.address1)) {
notifyActionError(intl.formatMessage({ id: 'noMoreThenNWords' }, { num: ADDRESS_LINE_MAX_LENGTH, fieldname: intl.formatMessage({ id: 'addressLine1' }) + ": " }));
} else if (!isAddressLineWithinLimit(values.address2)) {
notifyActionError(intl.formatMessage({ id: 'noMoreThenNWords' }, { num: ADDRESS_LINE_MAX_LENGTH, fieldname: intl.formatMessage({ id: 'addressLine2' }) + ": " }));
} else if (!isAddressLineWithinLimit(values.address3)) {
notifyActionError(intl.formatMessage({ id: 'noMoreThenNWords' }, { num: ADDRESS_LINE_MAX_LENGTH, fieldname: intl.formatMessage({ id: 'addressLine3' }) + ": " }));
}
} else if (!isDistrictSelectionValid()) {
setDistrictErrStr(getRequiredErrStr("district"));
setCheckDistrict(true);
notifyActionError(intl.formatMessage({ id: 'require' }, { fieldname: intl.formatMessage({ id: 'district' }) }));
@@ -721,14 +739,14 @@ const BusCustomFormWizard = (props) => {
</Typography>
</Button>
<div style={{ borderBottom: "3px solid #1A4399", width: "100%", margin_right: "15px" }}>
<Typography display="inline" variant="h3" sx={{ color: '#1A4399' }}>
<Typography display="inline" variant="h3"component="h1" sx={{ color: '#1A4399' }}>
<FormattedMessage id="becomeNewBusinessUser"/>
</Typography>
</div>
<Typography mt={0.25} variant="h6" sx={{ color: '#B00020' }}>
<Typography mt={0.25} variant="h6" component="span" sx={{ color: '#B00020' }}>
<FormattedMessage id="requireString"/>
</Typography>
<Typography mt={0.25} variant="h4" sx={{ color: 'primary.primary' }}>
<Typography mt={0.25} variant="h4" component="h2" sx={{ color: 'primary.primary' }}>
<FormattedMessage id="yourLoginInformation"/>
</Typography>
{/* <Typography component={Link} to="/login" variant="body1" sx={{ textDecoration: 'none' }} color="primary">
@@ -748,7 +766,7 @@ const BusCustomFormWizard = (props) => {
variant="contained"
onClick={handleCheckUsername}
sx={{ ml: 2, height: "40px" }}>
<Typography variant="h6">檢查是否重覆</Typography>
<Typography variant="h6" component="span">檢查是否重覆</Typography>
</Button> */}
</Typography>
</InputLabel>
@@ -815,10 +833,13 @@ const BusCustomFormWizard = (props) => {
endAdornment={
<InputAdornment position="end">
<IconButton
role="button"
tabIndex={0}
aria-label={intl.formatMessage({
id: showPassword ? "ariaHidePassword" : "ariaShowPassword"
})}
onClick={handleClickShowPassword}
onKeyDown={(event) => handleActionKeyDown(event, handleClickShowPassword)}
onMouseDown={handleMouseDownPassword}
edge="end"
size="large"
@@ -891,10 +912,13 @@ const BusCustomFormWizard = (props) => {
endAdornment={
<InputAdornment position="end">
<IconButton
role="button"
tabIndex={0}
aria-label={intl.formatMessage({
id: showConfirmPassword ? "ariaHidePassword" : "ariaShowPassword"
})}
onClick={handleClickShowConfirmPassword}
onKeyDown={(event) => handleActionKeyDown(event, handleClickShowConfirmPassword)}
onMouseDown={handleMouseDownPassword}
edge="end"
size="large"
@@ -929,7 +953,7 @@ const BusCustomFormWizard = (props) => {
</Grid>
<Grid item xs={12} mt={1} mb={1}>
<Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
<Typography display="inline" variant="h4" /*sx={{ color: '#1A4399' }}*/>
<Typography display="inline" variant="h4" component="h2" /*sx={{ color: '#1A4399' }}*/>
<FormattedMessage id="yourBusinessInformation"/>
</Typography>
{/* <Typography component={Link} to="/login" variant="body1" sx={{ textDecoration: 'none' }} color="primary">
@@ -1102,6 +1126,7 @@ const BusCustomFormWizard = (props) => {
onBlur={formik.handleBlur}
inputProps={{
"aria-label": intl.formatMessage({ id: "addressLine1" }),
maxLength: ADDRESS_LINE_MAX_LENGTH,
onKeyDown: (e) => {
if (e.key === 'Enter') {
e.preventDefault();
@@ -1120,6 +1145,7 @@ const BusCustomFormWizard = (props) => {
placeholder={intl.formatMessage({id: 'addressLine2'})}
inputProps={{
"aria-label": intl.formatMessage({ id: "addressLine2" }),
maxLength: ADDRESS_LINE_MAX_LENGTH,
onKeyDown: (e) => {
if (e.key === 'Enter') {
e.preventDefault();
@@ -1138,6 +1164,7 @@ const BusCustomFormWizard = (props) => {
placeholder={intl.formatMessage({id: 'addressLine3'})}
inputProps={{
"aria-label": intl.formatMessage({ id: "addressLine3" }),
maxLength: ADDRESS_LINE_MAX_LENGTH,
onKeyDown: (e) => {
if (e.key === 'Enter') {
e.preventDefault();
@@ -1246,7 +1273,7 @@ const BusCustomFormWizard = (props) => {
</Grid>
<Grid item xs={12} mt={1} mb={1}>
<Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
<Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
<Typography display="inline" variant="h4" component="h2" sx={{ color: 'primary.primary' }}>
<FormattedMessage id="yourContact"/>
</Typography>
</Stack>
@@ -1524,20 +1551,21 @@ const BusCustomFormWizard = (props) => {
<Grid container>
<Grid item xs={12} md={12}>
<Stack spacing={1} direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
<Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
<Typography display="inline" variant="h4" component="h2" sx={{ color: 'primary.primary' }}>
<FormattedMessage id="businessRegCertAndDoc"/>
<span style={{ color: '#B00020' }}>*</span>
</Typography>
<Typography display="inline" variant="h6" sx={{ color: 'primary.primary' }}>
<Typography display="inline" variant="h6" component="span" sx={{ color: 'primary.primary' }}>
<FormattedMessage id="pleaseUploadDoc"/>
</Typography>
{/* <Typography display="inline" variant="h6" sx={{ fontSize: 12,color: 'primary.primary'}}>如: 香港身份證; 護照; 中國內地身份證等</Typography> */}
{/* <Typography display="inline" variant="h6" component="span" sx={{ fontSize: 12,color: 'primary.primary'}}>如: 香港身份證; 護照; 中國內地身份證等</Typography> */}
<Stack mt={1} direction="row" justifyContent="flex-start" alignItems="center" spacing={2}>
<ThemeProvider theme={PNSPS_LONG_BUTTON_THEME}>
<Button
variant="contained"
sx={{ height: '40px' }}
type="button"
tabIndex={0}
onClick={() => {
if (fileInputRef.current) {
fileInputRef.current.click();
@@ -1565,7 +1593,7 @@ const BusCustomFormWizard = (props) => {
style={{ display: 'none' }}
/>
</ThemeProvider>
{/* <Typography display="inline" variant="h6" sx={{ fontSize: 12, color: 'primary.primary'}}></Typography> */}
{/* <Typography display="inline" variant="h6" component="span" sx={{ fontSize: 12, color: 'primary.primary'}}></Typography> */}
</Stack>
{fileList != null && props.step === 0 ?
<UploadFileTable key="uploadTable" recordList={fileListData} setUpdateRows={setUpdateRows} /> : null}
@@ -1581,7 +1609,7 @@ const BusCustomFormWizard = (props) => {
<Grid item xs={12} md={12}>
<Grid container>
<Grid item xs={12} md={12}>
<Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
<Typography display="inline" variant="h4" component="h2" sx={{ color: 'primary.primary' }}>
<FormattedMessage id="termsAndCondition"/>
<span style={{ color: '#B00020' }}>*</span>
</Typography>
@@ -1589,7 +1617,7 @@ const BusCustomFormWizard = (props) => {
<Grid item xs={12} md={12}>
<Grid container>
<Grid item xs={12} md={12}>
<Typography variant="h6" height="100%" sx={{ textAlign: "left", /*overflow: "scroll",*/ borderRadius: "inherit", borderStyle: "solid", borderWidth: "1px", borderColor: "#0C489E" }}>
<Typography variant="h6" height="100%" sx={{ textAlign: "left", /*overflow: "scroll",*/ borderRadius: "inherit", borderStyle: "solid", borderWidth: "1px", borderColor: "#0c489e" }}>
<div style={{padding: 12}} dangerouslySetInnerHTML={{__html: intl.formatMessage({id: "termsAndCon"})}} />
</Typography>
</Grid>
@@ -1642,7 +1670,7 @@ const BusCustomFormWizard = (props) => {
<Grid item xs={12} lg={12}>
<Grid container>
<Stack direction="column">
<Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
<Typography display="inline" variant="h4" component="h2" sx={{ color: 'primary.primary' }}>
<FormattedMessage id="verify"/>
<span style={{ color: '#B00020' }}>*</span>
</Typography>
@@ -1651,7 +1679,14 @@ const BusCustomFormWizard = (props) => {
<img src={captchaImg} alt="" />
</Grid>
<Grid item xs={1} lg={1} style={{ "border": "0px solid black" }}>
<IconButton aria-label={intl.formatMessage({ id: 'ariaRefreshCaptcha' })} size="large" onClick={() => { onCaptchaChange() }}>
<IconButton
role="button"
tabIndex={0}
aria-label={intl.formatMessage({ id: 'ariaRefreshCaptcha' })}
size="large"
onClick={() => { onCaptchaChange() }}
onKeyDown={(event) => handleActionKeyDown(event, () => onCaptchaChange())}
>
<LoopIcon fontSize="inherit" />
</IconButton>
</Grid>
@@ -1689,9 +1724,9 @@ const BusCustomFormWizard = (props) => {
onClick={playCaptchaAudio}
aria-label={intl.formatMessage({ id: "captchaPlayAudio" })}
sx={{
backgroundColor: '#0C489E',
backgroundColor: '#0c489e',
color: '#FFFFFF',
'&:hover': { backgroundColor: '#093A7A' },
'&:hover': { backgroundColor: '#1565c0' },
}}
>
<FormattedMessage id="captchaPlayAudio" />
@@ -1709,12 +1744,12 @@ const BusCustomFormWizard = (props) => {
<Grid item xs={12}>
<Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
<div style={{ borderBottom: "3px solid #1A4399", width: "100%", margin_right: "15px" }}>
<Typography display="inline" variant="h3" sx={{ color: '#1A4399' }}>
<Typography display="inline" variant="h3"component="h1" sx={{ color: '#1A4399' }}>
<FormattedMessage id="becomeNewBusinessUser"/>
</Typography>
</div>
{/* <Typography mt={0.25} variant="h6" sx={{ fontSize: 12,color: '#B00020'}}>註有*的項目必須輸入資料</Typography> */}
<Typography mt={0.25} variant="h4" sx={{ color: 'primary.primary' }}>
{/* <Typography mt={0.25} variant="h6" component="span" sx={{ fontSize: 12,color: '#B00020'}}>註有*的項目必須輸入資料</Typography> */}
<Typography mt={0.25} variant="h4" component="h2" sx={{ color: 'primary.primary' }}>
<FormattedMessage id="yourLoginInformation"/>
</Typography>
{/* <Typography component={Link} to="/login" variant="body1" sx={{ textDecoration: 'none' }} color="primary">
@@ -1736,7 +1771,7 @@ const BusCustomFormWizard = (props) => {
</Grid>
<Grid item xs={12} mt={1} mb={1}>
<Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
<Typography display="inline" variant="h4" /*sx={{ color: '#1A4399' }}*/>
<Typography display="inline" variant="h4" component="h2" /*sx={{ color: '#1A4399' }}*/>
<FormattedMessage id="yourBusinessInformation"/>
</Typography>
{/* <Typography component={Link} to="/login" variant="body1" sx={{ textDecoration: 'none' }} color="primary">
@@ -1837,7 +1872,7 @@ const BusCustomFormWizard = (props) => {
</Grid>
<Grid item xs={12} mt={1} mb={1}>
<Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
<Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
<Typography display="inline" variant="h4" component="h2" sx={{ color: 'primary.primary' }}>
<FormattedMessage id="yourContact"/>
</Typography>
</Stack>
@@ -1886,8 +1921,8 @@ const BusCustomFormWizard = (props) => {
<Grid container>
<Grid item xs={12} md={12}>
<Stack spacing={1} direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
<Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
<FormattedMessage id="userIdDoc"/>
<Typography display="inline" variant="h4" component="h2" sx={{ color: 'primary.primary' }}>
<FormattedMessage id="businessRegCertAndDoc"/>
</Typography>
{fileList != null && props.step === 1 ?
<PreviewUploadFileTable key="previewTable" recordList={fileListData} /> : null}
@@ -1909,10 +1944,10 @@ const BusCustomFormWizard = (props) => {
// SUCCESS page
<Stack mt={1} direction="column" justifyContent="flex-start" alignItems="center" spacing={2}>
<CheckCircleOutlineIcon color="success" sx={{ width: "200px", height: "200px" }} />
<Typography display="inline" variant="h4">
<Typography display="inline" variant="h4" component="span">
<FormattedMessage id="registerSubmitted"/>
</Typography>
<Typography display="inline" variant="h4">
<Typography display="inline" variant="h4" component="span">
<FormattedMessage id="emailSent"/>
</Typography>
<Button variant="outlined" component={Link} to="/login" >
@@ -1925,7 +1960,7 @@ const BusCustomFormWizard = (props) => {
<Stack mt={1} direction="column" justifyContent="flex-start" alignItems="center" spacing={2}>
{/* <Button disabled={true} hidden={true} variant="contained" type="submit" sx={{ fontSize: 12,height:'25px'}}>Submit</Button> */}
<CancelOutlinedIcon color="error" sx={{ width: "200px", height: "200px" }} />
<Typography display="inline" variant="h4">
<Typography display="inline" variant="h4" component="span">
<FormattedMessage id="registerFail" />
</Typography>
<Button color="error" variant="outlined" component={Link} to="/login" ><Typography variant="pnspsFormHeader">


+ 64
- 26
src/pages/authentication/auth-forms/CustomFormWizard.js Просмотреть файл

@@ -47,7 +47,8 @@ import { FormattedMessage, useIntl } from "react-intl";
import { Link } from 'react-router-dom';
import { PNSPS_LONG_BUTTON_THEME } from "../../../themes/buttonConst";
import * as HttpUtils from "../../../utils/HttpUtils";
import { notifyActionError } from 'utils/CommonFunction';
import { handleActionKeyDown, notifyActionError } from 'utils/CommonFunction';
import { ADDRESS_LINE_MAX_LENGTH, isAddressLineWithinLimit, isRegisterAddressValid } from 'utils/registerValidation';
// ============================|| FIREBASE - REGISTER ||============================ //

const CustomFormWizard = (props) => {
@@ -377,7 +378,7 @@ const CustomFormWizard = (props) => {
selectedIdDocType.type !== "" &&
data.idNo !== "" &&
handleName(data.enName, data.chName) &&
data.address1 !== "" &&
isRegisterAddressValid(data) &&
data.email !== "" &&
data.emailConfirm !== "" &&
data.email == data.emailConfirm &&
@@ -432,6 +433,10 @@ const CustomFormWizard = (props) => {

}

if (fileInputRef.current) {
fileInputRef.current.value = '';
}

}, [updateRows]);

const handleFileUpload = (event) => {
@@ -473,6 +478,8 @@ const CustomFormWizard = (props) => {

setFileListData(saveFileList)
setFileList(updatedFileList);
setUpdateRows(saveFileList);
event.target.value = '';
};

useEffect(() => {
@@ -586,6 +593,7 @@ const CustomFormWizard = (props) => {
) => {
// console.log(response)
setCheckUpload(true)
props.onRegistrationComplete?.();
setLoding(false);
})
.catch(error => {
@@ -890,7 +898,17 @@ const CustomFormWizard = (props) => {
const syncOk = computeStep0ValidSync(values);
if (!syncOk) {
setisValid(false);
if (!isDistrictSelectionValid()) {
if (!isRegisterAddressValid(values)) {
if (values.address1 === '') {
notifyActionError(intl.formatMessage({ id: 'validateAddressLine1' }));
} else if (!isAddressLineWithinLimit(values.address1)) {
notifyActionError(intl.formatMessage({ id: 'noMoreThenNWords' }, { num: ADDRESS_LINE_MAX_LENGTH, fieldname: intl.formatMessage({ id: 'addressLine1' }) + ": " }));
} else if (!isAddressLineWithinLimit(values.address2)) {
notifyActionError(intl.formatMessage({ id: 'noMoreThenNWords' }, { num: ADDRESS_LINE_MAX_LENGTH, fieldname: intl.formatMessage({ id: 'addressLine2' }) + ": " }));
} else if (!isAddressLineWithinLimit(values.address3)) {
notifyActionError(intl.formatMessage({ id: 'noMoreThenNWords' }, { num: ADDRESS_LINE_MAX_LENGTH, fieldname: intl.formatMessage({ id: 'addressLine3' }) + ": " }));
}
} else if (!isDistrictSelectionValid()) {
setDistrictErrStr(getRequiredErrStr("district"));
setCheckDistrict(true);
notifyActionError(intl.formatMessage({ id: 'require' }, { fieldname: intl.formatMessage({ id: 'district' }) }));
@@ -942,14 +960,14 @@ const CustomFormWizard = (props) => {
</Typography>
</Button>
<div style={{ borderBottom: "3px solid #1A4399", width: "100%", margin_right: "15px" }}>
<Typography display="inline" variant="h3" sx={{ color: '#1A4399' }}>
<Typography display="inline" variant="h3" component="h1" sx={{ color: '#1A4399' }}>
<FormattedMessage id="becomeNewPersonalUser" />
</Typography>
</div>
<Typography mt={0.25} variant="h6" sx={{ color: '#B00020' }}>
<Typography mt={0.25} variant="h6" component="span" sx={{ color: '#B00020' }}>
<FormattedMessage id="requireString" />
</Typography>
<Typography mt={0.25} variant="h4" sx={{ color: 'primary.primary' }}>
<Typography mt={0.25} variant="h4" component="h2" sx={{ color: 'primary.primary' }}>
<FormattedMessage id="yourLoginInformation" />
</Typography>
</Stack>
@@ -966,7 +984,7 @@ const CustomFormWizard = (props) => {
{/* variant="contained"*/}
{/* onClick={handleCheckUsername}*/}
{/* sx={{ ml: 2, height: "40px" }}>*/}
{/* <Typography variant="h6">檢查是否重覆</Typography>*/}
{/* <Typography variant="h6" component="span">檢查是否重覆</Typography>*/}
{/*</Button> **/}
</Typography>
</InputLabel>
@@ -1033,10 +1051,13 @@ const CustomFormWizard = (props) => {
endAdornment={
<InputAdornment position="end">
<IconButton
role="button"
tabIndex={0}
aria-label={intl.formatMessage({
id: showPassword ? "ariaHidePassword" : "ariaShowPassword"
})}
onClick={handleClickShowPassword}
onKeyDown={(event) => handleActionKeyDown(event, handleClickShowPassword)}
onMouseDown={handleMouseDownPassword}
edge="end"
size="large"
@@ -1109,10 +1130,13 @@ const CustomFormWizard = (props) => {
endAdornment={
<InputAdornment position="end">
<IconButton
role="button"
tabIndex={0}
aria-label={intl.formatMessage({
id: showConfirmPassword ? "ariaHidePassword" : "ariaShowPassword"
})}
onClick={handleClickShowConfirmPassword}
onKeyDown={(event) => handleActionKeyDown(event, handleClickShowConfirmPassword)}
onMouseDown={handleMouseDownPassword}
edge="end"
size="large"
@@ -1147,7 +1171,7 @@ const CustomFormWizard = (props) => {
</Grid>
<Grid item xs={12} mt={1} mb={1}>
<Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
<Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
<Typography display="inline" variant="h4" component="h2" sx={{ color: 'primary.primary' }}>
<FormattedMessage id="yourPersonalInformation" />
</Typography>
{/* <Typography component={Link} to="/login" variant="body1" sx={{ textDecoration: 'none' }} color="primary">
@@ -1161,7 +1185,7 @@ const CustomFormWizard = (props) => {
<InputLabel htmlFor="idDocType-signup">
<Typography variant="pnspsFormHeader">
<FormattedMessage id="userIdDoc" />
<span style={{ color: '#B00020' }}>*</span>
<span style={{ color: '#131313' }}>*</span>
</Typography>
</InputLabel>
{/* {formik.touched.enName && formik.errors.enName && (
@@ -1462,6 +1486,7 @@ const CustomFormWizard = (props) => {
onBlur={formik.handleBlur}
inputProps={{
"aria-label": intl.formatMessage({ id: "addressLine1" }),
maxLength: ADDRESS_LINE_MAX_LENGTH,
onKeyDown: (e) => {
if (e.key === 'Enter') {
e.preventDefault();
@@ -1480,6 +1505,7 @@ const CustomFormWizard = (props) => {
placeholder={intl.formatMessage({ id: 'addressLine2' })}
inputProps={{
"aria-label": intl.formatMessage({ id: "addressLine2" }),
maxLength: ADDRESS_LINE_MAX_LENGTH,
onKeyDown: (e) => {
if (e.key === 'Enter') {
e.preventDefault();
@@ -1498,6 +1524,7 @@ const CustomFormWizard = (props) => {
placeholder={intl.formatMessage({ id: 'addressLine3' })}
inputProps={{
"aria-label": intl.formatMessage({ id: "addressLine3" }),
maxLength: ADDRESS_LINE_MAX_LENGTH,
onKeyDown: (e) => {
if (e.key === 'Enter') {
e.preventDefault();
@@ -1607,7 +1634,7 @@ const CustomFormWizard = (props) => {
</Grid>
<Grid item xs={12} mt={1} mb={1}>
<Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
<Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
<Typography display="inline" variant="h4" component="h2" sx={{ color: 'primary.primary' }}>
<FormattedMessage id="yourContact" />
</Typography>
</Stack>
@@ -1851,7 +1878,7 @@ const CustomFormWizard = (props) => {
<Grid container>
<Grid item xs={12} md={12}>
<Stack spacing={1} direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
<Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
<Typography display="inline" variant="h4" component="h2" sx={{ color: 'primary.primary' }}>
<FormattedMessage id="userIdDoc" />
<span style={{ color: '#B00020' }}>*</span></Typography>
<Typography display="inline" variant="subtitle1" sx={{ color: 'primary.primary' }}>
@@ -1866,6 +1893,7 @@ const CustomFormWizard = (props) => {
variant="contained"
sx={{ height: '40px' }}
type="button"
tabIndex={0}
onClick={() => {
if (fileInputRef.current) {
fileInputRef.current.click();
@@ -1909,7 +1937,7 @@ const CustomFormWizard = (props) => {
<Grid item xs={12} md={12}>
<Grid container>
<Grid item xs={12} md={12}>
<Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
<Typography display="inline" variant="h4" component="h2" sx={{ color: 'primary.primary' }}>
<FormattedMessage id="termsAndCondition" />
<span style={{ color: '#B00020' }}>*</span>
</Typography>
@@ -1917,7 +1945,7 @@ const CustomFormWizard = (props) => {
<Grid item xs={12} md={12}>
<Grid container>
<Grid item xs={12} md={12}>
<Typography variant="h6" height="100%" sx={{ textAlign: "left", /*overflow: "scroll",*/ borderRadius: "inherit", borderStyle: "solid", borderWidth: "1px", borderColor: "#0C489E" }}>
<Typography height="100%" sx={{ textAlign: "left", /*overflow: "scroll",*/ borderRadius: "inherit", borderStyle: "solid", borderWidth: "1px", borderColor: "#0c489e" }}>
<div style={{padding: 12}} dangerouslySetInnerHTML={{__html: intl.formatMessage({id: "termsAndCon"})}} />
</Typography>
</Grid>
@@ -1970,7 +1998,7 @@ const CustomFormWizard = (props) => {
<Grid item xs={12} lg={12}>
<Grid container>
<Stack direction="column">
<Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
<Typography display="inline" variant="h4" component="h2" sx={{ color: 'primary.primary' }}>
<FormattedMessage id="verify" />
<span style={{ color: '#B00020' }}>*</span>
</Typography>
@@ -1979,7 +2007,14 @@ const CustomFormWizard = (props) => {
<img src={captchaImg} alt="" />
</Grid>
<Grid item xs={1} lg={1} style={{ "border": "0px solid black" }}>
<IconButton aria-label={intl.formatMessage({ id: 'ariaRefreshCaptcha' })} size="large" onClick={() => { onCaptchaChange() }}>
<IconButton
role="button"
tabIndex={0}
aria-label={intl.formatMessage({ id: 'ariaRefreshCaptcha' })}
size="large"
onClick={() => { onCaptchaChange() }}
onKeyDown={(event) => handleActionKeyDown(event, () => onCaptchaChange())}
>
<LoopIcon fontSize="inherit" />
</IconButton>
</Grid>
@@ -2017,9 +2052,9 @@ const CustomFormWizard = (props) => {
onClick={playCaptchaAudio}
aria-label={intl.formatMessage({ id: "captchaPlayAudio" })}
sx={{
backgroundColor: '#0C489E',
backgroundColor: '#0c489e',
color: '#FFFFFF',
'&:hover': { backgroundColor: '#093A7A' },
'&:hover': { backgroundColor: '#1565c0' },
}}
>
<FormattedMessage id="captchaPlayAudio" />
@@ -2037,12 +2072,12 @@ const CustomFormWizard = (props) => {
<Grid item xs={12} md={12}>
<Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
<div style={{ borderBottom: "3px solid #1A4399", width: "100%", margin_right: "15px" }}>
<Typography display="inline" variant="h3" sx={{ color: '#1A4399' }}>
<Typography display="inline" variant="h3" component="h1" sx={{ color: '#1A4399' }}>
<FormattedMessage id="becomeNewPersonalUser" />
</Typography>
</div>
{/* <Typography mt={0.25} variant="h6" sx={{ fontSize: 12,color: '#B00020'}}>註有*的項目必須輸入資料</Typography> */}
<Typography mt={0.25} variant="h4" sx={{ color: 'primary.primary' }}>
{/* <Typography mt={0.25} variant="h6" component="span" sx={{ fontSize: 12,color: '#B00020'}}>註有*的項目必須輸入資料</Typography> */}
<Typography mt={0.25} variant="h4" component="h2" sx={{ color: 'primary.primary' }}>
<FormattedMessage id="yourLoginInformation" />
</Typography>
{/* <Typography component={Link} to="/login" variant="body1" sx={{ textDecoration: 'none' }} color="primary">
@@ -2064,7 +2099,7 @@ const CustomFormWizard = (props) => {
</Grid>
<Grid item xs={12} mt={1} mb={1}>
<Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
<Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
<Typography display="inline" variant="h4" component="h2" sx={{ color: 'primary.primary' }}>
<FormattedMessage id="yourPersonalInformation" />
</Typography>
{/* <Typography component={Link} to="/login" variant="body1" sx={{ textDecoration: 'none' }} color="primary">
@@ -2107,8 +2142,11 @@ const CustomFormWizard = (props) => {
</Typography>
<IconButton
role="button"
tabIndex={0}
aria-label={intl.formatMessage({ id: 'ariaToggleIdVisibility' })}
onClick={handleClickShowId}
onKeyDown={(event) => handleActionKeyDown(event, handleClickShowId)}
onMouseDown={handleMouseDownId}
edge="end"
size="medium"
@@ -2180,7 +2218,7 @@ const CustomFormWizard = (props) => {
</Grid>
<Grid item xs={12} mt={1} mb={1}>
<Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
<Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
<Typography display="inline" variant="h4" component="h2" sx={{ color: 'primary.primary' }}>
<FormattedMessage id="yourContact" />
</Typography>
</Stack>
@@ -2221,7 +2259,7 @@ const CustomFormWizard = (props) => {
<Grid container>
<Grid item xs={12} md={12}>
<Stack spacing={1} direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
<Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
<Typography display="inline" variant="h4" component="h2" sx={{ color: 'primary.primary' }}>
<FormattedMessage id="userIdDoc" />
</Typography>
{fileList != null && props.step === 1 ?
@@ -2244,10 +2282,10 @@ const CustomFormWizard = (props) => {
// SUCCESS page
<Stack mt={1} direction="column" justifyContent="flex-start" alignItems="center" spacing={2}>
<CheckCircleOutlineIcon color="success" sx={{ width: "200px", height: "200px" }} />
<Typography display="inline" variant="h4">
<Typography display="inline" variant="h4" component="span">
<FormattedMessage id="registerSubmitted" />
</Typography>
<Typography display="inline" variant="h4">
<Typography display="inline" variant="h4" component="span">
<FormattedMessage id="emailSent" />
</Typography>
<Button variant="outlined" component={Link} to="/login" ><Typography variant="pnspsFormHeader">
@@ -2259,7 +2297,7 @@ const CustomFormWizard = (props) => {
<Stack mt={1} direction="column" justifyContent="flex-start" alignItems="center" spacing={2}>
{/* <Button disabled={true} hidden={true} variant="contained" type="submit" sx={{ fontSize: 12,height:'25px'}}>Submit</Button> */}
<CancelOutlinedIcon color="error" sx={{ width: "200px", height: "200px" }} />
<Typography display="inline" variant="h4">
<Typography display="inline" variant="h4" component="span">
<FormattedMessage id="registerFail" />
</Typography>
<Button color="error" variant="outlined" component={Link} to="/login" ><Typography variant="pnspsFormHeader">


+ 98
- 66
src/pages/authentication/auth-forms/IAmSmartFormWizard.js Просмотреть файл

@@ -40,7 +40,8 @@ import LoopIcon from '@mui/icons-material/Loop';
import { useTheme } from '@mui/material/styles';
import { useLocation } from "react-router-dom";
import { FormattedMessage, useIntl } from "react-intl";
import { notifyActionError } from 'utils/CommonFunction';
import { handleActionKeyDown, notifyActionError } from 'utils/CommonFunction';
import { ADDRESS_LINE_MAX_LENGTH, isAddressLineWithinLimit, isRegisterAddressValid, splitAddressIntoLines } from 'utils/registerValidation';

// ============================|| FIREBASE - REGISTER ||============================ //

@@ -199,20 +200,22 @@ const CustomFormWizard = (props) => {
"phoneCountryCode": rd?.mobileNumber?.CountryCode ?? "",
};

if (rd?.postalAddress) {
if (rd?.postalAddress?.EngPremisesAddress) {
data["address1"] = getAddressEng(rd?.postalAddress?.EngPremisesAddress);
} else if (rd.postalAddress.ChiPremisesAddress) {
data["address1"] = getAddressChi(rd?.postalAddress?.ChiPremisesAddress);
}
} else if (rd?.residentialAddress) {
if (rd?.residentialAddress?.EngPremisesAddress) {
data["address1"] = getAddressEng(rd?.residentialAddress?.EngPremisesAddress);
} else if (rd?.residentialAddress?.ChiPremisesAddress) {
data["address1"] = getAddressChi(rd?.residentialAddress?.ChiPremisesAddress);
}
let fullAddress = '';
if (rd?.postalAddress?.EngPremisesAddress) {
fullAddress = getAddressEng(rd.postalAddress.EngPremisesAddress);
} else if (rd?.postalAddress?.ChiPremisesAddress) {
fullAddress = getAddressChi(rd.postalAddress.ChiPremisesAddress);
} else if (rd?.residentialAddress?.EngPremisesAddress) {
fullAddress = getAddressEng(rd.residentialAddress.EngPremisesAddress);
} else if (rd?.residentialAddress?.ChiPremisesAddress) {
fullAddress = getAddressChi(rd.residentialAddress.ChiPremisesAddress);
}

const { address1, address2, address3 } = splitAddressIntoLines(fullAddress);
data["address1"] = address1;
data["address2"] = address2;
data["address3"] = address3;

setIAmSmartData(data);

}
@@ -300,6 +303,8 @@ const CustomFormWizard = (props) => {
formik.setFieldValue("phone", iAmSmartData.phone ?? "");
formik.setFieldValue("phoneCountryCode", iAmSmartData.phoneCountryCode ?? "");
formik.setFieldValue("address1", iAmSmartData.address1 ?? "");
formik.setFieldValue("address2", iAmSmartData.address2 ?? "");
formik.setFieldValue("address3", iAmSmartData.address3 ?? "");
props.setIdNo(iAmSmartData.idNo ?? "");
setLodingData(false)
}
@@ -321,7 +326,7 @@ const CustomFormWizard = (props) => {

/** All step-0 checks except duplicate-email result from /checkE1 (see checkEmail state). */
const computeStep0ValidSync = (data) => (
data.address1 !== "" &&
isRegisterAddressValid(data) &&
data.email !== "" &&
data.emailConfirm !== "" &&
data.email == data.emailConfirm &&
@@ -431,6 +436,7 @@ const CustomFormWizard = (props) => {
.then((response) => {
console.log(response)
setCheckUpload(true)
props.onRegistrationComplete?.();
setLoding(false);
})
.catch(error => {
@@ -509,7 +515,17 @@ const CustomFormWizard = (props) => {
const syncOk = computeStep0ValidSync(values);
if (!syncOk) {
setisValid(false);
if (!isDistrictSelectionValid()) {
if (!isRegisterAddressValid(values)) {
if (values.address1 === '') {
notifyActionError(intl.formatMessage({ id: 'validateAddressLine1' }));
} else if (!isAddressLineWithinLimit(values.address1)) {
notifyActionError(intl.formatMessage({ id: 'noMoreThenNWords' }, { num: ADDRESS_LINE_MAX_LENGTH, fieldname: intl.formatMessage({ id: 'addressLine1' }) + ": " }));
} else if (!isAddressLineWithinLimit(values.address2)) {
notifyActionError(intl.formatMessage({ id: 'noMoreThenNWords' }, { num: ADDRESS_LINE_MAX_LENGTH, fieldname: intl.formatMessage({ id: 'addressLine2' }) + ": " }));
} else if (!isAddressLineWithinLimit(values.address3)) {
notifyActionError(intl.formatMessage({ id: 'noMoreThenNWords' }, { num: ADDRESS_LINE_MAX_LENGTH, fieldname: intl.formatMessage({ id: 'addressLine3' }) + ": " }));
}
} else if (!isDistrictSelectionValid()) {
setDistrictErrStr(getRequiredErrStr("district"));
setCheckDistrict(true);
notifyActionError(intl.formatMessage({ id: 'require' }, { fieldname: intl.formatMessage({ id: 'district' }) }));
@@ -550,15 +566,15 @@ const CustomFormWizard = (props) => {
<Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
<div style={{ borderBottom: "3px solid #1A4399", width: "100%", margin_right: "15px" }}>
<Typography display="inline" variant="h3" sx={{ color: '#1A4399' }}>
<Typography display="inline" variant="h3" component="h1" sx={{ color: '#1A4399' }}>
<FormattedMessage id="becomeNewPersonalUser" />
</Typography>
</div>
<Typography mt={0.25} variant="h6" sx={{ color: '#B00020' }}>
<Typography mt={0.25} variant="h6" component="span" sx={{ color: '#B00020' }}>
<FormattedMessage id="requireString" />。
</Typography>
<Stack mt={1} direction="row" style={{ alignItems: "center" }}><img src={iAmSmartICon} alt="iAM Smart" width="25" /><Typography mt={0.25} variant="h6" >: <FormattedMessage id="MSG.providedByIAmSmart" /></Typography></Stack>
<Stack mt={1} direction="row" style={{ alignItems: "center" }}><img src={iAmSmartICon} alt="iAM Smart" width="25" /><Typography mt={0.25} variant="h6" component="span" >: <FormattedMessage id="MSG.providedByIAmSmart" /></Typography></Stack>
</Stack>
</Grid>
@@ -566,7 +582,7 @@ const CustomFormWizard = (props) => {
<Grid container spacing={1}>
<Grid item xs={12} mt={1} mb={1}>
<Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
<Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
<Typography display="inline" variant="h4" component="h2" sx={{ color: 'primary.primary' }}>
<FormattedMessage id="yourPersonalInformation" />
</Typography>
</Stack>
@@ -575,17 +591,20 @@ const CustomFormWizard = (props) => {
<Grid container sx={{ mb: 1 }}>
<InputLabel htmlFor="idDocType-signup">
<Typography variant="h5" sx={{ mr: 1 }}>
<Typography variant="h5" component="span" sx={{ mr: 1 }}>
<FormattedMessage id="HKIDcard" />: {iAmSmartData.idNo ? <img src={iAmSmartICon} alt="iAM Smart" width="25" /> : <></>}
{/* {iAmSmartData.idNo + "(" + iAmSmartData.checkDigit + ")"} */}
</Typography>
<Stack direction="row">
<Typography variant="h5">
<Typography variant="h5" component="span">
{iAmSmartData?.idNo?.slice(0, 4)}{showId ? iAmSmartData?.idNo?.slice(4) : "****"}{showId ? '(' + iAmSmartData.checkDigit + ')' : null}
</Typography>
<IconButton
role="button"
tabIndex={0}
aria-label={intl.formatMessage({ id: 'ariaToggleIdVisibility' })}
onClick={handleClickShowId}
onKeyDown={(event) => handleActionKeyDown(event, handleClickShowId)}
onMouseDown={handleMouseDownId}
edge="end"
size="medium"
@@ -600,7 +619,7 @@ const CustomFormWizard = (props) => {
<Grid item xs={12} md={6}>
<Stack spacing={1}>
<InputLabel htmlFor="enName-signup">
<Typography variant="h5">
<Typography variant="h5" component="span">
<FormattedMessage id="userEnglishName" />: {iAmSmartData.enName}{iAmSmartData.enName ? <img src={iAmSmartICon} alt="iAM Smart" width="25" /> : <></>}
</Typography>
@@ -610,7 +629,7 @@ const CustomFormWizard = (props) => {
<Grid item xs={12} md={6}>
<Stack spacing={1}>
<InputLabel htmlFor="chName-signup">
<Typography variant="h5">
<Typography variant="h5" component="span">
{intl.formatMessage({ id: 'userChineseName' })}: {iAmSmartData.chName}{iAmSmartData.chName ? <img src={iAmSmartICon} alt="iAM Smart" width="25" /> : <></>}
</Typography>
</InputLabel>
@@ -619,7 +638,7 @@ const CustomFormWizard = (props) => {
<Grid item xs={12}>
<Stack spacing={1}>
<InputLabel htmlFor="address1-signup">
<Typography variant="h5">
<Typography variant="h5" component="span">
<FormattedMessage id="formAddress" />
<span style={{ color: '#B00020' }}>*</span>
@@ -638,6 +657,7 @@ const CustomFormWizard = (props) => {
placeholder={intl.formatMessage({ id: 'addressLine1' })}
onBlur={formik.handleBlur}
inputProps={{
maxLength: ADDRESS_LINE_MAX_LENGTH,
onKeyDown: (e) => {
if (e.key === 'Enter') {
e.preventDefault();
@@ -659,6 +679,7 @@ const CustomFormWizard = (props) => {
onChange={formik.handleChange}
placeholder={intl.formatMessage({ id: 'addressLine2' })}
inputProps={{
maxLength: ADDRESS_LINE_MAX_LENGTH,
onKeyDown: (e) => {
if (e.key === 'Enter') {
e.preventDefault();
@@ -681,6 +702,7 @@ const CustomFormWizard = (props) => {
onChange={formik.handleChange}
placeholder={intl.formatMessage({ id: 'addressLine3' })}
inputProps={{
maxLength: ADDRESS_LINE_MAX_LENGTH,
onKeyDown: (e) => {
if (e.key === 'Enter') {
e.preventDefault();
@@ -772,7 +794,7 @@ const CustomFormWizard = (props) => {
</Grid>
<Grid item xs={12} mt={1} mb={1}>
<Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
<Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
<Typography display="inline" variant="h4" component="h2" sx={{ color: 'primary.primary' }}>
<FormattedMessage id="yourContact" />
</Typography>
</Stack>
@@ -782,7 +804,7 @@ const CustomFormWizard = (props) => {
<Grid item xs={12} md={6}>
<Stack spacing={1} sx={{ mr: { md: 1 }, mb: 1 }}>
<InputLabel htmlFor="email-login">
<Typography variant="h5">
<Typography variant="h5" component="span">
<FormattedMessage id="userContactEmail" />
<span style={{ color: '#B00020' }}>*</span>
@@ -828,7 +850,7 @@ const CustomFormWizard = (props) => {
<Grid item xs={12} md={6}>
<Stack spacing={1} >
<InputLabel htmlFor="emailConfirm-login">
<Typography variant="h5">
<Typography variant="h5" component="span">
<FormattedMessage id="confirmEmail" />
<span style={{ color: '#B00020' }}>*</span>
</Typography>
@@ -877,7 +899,7 @@ const CustomFormWizard = (props) => {
<Grid item xs={12} md={12}>
<Stack direction="column" spacing={1} sx={{ mr: { md: 1 }, mb: 1 }}>
<InputLabel htmlFor="phone-signup">
<Typography variant="h5">
<Typography variant="h5" component="span">
<FormattedMessage id="userContactNumber" />
<span style={{ color: '#B00020' }}>*</span>
@@ -956,7 +978,7 @@ const CustomFormWizard = (props) => {
<Grid item xs={12} md={12}>
<Stack spacing={1} direction="column">
<InputLabel htmlFor="fax-signup">
<Typography variant="h5">
<Typography variant="h5" component="span">
<FormattedMessage id="userFaxNumber" />
</Typography>
</InputLabel>
@@ -1023,7 +1045,7 @@ const CustomFormWizard = (props) => {
<Grid item xs={12} md={12}>
<Grid container>
<Grid item xs={12} md={12}>
<Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
<Typography display="inline" variant="h4" component="h2" sx={{ color: 'primary.primary' }}>
<FormattedMessage id="termsAndCondition" />
<span style={{ color: '#B00020' }}>*</span>
</Typography>
@@ -1031,7 +1053,7 @@ const CustomFormWizard = (props) => {
<Grid item xs={12} md={12}>
<Grid container>
<Grid item xs={12} md={12}>
<Typography variant="h5" sx={{ textAlign: "left", borderRadius: "inherit", borderStyle: "solid", borderWidth: "1px", borderColor: "#0C489E" }}>
<Typography sx={{ textAlign: "left", borderRadius: "inherit", borderStyle: "solid", borderWidth: "1px", borderColor: "#0c489e" }}>
<div style={{ padding: 12 }} dangerouslySetInnerHTML={{ __html: intl.formatMessage({ id: "termsAndCon" }) }} />
</Typography>
@@ -1049,7 +1071,7 @@ const CustomFormWizard = (props) => {
color="primary"
size="small"
/>
<Typography variant="h5">
<Typography variant="h5" component="span">
<FormattedMessage id="iConfirm" />
</Typography>
</Grid>
@@ -1066,7 +1088,7 @@ const CustomFormWizard = (props) => {
size="small"
/>
<Typography variant="h5">
<Typography variant="h5" component="span">
<FormattedMessage id="rejectTerms" />
</Typography>
</Grid>
@@ -1080,7 +1102,7 @@ const CustomFormWizard = (props) => {
<Grid item xs={12} lg={12}>
<Grid container>
<Stack direction="column">
<Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
<Typography display="inline" variant="h4" component="h2" sx={{ color: 'primary.primary' }}>
<FormattedMessage id="verify" />
<span style={{ color: '#B00020' }}>*</span>
</Typography>
@@ -1089,7 +1111,14 @@ const CustomFormWizard = (props) => {
<img src={captchaImg} alt="" />
</Grid>
<Grid item xs={1} lg={1} style={{ "border": "0px solid black" }}>
<IconButton aria-label={intl.formatMessage({ id: 'ariaRefreshCaptcha' })} size="large" onClick={() => { onCaptchaChange() }}>
<IconButton
role="button"
tabIndex={0}
aria-label={intl.formatMessage({ id: 'ariaRefreshCaptcha' })}
size="large"
onClick={() => { onCaptchaChange() }}
onKeyDown={(event) => handleActionKeyDown(event, () => onCaptchaChange())}
>
<LoopIcon fontSize="inherit" />
</IconButton>
</Grid>
@@ -1123,9 +1152,9 @@ const CustomFormWizard = (props) => {
onClick={playCaptchaAudio}
aria-label={intl.formatMessage({ id: "captchaPlayAudio" })}
sx={{
backgroundColor: '#0C489E',
backgroundColor: '#0c489e',
color: '#FFFFFF',
'&:hover': { backgroundColor: '#093A7A' },
'&:hover': { backgroundColor: '#1565c0' },
}}
>
<FormattedMessage id="captchaPlayAudio" />
@@ -1143,7 +1172,7 @@ const CustomFormWizard = (props) => {
<Grid item xs={12} md={12}>
<Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
<div style={{ borderBottom: "3px solid #1A4399", width: "100%", margin_right: "15px" }}>
<Typography display="inline" variant="h3" sx={{ color: '#1A4399' }}>
<Typography display="inline" variant="h3" component="h1" sx={{ color: '#1A4399' }}>
<FormattedMessage id="becomeNewPersonalUser" />
</Typography>
</div>
@@ -1153,7 +1182,7 @@ const CustomFormWizard = (props) => {
<Grid container spacing={2}>
<Grid item xs={12} mt={1} mb={1}>
<Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
<Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
<Typography display="inline" variant="h4" component="h2" sx={{ color: 'primary.primary' }}>
<FormattedMessage id="yourPersonalInformation" />
</Typography>
{/* <Typography component={Link} to="/login" variant="body1" sx={{ textDecoration: 'none' }} color="primary">
@@ -1163,20 +1192,23 @@ const CustomFormWizard = (props) => {
</Grid>
<Grid item xs={12} md={12} >
<Stack direction="row">
<Typography variant="h5" color={theme.palette.grey[600]} sx={{ mr: 1 }}>
<Typography variant="h5" component="h2" color={theme.palette.grey[600]} sx={{ mr: 1 }}>
<FormattedMessage id="userIdDoc" />
</Typography>
<Typography variant="h5" name="preview-idDocType-1">
<Typography variant="h5" component="span" name="preview-idDocType-1">
{formik?.values?.idNo?.slice(0, 4)}
{/* {formik.values.idNo + "(" + formik.values.checkDigit + ")"} */}
</Typography>
<Typography variant="h5" name="preview-idDocType-2">
<Typography variant="h5" component="span" name="preview-idDocType-2">
{showComId ? formik?.values?.idNo?.slice(4) : "****"}{showComId ? '(' + formik.values.checkDigit + ')' : null}
{/* {formik.values.idNo + "(" + formik.values.checkDigit + ")"} */}
</Typography>
<IconButton
role="button"
tabIndex={0}
aria-label={intl.formatMessage({ id: 'ariaToggleIdVisibility' })}
onClick={handleClickShowComId}
onKeyDown={(event) => handleActionKeyDown(event, handleClickShowComId)}
onMouseDown={handleMouseDownComId}
edge="end"
size="medium"
@@ -1187,10 +1219,10 @@ const CustomFormWizard = (props) => {
</Grid>
<Grid item xs={12} md={6}>
<Stack spacing={1} direction="row">
<Typography variant="h5" color={theme.palette.grey[600]}>
<Typography variant="h5" component="span" color={theme.palette.grey[600]}>
<FormattedMessage id="userEnglishName" />:
</Typography>
<Typography variant="h5" id="preview-enName-signup">
<Typography variant="h5" component="span" id="preview-enName-signup">
{formik.values.enName}
</Typography>
{iAmSmartData.enName ? <img src={iAmSmartICon} alt="iAM Smart" width="25" /> : <></>}
@@ -1198,48 +1230,48 @@ const CustomFormWizard = (props) => {
</Grid>
<Grid item xs={12} md={6}>
<Stack spacing={1} direction="row">
<Typography variant="h5" color={theme.palette.grey[600]}>
<Typography variant="h5" component="span" color={theme.palette.grey[600]}>
<FormattedMessage id="userChineseName" />:
</Typography>
<Typography variant="h5" id="preview-chName-signup">
<Typography variant="h5" component="span" id="preview-chName-signup">
{formik.values.chName}
</Typography>
</Stack>
</Grid>
<Grid item xs={12}>
<Stack spacing={1} direction="column">
<Typography variant="h5" color={theme.palette.grey[600]}>
<Typography variant="h5" component="span" color={theme.palette.grey[600]}>
<FormattedMessage id="formAddress" />:
</Typography>
<Stack spacing={1} direction="column">
<Typography variant="h5" id="preview-address1-signup">
<Typography variant="h5" component="span" id="preview-address1-signup">
{formik.values.address1}
</Typography>
{formik.values.address2 != null ?
<Typography variant="h5" id="preview-address2-signup">
<Typography variant="h5" component="span" id="preview-address2-signup">
{formik.values.address2}
</Typography>
: null}
{formik.values.address3 != null ?
<Typography variant="h5" id="preview-address3-signup">
<Typography variant="h5" component="span" id="preview-address3-signup">
{formik.values.address3}
</Typography>
: null}
{selectedAddress5.type === "hongKong" ?
<Stack direction="column">
{/* <Typography variant="h5" color={theme.palette.grey[600]} id="preview-address4-signup">
{/* <Typography variant="h5" component="span" color={theme.palette.grey[600]} id="preview-address4-signup">
<FormattedMessage id="region" />:
</Typography> */}
<Typography variant="h5">
<Typography variant="h5" component="span">
{!selectedAddress4 ? "" : intl.formatMessage({ id: selectedAddress4.type })}
</Typography>
</Stack>
: null}
<Stack direction="column">
{/* <Typography variant="h5" color={theme.palette.grey[600]} id="preview-address5-signup">
{/* <Typography variant="h5" component="span" color={theme.palette.grey[600]} id="preview-address5-signup">
<FormattedMessage id="regionOrCountry" />:
</Typography> */}
<Typography variant="h5">
<Typography variant="h5" component="span">
{intl.formatMessage({ id: selectedAddress5.type })}
</Typography>
</Stack>
@@ -1248,27 +1280,27 @@ const CustomFormWizard = (props) => {
</Grid>
<Grid item xs={12} mt={1} mb={1}>
<Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
<Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
<Typography display="inline" variant="h4" component="h2" sx={{ color: 'primary.primary' }}>
<FormattedMessage id="yourContact" />
</Typography>
</Stack>
</Grid>
<Grid item xs={12} md={12}>
<Stack spacing={1} direction="row">
<Typography variant="h5" color={theme.palette.grey[600]}>
<Typography variant="h5" component="span" color={theme.palette.grey[600]}>
<FormattedMessage id="userContactEmail" />:
</Typography>
<Typography variant="h5" id="preview-email-signup">
<Typography variant="h5" component="span" id="preview-email-signup">
{formik.values.email}
</Typography>
</Stack>
</Grid>
<Grid item xs={12} md={6}>
<Stack spacing={1} direction="row">
<Typography variant="h5" color={theme.palette.grey[600]}>
<Typography variant="h5" component="span" color={theme.palette.grey[600]}>
<FormattedMessage id="userContactNumber" />:
</Typography>
<Typography variant="h5" id="preview-phone-signup">
<Typography variant="h5" component="span" id="preview-phone-signup">
+{formik.values.phoneCountryCode} {formik.values.phone}
</Typography>
</Stack>
@@ -1276,10 +1308,10 @@ const CustomFormWizard = (props) => {
{formik.values.faxCountryCode != "" && formik.values.fax != "" ?
<Grid item xs={12} md={6}>
<Stack spacing={1} direction="row">
<Typography variant="h5" color={theme.palette.grey[600]}>
<Typography variant="h5" component="span" color={theme.palette.grey[600]}>
<FormattedMessage id="userFaxNumber" />:
</Typography>
<Typography variant="h5" id="preview-fax-signup">
<Typography variant="h5" component="span" id="preview-fax-signup">
+{formik.values.faxCountryCode} {formik.values.fax}
</Typography>
</Stack>
@@ -1299,13 +1331,13 @@ const CustomFormWizard = (props) => {
// SUCCESS page
<Stack mt={1} direction="column" justifyContent="flex-start" alignItems="center" spacing={2}>
<CheckCircleOutlineIcon color="success" sx={{ width: "200px", height: "200px" }} />
<Typography display="inline" variant="h4">
<Typography display="inline" variant="h4" component="span">
<FormattedMessage id="registerSubmitted" />
</Typography>
<Typography display="inline" variant="h4">
<Typography display="inline" variant="h4" component="span">
<FormattedMessage id="emailSent" />
</Typography>
<Button variant="outlined" component={Link} to="/login" ><Typography variant="h5">
<Button variant="outlined" component={Link} to="/login" ><Typography variant="h5" component="span">
<FormattedMessage id="backToLogin" />
</Typography></Button>
</Stack>
@@ -1314,10 +1346,10 @@ const CustomFormWizard = (props) => {
<Stack mt={1} direction="column" justifyContent="flex-start" alignItems="center" spacing={2}>
{/* <Button disabled={true} hidden={true} variant="contained" type="submit" sx={{ fontSize: 12,height:'25px'}}>Submit</Button> */}
<CancelOutlinedIcon color="error" sx={{ width: "200px", height: "200px" }} />
<Typography display="inline" variant="h4">
<Typography display="inline" variant="h4" component="span">
<FormattedMessage id="registerFail" />
</Typography>
<Button color="error" variant="outlined" component={Link} to="/login" ><Typography variant="h5">
<Button color="error" variant="outlined" component={Link} to="/login" ><Typography variant="h5" component="span">
<FormattedMessage id="backToLogin" />
</Typography></Button>
</Stack>


+ 56
- 84
src/pages/authentication/auth-forms/UploadFileTable.js Просмотреть файл

@@ -1,116 +1,88 @@
// material-ui
import RemoveCircleOutlineIcon from '@mui/icons-material/RemoveCircleOutline';
import {
DataGrid,
GridActionsCellItem,
GridRowModes
} from "@mui/x-data-grid";
import * as React from 'react';
import { useEffect } from "react";
// import {useNavigate} from "react-router-dom";
// import { useTheme } from '@mui/material/styles';
import {
Box,
Stack,
Table,
TableBody,
TableCell,
TableHead,
TableRow,
Typography
} from '@mui/material';
import { FormattedMessage, useIntl } from "react-intl";
import FileDeleteButton from 'components/FileDeleteButton';
// ==============================|| EVENT TABLE ||============================== //

export default function UploadFileTable({ recordList, setUpdateRows, }) {

const [rows, setRows] = React.useState(recordList);
const [rowModesModel, setRowModesModel] = React.useState({});
// const theme = useTheme();

const intl = useIntl();

// const navigate = useNavigate()

useEffect(() => {
setRows(recordList);
// console.log(disableDelete);
}, [recordList]);

function NoRowsOverlay() {
const handleCancelClick = (id) => {
setRows((prevRows) => {
const newRows = prevRows.filter((row) => row.id !== id);
setUpdateRows(newRows);
return newRows;
});
};

const formatFileSize = (size) => `${Math.ceil(size / 1024)} KB`;

if (rows.length === 0) {
return (
<Stack height="100%" alignItems="center" justifyContent="center">
<Box
sx={{
height: '200px',
width: '100%',
border: 1,
borderColor: 'divider',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
>
<Typography variant="h6">
<FormattedMessage id="noFile"/>
</Typography>
{/* <pre>(rows=&#123;[]&#125;)</pre> */}
</Stack>
</Box>
);
}

const handleCancelClick = (id) => () => {
setRowModesModel({
...rowModesModel,
[id]: { mode: GridRowModes.View, ignoreModifications: true },
});
// console.log("Starting Delete")
// const editedRow = rows.find((row) => row.id === id);
// console.log(editedRow)
// console.log(editedRow.isNew)
setUpdateRows(rows.filter((row) => row.id !== id));
setRows(rows.filter((row) => row.id !== id));
}

const columns = [
{
field: 'actions',
type: 'actions',
headerName: '',
width: 30,
cellClassName: 'actions',
// hide:true,
getActions: ({ id }) => {
return [
<GridActionsCellItem
key="OutSave"
icon={<RemoveCircleOutlineIcon />}
label="delete"
className="textPrimary"
onClick={handleCancelClick(id)}
color="error"
/>]
},
},
{
id: 'name',
field: 'name',
headerName: intl.formatMessage({ id: 'fileName' }),
flex: 4,
},
{
id: 'size',
field: 'size',
headerName: intl.formatMessage({ id: 'fileSize' }),
valueGetter: (params) => {
// console.log(params)
return Math.ceil(params.value / 1024) + " KB";
},
flex: 2,
},
];

return (
<Box style={{ height: '200px', width: '100%' }}>
<DataGrid
rows={rows}
columns={columns}
editMode="row"
sx={{ border: 1 }}
rowModesModel={rowModesModel}
disablePagination
components={{ NoRowsOverlay, }}
// hideFooterPagination={true}
disableSelectionOnClick
disableColumnMenu
disableColumnSelector
hideFooter
getRowHeight={()=>"auto"}
/>
<Box sx={{ height: '200px', width: '100%', border: 1, borderColor: 'divider', overflow: 'auto' }}>
<Table size="small" aria-label={intl.formatMessage({ id: 'fileName' })}>
<TableHead>
<TableRow>
<TableCell padding="checkbox" sx={{ width: 48 }} />
<TableCell>{intl.formatMessage({ id: 'fileName' })}</TableCell>
<TableCell align="right">{intl.formatMessage({ id: 'fileSize' })}</TableCell>
</TableRow>
</TableHead>
<TableBody>
{rows.map((row) => (
<TableRow key={row.id}>
<TableCell padding="checkbox">
<FileDeleteButton onDelete={() => handleCancelClick(row.id)} />
</TableCell>
<TableCell>
<Stack direction="row" alignItems="center">
<Typography variant="body2">{row.name}</Typography>
</Stack>
</TableCell>
<TableCell align="right">
<Typography variant="body2">{formatFileSize(row.size)}</Typography>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</Box>
);
}

+ 1
- 1
src/pages/components-overview/Color.js Просмотреть файл

@@ -68,7 +68,7 @@ const ComponentColor = () => (
<ColorBox bgcolor="primary.200" data={{ label: 'Blue-3', color: '#91d5ff' }} title="primary[200]" dark />
<ColorBox bgcolor="primary.light" data={{ label: 'Blue-4', color: '#69c0ff' }} title="primary.light" dark />
<ColorBox bgcolor="primary.400" data={{ label: 'Blue-5', color: '#40a9ff' }} title="primary[400]" />
<ColorBox bgcolor="primary.main" data={{ label: 'Blue-6', color: '#1890ff' }} title="primary.main" main />
<ColorBox bgcolor="primary.main" data={{ label: 'Blue-6', color: '#0c489e' }} title="primary.main" main />
<ColorBox bgcolor="primary.dark" data={{ label: 'Blue-7', color: '#096dd9' }} title="primary.dark" />
<ColorBox bgcolor="primary.700" data={{ label: 'Blue-8', color: '#0050b3' }} title="primary[700]" />
<ColorBox bgcolor="primary.darker" data={{ label: 'Blue-9', color: '#003a8c' }} title="primary.darker" />


+ 1
- 1
src/pages/dashboard/GLD/index.js Просмотреть файл

@@ -45,7 +45,7 @@ const DashboardDefault = () => {
<Grid item xs={12}>
<div style={BackgroundHead}>
<Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center">
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0C489E" }}>
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0c489e" }}>
{getWelcomeMsg()}, {userData.fullenName}
</Typography>
</Stack>


+ 9
- 3
src/pages/dashboard/Public/Notice.js Просмотреть файл

@@ -32,9 +32,15 @@ const SearchDemandNoteForm = (props) => {
listData.map((item, index) => {
list.push(
<Stack key={item.id != null ? item.id : `announce-${index}`} direction="column">
<Typography variant='h4' align="justify"><b>{locale === 'en' ?item.subjectEng:locale === 'zh-HK' ?item.subjectCht:item.subjectChs}</b></Typography>
<Typography align="justify">{DateUtils.dateValue(item.announceDate)}</Typography>
<Typography sx={{pt: 1}} align="justify">{locale === 'en' ?item.contentEng:locale === 'zh-HK' ?item.contentCht:item.contentChs}</Typography>
<Typography component="h3" variant="h5" align="justify">
{locale === 'en' ? item.subjectEng : locale === 'zh-HK' ? item.subjectCht : item.subjectChs}
</Typography>
<Typography component="span" variant="subtitle2" sx={{ color: '#000' }} align="justify">
{DateUtils.dateValue(item.announceDate)}
</Typography>
<Typography component="span" variant="h6" sx={{ pt: 1, fontWeight: 400 }} align="justify">
{locale === 'en' ? item.contentEng : locale === 'zh-HK' ? item.contentCht : item.contentChs}
</Typography>
<Divider sx={{ pt: 1 }} />
</Stack>
)


+ 24
- 11
src/pages/dashboard/Public/index.js Просмотреть файл

@@ -100,22 +100,35 @@ const DashboardDefault = () => {
p: 2,
justifyContent: "flex-start",
textTransform: "none",
fontSize: "inherit",
fontWeight: "inherit",

// text always readable
color: "#1A1A1A",

// unread gets subtle highlight
backgroundColor: item.readTime ? "transparent" : "#F5F7FA",
fontWeight: item.readTime ? 400 : 600,

"&:hover": {
backgroundColor: "#EEF2F7",
},
}}
>
<Stack direction="column" >
<Typography variant='string' align="justify"><b>{item.subject}</b></Typography>
<Typography align="justify">{DateUtils.datetimeStr(item.sentDate)}</Typography>
<Stack direction="column">
<Typography
component="h3"
variant="h6"
align="justify"
sx={(theme) => ({
...theme.typography.h6,
fontWeight: item.readTime ? 400 : 600,
})}
>
{item.subject}
</Typography>
<Typography component="span" variant="subtitle2" sx={{ color: '#000' }} align="justify">
{DateUtils.datetimeStr(item.sentDate)}
</Typography>
</Stack>
</Button>
));
@@ -191,9 +204,9 @@ const DashboardDefault = () => {
p: 4,
justifyContent: "flex-start",
backgroundColor: "#e1edfc",
border: "0px solid #0C489E", // DARKER border (3:1+)
border: "0px solid #0c489e", // DARKER border (3:1+)
borderRadius: "10px",
color: "#0C489E", // icon + default text color
color: "#1565C0", // icon + default text color
"&:hover": {
backgroundColor: "#d6e6fb"
}
@@ -202,7 +215,7 @@ const DashboardDefault = () => {
<Stack direction="row" spacing={2}>
<AdsClickRoundedIcon />
<Stack direction="column" alignItems="flex-start">
<Typography component="h2" variant="h4" sx={{ color: "#0C489E" }}>
<Typography component="h2" variant="h4" sx={{ color: "#1565C0" }}>
<FormattedMessage id="submitApplication" />
</Typography>
<Typography sx={{ color: "#1A1A1A" }}>
@@ -220,7 +233,7 @@ const DashboardDefault = () => {
aria-label={intl.formatMessage({ id: 'viewAllAnnouncement' })}
onClick={() => { navigate("/announcement/search"); }}
sx={{
color: '#0C489E',
color: '#1565C0',
textTransform: 'none',
textDecoration: 'underline',
'&:hover': { textDecoration: 'underline' }
@@ -245,7 +258,7 @@ const DashboardDefault = () => {
aria-label={intl.formatMessage({ id: 'viewAllSystemMessage' })}
onClick={() => { navigate("/msg/search"); }}
sx={{
color: '#0C489E',
color: '#1565C0',
textTransform: 'none',
textDecoration: 'underline',
'&:hover': {
@@ -256,7 +269,7 @@ const DashboardDefault = () => {
<FormattedMessage id="viewAllSystemMessage" />
</u></Button>
</Stack>
<Box xs={12} md={12} sx={{ p: 1, fontSize: 12, border: '3px solid #eee', borderRadius: '10px' }} >
<Box xs={12} md={12} sx={{ p: 1, border: '3px solid #eee', borderRadius: '10px' }} >
<Message
itemList = {itemList}
/>
@@ -281,7 +294,7 @@ const DashboardDefault = () => {
<FormattedMessage id="systemNotice" />
</Typography>
</DialogTitle>
<DialogContent style={{ color: 'red', display: 'flex', }}>
<DialogContent style={{ color: '#B00020', display: 'flex', }}>
<Typography variant="h5" style={{ padding: '16px' }}>
<div dangerouslySetInnerHTML={{ __html: intl.formatMessage({ id: "suspensionMessageText" }) }} />
</Typography>


+ 1
- 1
src/pages/extra-pages/UserMenuPub1/index.js Просмотреть файл

@@ -23,7 +23,7 @@ const BackgroundHead = {
height: "auto",
backgroundSize: "contain",
backgroundRepeat: "no-repeat",
backgroundColor: "#0C489E",
backgroundColor: "#0c489e",
backgroundPosition: "right",
};



+ 1
- 1
src/pages/pnspsUserGroupDetailPage/index.js Просмотреть файл

@@ -226,7 +226,7 @@ const UserMaintainPage = () => {
<Grid item xs={12}>
<div style={BackgroundHead}>
<Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center">
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0C489E" }}>{isNewRecord ? "Create User Group" : "Maintain User Group"}</Typography>
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0c489e" }}>{isNewRecord ? "Create User Group" : "Maintain User Group"}</Typography>
</Stack>
</div>
</Grid>


+ 1
- 1
src/pages/pnspsUserGroupSearchPage/index.js Просмотреть файл

@@ -72,7 +72,7 @@ const UserGroupSearchPanel = () => {
<Grid item xs={12}>
<div style={BackgroundHead}>
<Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center">
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0C489E" }}>
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0c489e" }}>
View User Group
</Typography>
</Stack>


+ 14
- 0
src/routes/GLDUserRoutes.js Просмотреть файл

@@ -30,6 +30,8 @@ const EmailTemplateDetailPage = Loadable(lazy(() => import('pages/EmailTemplate/
const HolidayPage = Loadable(lazy(() => import('pages/Holiday')));
const GazetteIssuePage = Loadable(lazy(() => import('pages/GazetteIssue/index')));
const DrImport = Loadable(lazy(() => import('pages/Setting/DrImport')));
const HkidKeyMigration = Loadable(lazy(() => import('pages/Setting/HkidKeyMigration')));
const UserPiiEncryption = Loadable(lazy(() => import('pages/Setting/UserPiiEncryption')));
const AuditLogPage = Loadable(lazy(() => import('pages/AuditLog/index')));
const ReconReportPage = Loadable(lazy(() => import('pages/Recon')));
const ChangePasswordPage = Loadable(lazy(() => import('pages/User/ChangePasswordPage')));
@@ -190,6 +192,18 @@ const GLDUserRoutes = {
element: <DrImport />
}:{},

isGranted("MAINTAIN_SETTING")?
{
path: '/setting/hkidKeyMigration',
element: <HkidKeyMigration />
}:{},

isGranted("MAINTAIN_SETTING")?
{
path: '/setting/userPiiEncryption',
element: <UserPiiEncryption />
}:{},

isGranted("MAINTAIN_SETTING")?
{
path: '/setting/auditLog',


+ 48
- 7
src/themes/buttonConst.js Просмотреть файл

@@ -20,7 +20,7 @@ export const PNSPS_BUTTON_THEME = createTheme({

},
save:{
main: '#448DF2',
main: '#0c489e',
contrastText: '#FFFFFF',
},
export:{
@@ -44,7 +44,7 @@ export const PNSPS_BUTTON_THEME = createTheme({
contrastText: '#FFFFFF',
},
success:{
main: '#448DF2',
main: '#0c489e',
contrastText: '#FFFFFF',
},
green:{
@@ -69,6 +69,9 @@ export const PNSPS_BUTTON_THEME = createTheme({
},
},
MuiButton: {
defaultProps: {
disableRipple: true,
},
styleOverrides: {
/* -----------------------------
Icon alignment
@@ -93,17 +96,24 @@ export const PNSPS_BUTTON_THEME = createTheme({
'@media (min-width: 1280px)': { minWidth: '9vw' },
textTransform: 'none',
alignItems: 'normal',
'&:active': {
boxShadow: 'none',
transform: 'none',
},
},

/* -----------------------------
Remove default contained elevation / blue focus
------------------------------ */
contained: {
contained: ({ theme, ownerState }) => ({
boxShadow: 'none',
'&:hover': { boxShadow: 'none' },
'&:active': { boxShadow: 'none' },
'&.Mui-focusVisible': { boxShadow: 'none' },
'&:active': {
backgroundColor: theme.palette[ownerState.color]?.main ?? theme.palette.primary.main,
boxShadow: 'none',
},
'&.Mui-focusVisible': { boxShadow: 'none' },
}),

/* -----------------------------
RESET / CANCEL (contained + cancel)
@@ -123,7 +133,7 @@ export const PNSPS_BUTTON_THEME = createTheme({
},

'&:active': {
backgroundColor: '#4A4A4A',
backgroundColor: '#616161',
boxShadow: 'none !important',
},

@@ -145,10 +155,20 @@ export const PNSPS_BUTTON_THEME = createTheme({
backgroundColor: 'transparent',
},

'&:active': {
backgroundColor: 'transparent',
},

'&.Mui-focusVisible': {
boxShadow: '0 0 0 3px rgba(66,66,66,0.4)',
},
},

outlined: {
'&:active': {
backgroundColor: 'transparent',
},
},
},
},
}
@@ -174,7 +194,7 @@ export const PNSPS_LONG_BUTTON_THEME = createTheme({

},
save:{
main: '#448DF2',
main: '#0c489e',
contrastText: '#FFFFFF',
},
export:{
@@ -215,6 +235,9 @@ export const PNSPS_LONG_BUTTON_THEME = createTheme({
},
},
MuiButton: {
defaultProps: {
disableRipple: true,
},
styleOverrides: {
startIcon:{
display: 'flex',
@@ -240,6 +263,24 @@ export const PNSPS_LONG_BUTTON_THEME = createTheme({
},
textTransform: "none",
alignItems: 'normal',
'&:active': {
boxShadow: 'none',
transform: 'none',
},
},
contained: ({ theme, ownerState }) => ({
boxShadow: 'none',
'&:hover': { boxShadow: 'none' },
'&:active': {
backgroundColor: theme.palette[ownerState.color]?.main ?? theme.palette.primary.main,
boxShadow: 'none',
},
'&.Mui-focusVisible': { boxShadow: 'none' },
}),
outlined: {
'&:active': {
backgroundColor: 'transparent',
},
},
},
},


+ 48
- 3
src/themes/colorConst.js Просмотреть файл

@@ -28,7 +28,7 @@ export const piechartColor2 = [
];

export const cardBorderColor = [
'#efb142', '#4bb641', '#448df2', '#e03c04'
'#efb142', '#4bb641', '#0c489e', '#e03c04'
];

export const chartLineColor = [
@@ -37,9 +37,9 @@ export const chartLineColor = [

export const GENERAL_RED_COLOR = '#e03c04';

export const TABLE_HEADER_TEXT_COLOR = "#3367D1";
export const TABLE_HEADER_TEXT_COLOR = "#1565C0";

export const GENERAL_INFO_COLOR = '#448df2';
export const GENERAL_INFO_COLOR = '#0c489e';

export const GENERAL_SETTING_COLOR = '#666666';

@@ -49,6 +49,51 @@ export const GENERAL_BORDER_COLOR ='#e6ebf1';

export const GENERAL_TEXT_COLOR ='#262626';

/** Page header bar background (gazette banner strip). */
export const HEADER_BACKGROUND_COLOR = '#0C489E';

/** MUI default primary — used by applyPublicNotice contained button (PNSPS_LONG_BUTTON_THEME). WCAG AA: 3:1+ for UI components on white. */
export const CONTAINED_PRIMARY_BLUE = '#0c489e';

/** Validation error text/border — matches FormHelperText in styles.css (e.g. "Please enter password"). WCAG AA on white. */
export const VALIDATION_ERROR_COLOR = '#B00020';

export const PRIMARY_CONTAINED_BUTTON_SX = {
backgroundColor: CONTAINED_PRIMARY_BLUE,
color: '#FFFFFF',
'&:hover': {
backgroundColor: '#1565c0',
},
};

/** Dark green for Pay actions — matches PNSPS_BUTTON_THEME create color (#57B962), not light green (#4ac234). */
export const CONTAINED_DARK_GREEN = '#57B962';

export const PAY_CONTAINED_BUTTON_SX = {
backgroundColor: CONTAINED_DARK_GREEN,
color: '#FFFFFF',
'&:hover': {
backgroundColor: '#488F52',
},
};

export const PRIMARY_OUTLINED_BUTTON_SX = {
color: CONTAINED_PRIMARY_BLUE,
borderColor: CONTAINED_PRIMARY_BLUE,
'&:hover': {
borderColor: CONTAINED_PRIMARY_BLUE,
backgroundColor: 'rgba(25, 118, 210, 0.08)',
},
};

export const PRIMARY_TEXT_BUTTON_SX = {
color: CONTAINED_PRIMARY_BLUE,
fontWeight: 600,
'&:hover': {
backgroundColor: 'rgba(25, 118, 210, 0.08)',
},
};

export const formTheme = createTheme({
components: {
MuiFormLabel: {


+ 18
- 6
src/themes/overrides/Button.js Просмотреть файл

@@ -10,17 +10,29 @@ export default function Button(theme) {
return {
MuiButton: {
defaultProps: {
disableElevation: true
disableElevation: true,
disableRipple: true
},
styleOverrides: {
root: {
fontWeight: 400
},
contained: {
...disabledStyle
fontWeight: 400,
'&:active': {
boxShadow: 'none',
transform: 'none'
}
},
contained: ({ theme: muiTheme, ownerState }) => ({
...disabledStyle,
'&:active': {
backgroundColor: muiTheme.palette[ownerState.color]?.main ?? muiTheme.palette.primary.main,
boxShadow: 'none'
}
}),
outlined: {
...disabledStyle
...disabledStyle,
'&:active': {
backgroundColor: 'transparent'
}
}
}
}


+ 17
- 0
src/themes/overrides/Checkbox.js Просмотреть файл

@@ -1,14 +1,31 @@
// ==============================|| OVERRIDES - CHECKBOX ||============================== //

import { CONTAINED_PRIMARY_BLUE } from '../colorConst';

export default function Checkbox(theme) {
const checkboxSize = "2rem"

return {
MuiCheckbox: {
defaultProps: {
disableRipple: true
},
styleOverrides: {
root: {
color: theme.palette.secondary[300],
'&:hover': {
backgroundColor: 'transparent'
},
'&:active': {
backgroundColor: 'transparent'
},
'&.Mui-checked': {
color: CONTAINED_PRIMARY_BLUE
},
'&.Mui-focusVisible': {
boxShadow: '0 0 0 3px rgba(25, 118, 210, 0.35)'
},
svg: {
width: checkboxSize,
height: checkboxSize,


Некоторые файлы не были показаны из-за большого количества измененных файлов

Загрузка…
Отмена
Сохранить