Comparar commits

...

266 Commits

Autor SHA1 Mensaje Fecha
  Alex Cheung 93c3fc3d85 update header hace 1 día
  Alex Cheung d2eafa69b8 fix case 1-5 hace 2 días
  Alex Cheung f8fa390d85 Merge branch 'New_Enhancement' into CR013B1 hace 2 días
  Jason Chuang 62c3a6bbfd FPS enable web-to-app hace 1 semana
  Alex Cheung fd9a595178 remove user guide add bib hace 1 semana
  Alex Cheung a12cb4da7d update check page hace 3 semanas
  Alex Cheung b9f2959e44 update db check page /databaseHealthCheck hace 4 semanas
  Alex Cheung 59988b5b67 update recon download file btn hace 1 mes
  Alex Cheung d42078b8fe update download btn disable hace 1 mes
  Alex Cheung 6f7b42e36c add get jvm info hace 2 meses
  Alex Cheung eb89e8a0be update jvm page hace 2 meses
  Alex Cheung 065acd93f6 FIx FPS cancel hace 2 meses
  Alex Cheung fe87557cc9 fix public notes save search criteria hace 2 meses
  Jason Chuang 3b7de3788e fix audit log export hace 2 meses
  Alex Cheung 664d9d49a7 update SearchCriteria save hace 2 meses
  Alex Cheung 1d72ac64c2 update save page number for data gird hace 2 meses
  Alex Cheung c152df6ba9 update massage hace 2 meses
  Alex Cheung 5a7999bb90 update message hace 2 meses
  Alex Cheung 3cdf8d0c90 update org register remove '()' checking hace 2 meses
  Alex Cheung 3d2ecf8186 update org user faxNo and org faxNo and dashboard clear search hace 3 meses
  Alex Cheung b7374bbfb7 fix clear combo hace 3 meses
  Alex Cheung c8f1f6093a update gld view searching and gld user search page bug fix hace 3 meses
  Alex Cheung 5c11ea708d update application and bug fix hace 3 meses
  Alex Cheung 78a5d3917e update public search criteria save hace 3 meses
  Alex Cheung 8307b7a052 update proof searchCriteria save hace 3 meses
  Alex Cheung 32c3b256da update check page hace 3 semanas
  Jason Chuang d59bff36dd date hardcode hace 3 semanas
  Alex Cheung fbd0a00b8b update db check page /databaseHealthCheck hace 4 semanas
  Jason Chuang 63d1af9565 Merge branch 'CR013B1' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into CR013B1 hace 1 mes
  Jason Chuang a73453306b update hace 1 mes
  Alex Cheung cf09c0215d update proof payment method check hace 1 mes
  Alex Cheung 345d0970e4 add sample date hace 1 mes
  Alex Cheung d94a603775 update application payment with issueDate show hace 1 mes
  Alex Cheung 520de2f87c update recon download file btn hace 1 mes
  Alex Cheung 8a873414c6 update download btn disable hace 1 mes
  Alex Cheung 0347064423 add get jvm info hace 2 meses
  Alex Cheung 3fdf6311bb update jvm page hace 2 meses
  Alex Cheung 7777e520c4 FIx FPS cancel hace 2 meses
  Alex Cheung f5e671ca7f fix public notes save search criteria hace 2 meses
  Jason Chuang 985118ae10 fix audit log export hace 2 meses
  Alex Cheung ad333c8621 update SearchCriteria save hace 2 meses
  Alex Cheung ab6377db8c update save page number for data gird hace 2 meses
  Alex Cheung afb6d486f7 add checking for creditor btn hace 2 meses
  Alex Cheung afd6fe0242 update massage hace 2 meses
  Alex Cheung 3cf55a0191 update message hace 2 meses
  Alex Cheung 673229bbe5 update org register remove '()' checking hace 2 meses
  Alex Cheung 5f22c8c649 update keep only online payment after 2026-01-28 hace 2 meses
  Alex Cheung 3cc816b55c update org user faxNo and org faxNo and dashboard clear search hace 3 meses
  Alex Cheung f85eb71007 fix clear combo hace 3 meses
  Alex Cheung 923c8577f3 update gld view searching and gld user search page bug fix hace 3 meses
  Alex Cheung c2fe95a1a6 update application and bug fix hace 3 meses
  Alex Cheung 70e6943b4a update public search criteria save hace 3 meses
  Alex Cheung 868e84838d update proof searchCriteria save hace 3 meses
  Alex Cheung ef23ec8af9 layout fix hace 7 meses
  Alex Cheung 75f4c51fff update home page message and about us hace 7 meses
  Alex Cheung d849afb6fc update about us hace 7 meses
  Alex Cheung b436ffa1d0 update application reset btn hace 7 meses
  Alex Cheung fe84a6f046 add back FPS auto cancel hace 8 meses
  Alex Cheung 6a07b6cc71 add careOf and org combo hace 9 meses
  Jason Chuang 257526d37c emport phone no hace 9 meses
  Alex Cheung 18a990b716 Merge branch 'New_Enhancement' into CR003 hace 9 meses
  Alex Cheung ebcccfc705 update proof combo hace 9 meses
  Alex Cheung d66410f7ac fix table field for dummy user hace 9 meses
  Alex Cheung d748c23f51 update fps web to app for testing hace 9 meses
  Alex Cheung 68914b6406 updated contactPerson with empty string when user is dummy user hace 9 meses
  Alex Cheung 71541441a5 update fps expired hace 9 meses
  Alex Cheung a591027d29 update fps hace 9 meses
  Alex Cheung 324548afbf update gen gdn hace 9 meses
  Alex Cheung 50a22d0d69 handle dummy user client display hace 9 meses
  Alex Cheung 48a88815c1 add search combo for gld views hace 9 meses
  Alex Cheung ded2428881 combo update hace 10 meses
  Alex Cheung 6015900f57 update audit log auth hace 10 meses
  Alex Cheung 77efaee1da add application remark auth hace 10 meses
  Alex Cheung c16e0af999 update group hace 10 meses
  Alex Cheung 35daecbf33 add auth hace 10 meses
  Alex Cheung 874aeeb2cc fix grid loading hace 11 meses
  Alex Cheung 9d537b917c remove build hace 11 meses
  Alex Cheung 4952fcab16 search button update hace 11 meses
  Alex Cheung efa7c3933b fix datagrid error hace 11 meses
  Alex Cheung 9d4ecf4390 fix datagird without search button hace 11 meses
  Alex Cheung 20902d5305 fix disable button with error hace 11 meses
  Alex Cheung 5b5589566a update search button hace 11 meses
  Alex Cheung 9c5bd9ac95 fix double search api for data table hace 11 meses
  Alex Cheung 50ddd841b4 add loading to datagird hace 11 meses
  Alex Cheung 63738d8b6a add loading for iAmsmart loading data hace 11 meses
  Anna Ho 44325ecc10 CriOS as iOS_Chrome hace 11 meses
  Alex Cheung 3ef7e45af1 update FPS test hace 11 meses
  Jason Chuang 46aa7177fe Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement hace 11 meses
  Jason Chuang 6b9998fccc FPS hace 11 meses
  Alex Cheung 3b0753f753 update user guide hace 11 meses
  Jason Chuang 505554a408 update user guide label hace 1 año
  Jason Chuang 0e92a27d81 update label hace 1 año
  Jason Chuang 70b87c12db update user guide pub link hace 1 año
  Anna Ho 3adb028a51 add hace 1 año
  Jason Chuang 8b0caa2231 Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement hace 1 año
  Jason Chuang f971b01920 update about us hace 1 año
  Anna Ho ddad685252 cn use zh user guide file hace 1 año
  Anna Ho e91b67420c change path hace 1 año
  Anna Ho 6d4e1cd767 add header hace 1 año
  Jason Chuang 5548862d84 Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement hace 1 año
  Jason Chuang c98e2c0a83 fps and about us hace 1 año
  Anna Ho f9e43b23e7 user-guide-pub hace 1 año
  Alex Cheung 4d74c29810 date change hace 1 año
  Alex Cheung 53ac90879b fix pending payment deadline hace 1 año
  Alex Cheung c1c38cdb53 update wordings hace 1 año
  Alex Cheung dd3c15fe40 Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement hace 1 año
  Alex Cheung c74c956d76 disable console.log hace 1 año
  Anna Ho 561610a51d change folder name hace 1 año
  Alex Cheung b6d805afa5 Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement hace 1 año
  Alex Cheung 78e85c246f update uat title color change hace 1 año
  Anna Ho 47da9555d4 AboutUs, ImportantNotice, PrivacyPolicy hace 1 año
  Jason Chuang 6b81ba3544 enable FPS web to app hace 1 año
  Alex Cheung 33f312ce75 update fps disable check mobile hace 1 año
  Alex Cheung 40ef9d6fe3 update district hace 1 año
  Anna Ho 0460eae108 about us color hace 1 año
  Anna Ho cddce62251 About Us UI fix hace 1 año
  Anna Ho 1f07220334 about us hace 1 año
  Alex Cheung bd313899b5 update wordings and userprofile hace 1 año
  Alex Cheung 8091aaeb27 Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement hace 1 año
  Alex Cheung 1bdbd45897 update idNo check hace 1 año
  Jason Chuang 3dfc109d63 iam smart label update hace 1 año
  Alex Cheung b1e5a946c4 fix display detail hace 1 año
  Alex Cheung b284fd5ba2 wording update hace 1 año
  Anna Ho 524272274d update hace 1 año
  Alex Cheung c0b27730d8 fix date bug hace 1 año
  Alex Cheung 0b46126b8c add admin header display hace 1 año
  Alex Cheung 1ceebfdb87 update wordings hace 1 año
  Anna Ho 3761c1184e iamsmart and fix dn sendDate bug hace 1 año
  Anna Ho ceed5c5cec change header to "Deadline for online manuscript revision (Pay online via PNSPS)" hace 1 año
  Anna Ho bd9655c4d2 fix bug hace 1 año
  Anna Ho 6880ed72ba iAM Smart set brokerPage=true hace 1 año
  Alex Cheung 0ee39a7fde update ui layout hace 1 año
  Alex Cheung 96b7bc6ef5 update i18n hace 1 año
  Alex Cheung 4afb60358b update i18n hace 1 año
  Alex Cheung e8a24e7403 update comment from Matt hace 1 año
  Alex Cheung ed089e64d1 fix i18n bug hace 1 año
  Alex Cheung 724e79b2fe Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement hace 1 año
  Alex Cheung 505af12820 update i18n hace 1 año
  Anna Ho 783bf7ccc8 update UI hace 1 año
  Anna Ho 602c4b420b fix bug hace 1 año
  Anna Ho c0811a72df fix i18n hace 1 año
  Anna Ho b04f433b4d update i18n hace 1 año
  Anna Ho 0cee61df7d remove "pnspsdev.gld.gov.hk" hace 1 año
  Anna Ho 875458a76f update UI hace 1 año
  Anna Ho a322555297 update UI hace 1 año
  Anna Ho ffd3f166fa update i18n hace 1 año
  Anna Ho 26b3f9597b update string hace 1 año
  Jason Chuang f378e4f16d Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement hace 1 año
  Jason Chuang 858d9d727e update message hace 1 año
  Alex Cheung f02a69cb4d Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement hace 1 año
  Alex Cheung 6e97e779d8 update payment status hace 1 año
  Anna Ho 428abdc670 on iamsmart fail page hace 1 año
  Alex Cheung 0cb399846f update payment status display hace 1 año
  Alex Cheung 5219813c26 fix gns routes hace 1 año
  Jason Chuang 2de38844d0 update access right for GDN hace 1 año
  Anna Ho f952d2a7fc fix url hace 1 año
  Anna Ho c2dabf0d9f update i18n hace 1 año
  Anna Ho cd93eccdc8 update user guide ui hace 1 año
  Anna Ho 09eb8afdd3 add userGuide hace 1 año
  Anna Ho aa370d75ed add Important Notice hace 1 año
  Anna Ho 6c3aca90bf update check ID hace 1 año
  Alex Cheung 07a6f593b6 fix user profile hace 1 año
  Anna Ho c91f032a2d Login Routes re hace 1 año
  Alex Cheung ab3adaad33 Merge branch 'test_HKID' into New_Enhancement hace 1 año
  Alex Cheung f1af83023b fix cnid cannot save hace 1 año
  Anna Ho 1a632f2cad add SYS.ui.manage.allowRegistration hace 1 año
  Alex Cheung a640af8c79 update change password page add text hace 1 año
  Alex Cheung f8d82db96d update user HKid and checkdigi hace 1 año
  Alex Cheung 51e3209acc Merge branch 'New_Enhancement' into test_HKID hace 1 año
  Anna Ho dedcbf29bd move iAM Smart api path to properties hace 1 año
  Alex Cheung dda5735faf fix login with wrong username hace 1 año
  Alex Cheung cdbf342265 update index icon hace 1 año
  Jason Chuang a683d36674 update about us hace 1 año
  Anna Ho ef73acfeb3 fix create proof bug hace 1 año
  Anna Ho a3217e28c3 update forgot username hace 1 año
  Anna Ho 89dcb5cad8 update reply proof UI hace 1 año
  Jason Chuang 524be841e9 Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement hace 1 año
  Jason Chuang bfe26b8160 update label hace 1 año
  Alex Cheung 4506564ee0 update fps prod url hace 1 año
  Anna Ho 6d3f5550a4 add about us hace 1 año
  Alex Cheung fd8b5427bc update gdn hace 1 año
  Anna Ho 7a5d5e6ede address5 change update phone hace 1 año
  Anna Ho ea4d92337c check proof column should > 0 hace 1 año
  Anna Ho ca0dca8c10 update words hace 1 año
  Alex Cheung 09bd2f5098 Merge branch 'New_Enhancement' into SRAA_Test hace 1 año
  Alex Cheung 8ec89dec0f sraa update hace 1 año
  Jason Chuang fe5d91e148 update locale hace 1 año
  Anna Ho 4f95510418 word hace 1 año
  Anna Ho 3c4e51ca35 update word hace 1 año
  Alex Cheung a5d16b54a6 update Axios version for Vulnerable JS Library hace 1 año
  Anna Ho 415c86d1b9 update word hace 1 año
  Jason Chuang e70b0cbf05 Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement hace 1 año
  Jason Chuang 5982711ad6 update label hace 1 año
  Anna Ho b727c5cb8f privacyPolicy hace 1 año
  Jason Chuang 1fcfcbe8ec update label hace 1 año
  Anna Ho 1db138f63e user group fix bug hace 1 año
  Anna Ho f43c78838d fix i am smart bug hace 1 año
  Alex Cheung 36ebdfce6f update fps mobile btn hace 1 año
  Jason Chuang bcf88deadd Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement hace 1 año
  Jason Chuang fa974d4856 update label hace 1 año
  Terence 51dce719c3 update route case sensitive hace 1 año
  Anna Ho 4dd1b26a02 update iAM Smart button hace 1 año
  Alex Cheung bf113662ee Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement hace 1 año
  Alex Cheung 414e5da675 update check pasword special character and update org btn auth and application Id i18n hace 1 año
  Anna Ho 6bfed621e7 update iAM Smart button text hace 1 año
  Alex Cheung cd687d6cb9 update hidle payment table for credit user hace 1 año
  Anna Ho 63400671a7 GLD proof search statue hace 1 año
  Jason Chuang cb28ce731c Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement hace 1 año
  Jason Chuang b4eb579409 update label hace 1 año
  Anna Ho b700fff6e2 iAM Smart & status i18n hace 1 año
  Anna Ho bdf58c0b2d "iAM Smart" update Login Success UI hace 1 año
  Anna Ho f6fbec0c45 "iAM Smart" from update hace 1 año
  Anna Ho 13bf252cdb "iAM Smart" update hace 1 año
  Alex Cheung a88c79deb8 update emailConfirm handle hace 1 año
  Alex Cheung 066ba60193 update Amendment zip hace 1 año
  Anna Ho 53e51f84c3 update gen O/S dn List hace 1 año
  Anna Ho 7b8b15398d status hace 1 año
  Anna Ho 6d76833cd4 iAm Smart fix typo hace 1 año
  Jason Chuang d36afa6ee9 Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement hace 1 año
  Jason Chuang 2999987498 update i18n hace 1 año
  Alex Cheung a91c53694e update check not accept btn checking and ui update hace 1 año
  Anna Ho 3aa8d99095 Proof Records Starus hace 1 año
  Anna Ho af54518f20 update status i18n hace 1 año
  Alex Cheung f120ab9edb update dummy user edit apply public notice fax and phone number hace 1 año
  Anna Ho 8fdc98276d fix bug hace 1 año
  Anna Ho 0c0b97456f GET_SEND_OVERDUE_CREDITOR_LIST hace 1 año
  Alex Cheung 99a229cf0c update setting hace 1 año
  Jason Chuang 646421d897 update label hace 1 año
  Jason Chuang a7b5878ecf update label hace 1 año
  Alex Cheung ad18ada2dc Merge branch 'master' into New_Enhancement hace 1 año
  Jason Chuang 1eed4d7f3d Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement hace 1 año
  Jason Chuang 55f53d384c update label hace 1 año
  Alex Cheung b8b843aae2 fix preferLocale and add orgPaymentRecord for org check online payment record hace 1 año
  Jason Chuang 922abf73ac Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement hace 1 año
  Jason Chuang 9234d74a74 label and layout update hace 1 año
  Alex Cheung 95e1b8c921 update hace 1 año
  Alex Cheung 13ec88f514 update fps second hace 1 año
  Alex Cheung e5614037b8 fix autoFocus hace 1 año
  Alex Cheung 51462e8283 fix eng name and cht name hace 1 año
  Alex Cheung 6ae8ba07a6 hidle error message without edit mode hace 1 año
  Alex Cheung 9e55135d38 update check captcha hace 1 año
  Alex Cheung 016ea6235d update check captcha hace 1 año
  Alex Cheung 39b150a58c update layout hace 1 año
  Alex Cheung e3cdffa2f5 update proof and payment page text hace 1 año
  Alex Cheung d7ae3c0ee1 update check name hace 1 año
  Anna Ho 4dca798a3a disable 15:00 Scheduled, add send mail Button hace 1 año
  Anna Ho 81639691e5 fix bug - reload after mark "published" hace 1 año
  Anna Ho ff0cbe1c05 Merge branch 'master' into New_Enhancement hace 1 año
  Anna Ho f13b166d63 Merge branch 'master' into New_Enhancement hace 1 año
  Alex Cheung cbc8eb2c90 update dashboard loading hace 1 año
  Alex Cheung 37a6b1f9e9 update hace 1 año
  Alex Cheung e9f2fdb852 update hace 1 año
  Alex Cheung b2a727ca61 add change password page hace 1 año
  Alex Cheung 55f9a1d78f Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement hace 1 año
  Alex Cheung bd40598a1d update password log hace 1 año
  Anna Ho da6bcd39fb fix bug hace 1 año
  Anna Ho 7af45e4e8d Merge branch 'master' into New_Enhancement hace 1 año
  Anna Ho c2e1d3a305 dn revoke paid hace 1 año
  Alex Cheung 630344cfc4 Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement hace 1 año
  Alex Cheung a78cdad254 add password remark hace 1 año
  Anna Ho 131b31f850 email and paid button at application hace 1 año
  Alex Cheung cb04b13088 Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement hace 1 año
  Alex Cheung b61dc7d04a update captcha hace 1 año
  Anna Ho a0d8c5f0db Merge branch 'master' into New_Enhancement hace 1 año
  Alex Cheung b7a919f44e Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement hace 1 año
  Alex Cheung ec5aa563e4 update gldRemarks for gld user hace 1 año
Se han modificado 100 ficheros con 4095 adiciones y 2839 borrados
Dividir vista
  1. +15
    -0
      .vscode/launch.json
  2. +1371
    -1569
      package-lock.json
  3. +1
    -1
      package.json
  4. BIN
      public/apple-touch-icon.png
  5. BIN
      public/favicon-16x16.png
  6. BIN
      public/favicon-32x32.png
  7. +9
    -38
      public/index.html
  8. +54
    -0
      public/safari-pinned-tab.svg
  9. BIN
      src/assets/images/icons/expiredQrcodeCN.png
  10. BIN
      src/assets/images/icons/expiredQrcodeEN.png
  11. BIN
      src/assets/images/icons/expiredQrcodeZH.png
  12. +2
    -0
      src/auth/index.js
  13. +33
    -20
      src/auth/utils.js
  14. +4
    -1
      src/components/AdminLogo/index.js
  15. +5
    -1
      src/components/AutoLogoutProvider.js
  16. +85
    -22
      src/components/FiDataGrid.js
  17. +10
    -0
      src/components/FileList.js
  18. +35
    -0
      src/components/SysSettingProvider.js
  19. +2
    -3
      src/components/cards/AuthFooter.js
  20. +8
    -4
      src/index.js
  21. +458
    -293
      src/layout/MainLayout/Header/index.js
  22. +23
    -13
      src/layout/MainLayout/index.js
  23. +9
    -3
      src/pages/Announcement/Search/DataGrid.js
  24. +5
    -2
      src/pages/Announcement/Search/SearchForm.js
  25. +26
    -5
      src/pages/Announcement/Search/index.js
  26. +10
    -4
      src/pages/Announcement/Search_Public/DataGrid.js
  27. +22
    -3
      src/pages/Announcement/Search_Public/SearchForm.js
  28. +26
    -5
      src/pages/Announcement/Search_Public/index.js
  29. +12
    -9
      src/pages/AuditLog/AuditLogSearchForm.js
  30. +10
    -4
      src/pages/AuditLog/AuditLogTable.js
  31. +10
    -1
      src/pages/AuditLog/index.js
  32. +1
    -1
      src/pages/DemandNote/Details/ApplicationDetailCard.js
  33. +15
    -9
      src/pages/DemandNote/Export/DataGrid.js
  34. +86
    -15
      src/pages/DemandNote/Search/DataGrid.js
  35. +48
    -6
      src/pages/DemandNote/Search/SearchForm.js
  36. +21
    -4
      src/pages/DemandNote/Search/index.js
  37. +14
    -6
      src/pages/DemandNote/Search_Public/DataGrid.js
  38. +23
    -3
      src/pages/DemandNote/Search_Public/SearchForm.js
  39. +22
    -5
      src/pages/DemandNote/Search_Public/index.js
  40. +3
    -3
      src/pages/EmailTemplate/Detail_GLD/index.js
  41. +8
    -4
      src/pages/EmailTemplate/Search_GLD/DataGrid.js
  42. +2
    -1
      src/pages/GFMIS/DataGrid.js
  43. +2
    -1
      src/pages/GFMIS/SearchForm.js
  44. +14
    -5
      src/pages/GFMIS/index.js
  45. +8
    -3
      src/pages/GazetteIssue/DataGrid.js
  46. +2
    -2
      src/pages/GazetteIssue/ExportForm.js
  47. +2
    -1
      src/pages/GazetteIssue/SearchForm.js
  48. +41
    -29
      src/pages/GazetteIssue/index.js
  49. +7
    -2
      src/pages/Holiday/DataGrid.js
  50. +2
    -1
      src/pages/Holiday/SearchForm.js
  51. +35
    -24
      src/pages/Holiday/index.js
  52. +121
    -0
      src/pages/JVM/index.js
  53. +38
    -22
      src/pages/Message/Search/DataGrid.js
  54. +5
    -2
      src/pages/Message/Search/SearchForm.js
  55. +46
    -24
      src/pages/Message/Search/index.js
  56. +142
    -85
      src/pages/Organization/DetailPage/OrganizationCard.js
  57. +51
    -55
      src/pages/Organization/DetailPage/OrganizationPubCard.js
  58. +14
    -12
      src/pages/Organization/DetailPage_FromUser/OrganizationCard_loadFromUser.js
  59. +30
    -4
      src/pages/Organization/SearchPage/OrganizationSearchForm.js
  60. +10
    -4
      src/pages/Organization/SearchPage/OrganizationTable.js
  61. +24
    -2
      src/pages/Organization/SearchPage/index.js
  62. +1
    -1
      src/pages/Payment/Details_GLD/DataGrid.js
  63. +10
    -10
      src/pages/Payment/Details_GLD/PaymentDetails.js
  64. +1
    -1
      src/pages/Payment/Details_GLD/index.js
  65. +1
    -1
      src/pages/Payment/Details_Public/DataGrid.js
  66. +43
    -20
      src/pages/Payment/Details_Public/PaymentDetails.js
  67. +6
    -6
      src/pages/Payment/Details_Public/index.js
  68. +38
    -26
      src/pages/Payment/FPS/AckPage.js
  69. +129
    -68
      src/pages/Payment/FPS/FPS.js
  70. +1
    -1
      src/pages/Payment/FPS/FPSTest.js
  71. +50
    -40
      src/pages/Payment/FPS/fpscallback.js
  72. +7
    -7
      src/pages/Payment/MultiPaymentWindow.js
  73. +24
    -14
      src/pages/Payment/PaymentCallback.js
  74. +11
    -5
      src/pages/Payment/Search_GLD/DataGrid.js
  75. +18
    -2
      src/pages/Payment/Search_GLD/SearchForm.js
  76. +26
    -6
      src/pages/Payment/Search_GLD/index.js
  77. +10
    -4
      src/pages/Payment/Search_Public/DataGrid.js
  78. +9
    -3
      src/pages/Payment/Search_Public/SearchForm.js
  79. +28
    -3
      src/pages/Payment/Search_Public/index.js
  80. +3
    -1
      src/pages/Payment/index.js
  81. +53
    -22
      src/pages/Proof/Create_FromApp/ApplicationDetails.js
  82. +16
    -1
      src/pages/Proof/Create_FromApp/ProofForm.js
  83. +4
    -4
      src/pages/Proof/Create_FromApp/UploadFileTable.js
  84. +1
    -1
      src/pages/Proof/Payment/Pay.js
  85. +1
    -0
      src/pages/Proof/Payment/Pay_Creditor.js
  86. +5
    -4
      src/pages/Proof/Payment/Pay_DN.js
  87. +4
    -3
      src/pages/Proof/Payment/Pay_Office.js
  88. +9
    -6
      src/pages/Proof/Payment/Pay_Online.js
  89. +60
    -25
      src/pages/Proof/Reply_GLD/ApplicationDetails.js
  90. +1
    -1
      src/pages/Proof/Reply_GLD/ProofForm.js
  91. +4
    -4
      src/pages/Proof/Reply_GLD/UploadFileTable.js
  92. +57
    -12
      src/pages/Proof/Reply_Public/ApplicationDetails.js
  93. +187
    -142
      src/pages/Proof/Reply_Public/ProofForm.js
  94. +4
    -4
      src/pages/Proof/Reply_Public/UploadFileTable.js
  95. +14
    -5
      src/pages/Proof/Search_GLD/DataGrid.js
  96. +71
    -12
      src/pages/Proof/Search_GLD/SearchForm.js
  97. +22
    -5
      src/pages/Proof/Search_GLD/index.js
  98. +32
    -21
      src/pages/Proof/Search_Public/DataGrid.js
  99. +32
    -8
      src/pages/Proof/Search_Public/SearchForm.js
  100. +20
    -4
      src/pages/Proof/Search_Public/index.js

+ 15
- 0
.vscode/launch.json Ver fichero

@@ -0,0 +1,15 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "chrome",
"request": "launch",
"name": "Launch Chrome against localhost",
"url": "http://localhost:3000",
"webRoot": "${workspaceFolder}/src"
}
]
}

+ 1371
- 1569
package-lock.json
La diferencia del archivo ha sido suprimido porque es demasiado grande
Ver fichero


+ 1
- 1
package.json Ver fichero

@@ -22,7 +22,7 @@
"@testing-library/user-event": "^14.4.3",
"@types/react-input-mask": "^3.0.2",
"apexcharts": "^3.35.5",
"axios": "^1.4.0",
"axios": "^1.7.1",
"date-fns": "^3.0.6",
"dayjs": "^1.11.9",
"formik": "^2.2.9",


BIN
public/apple-touch-icon.png Ver fichero

Antes Después
Anchura: 180  |  Altura: 180  |  Tamaño: 6.4 KiB

BIN
public/favicon-16x16.png Ver fichero

Antes Después
Anchura: 16  |  Altura: 16  |  Tamaño: 1.1 KiB

BIN
public/favicon-32x32.png Ver fichero

Antes Después
Anchura: 32  |  Altura: 32  |  Tamaño: 1.7 KiB

+ 9
- 38
public/index.html Ver fichero

@@ -2,52 +2,23 @@
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.svg" />
<link rel="icon" type="image/png" sizes="32x32" href="%PUBLIC_URL%/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="%PUBLIC_URL%/favicon-16x16.png">
<link rel="mask-icon" href="%PUBLIC_URL%/safari-pinned-tab.svg" color="#5bbad5">
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#1f1f1f" />
<meta name="theme-color" content="#ffffff" />
<meta name="msapplication-TileColor" content="#da532c">
<meta name="title" content="PNSPS" />
<meta
name="description"
content="Mantis is a free, super flexible and customizable react redux dashboard template built using MUI React components with open source MIT license."
content="The Government of the Hong Kong Special Administrative Region Gazette Public Notice Submission and Payment System."
/>
<meta
name="keywords"
content="react dashboard, react admin, react redux dashboard, ant design template, saas admin, free react dashboard"
content="PNSPS, GLD, react redux dashboard, Gazette, Public Notice"
/>
<meta name="author" content="CodedThemes" />
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!-- Open Graph / Facebook -->
<meta property="og:locale" content="en_US" />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://mantisdashboard.io/" />
<meta property="og:site_name" content="mantisdashboard.io" />
<meta property="article:publisher" content="https://www.facebook.com/codedthemes" />
<meta property="og:title" content="PNSPS" />
<meta
property="og:description"
content="Mantis is a free, super flexible and customizable react redux dashboard template built using MUI React components with open source MIT license."
/>
<meta property="og:image" content="https://mantisdashboard.io/adv-banner-images/og-social.png" />
<!-- Twitter -->
<meta property="twitter:card" content="summary_large_image" />
<meta property="twitter:url" content="https://mantisdashboard.io" />
<meta property="twitter:title" content="PNSPS" />
<meta
property="twitter:description"
content="Mantis is a free, super flexible and customizable react redux dashboard template built using MUI React components with open source MIT license."
/>
<meta property="twitter:image" content="https://mantisdashboard.io/adv-banner-images/og-social.png" />
<meta name="twitter:creator" content="@codedthemes" />

<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.

Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<meta name="author" content="Government Logistics Department" />
<link rel="apple-touch-icon" href="%PUBLIC_URL%/apple-touch-icon.png" />
<title>PNSPS</title>
<link rel="preconnect" href="https://fonts.gstatic.com" />
<link


+ 54
- 0
public/safari-pinned-tab.svg Ver fichero

@@ -0,0 +1,54 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="680.000000pt" height="680.000000pt" viewBox="0 0 680.000000 680.000000"
preserveAspectRatio="xMidYMid meet">
<metadata>
Created by potrace 1.14, written by Peter Selinger 2001-2017
</metadata>
<g transform="translate(0.000000,680.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M2270 4555 l0 -1345 912 2 913 3 0 340 0 340 -195 2 c-107 1 -322 2
-476 3 l-282 0 -1 928 c0 510 -1 960 -1 1000 l0 72 -435 0 -435 0 0 -1345z"/>
<path d="M4627 5044 c-1 -1 -45 -5 -97 -8 -85 -5 -126 -9 -210 -20 -56 -8
-159 -28 -215 -43 -33 -8 -68 -17 -78 -19 -47 -9 -204 -72 -307 -124 -170 -85
-180 -91 -181 -120 0 -14 -1 -151 -2 -306 l-2 -280 280 0 280 1 0 112 0 112
49 22 c86 37 195 69 286 84 19 3 46 7 60 10 21 4 175 17 205 17 24 1 212 -13
235 -16 14 -2 43 -7 65 -10 48 -7 203 -48 264 -71 76 -28 203 -95 291 -153 99
-66 288 -250 345 -337 22 -33 43 -62 46 -65 9 -7 98 -173 100 -185 0 -5 9 -26
19 -45 44 -86 102 -303 117 -435 13 -114 5 -428 -12 -454 -2 -4 -6 -26 -9 -49
-9 -79 -78 -288 -132 -401 -113 -237 -256 -417 -449 -561 -64 -47 -103 -70
-255 -144 -14 -7 -45 -18 -70 -25 -25 -8 -52 -15 -60 -18 -8 -2 -16 -4 -17 -4
-2 0 -16 -4 -33 -9 -87 -25 -340 -34 -472 -17 -32 4 -84 10 -115 13 -63 6
-116 13 -148 19 -11 2 -41 6 -67 10 l-47 8 -1 -260 c0 -200 2 -262 12 -270 7
-6 36 -16 63 -22 28 -7 57 -14 65 -17 186 -45 213 -49 420 -48 221 0 307 11
517 64 100 25 340 113 353 129 3 3 31 19 63 35 32 16 97 55 145 87 300 198
551 508 697 859 35 86 102 291 110 336 3 20 7 39 9 43 2 3 7 22 10 41 10 60
16 94 20 115 28 130 28 570 1 700 -3 11 -7 36 -10 55 -19 133 -79 336 -137
470 -79 181 -210 395 -312 508 -185 207 -395 366 -631 478 -103 49 -316 126
-381 138 -16 2 -40 7 -54 11 -24 5 -89 18 -155 30 -46 8 -155 19 -197 19 -21
1 -38 3 -38 6 0 4 -229 8 -233 4z"/>
<path d="M1958 5035 c-2 -1 -30 -5 -63 -8 -114 -11 -231 -31 -320 -54 -33 -8
-67 -17 -75 -18 -8 -2 -15 -4 -15 -5 0 -2 -14 -5 -53 -14 -12 -3 -27 -8 -32
-11 -5 -3 -18 -8 -27 -10 -122 -25 -529 -238 -603 -315 -3 -3 -30 -25 -60 -50
-184 -148 -367 -375 -487 -605 -77 -148 -171 -436 -188 -575 -4 -30 -9 -58
-11 -61 -17 -29 -26 -431 -11 -564 9 -86 20 -157 31 -205 3 -14 8 -36 11 -50
8 -44 42 -167 49 -179 4 -6 9 -21 11 -33 15 -78 144 -348 212 -445 13 -17 23
-36 23 -41 0 -5 9 -17 20 -27 11 -10 20 -22 20 -26 0 -10 0 -10 96 -124 178
-213 410 -391 664 -512 181 -86 425 -159 595 -179 22 -2 54 -7 70 -10 17 -3
109 -7 205 -9 200 -5 254 3 420 56 3 1 19 6 35 12 17 6 30 10 30 8 0 -1 45 21
100 49 185 96 342 213 510 384 104 105 185 194 185 202 0 3 9 15 21 27 31 33
126 159 179 237 8 12 20 29 27 38 8 13 11 -62 10 -317 -1 -210 2 -339 8 -347
8 -10 285 -111 355 -129 17 -5 97 -33 120 -42 23 -9 33 -12 55 -15 20 -3 20 5
20 947 l0 950 -910 0 -910 -1 -3 -277 -2 -277 287 -1 c159 0 372 -1 475 -2
204 -1 198 1 146 -58 -13 -15 -36 -44 -53 -65 -133 -169 -383 -441 -491 -534
-282 -242 -401 -288 -684 -266 -78 6 -97 8 -167 20 -24 4 -44 7 -45 6 -2 -1
-16 3 -31 9 -15 6 -42 13 -60 16 -76 13 -364 140 -397 175 -3 3 -30 23 -60 45
-30 22 -60 44 -66 50 -82 75 -126 120 -159 161 -21 27 -42 51 -45 54 -3 3 -27
38 -53 78 -79 118 -176 337 -201 452 -8 35 -25 120 -31 150 -26 135 -26 428 0
550 3 14 8 36 10 50 24 152 133 412 226 544 16 22 37 52 47 65 45 65 157 182
237 250 167 141 481 282 685 307 19 2 46 7 59 10 14 3 57 7 95 10 39 3 76 6
81 8 6 2 10 102 10 272 l-1 269 -62 1 c-34 1 -63 0 -64 -1z"/>
</g>
</svg>

BIN
src/assets/images/icons/expiredQrcodeCN.png Ver fichero

Antes Después
Anchura: 300  |  Altura: 300  |  Tamaño: 6.8 KiB

BIN
src/assets/images/icons/expiredQrcodeEN.png Ver fichero

Antes Después
Anchura: 300  |  Altura: 300  |  Tamaño: 8.8 KiB

BIN
src/assets/images/icons/expiredQrcodeZH.png Ver fichero

Antes Después
Anchura: 300  |  Altura: 300  |  Tamaño: 6.9 KiB

+ 2
- 0
src/auth/index.js Ver fichero

@@ -32,6 +32,7 @@ export const handleLogin = data => {
localStorage.setItem('accessToken', data.accessToken)
localStorage.setItem('refreshToken', data.refreshToken)
localStorage.setItem('axiosToken', "Bearer " + data.accessToken)
localStorage.setItem('searchCriteria',"")
//localStorage.setItem(config.storageUserRoleKeyName, JSON.stringify(data.role).slice(1).slice(0, -1))
localStorage.setItem(refreshIntervalName, "60")
// for demo only
@@ -91,6 +92,7 @@ export const handleLogoutFunction = () => {
localStorage.removeItem('refreshToken')
localStorage.removeItem('webtoken')
localStorage.removeItem('transactionid')
localStorage.removeItem('searchCriteria')
//localStorage.removeItem(config.storageUserRoleKeyName)
localStorage.removeItem('expiredAlertShown')
localStorage.removeItem(refreshIntervalName)


+ 33
- 20
src/auth/utils.js Ver fichero

@@ -14,25 +14,10 @@ export const paymentPath = window.location.href.match("localhost:3000") ? `${hos

export const delBugMode = true;

/**
* Testing:
* Domain: apigw-isit.staging-eid.gov.hk
* URL: hk.gov.iamsmart.testapp://
*
* Production
* Domain: apigw.iamsmart.gov.hk
* URL: hk.gov.iamsmart://
*/
export const iAmSmartPath = `https://apigw-isit.staging-eid.gov.hk`;
export const iAmSmartAppPath = `hk.gov.iamsmart.testapp://`;
export const clientId = "cf61fa7c121e4869966f69c8694b1cd2";

export const iAmSmartCallbackPath = () => {
let hostname = window.location.hostname;
if (hostname.match("pnspsuat")) {
hostname = "pnspsuat.gld.gov.hk";
} else {
hostname = "pnspsdev.gld.gov.hk";
}
return hostname;
};
@@ -57,7 +42,10 @@ export const getBowserType = () => {
if (navigator.userAgent.match(/Android/i)) return "Android_Chrome"
if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) return "iOS_Chrome"
return "PC_Browser"
} else if (navigator.userAgent.indexOf("Safari") != -1) {
} else if (navigator.userAgent.indexOf('CriOS') != -1) {
if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) return "iOS_Chrome"
return "PC_Browser"
} else if (navigator.userAgent.indexOf("Safari") != -1 && navigator.userAgent.indexOf("Chrome") == -1) {
if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) return "iOS_Safari"
return "PC_Browser"
} else if (navigator.userAgent.indexOf("Firefox") != -1) {
@@ -89,7 +77,7 @@ export const isGranted = (auth) => {
const abilities = getUserData() ? getUserData()["abilities"] : null;
if (abilities == null || abilities.length == 0) return false;
if (!Array.isArray(auth)) return _checkAuth(abilities, auth);
if (auth.length > abilities.length) return false;
let haveAuth = true;
for (let i = 0; i < auth.length; i++) {
@@ -138,8 +126,33 @@ export const local = { en: "en-us", zh: "zh-hk", cn: "zh-cn" };
export const preferpaymentmethods = ['visa', 'mastercard', 'pps', 'creditcard', 'fps'];

export const getPaymentMethod = (paymentMethod) => {
if(paymentMethod == "online") return 'payOnlineMethod';
if(paymentMethod == "demandNote") return 'payDnMethod';
if(paymentMethod == "office") return 'payNPGOMethod';
if (paymentMethod == "online") return 'payOnlineMethod';
if (paymentMethod == "demandNote") return 'payDnMethod';
if (paymentMethod == "office") return 'payNPGOMethod';
return "other";
}

export const getSearchCriteria = (path) =>{
let searchCriteria = ""
if (localStorage.getItem('searchCriteria')==""){
return searchCriteria
} else if (Object.keys(localStorage.getItem('searchCriteria')).length>0){
searchCriteria = JSON.parse(localStorage.getItem("searchCriteria"))
if (searchCriteria.path === path){
return searchCriteria.data
} else {
return ""
}
}
}

export const checkSearchCriteriaPath = (path) =>{
if(!path.startsWith("/application")
|| path === "/application/search"){
if(!path.startsWith("/user/")){
if(!path.startsWith("/publicNotice/")|| path === "/publicNotice"){
return true
}
}
}
}

+ 4
- 1
src/components/AdminLogo/index.js Ver fichero

@@ -11,6 +11,9 @@ import Logo from './AdminLogo';
import config from 'config';
import { activeItem } from 'store/reducers/menu';
import { Stack } from '@mui/material';
import {
checkSysEnv
} from "utils/Utils";

// ==============================|| MAIN LOGO ||============================== //

@@ -28,7 +31,7 @@ const LogoSection = ({ sx, to }) => {
>
<Logo />
</ButtonBase>
<span id="systemTitle" >PNSPS</span>
<span style={{ color: checkSysEnv()!=''?'red':'#0C489E'}} id="systemTitle">PNSPS</span>
</Stack>

);


+ 5
- 1
src/components/AutoLogoutProvider.js Ver fichero

@@ -5,7 +5,8 @@ import { handleLogoutFunction } from 'auth/index';
import { useDispatch } from "react-redux";
import {
isUserLoggedIn,
isGLDLoggedIn,
isGLDLoggedIn,
isPasswordExpiry
} from "utils/Utils";

const TimerContext = createContext();
@@ -81,6 +82,9 @@ const AutoLogoutProvider = ({ children }) => {
// console.log(logoutInterval)
const interval = setInterval(async () => {
const currentTime = Date.now();
if (isPasswordExpiry()){
navigate('/user/changePassword');
}
// getRemainingTime();
if(state !== "Active" && lastActiveTab){
const timeElapsed = currentTime - lastRequestTime;


+ 85
- 22
src/components/FiDataGrid.js Ver fichero

@@ -1,17 +1,18 @@
// material-ui
import {useState, useEffect} from 'react';
import { useState, useEffect } from 'react';
import {
DataGrid, GridOverlay,
} from "@mui/x-data-grid";
import * as HttpUtils from "utils/HttpUtils";
import {FormattedMessage, useIntl} from "react-intl";
import {TablePagination, Typography} from '@mui/material';
import { FormattedMessage, useIntl } from "react-intl";
import { TablePagination, Typography } from '@mui/material';
import { getSearchCriteria, checkSearchCriteriaPath } from "auth/utils";

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

export function FiDataGrid({ rows, columns, sx, autoHeight,
hideFooterSelectedRowCount, rowModesModel, editMode,
pageSizeOptions, filterItems, customPageSize, doLoad, ...props }) {
hideFooterSelectedRowCount, rowModesModel, editMode,
pageSizeOptions, filterItems, customPageSize, doLoad, applyGridOnReady, applySearch, tab, ...props }) {
const intl = useIntl();
const [_rows, set_rows] = useState([]);
const [_doLoad, set_doLoad] = useState({});
@@ -20,6 +21,7 @@ export function FiDataGrid({ rows, columns, sx, autoHeight,
const [_editMode, set_editMode] = useState("row");
const [_pageSizeOptions, set_pageSizeOptions] = useState([10]);
const [_filterItems, set_filterItems] = useState([]);
const [loading, setLoading] = useState(false);

const [page, setPage] = useState(0);
const [pageSize, setPageSize] = useState(10);
@@ -27,6 +29,7 @@ export function FiDataGrid({ rows, columns, sx, autoHeight,
const [myHideFooterSelectedRowCount, setMyHideFooterSelectedRowCount] = useState(true);
const [_sx, set_sx] = useState({
padding: "4 2 4 2",
lineHeight: "normal",
'& .MuiDataGrid-cell': {
borderTop: 1,
borderBottom: 1,
@@ -36,18 +39,38 @@ export function FiDataGrid({ rows, columns, sx, autoHeight,
border: 1,
borderColor: "#EEE"
},
"& .MuiDataGrid-columnHeaderTitle": {
whiteSpace: "normal",
lineHeight: "normal"
},
"& .MuiDataGrid-columnHeader": {
// Forced to use important since overriding inline styles
height: "unset !important"
},
});

const [rowCount, setRowCount] = useState(0);
useEffect(() => {
setPage(0);
set_doLoad(doLoad);

useEffect(() => {
if (doLoad !== undefined && Object.keys(doLoad).length>0 ){
if(applySearch!=undefined){
if (Object.keys(getSearchCriteria(window.location.pathname)).length>0){
const localStorageSearchCriteria = getSearchCriteria(window.location.pathname)
if(localStorageSearchCriteria.start!=undefined){
setPage(localStorageSearchCriteria.start/pageSize);
}
}
}else{
setPage(0);
}
set_doLoad(doLoad);
setLoading(true)
}
}, [doLoad]);

useEffect(()=>{
useEffect(() => {
getDataList();
},[_doLoad, page]);
}, [_doLoad, page]);


useEffect(() => {
@@ -70,18 +93,25 @@ export function FiDataGrid({ rows, columns, sx, autoHeight,
if (pageSizeOptions) {
set_pageSizeOptions(pageSizeOptions)
}
if(autoHeight !== undefined){
if (autoHeight !== undefined) {
set_autoHeight(autoHeight)
}
if(editMode){
if (editMode) {
set_editMode(editMode);
}
if(filterItems){
if (filterItems) {
set_filterItems(filterItems);
}
if(customPageSize){
if (customPageSize) {
setPageSize(customPageSize);
}
// console.log(_doLoad)
if (_doLoad !== undefined && Object.keys(_doLoad).length==0 ){
setLoading(false)
if (applyGridOnReady !== undefined){
applyGridOnReady(false)
}
}
}, [sx, hideFooterSelectedRowCount, rowModesModel, rows, columns, pageSizeOptions, autoHeight, editMode, filterItems, customPageSize]);

const handleChangePage = (event, newPage) => {
@@ -103,21 +133,51 @@ export function FiDataGrid({ rows, columns, sx, autoHeight,
);
}

function getDataList() {
if(_doLoad?.url == null) return;
if(_doLoad.params == null) _doLoad.params = {};
_doLoad.params.start = page*pageSize;
// console.log(Object.keys(_doLoad.params).length > 0)
// console.log(Object.keys(_doLoad.params).length > 0)

if (_doLoad?.url == null){
setLoading(false)
return;
}
if (_doLoad.params == undefined) return;
if (_doLoad.params.searchCriteria !== undefined) return;
if (_doLoad.params == null) _doLoad.params = {};
_doLoad.params.start = page * pageSize;
_doLoad.params.limit = pageSize;
if(checkSearchCriteriaPath(window.location.pathname)){
if(window.location.pathname === "/publicNotice"){
if (tab != undefined && tab ==="application"){
localStorage.setItem('searchCriteria', JSON.stringify({path:window.location.pathname,data:_doLoad.params}))
}
}else if (window.location.pathname != "/publicNotice"){
localStorage.setItem('searchCriteria', JSON.stringify({path:window.location.pathname,data:_doLoad.params}))
}
}
HttpUtils.get({
url: _doLoad.url,
params: _doLoad.params,
onSuccess: function (responseData) {
set_rows(responseData?.records);
setRowCount(responseData?.count);
if(_doLoad.callback != null){
if (_doLoad.callback != null) {
_doLoad.callback(responseData);
}
setLoading(false)
// console.log(applyGridOnReady)
if (applyGridOnReady !== undefined){
applyGridOnReady(false)
}
},
onError: function (error){
console.log(error)
setLoading(false)
if (applyGridOnReady !== undefined){
applyGridOnReady(false)
}
}
});
}
@@ -127,9 +187,11 @@ export function FiDataGrid({ rows, columns, sx, autoHeight,
<DataGrid
{...props}
rows={_rows}
rowCount={rowCount ? rowCount : 0}
columns={_columns}
paginationMode="server"
disableColumnMenu
shrinkWrap={true}
rowModesModel={_rowModesModel}
pageSizeOptions={_pageSizeOptions}
editMode={_editMode}
@@ -137,16 +199,17 @@ export function FiDataGrid({ rows, columns, sx, autoHeight,
hideFooterSelectedRowCount={myHideFooterSelectedRowCount}
filterModel={{ items: _filterItems }}
sx={_sx}
loading={loading}
components={{
noRowsOverlay: CustomNoRowsOverlay,
Pagination: () => (
<TablePagination
count={rowCount?rowCount:0}
count={rowCount ? rowCount : 0}
page={page}
rowsPerPage={pageSize}
rowsPerPageOptions={_pageSizeOptions}
labelDisplayedRows={() =>
`${(_rows?.length?page*pageSize+1:0)}-${page*pageSize+(_rows?.length??0)} ${intl.formatMessage({ id: "of" })} ${rowCount}`
`${(_rows?.length ? page * pageSize + 1 : 0)}-${page * pageSize + (_rows?.length ?? 0)} ${intl.formatMessage({ id: "of" })} ${rowCount}`
}
labelRowsPerPage={intl.formatMessage({ id: "rowsPerPage" }) + ":"}
onPageChange={handleChangePage}


+ 10
- 0
src/components/FileList.js Ver fichero

@@ -19,6 +19,7 @@ export default function FileList({ refType, refId, allowDelete, sx, dateHideable
const theme = useTheme();
const isMdOrLg = useMediaQuery(theme.breakpoints.up('md'));
const intl = useIntl();
const [onDownload, setOnDownload] = React.useState(false);

React.useEffect(() => {
loadData();
@@ -41,10 +42,17 @@ export default function FileList({ refType, refId, allowDelete, sx, dateHideable
};

const onDownloadClick = (fileId, skey, filename) => () => {
setOnDownload(true)
HttpUtils.fileDownload({
fileId: fileId,
skey: skey,
filename: filename,
onResponse:()=>{
setOnDownload(false)
},
onError:()=>{
setOnDownload(false)
}
});
};

@@ -91,6 +99,7 @@ export default function FileList({ refType, refId, allowDelete, sx, dateHideable
className="textPrimary"
onClick={onDownloadClick(params.id, params.row.skey, params.row.filename)}
color="primary"
disabled={onDownload}
/>]
},
},
@@ -139,6 +148,7 @@ export default function FileList({ refType, refId, allowDelete, sx, dateHideable
className="textPrimary"
onClick={onDownloadClick(params.id, params.row.skey, params.row.filename)}
color="primary"
disabled={onDownload}
/>]
},
},


+ 35
- 0
src/components/SysSettingProvider.js Ver fichero

@@ -0,0 +1,35 @@
import { useState, useEffect, createContext } from 'react';
import { get } from "utils/HttpUtils"
import {GET_SYS_SETTING} from "utils/ApiPathConst"


const SysContext = createContext();

const SysSettingProvider = ({ children }) => {

const [sysSetting, setSysSetting] = useState({});

useEffect(() => {
loadSysSetting();
}, []);


const loadSysSetting = () => {
get({
url: GET_SYS_SETTING,
onSuccess: (responseData) => {
// console.log(responseData)
setSysSetting(responseData);
localStorage.setItem('sysEnv', responseData.sysEnv)
}
});
}

return (
<SysContext.Provider value={{ sysSetting, setSysSetting }} >
{children}
</SysContext.Provider>
);
}

export {SysContext, SysSettingProvider};

+ 2
- 3
src/components/cards/AuthFooter.js Ver fichero

@@ -26,7 +26,7 @@ const AuthFooter = () => {
variant="subtitle2"
color="secondary"
component={Link}
// href="https://material-ui.com/store/contributors/codedthemes/"
href="/importantNotice"
target="_blank"
underline="hover"
>
@@ -36,8 +36,7 @@ const AuthFooter = () => {
variant="subtitle2"
color="secondary"
component={Link}
href="https://www.gld.gov.hk/zh-hk/privacy-policy/"
//href="/testMailPage"
href="/privacyPolicy"
target="_blank"
underline="hover"
>


+ 8
- 4
src/index.js Ver fichero

@@ -16,9 +16,10 @@ import 'assets/third-party/apex-chart.css';
import App from './App';
import { store } from 'store';
import reportWebVitals from './reportWebVitals';
import {I18nProvider} from "components/I18nProvider";
import {AutoLogoutProvider} from "components/AutoLogoutProvider";
import {RefreshTokenProvider} from "components/RefreshTokenProvider";
import { I18nProvider } from "components/I18nProvider";
import { AutoLogoutProvider } from "components/AutoLogoutProvider";
import { RefreshTokenProvider } from "components/RefreshTokenProvider";
import { SysSettingProvider } from "components/SysSettingProvider";

// ==============================|| MAIN - REACT DOM RENDER ||============================== //

@@ -26,18 +27,21 @@ const container = document.getElementById('root');
const root = createRoot(container); // createRoot(container!) if you use TypeScript
//const NotAuthorized = lazy(() => import('../views/NotAuthorized'))
//const Error = lazy(() => import('../views/Error'))

root.render(
<StrictMode>
<ReduxProvider store={store}>
<SysSettingProvider>
<I18nProvider>
<BrowserRouter basename="/">
<RefreshTokenProvider>
<AutoLogoutProvider>
<App />
<App />
</AutoLogoutProvider>
</RefreshTokenProvider>
</BrowserRouter>
</I18nProvider>
</SysSettingProvider>
</ReduxProvider>
</StrictMode>
);


+ 458
- 293
src/layout/MainLayout/Header/index.js Ver fichero

@@ -1,9 +1,10 @@
import PropTypes from 'prop-types';
import React
, { useState }
, { useState, useContext }
from 'react';
import { useDispatch } from "react-redux";
import { useNavigate } from "react-router-dom";
import { SysContext } from "components/SysSettingProvider"

// material-ui
// import { useTheme } from '@mui/material/styles';
@@ -47,7 +48,11 @@ import {
isPrimaryLoggedIn,
isCreditorLoggedIn,
isINDLoggedIn,
// isORGLoggedIn,
isPasswordExpiry,
haveOrgPaymentRecord,
haveOrgDnRecord,
isORGLoggedIn,
checkSysEnv
// getUserId
} from "utils/Utils";
import { handleLogoutFunction } from 'auth/index';
@@ -66,6 +71,7 @@ const drawerWidth = 300;
// ==============================|| MAIN LAYOUT - HEADER ||============================== //

function Header(props) {
const { sysSetting } = useContext(SysContext);
const { window } = props;
const [mobileOpen, setMobileOpen] = useState(false);
const dispatch = useDispatch()
@@ -76,346 +82,476 @@ function Header(props) {
};

const handleLogout = async () => {
dispatch(handleLogoutFunction());
await dispatch(handleLogoutFunction());
//await handleLogoutFunction();
navigate('/login');

await navigate('/login');
};

const loginContent = (
isGLDLoggedIn() ?
<div id="adminContent">
<li>
<Link className="dashboard" to='/dashboard'>
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }} >
Dashboard
</Typography>
</Link>
</li>
<li>
<Link className="application" to='/application/search'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Application</Typography></Link>
</li>
{
isGrantedAny(["VIEW_PROOF", "MAINTAIN_PROOF"]) ?
{isPasswordExpiry() ?
<div id="passwordExpiryedContent">
<li>
<Link className="proof" to='/proof/search'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Proof</Typography></Link>
<Link className="manageUser" to={'/user/changePassword'}>
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>
<FormattedMessage id="userChangePassword" />
</Typography>
</Link>
</li>
: <></>
}

{
isGrantedAny(["MAINTAIN_PAYMENT", "MAINTAIN_RECON", "VIEW_DEMANDNOTE", "MAINTAIN_DEMANDNOTE"]) ?
</div>
:
<div id="adminContentList">
<li>
<Link className="paymentTop" ><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Payment</Typography><KeyboardArrowDownIcon sx={{ fontSize: '1vw' }} /></Link>
<ul className='dropdown'>
{
isGranted("MAINTAIN_DEMANDNOTE") ?
<li>
<Link className="exportDemandNote" to='/paymentPage/exportGDN' ><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Export for GDN</Typography></Link>
</li>
:
<></>
}
<Link className="dashboard" to='/dashboard'>
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }} >
Dashboard
</Typography>
</Link>
</li>
{
isGrantedAny(["VIEW_APPLICATION", "MAINTAIN_APPLICATION"]) ?
<li>
<Link className="application" to='/application/search'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Application</Typography></Link>
</li>
: <></>
}
{
isGrantedAny(["VIEW_PROOF", "MAINTAIN_PROOF"]) ?
<li>
<Link className="proof" to='/proof/search'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Proof</Typography></Link>
</li>
: <></>
}

{
isGranted("MAINTAIN_PAYMENT") ?
<li>
<Link className="application" to='/application/markAsPaid/search'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Mark Payment</Typography></Link>
</li>
:
<></>
}
{
isGrantedAny(["MAINTAIN_PROOF", "MAINTAIN_PAYMENT", "MAINTAIN_RECON", "VIEW_DEMANDNOTE", "MAINTAIN_DEMANDNOTE"]) ?
<li>
<Link className="paymentTop" ><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Payment</Typography><KeyboardArrowDownIcon sx={{ fontSize: '1vw' }} /></Link>
<ul className='dropdown'>
{
isGranted("MAINTAIN_PROOF") ?
<li>
<Link className="exportDemandNote" to='/paymentPage/exportGDN' ><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Export for GDN</Typography></Link>
</li>
:
<></>
}

{
isGranted("MAINTAIN_PAYMENT") ?
<li>
<Link className="application" to='/application/markAsPaid/search'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Mark Payment</Typography></Link>
</li>
:
<></>
}

{
isGranted("MAINTAIN_PAYMENT") ?
<li>
<Link className="payment" to='/paymentPage/search'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Online Payment Record</Typography></Link>
</li>
:
<></>
}

{
isGranted("MAINTAIN_RECON") ?
<>
<li>
<Link className="downloadXML" to='/gfmis/search'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>GFMIS Generate XML</Typography></Link>
</li>
</>

:
<></>
}

{
isGranted("MAINTAIN_DEMANDNOTE") ?
<li>
<Link className="createDemandNote" to='/paymentPage/createDemandNote' ><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Create Demand Note</Typography></Link>
</li>
:
<></>
}
{
isGrantedAny(["VIEW_DEMANDNOTE", "MAINTAIN_DEMANDNOTE"]) ?
<li>
<Link className="demandNote" to='/paymentPage/demandNote' ><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Demand Note</Typography></Link>
</li>
:
<></>
}
{
isGranted("MAINTAIN_RECON") ?
<>
<li>
<Link className="reconReport" to='/paymentPage/reconReport'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Recon Report</Typography></Link>
</li>
</>

:
<></>
}
</ul>
</li>
:
<></>
}

{
isGrantedAny(["VIEW_USER", "MAINTAIN_USER", "VIEW_ORG", "MAINTAIN_ORG", "VIEW_GROUP", "MAINTAIN_GROUP", "VIEW_GLD_USER", "VIEW_IND_USER", "VIEW_ORG_USER", "MAINTAIN_GLD_USER", "MAINTAIN_IND_USER", "MAINTAIN_ORG_USER"]) ?
<li>
<Link className="client" ><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Client</Typography><KeyboardArrowDownIcon sx={{ fontSize: '1vw' }} /></Link>
<ul className='dropdown'>
{
isGrantedAny(["VIEW_USER","MAINTAIN_USER"]) ?
<>
<li>
<Link className="userSearchview" to='/userSearchview'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Users (GLD)</Typography></Link>
</li>
<li>
<Link className="indUser" to='/indUser'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Users (Individual)</Typography></Link>
</li>
<li>
<Link className="orgUser" to='/orgUser'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Users (Organisation)</Typography></Link>
</li>
</>
:
<>
{
isGrantedAny(["VIEW_GLD_USER" ,"MAINTAIN_GLD_USER"]) ?
<li>
<Link className="userSearchview" to='/userSearchview'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Users (GLD)</Typography></Link>
</li> : <></>
}
{
isGrantedAny(["VIEW_IND_USER", "MAINTAIN_IND_USER"]) ?
<li>
<Link className="indUser" to='/indUser'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Users (Individual)</Typography></Link>
</li> : <></>
}
{
isGrantedAny(["VIEW_ORG_USER", "MAINTAIN_ORG_USER"]) ?
<li>
<Link className="orgUser" to='/orgUser'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Users (Organisation)</Typography></Link>
</li> : <></>
}
</>
}
{
isGrantedAny(["VIEW_ORG", "MAINTAIN_ORG"]) ?
<li>
<Link className="org" to='/org'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Organisation</Typography></Link>
</li>
:
<></>
}
{
isGrantedAny(["VIEW_GROUP", "MAINTAIN_GROUP"]) ?
<li>
<Link className="usergroupSearchview" to='/usergroupSearchview'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>User Group</Typography></Link>
</li>
:
<></>
}

</ul>
</li>
:
<></>
}
<li>
<Link className="setting" ><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Settings</Typography><KeyboardArrowDownIcon sx={{ fontSize: '1vw' }} /></Link>
<ul className='dropdown'>
<li>
<Link className="userProfileGld" to='/user/profile'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>My Profile</Typography></Link>
</li>
<li>
<Link className="manageUser" to={'/user/changePassword'}>
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>
<FormattedMessage id="userChangePassword" />
</Typography>
</Link>
</li>
{
isGranted("MAINTAIN_PAYMENT") ?
<li>
<Link className="payment" to='/paymentPage/search'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Online Payment Record</Typography></Link>
</li>
:
<></>
}
{
isGranted("MAINTAIN_RECON") ?
isGranted("VIEW_GAZETTE_ISSUE", "MAINTAIN_GAZETTE_ISSUE") ?
<>
<li>
<Link className="downloadXML" to='/gfmis/search'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>GFMIS Generate XML</Typography></Link>
<Link className="holidaySetting" to='/setting/holiday'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Holiday Settings</Typography></Link>
</li>
<li>
<Link className="gazetteissueSetting" to='/setting/gazetteissuepage'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Gazette Issues</Typography></Link>
</li>
</>

:
<></>
}

{
isGranted("MAINTAIN_DEMANDNOTE") ?
isGranted("MAINTAIN_ANNOUNCEMENT") ?
<li>
<Link className="createDemandNote" to='/paymentPage/createDemandNote' ><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Create Demand Note</Typography></Link>
<Link className="announcement" to='/setting/announcement'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Announcement</Typography></Link>
</li>
:
<></>
}

{
isGrantedAny(["VIEW_DEMANDNOTE", "MAINTAIN_DEMANDNOTE"]) ?
<li>
<Link className="demandNote" to='/paymentPage/demandNote' ><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Demand Note</Typography></Link>
</li>
:
<></>
}
{
isGranted("MAINTAIN_RECON") ?
<>
<li>
<Link className="reconReport" to='/paymentPage/reconReport'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Recon Report</Typography></Link>
</li>
</>

:
<></>
{isGranted("MAINTAIN_EMAIL") ?
<li>
<Link className="emailTemplate" to='/setting/emailTemplate'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Email Template</Typography></Link>
</li>
:
<></>
}

</ul>
</li>
:
<></>
}

{
isGrantedAny(["VIEW_USER", "MAINTAIN_USER", "VIEW_ORG", "MAINTAIN_ORG", "VIEW_GROUP", "MAINTAIN_GROUP"]) ?
<li>
<Link className="client" ><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Client</Typography><KeyboardArrowDownIcon sx={{ fontSize: '1vw' }} /></Link>
<ul className='dropdown'>
{
isGrantedAny(["VIEW_USER", "MAINTAIN_USER"]) ?
<>
<li>
<Link className="userSearchview" to='/userSearchview'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Users (GLD)</Typography></Link>
</li>
<li>
<Link className="indUser" to='/indUser'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Users (Individual)</Typography></Link>
</li>
<li>
<Link className="orgUser" to='/orgUser'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Users (Organisation)</Typography></Link>
</li>
</>
isGranted("MAINTAIN_DR") ?
<li>
<Link className="drImport" to='/setting/drImport'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>DR Import</Typography></Link>
</li>
:
<></>
}

{
isGrantedAny(["VIEW_ORG", "MAINTAIN_ORG"]) ?
isGranted("MAINTAIN_SETTING") ?
<li>
<Link className="org" to='/org'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Organisation</Typography></Link>
<Link className="systemSetting" to='/setting/sys'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>System Settings</Typography></Link>
</li>
:
<></>
}

{
isGrantedAny(["VIEW_GROUP", "MAINTAIN_GROUP"]) ?
isGranted("MAINTAIN_SETTING") ?
<li>
<Link className="usergroupSearchview" to='/usergroupSearchview'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>User Group</Typography></Link>
<Link className="auditLogSetting" to='/setting/auditLog'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Audit Log</Typography></Link>
</li>
:
<></>
}

</ul>
</li>
:
<></>
}


<li>
<Link className="setting" ><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>Settings</Typography><KeyboardArrowDownIcon sx={{ fontSize: '1vw' }} /></Link>
<ul className='dropdown'>
<li>
<Link className="userProfileGld" to='/user/profile'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>My Profile</Typography></Link>
</li>
{
isGranted("MAINTAIN_GAZETTE_ISSUE") ?
<>
<li>
<Link className="holidaySetting" to='/setting/holiday'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Holiday Settings</Typography></Link>
</li>
<li>
<Link className="gazetteissueSetting" to='/setting/gazetteissuepage'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Gazette Issues</Typography></Link>
</li>
</>
:
<></>
}

{
isGranted("MAINTAIN_ANNOUNCEMENT") ?
<li>
<Link className="announcement" to='/setting/announcement'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Announcement</Typography></Link>
</li>
:
<></>
}

{isGranted("MAINTAIN_EMAIL") ?
<Box sx={{ display: { xs: 'none', sm: 'none', md: 'block' } }}>
<li>
<Link className="emailTemplate" to='/setting/emailTemplate'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Email Template</Typography></Link>
<Link className="logout" onClick={handleLogout}><Typography variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>Logout</Typography></Link>
</li>
:
<></>
}

{
isGranted("MAINTAIN_DR") ?
<li>
<Link className="drImport" to='/setting/drImport'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>DR Import</Typography></Link>
</li>
:
<></>
}

{
isGranted("MAINTAIN_SETTING") ?
<li>
<Link className="systemSetting" to='/setting/sys'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>System Settings</Typography></Link>
</li>
:
<></>
}

<li>
<Link className="auditLogSetting" to='/setting/auditLog'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2, mt: 1, mb: 1 }}>Audit Log</Typography></Link>
</li>
</ul>
</li>
<Box sx={{ display: { xs: 'none', sm: 'none', md: 'block' } }}>
<li>
<Link className="logout" onClick={handleLogout}><Typography variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>Logout</Typography></Link>
</li>
</Box>
</Box>
</div>
}
</div>
:
<div id="individualUserContent">
<li>
<Link className="dashboard" to='/dashboard'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
<FormattedMessage id="mainPage" />
</Typography></Link>
</li>
<li>
<Link className="myDocumet" to='/publicNotice'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
<FormattedMessage id="myPublicNotice" />
</Typography></Link>
</li>
<li>
<Link className="documentRecord" to='/proof/search'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
<FormattedMessage id="proofRecord" />
</Typography></Link>
</li>
<li>
{isCreditorLoggedIn() ?
<>
<Link className="paymentRecord">
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
<FormattedMessage id="paymentHistory" />
{isPasswordExpiry() ?
<div id="passwordExpiryedContent">
<li>
<Link className="manageUser" to={'/user/changePassword'}>
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>
<FormattedMessage id="userChangePassword" />
</Typography>
<KeyboardArrowDownIcon sx={{ fontSize: '1.0rem' }} />
</Link>
<ul className='dropdown'>
<li>
<Link className="manageOrgUser" to='/paymentPage/search'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
<FormattedMessage id="onlinePaymentHistory" />
</Typography></Link>
</li>
<li>
</li>
</div>
:
<div id="individualUserContentList">
<li>
<Link className="dashboard" to='/dashboard'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
<FormattedMessage id="mainPage" />
</Typography></Link>
</li>
<li>
<Link className="myDocumet" to='/publicNotice'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
<FormattedMessage id="myPublicNotice" />
</Typography></Link>
</li>
<li>
<Link className="documentRecord" to='/proof/search'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
<FormattedMessage id="proofRecord" />
</Typography></Link>
</li>
<li>
{isCreditorLoggedIn() ?
haveOrgPaymentRecord() ?
<>
<Link className="paymentRecord">
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
<FormattedMessage id="paymentHistory" />
</Typography>
<KeyboardArrowDownIcon sx={{ fontSize: '1.0rem' }} />
</Link>
<ul className='dropdown'>
<li>
<Link className="manageOrgUser" to='/paymentPage/search'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
<FormattedMessage id="onlinePaymentHistory" />
</Typography></Link>
</li>
<li>
<Link className="manageOrgUser" to='/paymentPage/demandNote'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
<FormattedMessage id="paymentInfoRecord" />
</Typography></Link>
</li>
</ul>
</>
:
<Link className="manageOrgUser" to='/paymentPage/demandNote'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
<FormattedMessage id="paymentInfoRecord" />
</Typography></Link>
</li>
</ul>
</>
:
<Link className="manageOrgUser" to='/paymentPage/search'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
<FormattedMessage id="onlinePaymentHistory" />
</Typography></Link>
}
</li>
<li>

{isPrimaryLoggedIn() ?
<>
<Link className="userSetting" >
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }} onClick={(event) => console.log(event)}>
<FormattedMessage id="setting" />
</Typography>
<KeyboardArrowDownIcon sx={{ fontSize: '1.0rem' }} />
</Link>
<ul className='dropdown' style={{ width: "max-content" }}>
<li>
<Link className="manageOrgUser" to='setting/manageUser'>
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>
<FormattedMessage id="companyOrUserRecord" />
</Typography>
</Link>
</li>
<li>
<Link className="manageUser" to={'/orgUser'}>
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>
{/* <FormattedMessage id="companyOrUserRecord" /> */}
<FormattedMessage id="userProfile" />
</Typography>
</Link>
</li>
<li>
<Link className="manageUser" to={'/org'}>
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>
{/* <FormattedMessage id="companyOrUserRecord" /> */}
<FormattedMessage id="organizationProfile" />
:
isORGLoggedIn() ?
haveOrgPaymentRecord() ?
<>
<Link className="paymentRecord">
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
<FormattedMessage id="paymentHistory" />
</Typography>
<KeyboardArrowDownIcon sx={{ fontSize: '1.0rem' }} />
</Link>
<ul className='dropdown'>
<li>
<Link className="manageOrgUser" to='/paymentPage/search'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
<FormattedMessage id="onlinePaymentHistory" />
</Typography></Link>
</li>
{haveOrgDnRecord()?
<li>
<Link className="manageOrgUser" to='/paymentPage/demandNote'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
<FormattedMessage id="paymentInfoRecord" />
</Typography></Link>
</li>:null
}
</ul>
</>
:
<Link className="manageOrgUser" to='/paymentPage/demandNote'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
<FormattedMessage id="paymentInfoRecord" />
</Typography></Link>
:
<>
<Link className="paymentRecord">
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
<FormattedMessage id="paymentHistory" />
</Typography>
<KeyboardArrowDownIcon sx={{ fontSize: '1.0rem' }} />
</Link>
<ul className='dropdown'>
<li>
<Link className="manageOrgUser" to='/paymentPage/search'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
<FormattedMessage id="onlinePaymentHistory" />
</Typography></Link>
</li>
{haveOrgDnRecord()?
<li>
<Link className="manageOrgUser" to='/paymentPage/demandNote'><Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }}>
<FormattedMessage id="paymentInfoRecord" />
</Typography></Link>
</li>:null
}
</ul>
</>
}
</li>
<li>

{isPrimaryLoggedIn() ?
<>
<Link className="userSetting" >
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }} onClick={(event) => console.log(event)}>
<FormattedMessage id="setting" />
</Typography>
<KeyboardArrowDownIcon sx={{ fontSize: '1.0rem' }} />
</Link>
</li>
</ul>
</>
:
isINDLoggedIn() ?
<>
<Link className="userSetting" >
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }} onClick={(event) => console.log(event)}>
<FormattedMessage id="setting" />
</Typography>
<KeyboardArrowDownIcon sx={{ fontSize: '1.0rem' }} />
</Link>
<ul className='dropdown' style={{ width: "max-content" }}>
<li>
<Link className="manageUser" to={'/indUser'}>
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>
{/* <FormattedMessage id="companyOrUserRecord" /> */}
<FormattedMessage id="userProfile" />
<ul className='dropdown' style={{ width: "max-content" }}>
<li>
<Link className="manageOrgUser" to='setting/manageUser'>
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>
<FormattedMessage id="companyOrUserRecord" />
</Typography>
</Link>
</li>
<li>
<Link className="manageUser" to={'/org'}>
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>
{/* <FormattedMessage id="companyOrUserRecord" /> */}
<FormattedMessage id="organizationProfile" />
</Typography>
</Link>
</li>
<li>
<Link className="manageUser" to={'/orgUser'}>
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>
{/* <FormattedMessage id="companyOrUserRecord" /> */}
<FormattedMessage id="userProfile" />
</Typography>
</Link>
</li>
<li>
<Link className="manageUser" to={'/user/changePassword'}>
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>
<FormattedMessage id="userChangePassword" />
</Typography>
</Link>
</li>
</ul>
</>
:
isINDLoggedIn() ?
<>
<Link className="userSetting" >
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }} onClick={(event) => console.log(event)}>
<FormattedMessage id="setting" />
</Typography>
<KeyboardArrowDownIcon sx={{ fontSize: '1.0rem' }} />
</Link>
</li>
</ul>
</>
:
<>
<Link className="userSetting" >
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }} onClick={(event) => console.log(event)}>
<FormattedMessage id="setting" />
</Typography>
<KeyboardArrowDownIcon sx={{ fontSize: '1.0rem' }} />
</Link>
<ul className='dropdown' style={{ width: "max-content" }}>
<li>
<Link className="manageUser" to={'/orgUser'}>
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>
<FormattedMessage id="userProfile" />
<ul className='dropdown' style={{ width: "max-content" }}>
<li>
<Link className="manageUser" to={'/indUser'}>
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>
{/* <FormattedMessage id="companyOrUserRecord" /> */}
<FormattedMessage id="userProfile" />
</Typography>
</Link>
</li>
<li>
<Link className="manageUser" to={'/user/changePassword'}>
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>
<FormattedMessage id="userChangePassword" />
</Typography>
</Link>
</li>
</ul>
</>
:
<>
<Link className="userSetting" >
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 1 }} onClick={(event) => console.log(event)}>
<FormattedMessage id="setting" />
</Typography>
<KeyboardArrowDownIcon sx={{ fontSize: '1.0rem' }} />
</Link>
</li>
</ul>
</>
}
</li>
<ul className='dropdown' style={{ width: "max-content" }}>
<li>
<Link className="manageUser" to={'/orgUser'}>
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>
<FormattedMessage id="userProfile" />
</Typography>
</Link>
</li>
<li>
<Link className="manageUser" to={'/user/changePassword'}>
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>
<FormattedMessage id="userChangePassword" />
</Typography>
</Link>
</li>
</ul>
</>
}
</li>
</div>
}
<Box sx={{ display: { xs: 'none', sm: 'none', md: 'block' } }}>
<li>
<Link className="logout" onClick={handleLogout}><Typography variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>
@@ -429,19 +565,38 @@ function Header(props) {
const logoutContent = (
<div>
<li>
<Link className="login" to='/login'>
<Link className="login" to={'/aboutUs'}>
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>
<FormattedMessage id="login" />
<FormattedMessage id="aboutUs" />
</Typography>
</Link>
</li>
<li>
<Link className="login" to={'/userGuidePub'}>
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>
<FormattedMessage id="userGuide" />
</Typography>
</Link>
</li>
<li>
<Link className="register" to='/register'>
<Link className="login" to='/login'>
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>
<FormattedMessage id="register" />
<FormattedMessage id="login" />
</Typography>
</Link>
</li>
{
sysSetting?.allowRegistration ?
<li>
<Link className="register" to='/register'>
<Typography style={{ opacity: 0.9 }} variant={"pnspsHeaderTitle"} sx={{ ml: 2 }}>
<FormattedMessage id="register" />
</Typography>
</Link>
</li>
:
<></>
}
</div>
);

@@ -453,7 +608,7 @@ function Header(props) {
</Typography> */}
<Box sx={{ mr: 2, mt: 1, display: { md: 'none' } }}>
<MobileLogo />
<span id="mobileTitle" >PNSPS</span>
<span style={{ color: checkSysEnv()!=''?'red':'#0C489E'}} id="mobileTitle" >PNSPS</span>
</Box>
<Divider />
<ul id="sidebartop">
@@ -472,7 +627,7 @@ function Header(props) {
<Stack id="sidebar" direction="column" justifyContent="center" alignItems="center" onClick={handleDrawerToggle} sx={{ textAlign: 'center' }}>
<Box sx={{ mr: 2, mt: 1, display: { md: 'none' } }}>
<MobileLogo />
<span id="mobileTitle" >PNSPS</span>
<span style={{ color: checkSysEnv()!=''?'red':'#0C489E'}} id="mobileTitle" >PNSPS</span>
</Box>
<Divider />
<ul id="logoutContent">
@@ -495,8 +650,9 @@ function Header(props) {
justifyContent="flex-start"
alignItems="center"
spacing={0}
sx={{ width: { xs: '100%', md: '5%' } }}
>
<Box mt={0.5} sx={{ display: { xs: 'none', sm: 'none', md: 'block' } }}>
<Box mt={0.5} sx={{ flexGrow: 1, display: { xs: 'none', sm: 'none', md: 'block' } }}>
<AdminLogo />
</Box>
<IconButton
@@ -508,9 +664,16 @@ function Header(props) {
>
<MenuIcon style={{ color: '#0C489E' }} />
</IconButton>
<Box sx={{ mr: 2, display: { md: 'none' } }}>
<MobileLogo />
<span id="mobileTitle" >PNSPS</span>
<Box sx={{ flexGrow: 1, mr: 2, display: { sm: 'block', md: 'none' } }}>
<Stack direction="row" justifyContent="space-between" alignItems="center" width="100%">
<MobileLogo />
<Stack justifyContent="flex-start" alignItems="flex-start" width="100%" ml={2}>
<span style={{ color: checkSysEnv()!=''?'red':'#0C489E'}} id="mobileTitle">PNSPS</span>
</Stack>
<Stack justifyContent="flex-end" alignItems="center">
<span style={{color:"#B11B1B",fontWeight:'bold',fontSize:'15px'}}>RESTRICTED</span>
</Stack>
</Stack>
</Box>
</Stack> :
<Stack
@@ -520,13 +683,13 @@ function Header(props) {
spacing={0}
sx={{ width: { xs: '100%', md: '25%' } }}
>
<Box sx={{ width: '260px', flexGrow: 1, display: { xs: 'none', sm: 'none', md: 'block' } }}>
<Box sx={{ width: '450px', flexGrow: 1, display: { xs: 'none', sm: 'none', md: 'block' } }}>
<Stack direction="row" justifyContent="flex-start" alignItems="center">
<Logo />
<Stack justifyContent="flex-start" alignItems="center">
{/*<span id="systemTitle">公共啟事提交</span>*/}
{/*<span id="systemTitle">及繳費系統</span>*/}
<span id="systemTitle">
<span style={{ color: checkSysEnv()!=''?'red':'#0C489E'}} id="systemTitle">
<FormattedMessage id="PNSPS" />
</span>
</Stack>
@@ -545,7 +708,7 @@ function Header(props) {
<Stack direction="row" justifyContent="space-between" alignItems="center" width="100%">
<MobileLogo />
<Stack justifyContent="flex-start" alignItems="flex-start" width="100%" ml={2}>
<span id="mobileTitle">
<span style={{ color: checkSysEnv()!=''?'red':'#0C489E'}} id="mobileTitle">
<FormattedMessage id="PNSPS" />
</span>
</Stack>
@@ -576,7 +739,9 @@ function Header(props) {
>
{
isGLDLoggedIn() ?
<Grid item />
<Grid item >
<span style={{color:"#B11B1B",fontWeight:'bold',fontSize:'15px'}}>RESTRICTED</span>
</Grid>
:
<Grid item>
<LocaleSelector />
@@ -642,7 +807,7 @@ function Header(props) {
<Stack direction="row" justifyContent="space-between" alignItems="center" width="100%">
<MobileLogo />
<Stack justifyContent="flex-start" alignItems="flex-start" width="100%" ml={2}>
<span id="mobileTitle">
<span style={{ color: checkSysEnv()!=''?'red':'#0C489E'}} id="mobileTitle">
<FormattedMessage id="PNSPS" />
</span>
</Stack>


+ 23
- 13
src/layout/MainLayout/index.js Ver fichero

@@ -1,6 +1,7 @@
import { useEffect, useState } from 'react';
import { Outlet } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import { useLocation } from 'react-router-dom';

// material-ui
import { useTheme } from '@mui/material/styles';
@@ -31,7 +32,8 @@ const MainLayout = () => {
const theme = useTheme();
const matchDownLG = useMediaQuery(theme.breakpoints.down('lg'));
const dispatch = useDispatch();

const location = useLocation();
const hideNavbarRoutes = ['/databaseHealthCheck']
const { drawerOpen } = useSelector((state) => state.menu);

// drawer toggler
@@ -55,18 +57,26 @@ const MainLayout = () => {
}, [drawerOpen]);

return (
<Box sx={{backgroundColor:'#ffffff', display: 'flex', width: '100%', flexDirection: "column", paddingTop: { xs: "5px", sm: "25px", md: "43px" }}}>
<Header/>
{/* <Drawer open={open} handleDrawerToggle={handleDrawerToggle} /> */}
<Box style={{ width: '100%', flexGrow: 1 } } sx={{ paddingTop: "38px" }}>
{/* <Toolbar /> */}
{/* <Breadcrumbs navigation={navigation} title /> */}
<Outlet />
</Box>
<Box sx={{borderTop: "3px solid #0C489E"}}>
<Footer/>
</Box>
</Box>
<>
{!hideNavbarRoutes.includes(location.pathname) && (
<Box sx={{backgroundColor:'#ffffff', display: 'flex', width: '100%', flexDirection: "column", paddingTop: { xs: "5px", sm: "25px", md: "43px" }}}>
<Header/>
{/* <Drawer open={open} handleDrawerToggle={handleDrawerToggle} /> */}
<Box style={{ width: '100%', flexGrow: 1 } } sx={{ paddingTop: "38px" }}>
{/* <Toolbar /> */}
{/* <Breadcrumbs navigation={navigation} title /> */}
<Outlet />
</Box>
<Box sx={{borderTop: "3px solid #0C489E"}}>
<Footer/>
</Box>
</Box>
)}
{hideNavbarRoutes.includes(location.pathname) && (
<Outlet />
)}
</>
);
};



+ 9
- 3
src/pages/Announcement/Search/DataGrid.js Ver fichero

@@ -10,7 +10,7 @@ import { clickableLink } from 'utils/CommonFunction';
import {GET_ANNOUNCE_LIST} from "utils/ApiPathConst";
// ==============================|| EVENT TABLE ||============================== //

export default function SearchPublicNoticeTable({ searchCriteria }) {
export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnReady, applySearch}) {

const navigate = useNavigate()

@@ -73,10 +73,16 @@ export default function SearchPublicNoticeTable({ searchCriteria }) {
customPageSize={10}
getRowHeight={() => 'auto'}
onRowDoubleClick={handleRowDoubleClick}
doLoad={{
applyGridOnReady={applyGridOnReady}
applySearch = {applySearch}
// doLoad={{
// url: GET_ANNOUNCE_LIST,
// params: _searchCriteria,
// }}
doLoad={React.useMemo(() => ({
url: GET_ANNOUNCE_LIST,
params: _searchCriteria,
}}
}), [_searchCriteria])}
/>
</div>
);


+ 5
- 2
src/pages/Announcement/Search/SearchForm.js Ver fichero

@@ -17,8 +17,9 @@ import dayjs from "dayjs";
import {DemoItem} from "@mui/x-date-pickers/internals/demo";
import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider";
import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs";

// ==============================|| DASHBOARD - DEFAULT ||============================== //
const SearchPublicNoticeForm = ({ applySearch, searchCriteria}) => {
const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady}) => {
const navigate = useNavigate()

const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom);
@@ -58,7 +59,8 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria}) => {
function resetForm() {
setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)))
setMaxDate(DateUtils.dateValue(new Date()))
reset();
reset({key:""});
localStorage.setItem('searchCriteria',"")
}


@@ -180,6 +182,7 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria}) => {
<Button
variant="contained"
type="submit"
disabled={onGridReady}
>
Submit
</Button>


+ 26
- 5
src/pages/Announcement/Search/index.js Ver fichero

@@ -7,6 +7,7 @@ import {
import MainCard from "components/MainCard";
import * as React from "react";
import * as DateUtils from "utils/DateUtils";
import { getSearchCriteria } from "auth/utils";

import Loadable from 'components/Loadable';
const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent')));
@@ -28,20 +29,37 @@ const BackgroundHead = {

const UserSearchPage_Individual = () => {

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

React.useEffect(() => {
if (Object.keys(getSearchCriteria(window.location.pathname)).length>0){
setSearchCriteria(getSearchCriteria(window.location.pathname))
}else{
localStorage.setItem('searchCriteria',"")
setSearchCriteria({
dateTo: DateUtils.dateValue(new Date()),
dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)),
})
}
}, []);

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

function applySearch(input) {
setGridOnReady(true)
setSearchCriteria(input);
localStorage.setItem('searchCriteria', JSON.stringify({path:window.location.pathname,data:input}))
}

function applyGridOnReady(input) {
setGridOnReady(input);
}


return (
!onReady ?
<Grid container sx={{ minHeight: '95vh', mb: 3 }} direction="column" justifyContent="center" alignItems="center">
@@ -63,6 +81,7 @@ const UserSearchPage_Individual = () => {
<SearchForm
applySearch={applySearch}
searchCriteria={searchCriteria}
onGridReady={onGridReady}
/>
</Grid>
{/*row 2*/}
@@ -73,7 +92,9 @@ const UserSearchPage_Individual = () => {
sx={{ backgroundColor: '#fff' }}
>
<EventTable
searchCriteria={searchCriteria}
searchCriteria={searchCriteria}
applyGridOnReady={applyGridOnReady}
applySearch={applySearch}
/>
</MainCard>
</Grid>


+ 10
- 4
src/pages/Announcement/Search_Public/DataGrid.js Ver fichero

@@ -6,7 +6,7 @@ import { FormattedMessage, useIntl } from "react-intl";
import {GET_ANNOUNCE_LIST} from "utils/ApiPathConst";
// ==============================|| EVENT TABLE ||============================== //

export default function SearchPublicNoticeTable({ searchCriteria }) {
export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnReady,applySearch }) {

const intl = useIntl();
const { locale } = intl;
@@ -57,10 +57,16 @@ export default function SearchPublicNoticeTable({ searchCriteria }) {
columns={columns}
customPageSize={10}
getRowHeight={() => 'auto'}
doLoad={{
applyGridOnReady={applyGridOnReady}
applySearch={applySearch}
// doLoad={{
// url: GET_ANNOUNCE_LIST,
// params: _searchCriteria
// }}
doLoad={React.useMemo(() => ({
url: GET_ANNOUNCE_LIST,
params: _searchCriteria
}}
params: _searchCriteria,
}), [_searchCriteria])}
/>
</div>
);


+ 22
- 3
src/pages/Announcement/Search_Public/SearchForm.js Ver fichero

@@ -19,7 +19,7 @@ import {DemoItem} from "@mui/x-date-pickers/internals/demo";
import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider";
import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs";
// ==============================|| DASHBOARD - DEFAULT ||============================== //
const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => {
const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady }) => {
// const navigate = useNavigate()

const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom);
@@ -39,6 +39,22 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => {
setToDateValue(maxDate);
}, [maxDate]);

const _sx = {
padding: "4 2 4 2",
boxShadow: 1,
border: 1,
borderColor: '#DDD',
'& .MuiDataGrid-cell': {
borderTop: 1,
borderBottom: 1,
borderColor: "#EEE"
},
'& .MuiDataGrid-footerContainer': {
border: 1,
borderColor: "#EEE"
}
}

const marginBottom = 2.5;
const { reset, register, handleSubmit } = useForm()
const onSubmit = (data) => {
@@ -60,7 +76,8 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => {
function resetForm() {
setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)))
setMaxDate(DateUtils.dateValue(new Date()))
reset();
reset({key:""});
localStorage.setItem('searchCriteria',"")
}


@@ -68,7 +85,7 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => {
<MainCard xs={12} md={12} lg={12}
border={false}
content={false}
sx={{ backgroundColor: '#fff' }}
sx={_sx}
>

<form onSubmit={handleSubmit(onSubmit)}>
@@ -186,6 +203,8 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => {
<Button
variant="contained"
type="submit"
disabled={onGridReady}
aria-label={intl.formatMessage({id: 'submit'})}
>
<FormattedMessage id="submit"></FormattedMessage>
</Button>


+ 26
- 5
src/pages/Announcement/Search_Public/index.js Ver fichero

@@ -14,6 +14,7 @@ const SearchForm = Loadable(React.lazy(() => import('./SearchForm')));
const EventTable = Loadable(React.lazy(() => import('./DataGrid')));
import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png'
import { FormattedMessage } from "react-intl";
import { getSearchCriteria } from "auth/utils";

const BackgroundHead = {
backgroundImage: `url(${titleBackgroundImg})`,
@@ -29,19 +30,36 @@ const BackgroundHead = {

const UserSearchPage_Individual = () => {

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

React.useEffect(() => {
setOnReady(true);
if (Object.keys(getSearchCriteria(window.location.pathname)).length>0){
setSearchCriteria(getSearchCriteria(window.location.pathname))
}else{
localStorage.setItem('searchCriteria',"")
setSearchCriteria({
dateTo: DateUtils.dateValue(new Date()),
dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)),
})
}
}, []);

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


function applySearch(input) {
setSearchCriteria(input);
localStorage.setItem('searchCriteria', JSON.stringify({path:window.location.pathname,data:input}))
}

function applyGridOnReady(input) {
setGridOnReady(input);
}

return (
@@ -65,6 +83,7 @@ const UserSearchPage_Individual = () => {
<SearchForm
applySearch={applySearch}
searchCriteria={searchCriteria}
onGridReady={onGridReady}
/>
</Grid>
{/*row 2*/}
@@ -76,6 +95,8 @@ const UserSearchPage_Individual = () => {
>
<EventTable
searchCriteria={searchCriteria}
applyGridOnReady={applyGridOnReady}
applySearch={applySearch}
/>
</MainCard>
</Grid>


+ 12
- 9
src/pages/AuditLog/AuditLogSearchForm.js Ver fichero

@@ -21,16 +21,18 @@ import {ThemeProvider} from "@emotion/react";
import * as DateUtils from "utils/DateUtils";
import * as UrlUtils from "utils/ApiPathConst";
import * as HttpUtils from "utils/HttpUtils";
import Loadable from 'components/Loadable';
const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent')));
// import Loadable from 'components/Loadable';
// const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent')));

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

// ==============================|| DASHBOARD - DEFAULT ||============================== //
const AuditLogSearchForm = ({ applySearch, searchCriteria}) => {
const AuditLogSearchForm = ({ applySearch, searchCriteria, onGridReady}) => {
// const navigate = useNavigate();

const [minDate, setMinDate] = React.useState(searchCriteria.modifiedFrom);
@@ -77,6 +79,7 @@ const AuditLogSearchForm = ({ applySearch, searchCriteria}) => {
setOnDownload(true)
HttpUtils.fileDownload({
url: UrlUtils.AUDIT_LOG_EXPORT,
params: searchCriteria,
onResponse:()=>{
setOnDownload(false)
},
@@ -185,18 +188,17 @@ const AuditLogSearchForm = ({ applySearch, searchCriteria}) => {
<ThemeProvider theme={PNSPS_BUTTON_THEME}>
<Grid item xs={12} md={12}>
<Grid container maxWidth justifyContent="flex-end">
<Grid item sx={{ ml: 3, mr: 3, mb: 3,}}>
{onDownload?
<LoadingComponent disableText={true} alignItems="flex-start"/>
:
{isGranted("MAINTAIN_SETTING") ?
<Grid item sx={{ ml: 3, mr: 3, mb: 3,}}>
<Button
variant="contained"
onClick={exportExcel}
disabled={onDownload}
>
Export
</Button>
}
</Grid>
</Grid> : null
}
<Grid item sx={{ ml: 3, mr: 3, mb: 3,}}>
<Button
variant="contained"
@@ -210,6 +212,7 @@ const AuditLogSearchForm = ({ applySearch, searchCriteria}) => {
<Button
variant="contained"
type="submit"
disabled={onGridReady}
>
Search
</Button>


+ 10
- 4
src/pages/AuditLog/AuditLogTable.js Ver fichero

@@ -12,7 +12,7 @@ import {
} from '@mui/material';
// ==============================|| EVENT TABLE ||============================== //

export default function AuditLogTable({searchCriteria}) {
export default function AuditLogTable({searchCriteria, applyGridOnReady,applySearch}) {
const [_searchCriteria, set_searchCriteria] = React.useState(searchCriteria);

useEffect(() => {
@@ -87,10 +87,16 @@ export default function AuditLogTable({searchCriteria}) {
columns={columns}
customPageSize={10}
getRowHeight={() => 'auto'}
doLoad={{
applyGridOnReady={applyGridOnReady}
applySearch={applySearch}
// doLoad={{
// url: GET_AUDIT_LOG_LIST,
// params: _searchCriteria
// }}
doLoad={React.useMemo(() => ({
url: GET_AUDIT_LOG_LIST,
params: _searchCriteria
}}
params: _searchCriteria,
}), [_searchCriteria])}
/>
</div>
);


+ 10
- 1
src/pages/AuditLog/index.js Ver fichero

@@ -8,6 +8,7 @@ import {
import MainCard from "components/MainCard";
import { useEffect, useState } from "react";
import * as DateUtils from "utils/DateUtils";
import * as React from "react";

import Loadable from 'components/Loadable';
import { lazy } from 'react';
@@ -33,15 +34,21 @@ const AuditLogPage = () => {
modifiedFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)),
});
const [onReady, setOnReady] = useState(false);
const [onGridReady, setGridOnReady] = React.useState(false);

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

function applySearch(input) {
setGridOnReady(true)
setSearchCriteria(input);
}

function applyGridOnReady(input) {
setGridOnReady(input);
}
return (
!onReady ?
<Grid container sx={{ minHeight: '87vh', mb: 3 }} direction="column" justifyContent="center" alignItems="center">
@@ -64,7 +71,7 @@ const AuditLogPage = () => {
<SearchForm
applySearch={applySearch}
searchCriteria={searchCriteria}
onGridReady={onGridReady}
/>
</Grid>
{/*row 2*/}
@@ -75,6 +82,8 @@ const AuditLogPage = () => {
>
<EventTable
searchCriteria={searchCriteria}
applyGridOnReady={applyGridOnReady}
applySearch={applySearch}
/>
</MainCard>
</Grid>


+ 1
- 1
src/pages/DemandNote/Details/ApplicationDetailCard.js Ver fichero

@@ -143,7 +143,7 @@ const ApplicationDetailCard = ({ data }) => {
</Grid>
<Grid container direction="row" justifyContent="space-between"
alignItems="center">
<Grid item xs={12} md={6} lg={6} mt={1}>
<Grid item xs={12} md={6} lg={6} mt={1} mb={2}>
<Grid container alignItems={"center"}>
<Grid item xs={12} md={12} lg={12}>
<Grid container direction="row">


+ 15
- 9
src/pages/DemandNote/Export/DataGrid.js Ver fichero

@@ -77,9 +77,9 @@ export default function SearchPublicNoticeTable({ searchCriteria,}) {
// let user = params.row.enCompanyName != null ? params.row.enCompanyName : params.row.chCompanyName;
let user = params.row.contactPerson;
// user = user != null ? user : "";
if (params.row.sysType != null && params.row.sysType == "dummy"){
user = "Dummy - PD"
}
// if (params.row.sysType != null && params.row.sysType == "dummy"){
// user = "Dummy - PD"
// }
return <div>
{user}
</div>;
@@ -95,7 +95,7 @@ export default function SearchPublicNoticeTable({ searchCriteria,}) {
let company = params.row.enCompanyName != null ? params.row.enCompanyName : params.row.chCompanyName;
company = company != null ? company : "";
if (params.row.sysType != null && params.row.sysType == "dummy"){
company = params.row.contactPerson
company = params.row.custName
}
return <div>
{company}
@@ -109,7 +109,13 @@ export default function SearchPublicNoticeTable({ searchCriteria,}) {
flex: 2,
minWidth: 200,
renderCell: (params) => {
return <>{(params?.value)}</>;
let careOf = params.row.careOf
// if (params.row.sysType != null && params.row.sysType == "dummy"){
// careOf = ''
// }
return <div>
{careOf}
</div>;
}
},
{
@@ -120,13 +126,13 @@ export default function SearchPublicNoticeTable({ searchCriteria,}) {
minWidth: 100,
valueGetter: (params) => {
let length = params.row.length
let colCount = params.row.colCount
// let colCount = params.row.colCount
let noOfPages = params.row.noOfPages
let dimension = 0
if (noOfPages != null){
dimension = length*colCount*noOfPages
dimension = length*noOfPages
}else{
dimension = length*colCount
dimension = length
}
return dimension;
}
@@ -134,7 +140,7 @@ export default function SearchPublicNoticeTable({ searchCriteria,}) {
{
id: 'fee',
field: 'fee',
headerName: 'Amount(HK$)',
headerName: 'Amount($)',
flex: 1,
minWidth: 100,
valueGetter: (params) => {


+ 86
- 15
src/pages/DemandNote/Search/DataGrid.js Ver fichero

@@ -19,7 +19,8 @@ import {
DEMAND_NOTE_SEND,
DEMAND_NOTE_ATTACH,
DEMAND_NOTE_MARK_PAID,
DEMAND_NOTE_LIST_ALL
DEMAND_NOTE_LIST_ALL,
DEMAND_NOTE_REVOKE_PAID
} from "utils/ApiPathConst";
import * as HttpUtils from "utils/HttpUtils";
import { PNSPS_BUTTON_THEME } from "themes/buttonConst";
@@ -27,23 +28,26 @@ import { ThemeProvider } from "@emotion/react";
import { isGrantedAny } from "auth/utils";
// ==============================|| EVENT TABLE ||============================== //

export default function SearchDemandNote({ searchCriteria, applySearch }) {
export default function SearchDemandNote({ applySearch, searchCriteria, applyGridOnReady }) {

const [isConfirmPopUp, setConfirmPopUp] = useState(false);
const [isRevokePopUp, setRevokePopUp] = useState(false);
const [isSendPopUp, setSendPopUp] = useState(false);
const [isErrorPopUp, setIsErrorPopUp] = useState(false);
const [selectonWarning, setSelectonWarning] = useState(false);
const [wait, setWait] = useState(false);
const [reload, setReload] = useState(new Date());
const [rows, setRows] = useState([]);
const [_searchCriteria, set_searchCriteria] = useState(searchCriteria);
const [_searchCriteria, set_searchCriteria] = useState({});
const [selectedRowItems, setSelectedRowItems] = useState([]);
const navigate = useNavigate()
const [onDownload, setOnDownload] = useState(false);

useEffect(() => {
set_searchCriteria(searchCriteria);
}, [searchCriteria]);


const handleDnClick = (params) => () => {
navigate('/paymentPage/demandNote/details/' + params.id);
};
@@ -83,10 +87,17 @@ export default function SearchDemandNote({ searchCriteria, applySearch }) {
}

const onDownloadClick = (params) => () => {
setOnDownload(true)
HttpUtils.fileDownload({
fileId: params.row.fileId,
skey: params.row.skey,
filename: params.row.filename,
onResponse:()=>{
setOnDownload(false)
},
onError:()=>{
setOnDownload(false)
}
});
};

@@ -109,7 +120,7 @@ export default function SearchDemandNote({ searchCriteria, applySearch }) {
dnIdList: idList
},
onSuccess: () => {
if (reloadFun) reloadFun();
setReload(new Date());
}
});

@@ -133,13 +144,36 @@ export default function SearchDemandNote({ searchCriteria, applySearch }) {
},
files: [file],
onSuccess() {
setWait(false);
if (reloadFun) reloadFun();
setReload(new Date());
},
});
document.getElementById("uploadFileBtn").value = "";
}

const revokePaid = () => {
setRevokePopUp(false);
let idList = [];
const datas = rows?.filter((row) =>
selectedRowItems.includes(row.id)
);
if (datas?.length < 1) {
setSelectonWarning(true);
return;
}
for (var i = 0; i < datas?.length; i++) {
idList.push(datas[i].id);
}
HttpUtils.post({
url: DEMAND_NOTE_REVOKE_PAID,
params: {
dnIdList: idList
},
onSuccess: () => {
setReload(new Date());
}
});
}

const markPaid = () => {
setConfirmPopUp(false);
let idList = [];
@@ -159,7 +193,7 @@ export default function SearchDemandNote({ searchCriteria, applySearch }) {
dnIdList: idList
},
onSuccess: () => {
if (reloadFun) reloadFun();
setReload(new Date());
}
});
}
@@ -240,9 +274,11 @@ export default function SearchDemandNote({ searchCriteria, applySearch }) {
width: 300,
renderCell: (params) => {
return (<table>
<tr><td>Issue:</td><td>{DateUtils.dateStr(params?.row.issueDate)}</td></tr>
<tr><td>Due:</td><td>{params?.value ? DateUtils.dateStr(params?.value) : "--"}</td></tr>
<tr><td>Sent:</td><td>{params.row.sentDate ? <> {DateUtils.datetimeStr(params.row.sentDate)} - {params.row.sentBy} </> : <> To be sent</>}</td></tr>
<tbody>
<tr><td>Issue:</td><td>{DateUtils.dateStr(params?.row.issueDate)}</td></tr>
<tr><td>Due:</td><td>{params?.value ? DateUtils.dateStr(params?.value) : "--"}</td></tr>
<tr><td>Sent:</td><td>{params.row.sentDate ? DateUtils.datetimeStr(params.row.sentDate) +" - "+ params.row.sentBy : "To be sent"}</td></tr>
</tbody>
</table>);
}
},
@@ -254,7 +290,7 @@ export default function SearchDemandNote({ searchCriteria, applySearch }) {
),
width: 280,
renderCell: (params) => {
return <Button onClick={onDownloadClick(params)}><u>{params.row.filename}</u></Button>;
return <Button disabled={onDownload} onClick={onDownloadClick(params)}><u>{params.row.filename}</u></Button>;
},
},
{
@@ -262,7 +298,7 @@ export default function SearchDemandNote({ searchCriteria, applySearch }) {
headerName: 'Status',
width: 175,
renderCell: (params) => {
return [StatusUtils.getStatus_Eng(params)]
return StatusUtils.getStatus_Eng(params)
},
},
];
@@ -300,6 +336,7 @@ export default function SearchDemandNote({ searchCriteria, applySearch }) {
</Button>
</label>
</Grid>

<Grid item sx={{ ml: 3, mr: 3, mb: 3, mt: 3 }}>
<Button
variant="contained"
@@ -334,13 +371,23 @@ export default function SearchDemandNote({ searchCriteria, applySearch }) {
Mark as Paid
</Button>
</Grid>

<Grid item sx={{ ml: 3, mr: 3, mb: 3, mt: 3 }}>
<Button
variant="contained"
onClick={() => setRevokePopUp(true)}
>
Revoke payment
</Button>
</Grid>

</ThemeProvider>
</Grid>
: <></>
}
<Box sx={{ backgroundColor: "#fff", ml: 2 }} width="98%">
<FiDataGrid
checkboxSelection = {isGrantedAny(["MAINTAIN_DEMANDNOTE"])}
checkboxSelection={isGrantedAny(["MAINTAIN_DEMANDNOTE"])}
disableRowSelectionOnClick
onRowSelectionModelChange={(newSelection) => {
setSelectedRowItems(newSelection);
@@ -349,13 +396,15 @@ export default function SearchDemandNote({ searchCriteria, applySearch }) {
customPageSize={100}
getRowHeight={() => 'auto'}
onRowDoubleClick={handleRowDoubleClick}
applyGridOnReady={applyGridOnReady}
applySearch={applySearch}
doLoad={useMemo(() => ({
url: DEMAND_NOTE_LIST_ALL,
params: _searchCriteria,
callback: function (responseData) {
setRows(responseData?.records);
}
}), [_searchCriteria])}
}), [_searchCriteria, reload])}
/>
</Box>
<div>
@@ -422,6 +471,28 @@ export default function SearchDemandNote({ searchCriteria, applySearch }) {
</DialogActions>
</Dialog>
</div>
<div>
<Dialog
open={isRevokePopUp}
onClose={() => setRevokePopUp(false)}
PaperProps={{
sx: {
minWidth: '40vw',
maxWidth: { xs: '90vw', s: '90vw', m: '70vw', lg: '70vw' },
maxHeight: { xs: '90vh', s: '70vh', m: '70vh', lg: '60vh' }
}
}}
>
<DialogTitle><Typography variant="h3">Confirm</Typography></DialogTitle>
<DialogContent style={{ display: 'flex', }}>
<Typography variant="h4" style={{ padding: '16px' }}>Are you sure to revoke DN as To Be Paid?</Typography>
</DialogContent>
<DialogActions>
<Button onClick={() => setRevokePopUp(false)}><Typography variant="h5">Cancel</Typography></Button>
<Button onClick={() => revokePaid()}><Typography variant="h5">Confirm</Typography></Button>
</DialogActions>
</Dialog>
</div>
<div>
<Dialog
open={isSendPopUp}


+ 48
- 6
src/pages/DemandNote/Search/SearchForm.js Ver fichero

@@ -21,7 +21,7 @@ import {DemoItem} from "@mui/x-date-pickers/internals/demo";
import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider";
import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs";
// ==============================|| DASHBOARD - DEFAULT ||============================== //
const SearchDemandNoteForm = ({ applySearch, orgComboData, searchCriteria, issueComboData
const SearchDemandNoteForm = ({ applySearch, orgComboData, searchCriteria, issueComboData, onGridReady
}) => {

const [type, setType] = React.useState([]);
@@ -44,6 +44,28 @@ const SearchDemandNoteForm = ({ applySearch, orgComboData, searchCriteria, issue
const intl = useIntl();
const { locale } = intl;
React.useEffect(() => {
if(searchCriteria.status!=undefined){
if(searchCriteria.status === ""){
ComboData.denmandNoteStatus[0]
}else{
setSelectedStatus(ComboData.denmandNoteStatus.find(item => item.type === searchCriteria.status))
}
if(searchCriteria.dueDateFrom != ""){
setMinDueDate(DateUtils.dateValue(searchCriteria.dueDateFrom))
}else{
setMinDueDate(null)
}
if(searchCriteria.dueDateTo != ""){
setMaxDueDate(DateUtils.dateValue(searchCriteria.dueDateTo))
}else{
setMaxDueDate(null);
}
}else{
setSelectedStatus(ComboData.denmandNoteStatus[0])
}
}, [searchCriteria]);
React.useEffect(() => {
setFromDateValue(minDate);
}, [minDate]);
@@ -101,12 +123,18 @@ const SearchDemandNoteForm = ({ applySearch, orgComboData, searchCriteria, issue
React.useEffect(() => {
if (orgComboData && orgComboData.length > 0) {
setOrgCombo(orgComboData);
if(searchCriteria.orgId!=undefined){
setOrgSelected(orgComboData.find(item => item.key === searchCriteria.orgId))
}
}
}, [orgComboData]);

React.useEffect(() => {
if (issueComboData && issueComboData.length > 0) {
setIssueCombo(issueComboData);
if(searchCriteria.issueId!=undefined){
setIssueSelected(issueComboData.find(item => item.id === searchCriteria.issueId))
}
}
}, [issueComboData]);

@@ -117,9 +145,13 @@ const SearchDemandNoteForm = ({ applySearch, orgComboData, searchCriteria, issue
setSelectedStatus(ComboData.denmandNoteStatus[0]);
setMinDueDate(null);
setMaxDueDate(null);
setMinDate(searchCriteria.dateFrom);
setMaxDate(searchCriteria.dateTo);
reset();
setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)))
setMaxDate(DateUtils.dateValue(new Date()))
reset({
appNo:"",
dnNo:"",
});
localStorage.setItem('searchCriteria',"")
}

function getIssueLabel(data) {
@@ -209,10 +241,12 @@ const SearchDemandNoteForm = ({ applySearch, orgComboData, searchCriteria, issue
disablePortal
id="orgId"
options={orgCombo}
groupBy={(option) => option.groupType}
size="small"
value={orgSelected}
getOptionLabel={(option) => option.name? option.name : ""}
inputValue={orgSelected ? orgSelected.name : ""}
inputValue={orgSelected ? orgSelected.name!=undefined?orgSelected.name:"" : ""}

onChange={(event, newValue) => {
if (newValue !== null) {
setOrgSelected(newValue);
@@ -228,12 +262,19 @@ const SearchDemandNoteForm = ({ applySearch, orgComboData, searchCriteria, issue
}}
/>
)}
renderGroup={(params) => (
<Grid item key={params.key}>
<Typography fontSize={20} fontStyle="italic" p={1}>
{params.group}
</Typography>
{params.children}
</Grid>
)}
/>
</Grid>
: <></>
}


<Grid item xs={9} s={6} md={5} lg={3} sx={{ ml: 3, mr: 3, mb: 3 }}>
<TextField
fullWidth
@@ -411,6 +452,7 @@ const SearchDemandNoteForm = ({ applySearch, orgComboData, searchCriteria, issue
<Button
variant="contained"
type="submit"
disabled={onGridReady}
>
Submit
</Button>


+ 21
- 4
src/pages/DemandNote/Search/index.js Ver fichero

@@ -10,6 +10,7 @@ import * as React from "react";
import * as UrlUtils from "utils/ApiPathConst";
import * as HttpUtils from "utils/HttpUtils";
import * as DateUtils from "utils/DateUtils";
import { getSearchCriteria } from "auth/utils";

import Loadable from 'components/Loadable';
const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent')));
@@ -35,16 +36,26 @@ const UserSearchPage_Individual = () => {
const [orgCombo, setOrgCombo] = React.useState([]);
const [issueCombo, setIssueCombo] = React.useState([]);
const [searchCriteria, setSearchCriteria] = React.useState({
dateTo: DateUtils.dateValue(new Date()),
dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate() - 14)),
// dateTo: DateUtils.dateValue(new Date()),
// dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate() - 14)),
// dueDateTo: DateUtils.dateValue(new Date()),
// dueDateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate() - 14)),
});
const [onReady, setOnReady] = React.useState(false);
const [onGridReady, setGridOnReady] = React.useState(false);

React.useEffect(() => {
getOrgCombo();
getIssueCombo();
if (Object.keys(getSearchCriteria(window.location.pathname)).length>0){
setSearchCriteria(getSearchCriteria(window.location.pathname))
}else{
localStorage.setItem('searchCriteria',"")
setSearchCriteria({
dateTo: DateUtils.dateValue(new Date()),
dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)),
})
}
}, []);

React.useEffect(() => {
@@ -72,9 +83,14 @@ const UserSearchPage_Individual = () => {
});
}


function applySearch(input) {
setGridOnReady(true)
setSearchCriteria(input);
localStorage.setItem('searchCriteria', JSON.stringify({path:window.location.pathname,data:input}))
}

function applyGridOnReady(input) {
setGridOnReady(input);
}

return (
@@ -102,7 +118,7 @@ const UserSearchPage_Individual = () => {
orgComboData={orgCombo}
issueComboData={issueCombo}
searchCriteria={searchCriteria}
onGridReady={onGridReady}
/>
</Grid>
{/*row 2*/}
@@ -115,6 +131,7 @@ const UserSearchPage_Individual = () => {
<EventTable
applySearch={applySearch}
searchCriteria={searchCriteria}
applyGridOnReady={applyGridOnReady}
/>
</MainCard>
</Grid>


+ 14
- 6
src/pages/DemandNote/Search_Public/DataGrid.js Ver fichero

@@ -15,11 +15,12 @@ import {useIntl} from "react-intl";
import {DEMAND_NOTE_LIST} from "utils/ApiPathConst";
// ==============================|| EVENT TABLE ||============================== //

export default function SearchDemandNote({ searchCriteria }) {
export default function SearchDemandNote({ searchCriteria, applyGridOnReady,applySearch }) {
const intl = useIntl();
const theme = useTheme();
const isMdOrLg = useMediaQuery(theme.breakpoints.up('md'));
const { locale } = intl;


const [_searchCriteria, set_searchCriteria] = React.useState(searchCriteria);
@@ -52,7 +53,7 @@ export default function SearchDemandNote({ searchCriteria }) {
{
id: 'issueDate',
field: 'issueDate',
headerName: intl.formatMessage({id: 'receiptDate'}),
headerName: intl.formatMessage({id: 'sendDate'}),
width: isMdOrLg ? 'auto' : 175,
flex: isMdOrLg ? 1 : undefined,
valueGetter: (params) => {
@@ -65,12 +66,13 @@ export default function SearchDemandNote({ searchCriteria }) {
width: isMdOrLg ? 'auto' : 175,
flex: isMdOrLg ? 1 : undefined,
renderCell: (params) => {
return [StatusUtils.getStatus_Cht(params)]

return [StatusUtils.getStatus_i18n(params, locale) ]
},
},
{
field: 'sentDate',
headerName: intl.formatMessage({id: 'sendDate'}),
headerName: intl.formatMessage({id: 'sendDateTime'}),
width: isMdOrLg ? 'auto' : 200,
flex: isMdOrLg ? 1 : undefined,
valueGetter: (params) => {
@@ -95,10 +97,16 @@ export default function SearchDemandNote({ searchCriteria }) {
columns={columns}
customPageSize={10}
getRowHeight={() => 'auto'}
doLoad={{
applyGridOnReady={applyGridOnReady}
applySearch={applySearch}
// doLoad={{
// url: DEMAND_NOTE_LIST,
// params: _searchCriteria,
// }}
doLoad={React.useMemo(() => ({
url: DEMAND_NOTE_LIST,
params: _searchCriteria,
}}
}), [_searchCriteria])}
/>
</Box>
</div>


+ 23
- 3
src/pages/DemandNote/Search_Public/SearchForm.js Ver fichero

@@ -22,7 +22,7 @@ import {DemoItem} from "@mui/x-date-pickers/internals/demo";
import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider";
import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs";
// ==============================|| DASHBOARD - DEFAULT ||============================== //
const SearchDemandNoteForm = ({ applySearch, searchCriteria, issueComboData
const SearchDemandNoteForm = ({ applySearch, searchCriteria, issueComboData, onGridReady
}) => {

const intl = useIntl();
@@ -38,6 +38,18 @@ const SearchDemandNoteForm = ({ applySearch, searchCriteria, issueComboData
const [fromDateValue, setFromDateValue] = React.useState("dd / mm / yyyy");
const [toDateValue, setToDateValue] = React.useState("dd / mm / yyyy");

React.useEffect(() => {
if(searchCriteria.status!=undefined){
if(searchCriteria.status === ""){
ComboData.denmandNoteStatus_Public[0]
}else{
setSelectedStatus(ComboData.denmandNoteStatus_Public.find(item => item.type === searchCriteria.status))
}
}else{
setSelectedStatus(ComboData.denmandNoteStatus_Public[0])
}
}, [searchCriteria]);

React.useEffect(() => {
setFromDateValue(minDate);
}, [minDate]);
@@ -76,17 +88,23 @@ const SearchDemandNoteForm = ({ applySearch, searchCriteria, issueComboData
React.useEffect(() => {
if (issueComboData && issueComboData.length > 0) {
setIssueCombo(issueComboData);
if(searchCriteria.issueId!=undefined){
setIssueSelected(issueComboData.find(item => item.id === searchCriteria.issueId))
}
}
}, [issueComboData]);

function resetForm() {
setType([]);
// setStatus({ key: 0, label: 'All', type: 'all' });
setSelectedStatus(ComboData.denmandNoteStatus_Public[0]);
// setOrgSelected({});
setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)))
setMaxDate(DateUtils.dateValue(new Date()))
setIssueSelected({});
reset();
reset({
appNo:"",
dnNo:"",
});
}

function getIssueLabel(data) {
@@ -246,6 +264,7 @@ const SearchDemandNoteForm = ({ applySearch, searchCriteria, issueComboData
{...register("status")}
id="status"
size="small"
disableClearable
options={ComboData.denmandNoteStatus_Public}
getOptionLabel={(option) => option?.i18nLabel ? intl.formatMessage({ id: option.i18nLabel }) : ""}
inputValue={selectedStatus?.i18nLabel ? intl.formatMessage({ id: selectedStatus.i18nLabel }) : ""}
@@ -288,6 +307,7 @@ const SearchDemandNoteForm = ({ applySearch, searchCriteria, issueComboData
<Button
variant="contained"
type="submit"
disabled={onGridReady}
>
<FormattedMessage id="submit" />
</Button>


+ 22
- 5
src/pages/DemandNote/Search_Public/index.js Ver fichero

@@ -10,6 +10,7 @@ import * as React from "react";
import {GET_ORG_COMBO, GET_ISSUE_COMBO} from "utils/ApiPathConst";
import * as HttpUtils from "utils/HttpUtils";
import * as DateUtils from "utils/DateUtils";
import { getSearchCriteria } from "auth/utils";

import Loadable from 'components/Loadable';
const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent')));
@@ -34,15 +35,22 @@ const SearchPage_DemandNote_Pub = () => {

const [orgCombo, setOrgCombo] = React.useState([]);
const [issueCombo, setIssueCombo] = React.useState([]);
const [searchCriteria, setSearchCriteria] = React.useState({
dateTo: DateUtils.dateValue(new Date()),
dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate() - 14)),
});
const [searchCriteria, setSearchCriteria] = React.useState({});
const [onReady, setOnReady] = React.useState(false);
const [onGridReady, setGridOnReady] = React.useState(false);

React.useEffect(() => {
getOrgCombo();
getIssueCombo();
if (Object.keys(getSearchCriteria(window.location.pathname)).length>0){
setSearchCriteria(getSearchCriteria(window.location.pathname))
}else{
localStorage.setItem('searchCriteria',"")
setSearchCriteria({
dateTo: DateUtils.dateValue(new Date()),
dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)),
})
}
}, []);

React.useEffect(() => {
@@ -72,7 +80,13 @@ const SearchPage_DemandNote_Pub = () => {


function applySearch(input) {
setGridOnReady(true)
setSearchCriteria(input);
localStorage.setItem('searchCriteria', JSON.stringify({path:window.location.pathname,data:input}))
}

function applyGridOnReady(input) {
setGridOnReady(input);
}

return (
@@ -100,6 +114,7 @@ const SearchPage_DemandNote_Pub = () => {
orgComboData={orgCombo}
issueComboData={issueCombo}
searchCriteria={searchCriteria}
onGridReady={onGridReady}
/>
</Grid>
{/*row 2*/}
@@ -110,7 +125,9 @@ const SearchPage_DemandNote_Pub = () => {
sx={{ backgroundColor: '#fff' }}
>
<EventTable
searchCriteria={searchCriteria}
searchCriteria={searchCriteria}
applyGridOnReady={applyGridOnReady}
applySearch={applySearch}
/>
</MainCard>
</Grid>


+ 3
- 3
src/pages/EmailTemplate/Detail_GLD/index.js Ver fichero

@@ -50,7 +50,7 @@ const Index = () => {
axios.get(`${UrlUtils.GET_EMAIL}/${params.id}`)
.then((response) => {
if (response.status === 200) {
console.log(response)
// console.log(response)
setRecord(response.data.data)
}
})
@@ -95,14 +95,14 @@ const Index = () => {
console.log(error);
return false;
});
console.log(data)
// console.log(data)
}

const handleDelete = () => {
axios.delete(`${UrlUtils.DELETE_EMAIL}/${params.id}`,
)
.then((response) => {
console.log(response)
// console.log(response)
if (response.status === 204) {
// location.reload();
navigate('/setting/emailTemplate');


+ 8
- 4
src/pages/EmailTemplate/Search_GLD/DataGrid.js Ver fichero

@@ -97,10 +97,14 @@ export default function EmailTemplateTable({ responseData }) {
customPageSize={10}
onRowDoubleClick={handleRowDoubleClick}
getRowHeight={() => 'auto'}
doLoad={{
url:GET_EMAIL_LIST,
params: _responseData
}}
// doLoad={{
// url:GET_EMAIL_LIST,
// params: _responseData
// }}
doLoad={React.useMemo(() => ({
url: GET_EMAIL_LIST,
params: _responseData,
}), [_responseData])}
/>
</div>
);

+ 2
- 1
src/pages/GFMIS/DataGrid.js Ver fichero

@@ -6,7 +6,7 @@ import { useNavigate } from "react-router-dom";
import { FiDataGrid } from "components/FiDataGrid";
// ==============================|| EVENT TABLE ||============================== //

export default function SearchTable({ searchCriteria }) {
export default function SearchTable({ searchCriteria, applyGridOnReady }) {
const [_searchCriteria, set_searchCriteria] = React.useState(searchCriteria);
const navigate = useNavigate()
// const [rows, setRows] = React.useState([]);
@@ -67,6 +67,7 @@ export default function SearchTable({ searchCriteria }) {
columns={columns}
customPageSize={10}
onRowDoubleClick={handleEditClick}
applyGridOnReady={applyGridOnReady}
doLoad={React.useMemo(() => ({
url: GFIMIS_LIST,
params: _searchCriteria,


+ 2
- 1
src/pages/GFMIS/SearchForm.js Ver fichero

@@ -21,7 +21,7 @@ import {DemoItem} from "@mui/x-date-pickers/internals/demo";
import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider";
import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs";
// ==============================|| DASHBOARD - DEFAULT ||============================== //
const SearchPublicNoticeForm = ({ applySearch, generateXML, searchCriteria }) => {
const SearchPublicNoticeForm = ({ applySearch, generateXML, searchCriteria, onGridReady }) => {

// const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom);
const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom);
@@ -146,6 +146,7 @@ const SearchPublicNoticeForm = ({ applySearch, generateXML, searchCriteria }) =>
<Button
variant="contained"
type="submit"
disabled={onGridReady}
>
Preview
</Button>


+ 14
- 5
src/pages/GFMIS/index.js Ver fichero

@@ -35,6 +35,7 @@ const Index = () => {
// dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)),
});
const [onReady, setOnReady] = React.useState(false);
const [onGridReady, setGridOnReady] = React.useState(false);

React.useEffect(() => {
setOnReady(true);
@@ -50,7 +51,7 @@ const Index = () => {
dateFrom: input.dateFrom,
},
onSuccess: (responseData) => {
console.log(responseData)
// console.log(responseData)
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(responseData, 'application/xml');
// Get the DCBHeader element
@@ -75,7 +76,7 @@ const Index = () => {
const updatedXmlString = new XMLSerializer().serializeToString(xmlDoc);
const filename = xmlDoc.querySelector('FileHeader').getAttribute('H_Filename');
console.log(updatedXmlString)
// console.log(updatedXmlString)
const blob = new Blob([updatedXmlString], { type: 'application/xml' });
// Create a download link
const link = document.createElement('a');
@@ -97,9 +98,14 @@ const Index = () => {


function applySearch(input) {
setGridOnReady(true)
setSearchCriteria(input);
}

function applyGridOnReady(input) {
setGridOnReady(input);
}

function generateXML(input) {
downloadXML(input);
}
@@ -121,9 +127,10 @@ const Index = () => {
{/*row 1*/}
<Grid item xs={12} md={12} lg={12} sx={{mb:-1}}>
<SearchForm
applySearch={applySearch}
generateXML={generateXML}
searchCriteria={searchCriteria}
applySearch={applySearch}
generateXML={generateXML}
searchCriteria={searchCriteria}
onGridReady={onGridReady}
/>
</Grid>
{/*row 2*/}
@@ -135,6 +142,8 @@ const Index = () => {
>
<EventTable
searchCriteria={searchCriteria}
applyGridOnReady={applyGridOnReady}
applySearch={applySearch}
/>
</MainCard>
</Grid>


+ 8
- 3
src/pages/GazetteIssue/DataGrid.js Ver fichero

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

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

export default function GazetteIssueTable({ searchCriteria }) {
export default function GazetteIssueTable({ searchCriteria, applyGridOnReady }) {
const [_searchCriteria, set_searchCriteria] = React.useState(searchCriteria);

React.useEffect(() => {
@@ -100,10 +100,15 @@ export default function GazetteIssueTable({ searchCriteria }) {
customPageSize={10}
// onRowDoubleClick={handleRowDoubleClick}
getRowHeight={() => 'auto'}
doLoad={{
applyGridOnReady={applyGridOnReady}
// doLoad={{
// url: GET_ISSUE,
// params: _searchCriteria,
// }}
doLoad={React.useMemo(() => ({
url: GET_ISSUE,
params: _searchCriteria,
}}
}), [_searchCriteria])}
/>
</div>
);

+ 2
- 2
src/pages/GazetteIssue/ExportForm.js Ver fichero

@@ -27,9 +27,9 @@ const SearchGazetteIssueForm = ({ applyExport, comboData, waitDownload}) => {
handleSubmit } = useForm()

const onSubmit = () => {
console.log(selectedYear)
// console.log(selectedYear)
if (selectedYear !=null && Object.keys(selectedYear).length>0){
console.log("okkkkkkkkkkkkkkkk")
// console.log("okkkkkkkkkkkkkkkk")
const temp = {
year: selectedYear.label,
};


+ 2
- 1
src/pages/GazetteIssue/SearchForm.js Ver fichero

@@ -16,7 +16,7 @@ import {ThemeProvider} from "@emotion/react";
// ==============================|| DASHBOARD - DEFAULT ||============================== //


const SearchGazetteIssueForm = ({ applySearch, comboData}) => {
const SearchGazetteIssueForm = ({ applySearch, comboData, onGridReady}) => {
const [selectedYear, setSelectedYear] = React.useState([]);
// const [defaultYear, setDefaultYear] = React.useState(searchCriteria.year);
const [comboList, setComboList] = React.useState([]);
@@ -114,6 +114,7 @@ const SearchGazetteIssueForm = ({ applySearch, comboData}) => {
<Button
variant="contained"
type="submit"
disabled={onGridReady}
>
Search
</Button>


+ 41
- 29
src/pages/GazetteIssue/index.js Ver fichero

@@ -31,6 +31,7 @@ import {PNSPS_LONG_BUTTON_THEME} from "themes/buttonConst";
import {ThemeProvider} from "@emotion/react";
import { dateStr_Year } from "utils/DateUtils";
import { notifySaveSuccess } from 'utils/CommonFunction';
import { isGrantedAny } from "auth/utils";

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

@@ -38,6 +39,8 @@ const Index = () => {
const [comboData, setComboData] = React.useState([]);
const [holidayComboData, setHolidayComboData] = React.useState([]);
const [onReady, setOnReady] = React.useState(false);
const [onGridReady, setGridOnReady] = React.useState(false);

const [onSearchReady, setOnSearchReady] = React.useState(false);
const [onExportReady, setOnExportReady] = React.useState(false);
const [searchCriteria, setSearchCriteria] = React.useState({
@@ -89,6 +92,7 @@ const Index = () => {
}

function applySearch(input) {
setGridOnReady(true)
setSearchCriteria(input);
}
@@ -96,6 +100,10 @@ const Index = () => {
setExportCriteria(input);
}

function applyGridOnReady(input) {
setGridOnReady(input);
}

React.useEffect(() => {
if (Object.keys(exportCriteria).length > 0) {
// console.log(exportCriteria)
@@ -185,40 +193,43 @@ const Index = () => {
/>
</Grid>
}
<Grid item xs={12} md={12} lg={6} width="100%">
<Stack direction="row" justifyContent="flex-start" alignItems="center" spacing={2} sx={{ml:2,mt:1}} >
<ThemeProvider theme={PNSPS_LONG_BUTTON_THEME}>
<input
id="uploadFileBtn"
name="file"
type="file"
accept=".xlsx"
style={{ display: 'none' }}
disabled={waitImport}
onChange={(event) => {
readFile(event)
}}
/>
<label htmlFor="uploadFileBtn">
<Button
component="span"
variant="contained"
size="large"
{isGrantedAny(["MAINTAIN_GAZETTE_ISSUE"]) ?
<Grid item xs={12} md={12} lg={6} width="100%">
<Stack direction="row" justifyContent="flex-start" alignItems="center" spacing={2} sx={{ml:2,mt:1}} >
<ThemeProvider theme={PNSPS_LONG_BUTTON_THEME}>
<input
id="uploadFileBtn"
name="file"
type="file"
accept=".xlsx"
style={{ display: 'none' }}
disabled={waitImport}
>
<Typography variant="h5">Upload Files</Typography>
</Button>
</label>
</ThemeProvider>
</Stack>
</Grid>
onChange={(event) => {
readFile(event)
}}
/>
<label htmlFor="uploadFileBtn">
<Button
component="span"
variant="contained"
size="large"
disabled={waitImport}
>
<Typography variant="h5">Upload Files</Typography>
</Button>
</label>
</ThemeProvider>
</Stack>
</Grid>
:null
}
{/*row 1*/}
<Grid item xs={12} md={12} lg={12} width="100%">
<SearchForm
applySearch={applySearch}
comboData={comboData}
onGridReady={onGridReady}
/>
</Grid>
{/*row 2*/}
@@ -230,7 +241,8 @@ const Index = () => {
content={false}
>
<GazetteIssueTable
searchCriteria={searchCriteria}
searchCriteria={searchCriteria}
applyGridOnReady={applyGridOnReady}
/>
</MainCard>
</Grid>


+ 7
- 2
src/pages/Holiday/DataGrid.js Ver fichero

@@ -9,13 +9,13 @@ import { dateStr } from "utils/DateUtils";

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

export default function HolidayTable({ recordList }) {
export default function HolidayTable({ recordList, applyGridOnReady }) {
const [rows, setRows] = React.useState(recordList);

// const navigate = useNavigate()

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

@@ -48,8 +48,13 @@ export default function HolidayTable({ recordList }) {
rows={rows}
columns={columns}
customPageSize={20}
applyGridOnReady={applyGridOnReady}
// onRowDoubleClick={handleRowDoubleClick}
getRowHeight={() => 'auto'}
// doLoad={React.useMemo(() => ({
// url: LIST_PROOF,
// params: _searchCriteria,
// }), [_searchCriteria])}
/>
</div>
);

+ 2
- 1
src/pages/Holiday/SearchForm.js Ver fichero

@@ -16,7 +16,7 @@ import {ThemeProvider} from "@emotion/react";
// ==============================|| DASHBOARD - DEFAULT ||============================== //


const SearchHolidayForm = ({ applySearch, comboData}) => {
const SearchHolidayForm = ({ applySearch, comboData, onGridReady}) => {
const [selectedYear, setSelectedYear] = React.useState([]);
// const [defaultYear, setDefaultYear] = React.useState(searchCriteria.year);
const [comboList, setComboList] = React.useState([]);
@@ -114,6 +114,7 @@ const SearchHolidayForm = ({ applySearch, comboData}) => {
<Button
variant="contained"
type="submit"
disabled={onGridReady}
>
Search
</Button>


+ 35
- 24
src/pages/Holiday/index.js Ver fichero

@@ -32,6 +32,7 @@ import {PNSPS_LONG_BUTTON_THEME} from "themes/buttonConst";
import {ThemeProvider} from "@emotion/react";
import { dateStr_Year } from "utils/DateUtils";
import { notifySaveSuccess } from 'utils/CommonFunction';
import { isGrantedAny } from "auth/utils";

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

@@ -41,6 +42,8 @@ const Index = () => {
const [comboData, setComboData] = React.useState([]);
const [onReady, setOnReady] = React.useState(false);
const [onSearchReady, setOnSearchReady] = React.useState(false);
const [onGridReady, setGridOnReady] = React.useState(false);

// const navigate = useNavigate()
const [searchCriteria, setSearchCriteria] = React.useState({
year: dateStr_Year(new Date()),
@@ -97,9 +100,14 @@ const Index = () => {
}

function applySearch(input) {
setGridOnReady(true)
setSearchCriteria(input);
}

function applyGridOnReady(input) {
setGridOnReady(input);
}

React.useEffect(() => {
if (attachments.length > 0) {
importHoliday();
@@ -187,31 +195,32 @@ const Index = () => {
</Button>
</label>
</ThemeProvider>
<ThemeProvider theme={PNSPS_LONG_BUTTON_THEME}>
<input
id="uploadFileBtn"
name="file"
type="file"
accept=".xlsx"
style={{ display: 'none' }}
disabled={waitImport}
onChange={(event) => {
readFile(event)
}}
/>
<label htmlFor="uploadFileBtn">
<Button
component="span"
variant="contained"
size="large"
{isGrantedAny(["MAINTAIN_GAZETTE_ISSUE"]) ?
<ThemeProvider theme={PNSPS_LONG_BUTTON_THEME}>
<input
id="uploadFileBtn"
name="file"
type="file"
accept=".xlsx"
style={{ display: 'none' }}
disabled={waitImport}
>
<Typography variant="h5">Upload Files</Typography>
</Button>
</label>
</ThemeProvider>
onChange={(event) => {
readFile(event)
}}
/>
<label htmlFor="uploadFileBtn">
<Button
component="span"
variant="contained"
size="large"
disabled={waitImport}
>
<Typography variant="h5">Upload Files</Typography>
</Button>
</label>
</ThemeProvider>
:null
}
</Stack>
</Grid>

@@ -222,6 +231,7 @@ const Index = () => {
// generateXML={generateXML}
searchCriteria={searchCriteria}
comboData={comboData}
onGridReady={onGridReady}
/>
</Grid>
{/*row 2*/}
@@ -234,6 +244,7 @@ const Index = () => {
>
<HolidayTable
recordList={record}
applyGridOnReady={applyGridOnReady}
/>
</MainCard>
</Grid>


+ 121
- 0
src/pages/JVM/index.js Ver fichero

@@ -0,0 +1,121 @@
// import { useState } from 'react';

// material-ui
import {
Grid,
Typography,
Stack,
Paper,
Box,
CircularProgress,
Button
} from '@mui/material';
import * as React from "react";
import { GET_JVM_INFO } from "utils/ApiPathConst";
import axios from "axios";

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

const JVMDefault = () => {
const [jvmInfo, setJvmInfo] = React.useState(null);
const [loading, setLoading] = React.useState(true);
const [error, setError] = React.useState(null);
const fetchJvmInfo = () => {
setLoading(true);
setError(null);
axios.get(`${GET_JVM_INFO}`)
.then((response) => {
if (response.status === 200) {
console.log(response)
setJvmInfo(response.data);
}
})
.catch(error => {
setError(error);
setLoading(false);
});
};

React.useEffect(() => {
localStorage.setItem('searchCriteria', "");
setLoading(false);
}, []);

React.useEffect(() => {
if(jvmInfo != null) {
if (Object.keys(jvmInfo).length > 0 && jvmInfo !== undefined) {
setLoading(false);
}
}
}, [jvmInfo]);
const BackgroundHead = {
backgroundImage: `url(${titleBackgroundImg})`,
width: '100%',
height: '100%',
backgroundSize: 'contain',
backgroundRepeat: 'no-repeat',
backgroundColor: '#0C489E',
backgroundPosition: 'right'
};

return (
<Grid container sx={{ minHeight: '87vh', backgroundColor: "backgroundColor.default" }} direction="column">
<Grid item xs={12}>
<div style={BackgroundHead}>
<Stack direction="row" height='70px' justifyContent="space-between" alignItems="center">
<Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0C489E" }}>
JVM Information
</Typography>
</Stack>
</div>
</Grid>
<Grid item xs={12} ml={15} mb={2} mt={2}>
<Button
size="large"
variant="contained"
type="submit"
sx={{
textTransform: 'capitalize',
alignItems: 'end'
}}
onClick={fetchJvmInfo}
disabled={loading}
>
<Typography variant="h5">JVM Info</Typography>
</Button>
</Grid>
<Grid item xs={12} ml={15} mb={2} mt={2}>
<Paper elevation={3} sx={{ p: 2, bgcolor: 'background.paper' }}>
{loading ? (
<Box display="flex" justifyContent="center" alignItems="center" minHeight={200}>
<CircularProgress />
</Box>
) : error ? (
<Typography color="error">Error: {error.message}</Typography>
) : jvmInfo ? (
<Box
component="pre"
sx={{
p: 2,
borderRadius: 1,
bgcolor: 'grey.100',
overflow: 'auto',
maxHeight: 400,
fontSize: '0.875rem',
lineHeight: 1.6
}}
>
{JSON.stringify(jvmInfo, null, 2)}
</Box>
) : (
<Typography>No data available</Typography>
)}
</Paper>
</Grid>
</Grid>
);
};

export default JVMDefault;

+ 38
- 22
src/pages/Message/Search/DataGrid.js Ver fichero

@@ -5,13 +5,21 @@ import { useNavigate } from "react-router-dom";
import { FiDataGrid } from "components/FiDataGrid";
import {useIntl} from "react-intl";
import { clickableLink } from 'utils/CommonFunction';
import {GET_MSG_LIST} from "utils/ApiPathConst";

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

export default function MsgTable({ recordList }) {
const [rows, setRows] = React.useState(recordList);
export default function MsgTable({ searchCriteria, applyGridOnReady, applySearch}) {
const navigate = useNavigate()
const intl = useIntl();

const [_searchCriteria, set_searchCriteria] = React.useState(searchCriteria);
React.useEffect(() => {
set_searchCriteria(searchCriteria);
}, [searchCriteria]);

const _sx = {
padding: "4 2 4 2",
boxShadow: 1,
@@ -25,48 +33,56 @@ export default function MsgTable({ recordList }) {
'& .MuiDataGrid-footerContainer': {
border: 1,
borderColor: "#EEE"
}
},
"& .MuiDataGrid-columnHeaderTitle": {
whiteSpace: "normal",
lineHeight: "normal"
},
"& .MuiDataGrid-columnHeader": {
// Forced to use important since overriding inline styles
height: "unset !important"
},
}

React.useEffect(() => {
setRows(recordList);
}, [recordList]);

const handleEditClick = (params) => () => {
navigate('/msg/details/' + params.row.id);
};

const columns = [
{
id: 'sentDate',
field: 'sentDate',
headerName: intl.formatMessage({id: 'date'}),
width: 160,
renderCell: (params) => {
return DateUtils.datetimeStr(params.row.sentDate);
width: 170,
valueGetter: (params) => {
return DateUtils.datetimeStr(params?.value);
},
},
{
field: 'actions',
headerName: intl.formatMessage({id: 'payId'}),
field: 'subject',
headerName: intl.formatMessage({id: 'subject'}),
flex: 1 ,
cellClassName: 'actions',
cellClassName: 'subject',
renderCell: (params) => {
return clickableLink('/msg/details/' + params.row.id, params.row.subject);
},
},
];

function handleEditClick(params) {
navigate('/msg/details/' + params.row.id);
}

return (
<div style={{ minHeight: 400, width: '100%' }}>
<div style={{ width: '100%', overflowX: 'auto'}}>

<FiDataGrid
sx={_sx}
rowHeight={80}
rows={rows}
columns={columns}
customPageSize={20}
customPageSize={10}
getRowHeight={() => 'auto'}
onRowDoubleClick={handleEditClick}
applyGridOnReady={applyGridOnReady}
applySearch={applySearch}
doLoad={React.useMemo(() => ({
url: GET_MSG_LIST,
params: _searchCriteria,
}), [_searchCriteria])}
/>
</div>
);


+ 5
- 2
src/pages/Message/Search/SearchForm.js Ver fichero

@@ -21,7 +21,7 @@ import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs";
// ==============================|| DASHBOARD - DEFAULT ||============================== //


const SearchForm = ({ applySearch, searchCriteria }) => {
const SearchForm = ({ applySearch, searchCriteria, onGridReady }) => {
const intl = useIntl();
const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom);
const [maxDate, setMaxDate] = React.useState(searchCriteria.dateTo);
@@ -64,7 +64,7 @@ const SearchForm = ({ applySearch, searchCriteria }) => {
sentDateTo = DateUtils.dateValue(toDateValue)
}
const temp = {
keywork: data.keywork,
keyword: data.keyword,
dateFrom: sentDateFrom,
dateTo: sentDateTo,
};
@@ -75,6 +75,8 @@ const SearchForm = ({ applySearch, searchCriteria }) => {
setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)))
setMaxDate(DateUtils.dateValue(new Date()))
reset();
localStorage.setItem('searchCriteria',"")

}


@@ -196,6 +198,7 @@ const SearchForm = ({ applySearch, searchCriteria }) => {
<Button
variant="contained"
type="submit"
disabled={onGridReady}
aria-label={intl.formatMessage({id: 'submit'})}
>
<FormattedMessage id="submit"/>


+ 46
- 24
src/pages/Message/Search/index.js Ver fichero

@@ -5,9 +5,9 @@ import {
Stack
} from '@mui/material';
import MainCard from "components/MainCard";
import * as UrlUtils from "utils/ApiPathConst";
// import * as UrlUtils from "utils/ApiPathConst";
import * as React from "react";
import * as HttpUtils from "utils/HttpUtils";
// import * as HttpUtils from "utils/HttpUtils";
import * as DateUtils from "utils/DateUtils";

import Loadable from 'components/Loadable';
@@ -16,6 +16,7 @@ const SearchForm = Loadable(React.lazy(() => import('./SearchForm')));
const EventTable = Loadable(React.lazy(() => import('./DataGrid')));
import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png'
import {FormattedMessage} from "react-intl";
import { getSearchCriteria } from "auth/utils";

const BackgroundHead = {
backgroundImage: `url(${titleBackgroundImg})`,
@@ -31,41 +32,58 @@ const BackgroundHead = {

const Index = () => {

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

React.useEffect(() => {
setOnReady(true);
}, [record]);
if (Object.keys(getSearchCriteria(window.location.pathname)).length>0){
setSearchCriteria(getSearchCriteria(window.location.pathname))
}else{
localStorage.setItem('searchCriteria',"")
setSearchCriteria({
dateTo: DateUtils.dateValue(new Date()),
dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)),
})
}
}, []);

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

function loadGrid(){
HttpUtils.get({
url: UrlUtils.GET_MSG_LIST,
params: searchCriteria,
onSuccess: function(responseData){
setRecord(responseData);
}
});
}
// function loadGrid(){
// HttpUtils.get({
// url: UrlUtils.GET_MSG_LIST,
// params: searchCriteria,
// onSuccess: function(responseData){
// setRecord(responseData);
// }
// });
// }


function applySearch(input) {
setGridOnReady(true)
setSearchCriteria(input);
localStorage.setItem('searchCriteria', JSON.stringify({path:window.location.pathname,data:input}))
}

function applyGridOnReady(input) {
setGridOnReady(input);
}

return (
!onReady ?
<LoadingComponent/>
<Grid container sx={{ minHeight: '95vh', mb: 3 }} direction="column" justifyContent="center" alignItems="center">
<Grid item>
<LoadingComponent />
</Grid>
</Grid>
:
<Grid container sx={{minHeight: '85vh',backgroundColor:'#ffffff'}} direction="column">
<Grid container sx={{ minHeight: '95vh',backgroundColor: 'backgroundColor.default' }} direction="column">
<Grid item xs={12}>
<div style={BackgroundHead}>
<Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center">
@@ -78,8 +96,9 @@ const Index = () => {
{/*row 1*/}
<Grid item xs={12} md={12} lg={12}>
<SearchForm
applySearch={applySearch}
searchCriteria={searchCriteria}
applySearch={applySearch}
searchCriteria={searchCriteria}
onGridReady={onGridReady}
/>
</Grid>
{/*row 2*/}
@@ -90,7 +109,10 @@ const Index = () => {
sx={{width: "-webkit-fill-available"}}
>
<EventTable
recordList={record}
// recordList={record}
searchCriteria={searchCriteria}
applyGridOnReady={applyGridOnReady}
applySearch={applySearch}
/>
</MainCard>
</Grid>


+ 142
- 85
src/pages/Organization/DetailPage/OrganizationCard.js Ver fichero

@@ -14,6 +14,7 @@ import { useEffect, useState, lazy } from "react";
import * as DateUtils from 'utils/DateUtils';
import * as HttpUtils from 'utils/HttpUtils';
import * as UrlUtils from "utils/ApiPathConst";
import {checkMarkAsCreditClient} from 'utils/Utils';
import * as FieldUtils from "utils/FieldUtils";
import * as ComboData from "utils/ComboData";
const LoadingComponent = Loadable(lazy(() => import('../../extra-pages/LoadingComponent')));
@@ -24,18 +25,20 @@ import { PNSPS_BUTTON_THEME } from "themes/buttonConst";
import { ThemeProvider } from "@emotion/react";
import { isGrantedAny } from "auth/utils";

import {DatePicker} from "@mui/x-date-pickers/DatePicker";
import { DatePicker } from "@mui/x-date-pickers/DatePicker";
import dayjs from "dayjs";
import {DemoItem} from "@mui/x-date-pickers/internals/demo";
import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider";
import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs";
import { DemoItem } from "@mui/x-date-pickers/internals/demo";
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
// ==============================|| DASHBOARD - DEFAULT ||============================== //
const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => {
const intl = useIntl();
const [creditorConfirmPopUp, setCreditorConfirmPopUp] = React.useState(false);
const [nonCreditorConfirmPopUp, setNonCreditorConfirmPopUp] = React.useState(false);
const [afterSendPopUp, setAfterSendPopUp] = React.useState(false);

const [currentUserData, setCurrentUserData] = useState({});
const [overduePublicNotice, setOverduePublicNotice] = useState(0);
const [editMode, setEditMode] = useState(false);
const [createMode, setCreateMode] = useState(false);
const [onReady, setOnReady] = useState(false);
@@ -44,7 +47,7 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => {
const [fromDate, setFromDate] = React.useState(null);
const [currentFromDate, setCurrentFromDate] = React.useState(null);
const [fromDateValue, setFromDateValue] = React.useState(null);
const {register, handleSubmit, reset} = useForm()
const { register, handleSubmit, reset } = useForm()

React.useEffect(() => {
setFromDateValue(fromDate);
@@ -54,14 +57,14 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => {
//if state data are ready and assign to different field
// console.log(currentApplicationDetailData)
if (Object.keys(currentUserData).length > 0) {
console.log(currentUserData)
if(DateUtils.dateValue(currentUserData.brExpiryDate)>DateUtils.dateValue(minDate)){
// console.log(currentUserData)
if (DateUtils.dateValue(currentUserData.brExpiryDate) > DateUtils.dateValue(minDate)) {
setFromDate(currentUserData.brExpiryDate);
}else{
} else {
setCurrentFromDate(currentUserData.brExpiryDate);
// setErrorMsg("Please select a date after today.")
}
setOnReady(true);
}
}, [currentUserData]);
@@ -115,7 +118,7 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => {
let sentDateFrom = "";
if (fromDateValue == null) {
setErrorMsg(intl.formatMessage({ id: 'pleaseFillInBusinessRegCertValidityDate' }))
}else{
} else {
sentDateFrom = DateUtils.dateValue(fromDateValue)
HttpUtils.post({
url: UrlUtils.POST_ORG_SAVE_PATH,
@@ -123,7 +126,7 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => {
id: id > 0 ? id : null,
enCompanyName: values.enCompanyName,
chCompanyName: values.chCompanyName,
orgShortName: values.orgShortName==="N/A"?"":values.orgShortName,
orgShortName: values.orgShortName === "N/A" ? "" : values.orgShortName,
brNo: values.brNo,
// brExpiryDate: values.brExpiryDate,
brExpiryDate: sentDateFrom,
@@ -188,9 +191,9 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => {

const onSubmit = (data) => {
let sentOrgShortName = "";
if(data.orgShortName!=null && data.orgShortName!="" && data.orgShortName!="N/A"){
sentOrgShortName = data.orgShortName
if (sentOrgShortName.length <=24){
if (data.orgShortName != null && data.orgShortName != "" && data.orgShortName != "N/A") {
sentOrgShortName = data.orgShortName
if (sentOrgShortName.length <= 24) {
const temp = {
orgShortName: sentOrgShortName,
};
@@ -230,6 +233,17 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => {
});
}

const sendDn_Overdue = () => {
setNonCreditorConfirmPopUp(false);
HttpUtils.get({
url: UrlUtils.GET_SEND_OVERDUE_CREDITOR_LIST + "/" + id,
onSuccess: (responseData) => {
setOverduePublicNotice(responseData.overduePublicNotice);
setAfterSendPopUp(true);
}
});
}

return (
<MainCard elevation={0}
border={false}
@@ -299,29 +313,47 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => {

{
currentUserData.creditor ?
<Grid item sx={{ ml: 3, mr: 3 }}>
<ThemeProvider theme={PNSPS_BUTTON_THEME}>
<Button
variant="contained"
color="error"
onClick={() => setNonCreditorConfirmPopUp(true)}
>
Mark as Non-Credit Client
</Button>
</ThemeProvider>
</Grid>
!checkMarkAsCreditClient()?
<Grid item sx={{ ml: 3, mr: 3 }}>
<ThemeProvider theme={PNSPS_BUTTON_THEME}>
<Button
variant="contained"
color="error"
onClick={() => setNonCreditorConfirmPopUp(true)}
>
Mark as Non-Credit Client
</Button>
</ThemeProvider>
</Grid>:null
:
<Grid item sx={{ ml: 3, mr: 3 }}>
<ThemeProvider theme={PNSPS_BUTTON_THEME}>
<Button
variant="contained"
color="orange"
onClick={() => setCreditorConfirmPopUp(true)}
>
Mark as Credit Client
</Button>
</ThemeProvider>
</Grid>
<>
{!checkMarkAsCreditClient()?
<Grid item sx={{ ml: 3, mr: 3 }}>
<ThemeProvider theme={PNSPS_BUTTON_THEME}>
<Button
variant="contained"
color="orange"
onClick={() => setCreditorConfirmPopUp(true)}
>
Mark as Credit Client
</Button>
</ThemeProvider>
</Grid>:null
}
{ isGrantedAny("MAINTAIN_DEMANDNOTE")?
<Grid item sx={{ ml: 3, mr: 3 }}>
<ThemeProvider theme={PNSPS_BUTTON_THEME}>
<Button
variant="contained"
color="primary"
onClick={() => sendDn_Overdue(true)}
>
Generate O&#47;S DN List
</Button>
</ThemeProvider>
</Grid> : null
}
</>
}
</>
}
@@ -357,18 +389,20 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => {
})}
</Grid>

<Grid item xs={12} lg={4} >
<FormControlLabel
control={<Checkbox checked={formik.values.creditor} />}
label="is Credit Client"
name="creditor"
onChange={() => {
formik.setFieldValue("creditor", !formik.values.creditor);
}}
disabled={true}
//disabled={!editMode && !createMode}
/>
</Grid>
{!checkMarkAsCreditClient()?
<Grid item xs={12} lg={4} >
<FormControlLabel
control={<Checkbox checked={formik.values.creditor} />}
label="is Credit Client"
name="creditor"
onChange={() => {
formik.setFieldValue("creditor", !formik.values.creditor);
}}
disabled={true}
//disabled={!editMode && !createMode}
/>
</Grid>:null
}

<Grid item xs={12} lg={4} ></Grid>

@@ -396,18 +430,18 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => {
<Typography variant="pnspsFormParagraphBold">{FieldUtils.notNullFieldLabel("Expiry Date:")}</Typography>
</Grid>
<Grid item xs={12} md={6} lg={6}>
{(!editMode && !createMode)?
{(!editMode && !createMode) ?
<TextField
fullWidth
id="currentExDate"
// error={(fromDate===null)}
// type="date"
name="currentExDate"
value={fromDate!=null?DateUtils.dateStr(fromDate):DateUtils.dateStr(currentFromDate)}
value={fromDate != null ? DateUtils.dateStr(fromDate) : DateUtils.dateStr(currentFromDate)}
disabled={true}
/>:
/> :
<LocalizationProvider dateAdapter={AdapterDayjs}>
<DemoItem components={['DatePicker']}>
<DemoItem components={['DatePicker']}>
<DatePicker
id="brExpiryDate"
name="brExpiryDate"
@@ -426,9 +460,9 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => {
onChange={(newValue) => {
// console.log(newValue)
// setErrorMsg("")
if(DateUtils.dateValue(newValue)>DateUtils.dateValue(new Date())){
if (DateUtils.dateValue(newValue) > DateUtils.dateValue(new Date())) {
setFromDate(newValue);
}else{
} else {
// setErrorMsg("Please select a date after today.")
}
}}
@@ -438,19 +472,20 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => {
}
</Grid>
{
fromDate==null?
(!editMode && !createMode)?
<FormHelperText error id="helper-text-date">
Please select a date after today.
</FormHelperText>
:
fromDate == null ?
(!editMode && !createMode) ?
// <FormHelperText error id="helper-text-date">
// Please select a date after today.
// </FormHelperText>
null
:
<FormHelperText error id="helper-text-date">
{intl.formatMessage({ id: 'pleaseFillInBusinessRegCertValidityDate' })}
</FormHelperText>
:
:
null
}
}
</Grid>

</Grid>
@@ -488,27 +523,6 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => {
})}
</Grid>

<Grid item xs={12} lg={4} >
{FieldUtils.getComboField({
label: FieldUtils.notNullFieldLabel("Country:"),
valueName: "country",
disabled: (!editMode && !createMode),
dataList: ComboData.country,
getOptionLabel: (option) => option.type ? intl.formatMessage({ id: option.type }) : "",
form: formik
})}
</Grid>

<Grid item xs={12} lg={4} >
{FieldUtils.getComboField({
label: FieldUtils.notNullFieldLabel("District:"),
valueName: "district",
disabled: (!editMode && !createMode),
dataList: ComboData.district,
getOptionLabel: (option) => option.type ? intl.formatMessage({ id: option.type }) : "",
form: formik
})}
</Grid>
{
currentUserData.creditor ?
<Grid item xs={12} lg={4} >
@@ -533,6 +547,28 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => {
})}
</Grid>

<Grid item xs={12} lg={12} >
{FieldUtils.getProfileComboField({
label: "",
valueName: "district",
disabled: (!editMode && !createMode),
dataList: ComboData.district,
getOptionLabel: (option) => option.type ? intl.formatMessage({ id: option.type }) : "",
form: formik
})}
</Grid>

<Grid item xs={12} lg={12} >
{FieldUtils.getProfileComboField({
label: "",
valueName: "country",
disabled: true,
dataList: ComboData.country,
getOptionLabel: (option) => option.type ? intl.formatMessage({ id: option.type }) : "",
form: formik
})}
</Grid>

<Grid item lg={12} ></Grid>

</Grid>
@@ -566,7 +602,7 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => {
{...register("orgShortName")}
id='orgShortName'
label="Organisation Short Name"
defaultValue={currentUserData.orgShortName!="N/A"?currentUserData.orgShortName:""}
defaultValue={currentUserData.orgShortName != "N/A" ? currentUserData.orgShortName : ""}
InputLabelProps={{
shrink: true
}}
@@ -605,6 +641,27 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => {
</DialogActions>
</Dialog>
</div>
<div>
<Dialog
open={afterSendPopUp}
onClose={() => setAfterSendPopUp(false)}
PaperProps={{
sx: {
minWidth: '40vw',
maxWidth: { xs: '90vw', s: '90vw', m: '70vw', lg: '70vw' },
maxHeight: { xs: '90vh', s: '70vh', m: '70vh', lg: '60vh' }
}
}}
>
<DialogTitle><Typography variant="h3">Info</Typography></DialogTitle>
<DialogContent style={{ display: 'flex', }}>
<Typography variant="h4" style={{ padding: '16px' }}>Overdue Public Notice count: {overduePublicNotice}</Typography>
</DialogContent>
<DialogActions>
<Button onClick={() => setAfterSendPopUp(false)}><Typography variant="h5">OK</Typography></Button>
</DialogActions>
</Dialog>
</div>
</MainCard>
);
};


+ 51
- 55
src/pages/Organization/DetailPage/OrganizationPubCard.js Ver fichero

@@ -1,6 +1,6 @@
// material-ui
import {
Grid, Button,
Grid, Button,
// Checkbox, FormControlLabel,
Typography,
Dialog, DialogTitle, DialogContent, DialogActions,
@@ -20,9 +20,9 @@ const LoadingComponent = Loadable(lazy(() => import('../../extra-pages/LoadingCo
import Loadable from 'components/Loadable';
import { lazy } from 'react';
import { notifySaveSuccess } from 'utils/CommonFunction';
import {FormattedMessage, useIntl} from "react-intl";
import {PNSPS_BUTTON_THEME} from "themes/buttonConst";
import {ThemeProvider} from "@emotion/react";
import { FormattedMessage, useIntl } from "react-intl";
import { PNSPS_BUTTON_THEME } from "themes/buttonConst";
import { ThemeProvider } from "@emotion/react";

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

@@ -54,19 +54,19 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => {
enableReinitialize: true,
initialValues: currentUserData,
validationSchema: yup.object().shape({
addressLine1: yup.string().max(40).required(displayErrorMsg(intl.formatMessage({id: 'validateAddressLine1'}))),
addressLine2: yup.string().max(40, displayErrorMsg(intl.formatMessage({id: 'noMoreThen40Words'}))),
addressLine3: yup.string().max(40, displayErrorMsg(intl.formatMessage({id: 'noMoreThen40Words'}))),
tel_countryCode: yup.string().min(3, displayErrorMsg(intl.formatMessage({id: 'requireDialingCode'}))),
phoneNumber: yup.string().min(8, displayErrorMsg(intl.formatMessage({id: 'requiredValidNumber'}))).required(displayErrorMsg(intl.formatMessage({id: 'requireContactNumber'}))),
addressLine1: yup.string().max(40).required(displayErrorMsg(intl.formatMessage({ id: 'validateAddressLine1' }))),
addressLine2: yup.string().max(40, displayErrorMsg(intl.formatMessage({ id: 'noMoreThen40Words' }))),
addressLine3: yup.string().max(40, displayErrorMsg(intl.formatMessage({ id: 'noMoreThen40Words' }))),
tel_countryCode: yup.string().min(3, displayErrorMsg(intl.formatMessage({ id: 'requireDialingCode' }))),
phoneNumber: yup.string().min(8, displayErrorMsg(intl.formatMessage({ id: 'requiredValidNumber' }))).required(displayErrorMsg(intl.formatMessage({ id: 'requireContactNumber' }))),
faxNumber: yup.string().min(8, displayErrorMsg(intl.formatMessage({ id: 'require8Number' }))).nullable(),
}),
onSubmit: values => {
if (values.country==null){
setErrorMsg(intl.formatMessage({id: 'pleaseFillInCountry'}))
if (values.country == null) {
setErrorMsg(intl.formatMessage({ id: 'pleaseFillInCountry' }))
} else {
if (values.country.type =="hongKong" && values.district == null){
setErrorMsg(intl.formatMessage({id: 'pleaseFillInDistrict'}))
if (values.country.type == "hongKong" && values.district == null) {
setErrorMsg(intl.formatMessage({ id: 'pleaseFillInDistrict' }))
} else {
HttpUtils.post({
url: UrlUtils.POST_PUB_ORG_SAVE_PATH,
@@ -100,9 +100,9 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => {
}
});

useEffect(()=>{
useEffect(() => {
setEditModeFun(editMode);
},[editMode]);
}, [editMode]);

useEffect(() => {
if (Object.keys(userData).length > 0) {
@@ -188,7 +188,7 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => {
onClick={onEditClick}
color="success"
>
< FormattedMessage id="edit" />
< FormattedMessage id="edit" />
</Button>
</ThemeProvider>
</Grid>
@@ -202,11 +202,11 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => {
<LoadingComponent />
:
<Grid container spacing={1}>
<Grid item xs={12}>
{/* <Grid item xs={12}>
<Typography variant="h4" sx={{ mb: 2, mr: 3, borderBottom: "1px solid black" }}>
<FormattedMessage id="organizationDetails" />
</Typography>
</Grid>
</Grid> */}
<Grid item xs={12}>
<FormHelperText error id="helper-text-address1-signup">
<Typography variant="errorMessage1">
@@ -216,27 +216,27 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => {
</Grid>
<Grid item xs={12} lg={4} >
{FieldUtils.getTextField({
label: intl.formatMessage({id: 'brNo'}) + ":",
label: intl.formatMessage({ id: 'brNo' }) + ":",
valueName: "brNo",
disabled: true,
form: formik
})}
</Grid>
<Grid item xs={12} lg={4} >
{/* {FieldUtils.getTextField({
label: intl.formatMessage({id: 'creditorAccount'}) + ":",
valueName: "creditor",
disabled: true,
form: formik
})} */}
{FieldUtils.getTextField({
label: FieldUtils.notNullFieldLabel(intl.formatMessage({ id: 'expiryDate' }) + ":"),
valueName: "brExpiryDate",
disabled: true,
form: formik
})}
</Grid>

<Grid item xs={12} lg={4} ></Grid>

<Grid item xs={12} lg={4} >
{FieldUtils.getTextField({
label: FieldUtils.notNullFieldLabel(intl.formatMessage({id: 'nameEng'}) + ":"),
label: FieldUtils.notNullFieldLabel(intl.formatMessage({ id: 'nameEng' }) + ":"),
valueName: "enCompanyName",
disabled: true,
form: formik
@@ -245,7 +245,7 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => {

<Grid item xs={12} lg={4} >
{FieldUtils.getTextField({
label: intl.formatMessage({id: 'nameChi'}) + ":",
label: intl.formatMessage({ id: 'nameChi' }) + ":",
valueName: "chCompanyName",
disabled: true,
form: formik
@@ -253,17 +253,12 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => {
</Grid>

<Grid item xs={12} lg={4} >
{FieldUtils.getTextField({
label: FieldUtils.notNullFieldLabel(intl.formatMessage({id: 'expiryDate'}) + ":"),
valueName: "brExpiryDate",
disabled: true,
form: formik
})}

</Grid>

<Grid item xs={12} lg={4} >
{FieldUtils.getTextField({
label: FieldUtils.notNullFieldLabel(intl.formatMessage({id: 'contactPerson'}) + ":"),
label: FieldUtils.notNullFieldLabel(intl.formatMessage({ id: 'contactPerson' }) + ":"),
valueName: "contactPerson",
disabled: (!editMode && !createMode),
form: formik
@@ -272,7 +267,7 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => {

<Grid item xs={12} lg={4} >
{FieldUtils.getPhoneField({
label: FieldUtils.notNullFieldLabel(intl.formatMessage({id: 'userContactNumber'}) + ":"),
label: FieldUtils.notNullFieldLabel(intl.formatMessage({ id: 'userContactNumber' }) + ":"),
valueName: {
code: "tel_countryCode",
num: "phoneNumber"
@@ -284,7 +279,7 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => {

<Grid item xs={12} lg={4} >
{FieldUtils.getPhoneField({
label: intl.formatMessage({id: 'contactFaxNumber'}) + ":",
label: intl.formatMessage({ id: 'contactFaxNumber' }) + ":",
valueName: {
code: "fax_countryCode",
num: "faxNumber"
@@ -294,34 +289,35 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => {
})}
</Grid>

<Grid item xs={12} lg={4} >
{FieldUtils.getComboField({
label: FieldUtils.notNullFieldLabel(intl.formatMessage({id: 'country'}) + ":"),
valueName: "country",
<Grid item xs={12} lg={12} >
{FieldUtils.getAddressField({
label: FieldUtils.notNullFieldLabel(intl.formatMessage({ id: 'formAddress' }) + ":"),
valueName: ["addressLine1", "addressLine2", "addressLine3"],
disabled: (!editMode && !createMode),
dataList: ComboData.country,
getOptionLabel: (option) => option.type? intl.formatMessage({ id: option.type }) : "",
form: formik
})}
</Grid>

<Grid item xs={12} lg={4} >
{FieldUtils.getComboField({
label: FieldUtils.notNullFieldLabel(intl.formatMessage({id: 'district'}) + ":"),
<Grid item xs={12} lg={12} >
{FieldUtils.getProfileComboField({
// label: FieldUtils.notNullFieldLabel(""),
label: "",
valueName: "district",
disabled: (!editMode && !createMode),
dataList: ComboData.district,
getOptionLabel: (option) => option.type? intl.formatMessage({ id: option.type }) : "",
getOptionLabel: (option) => option.type ? intl.formatMessage({ id: option.type }) : "",
form: formik
})}
</Grid>


<Grid item xs={12} lg={12} >
{FieldUtils.getAddressField({
label: FieldUtils.notNullFieldLabel(intl.formatMessage({id: 'formAddress'}) + ":"),
valueName: ["addressLine1", "addressLine2", "addressLine3"],
disabled: (!editMode && !createMode),
{FieldUtils.getProfileComboField({
// label: FieldUtils.notNullFieldLabel(""),
label: "",
valueName: "country",
disabled: true,
dataList: ComboData.country,
getOptionLabel: (option) => option.type ? intl.formatMessage({ id: option.type }) : "",
form: formik
})}
</Grid>
@@ -348,7 +344,7 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => {
<Typography variant="h4" style={{ padding: '16px' }}>Are you sure mark as Credit Client?</Typography>
</DialogContent>
<DialogActions>
<Button onClick={() => setCreditorConfirmPopUp(false)}><Typography variant="h5">Cancel</Typography></Button>
<Button onClick={() => setCreditorConfirmPopUp(false)}><Typography variant="h5">Cancel</Typography></Button>
<Button onClick={() => markAsCreditor()}><Typography variant="h5">Confirm</Typography></Button>
</DialogActions>
</Dialog>
@@ -370,7 +366,7 @@ const OrganizationPubCard = ({ userData, loadDataFun, id, setEditModeFun }) => {
<Typography variant="h4" style={{ padding: '16px' }}>Are you sure mark as Non-Credit Client?</Typography>
</DialogContent>
<DialogActions>
<Button onClick={() => setNonCreditorConfirmPopUp(false)}><Typography variant="h5">Cancel</Typography></Button>
<Button onClick={() => setNonCreditorConfirmPopUp(false)}><Typography variant="h5">Cancel</Typography></Button>
<Button onClick={() => markAsNonCreditor()}><Typography variant="h5">Confirm</Typography></Button>
</DialogActions>
</Dialog>


+ 14
- 12
src/pages/Organization/DetailPage_FromUser/OrganizationCard_loadFromUser.js Ver fichero

@@ -310,19 +310,17 @@ const OrganizationCard_loadFromUser = ({ userData, userId }) => {
})}
</Grid>

<Grid item xs={12} lg={4}>
{FieldUtils.getComboField({
label: FieldUtils.notNullFieldLabel("Country:"),
valueName: "country",
dataList: ComboData.country,
getOptionLabel: (option) => option.type ? intl.formatMessage({ id: option.type }) : "",
<Grid item xs={12}>
{FieldUtils.getAddressField({
label: FieldUtils.notNullFieldLabel("Address:"),
valueName: ["addressLine1", "addressLine2", "addressLine3"],
form: formik
})}
</Grid>

<Grid item xs={12} lg={4}>
<Grid item xs={12} lg={12}>
{FieldUtils.getComboField({
label: FieldUtils.notNullFieldLabel("District:"),
label: "",
valueName: "district",
dataList: ComboData.district,
getOptionLabel: (option) => option.type ? intl.formatMessage({ id: option.type }) : "",
@@ -330,13 +328,17 @@ const OrganizationCard_loadFromUser = ({ userData, userId }) => {
})}
</Grid>

<Grid item xs={12}>
{FieldUtils.getAddressField({
label: FieldUtils.notNullFieldLabel("Address:"),
valueName: ["addressLine1", "addressLine2", "addressLine3"],
<Grid item xs={12} lg={12}>
{FieldUtils.getComboField({
label: "",
valueName: "country",
disabled: true,
dataList: ComboData.country,
getOptionLabel: (option) => option.type ? intl.formatMessage({ id: option.type }) : "",
form: formik
})}
</Grid>

</Grid>
}
</form>


+ 30
- 4
src/pages/Organization/SearchPage/OrganizationSearchForm.js Ver fichero

@@ -8,7 +8,7 @@ import {
import MainCard from "components/MainCard";
import { useForm } from "react-hook-form";

import { useState } from "react";
import { useState,useEffect } from "react";
import * as React from "react";

import * as UrlUtils from "utils/ApiPathConst";
@@ -19,11 +19,21 @@ import {ThemeProvider} from "@emotion/react";
// ==============================|| DASHBOARD - DEFAULT ||============================== //


const OrganizationSearchForm = ({ applySearch }) => {
const OrganizationSearchForm = ({ applySearch, onGridReady, searchCriteria }) => {

const [type, setType] = useState([]);
const [creditorSelected, setCreditorSelected] = React.useState(ComboData.CreditorStatus[0]);
const { reset, register, handleSubmit } = useForm()
const [onDownload, setOnDownload] = React.useState(false);
useEffect(() => {
if(searchCriteria.creditor!=undefined){
setCreditorSelected(ComboData.CreditorStatus.find(item => item.type === searchCriteria.creditor.toString()))
}else{
setCreditorSelected(ComboData.CreditorStatus[0]);
}
}, [searchCriteria]);

const onSubmit = (data) => {

let typeArray = [];
@@ -48,12 +58,23 @@ const OrganizationSearchForm = ({ applySearch }) => {
function resetForm() {
setType([]);
setCreditorSelected(ComboData.CreditorStatus[0]);
reset();
reset({
brNo: "",
enCompanyName: "",
chCompanyName: "",
});
}

const doExport=()=>{
setOnDownload(true)
HttpUtils.fileDownload({
url: UrlUtils.GET_ORG_EXPORT
url: UrlUtils.GET_ORG_EXPORT,
onResponse:()=>{
setOnDownload(false)
},
onError:()=>{
setOnDownload(false)
}
});
}

@@ -80,6 +101,7 @@ const OrganizationSearchForm = ({ applySearch }) => {
{...register("brNo")}
id='brNo'
label="BR No."
defaultValue={searchCriteria.brNo}
InputLabelProps={{
shrink: true
}}
@@ -92,6 +114,7 @@ const OrganizationSearchForm = ({ applySearch }) => {
{...register("enCompanyName")}
id="enCompanyName"
label="Name (English)"
defaultValue={searchCriteria.enCompanyName}
InputLabelProps={{
shrink: true
}}
@@ -104,6 +127,7 @@ const OrganizationSearchForm = ({ applySearch }) => {
{...register("chCompanyName")}
id="chCompanyName"
label="Name (Chinese)"
defaultValue={searchCriteria.chCompanyName}
InputLabelProps={{
shrink: true
}}
@@ -148,6 +172,7 @@ const OrganizationSearchForm = ({ applySearch }) => {
<Button
variant="contained"
onClick={doExport}
disabled={onDownload}
>
Export
</Button>
@@ -167,6 +192,7 @@ const OrganizationSearchForm = ({ applySearch }) => {
<Button
variant="contained"
type="submit"
disabled={onGridReady}
>
Submit
</Button>


+ 10
- 4
src/pages/Organization/SearchPage/OrganizationTable.js Ver fichero

@@ -11,7 +11,7 @@ import { clickableLink} from 'utils/CommonFunction';
import {GET_ORG_PATH} from "utils/ApiPathConst";
// ==============================|| EVENT TABLE ||============================== //

export default function OrganizationTable({ searchCriteria }) {
export default function OrganizationTable({ searchCriteria, applyGridOnReady, applySearch}) {
const [_searchCriteria, set_searchCriteria] = React.useState(searchCriteria);
const navigate = useNavigate()

@@ -111,12 +111,18 @@ export default function OrganizationTable({ searchCriteria }) {
<div style={{ height: "fit-content", width: '100%' }}>
<FiDataGrid
columns={columns}
customPageSize={5}
customPageSize={10}
onRowDoubleClick={handleRowDoubleClick}
doLoad={{
applyGridOnReady={applyGridOnReady}
applySearch={applySearch}
// doLoad={{
// url: GET_ORG_PATH,
// params: _searchCriteria,
// }}
doLoad={React.useMemo(() => ({
url: GET_ORG_PATH,
params: _searchCriteria,
}}
}), [_searchCriteria])}
/>
</div>
);


+ 24
- 2
src/pages/Organization/SearchPage/index.js Ver fichero

@@ -5,7 +5,7 @@ import {
import MainCard from "components/MainCard";
import { useEffect, useState } from "react";
import * as React from "react";
import { getSearchCriteria } from "auth/utils";

// import LoadingComponent from "../extra-pages/LoadingComponent";
// import SearchForm from "./OrganizationSearchForm";
@@ -32,13 +32,29 @@ const OrganizationSearchPage = () => {

const [searchCriteria, setSearchCriteria] = useState({});
const [onReady, setOnReady] = useState(false);
const [onGridReady, setGridOnReady] = React.useState(false);

useEffect(() => {
if (Object.keys(getSearchCriteria(window.location.pathname)).length>0){
setSearchCriteria(getSearchCriteria(window.location.pathname))
}else{
localStorage.setItem('searchCriteria',"")
setSearchCriteria({})
}
}, []);

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

function applySearch(input) {
setGridOnReady(true)
setSearchCriteria(input);
localStorage.setItem('searchCriteria', JSON.stringify({path:window.location.pathname,data:input}))
}

function applyGridOnReady(input) {
setGridOnReady(input);
}

return (
@@ -59,7 +75,11 @@ const OrganizationSearchPage = () => {
</Grid>
{/*row 1*/}
<Grid item xs={12} md={12} lg={12} sx={{ mb: -1 }}>
<SearchForm applySearch={applySearch} />
<SearchForm
applySearch={applySearch}
onGridReady={onGridReady}
searchCriteria={searchCriteria}
/>
</Grid>
{/*row 2*/}
<Grid item xs={12} md={12} lg={12}>
@@ -69,6 +89,8 @@ const OrganizationSearchPage = () => {
>
<EventTable
searchCriteria={searchCriteria}
applyGridOnReady={applyGridOnReady}
applySearch={applySearch}
/>
</MainCard>
</Grid>


+ 1
- 1
src/pages/Payment/Details_GLD/DataGrid.js Ver fichero

@@ -43,7 +43,7 @@ export default function SearchPublicNoticeTable({ recordList }) {
flex: 1,
renderCell: (params) => {
let appNo = params.row.appNo;
console.log(params.row)
// console.log(params.row)
return <div style={{ margin: 4, textAlign:"left"}}>Gazette Supplement No. 6 <br/>
{isORGLoggedIn()&&params.row.careOf!=null&&params.row.careOf!=""?<>{params.row.careOf}<br /></>:null}
App No: {appNo}<br/>


+ 10
- 10
src/pages/Payment/Details_GLD/PaymentDetails.js Ver fichero

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

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

React.useEffect(() => {
if (formData != null && formData != undefined && Object.keys(formData).length > 0) {
@@ -89,7 +93,7 @@ const PaymentDetails = ({ formData,doPrint,onDownload }) => {
</Grid>
<Grid item xs={6} md={5} sx={{ml:5, textAlign: "left" }}>
<FormLabel sx={{ color: "#000000" }}>
{data.transDateStr + " (DD/MM/YYYY)"}
{DateUtils.dateFormat(data.transDateStr, intl.formatMessage({id: "dateStrFormat"})) +" ("+intl.formatMessage({id: "dateStrFormat"})+")"}
</FormLabel>
</Grid>
</Grid>
@@ -131,7 +135,7 @@ const PaymentDetails = ({ formData,doPrint,onDownload }) => {
</Grid>
<Grid item xs={6} md={5} sx={{ml:5, textAlign: "left" }}>
<FormLabel sx={{ color: "#000000" }}>
{"HK$ " + FormatUtils.currencyFormat(data.payload?.amount)}
{"$ " + FormatUtils.currencyFormat(data.payload?.amount)}
</FormLabel>
</Grid>
</Grid>
@@ -161,14 +165,10 @@ const PaymentDetails = ({ formData,doPrint,onDownload }) => {
</FormLabel>
</Grid>
<Grid xs={6} md={5} sx={{ml:5,textAlign: "left" }}>
{onDownload?
<LoadingComponent disableText={true} alignItems="flex-start"/>
:
<Button className="printHidden" variant="contained" sx={{ mt:2 }} onClick={doPrint}>
<DownloadIcon/>
<Typography sx={{fontSize: "16px"}}>Download</Typography>
</Button>
}
<Button className="printHidden" variant="contained" disabled={onDownload} sx={{ mt:2 }} onClick={doPrint}>
<DownloadIcon/>
<Typography sx={{fontSize: "16px"}}>Download</Typography>
</Button>
</Grid>
</Grid>
</Grid>


+ 1
- 1
src/pages/Payment/Details_GLD/index.js Ver fichero

@@ -77,7 +77,7 @@ const Index = () => {
if (!responseData.data?.id) {
navigate("/paymentPage/search");
}
responseData.data["transDateStr"] = DateUtils.dateFormat(responseData.data.transDateTime, "DD/MM/YYYY");
responseData.data["transDateStr"] = responseData.data.transDateTime;
responseData.data["transTimeStr"] = DateUtils.dateFormat(responseData.data.transDateTime, "HH:mm:ss");
setItemList(responseData.paymentItemList)
setRecord(responseData.data);


+ 1
- 1
src/pages/Payment/Details_Public/DataGrid.js Ver fichero

@@ -81,7 +81,7 @@ export default function SearchPublicNoticeTable({ recordList }) {
{
id: 'fee',
field: 'fee',
headerName: intl.formatMessage({id: 'currencyAmount'}) + ' ($)',
headerName: intl.formatMessage({id: 'currencyAmount'}),
width: 200,
valueGetter: (params) => {
return (params?.value) ? "$ " + FormatUtils.currencyFormat(params?.value) : "";


+ 43
- 20
src/pages/Payment/Details_Public/PaymentDetails.js Ver fichero

@@ -9,6 +9,7 @@ import {
import * as React from "react";
import * as FormatUtils from "utils/FormatUtils";
import * as PaymentStatus from "utils/statusUtils/PaymentStatus";
import * as DateUtils from "utils/DateUtils";
import Loadable from 'components/Loadable';
const MainCard = Loadable(React.lazy(() => import('components/MainCard')));
const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent')));
@@ -24,30 +25,56 @@ const PaymentDetails = ({ formData,doPrint,onDownload }) => {

React.useEffect(() => {
if (formData != null && formData != undefined && Object.keys(formData).length > 0) {
console.log(formData)
// console.log(formData)
setData(formData);
}
}, [formData]);
React.useEffect(() => {
if (data != null && data != undefined && Object.keys(data).length > 0) {
console.log(data)
// console.log(data)
setOnReady(data != {});
}
}, [data]);

const getPaymentMethod=()=>{
let paymentmethod = ""
// console.log(locale)
if (data?.payload!=null) {
paymentmethod = data.payload?.paymentdetail.paymentmethod;
if("01" == paymentmethod) return "PPS";
if("02" == paymentmethod || "03" == paymentmethod) return "Credit Card";
if("04" == paymentmethod) return "FPS";
if (locale == "zh-HK"){
if("01" == paymentmethod) return "繳費靈";
if("02" == paymentmethod || "03" == paymentmethod) return "信用卡";
if("04" == paymentmethod) return "轉數快";
}
else if (locale == "zh-CN"){
if("01" == paymentmethod) return "缴费灵";
if("02" == paymentmethod || "03" == paymentmethod) return "信用卡";
if("04" == paymentmethod) return "转数快";
}
else {
if("01" == paymentmethod) return "PPS";
if("02" == paymentmethod || "03" == paymentmethod) return "Credit Card";
if("04" == paymentmethod) return "FPS";
}
} else {
paymentmethod = data.payMethod;
if("01,PPSB,PPS" == paymentmethod) return "PPS";
if("02,BCMP,CreditCard" == paymentmethod || "03,BCMP,CreditCard" == paymentmethod) return "Credit Card";
if("04,BCFP,FPS" == paymentmethod) return "FPS";
if (locale == "zh-HK"){
if("01,PPSB,PPS" == paymentmethod) return "繳費靈";
if("02,BCMP,CreditCard" == paymentmethod || "03,BCMP,CreditCard" == paymentmethod) return "信用卡";
if("04,BCFP,FPS" == paymentmethod) return "轉數快";
}
else if (locale == "zh-CN"){
if("01,PPSB,PPS" == paymentmethod) return "缴费灵";
if("02,BCMP,CreditCard" == paymentmethod || "03,BCMP,CreditCard" == paymentmethod) return "信用卡";
if("04,BCFP,FPS" == paymentmethod) return "转数快";
}
else {
if("01,PPSB,PPS" == paymentmethod) return "PPS";
if("02,BCMP,CreditCard" == paymentmethod || "03,BCMP,CreditCard" == paymentmethod) return "Credit Card";
if("04,BCFP,FPS" == paymentmethod) return "FPS";
}
}
return paymentmethod;
}
@@ -109,7 +136,7 @@ const PaymentDetails = ({ formData,doPrint,onDownload }) => {
</Grid>
<Grid item xs={6} md={6} sx={{textAlign: "left" }}>
<FormLabel sx={{ fontSize: "16px", color: "#000000" }}>
{data.transDateStr + " (DD/MM/YYYY)"}
{DateUtils.dateFormat(data.transDateStr, intl.formatMessage({id: "dateStrFormat"})) +" ("+intl.formatMessage({id: "dateStrFormat"})+")"}
</FormLabel>
</Grid>
</Grid>
@@ -151,7 +178,7 @@ const PaymentDetails = ({ formData,doPrint,onDownload }) => {
</Grid>
<Grid item xs={6} md={6} sx={{textAlign: "left" }}>
<FormLabel sx={{ fontSize: "16px", color: "#000000" }}>
{"HK$ " + FormatUtils.currencyFormat(data.payload?.amount?data.payload?.amount:data.payAmount)}
{"$ " + FormatUtils.currencyFormat(data.payload?.amount?data.payload?.amount:data.payAmount)}
</FormLabel>
</Grid>
</Grid>
@@ -181,16 +208,12 @@ const PaymentDetails = ({ formData,doPrint,onDownload }) => {
</FormLabel>
</Grid>
<Grid item xs={6} md={5} sx={{textAlign: "left" }}>
{onDownload?
<LoadingComponent disableText={true} alignItems="flex-start"/>
:
<Button className="printHidden" variant="contained" sx={{ mt:2 }} onClick={doPrint}>
<DownloadIcon/>
<Typography sx={{fontSize: "16px"}}>
<FormattedMessage id="download"/>
</Typography>
</Button>
}
<Button className="printHidden" variant="contained" disabled={onDownload} sx={{ mt:2 }} onClick={doPrint}>
<DownloadIcon/>
<Typography sx={{fontSize: "16px"}}>
<FormattedMessage id="download"/>
</Typography>
</Button>
</Grid>
</Grid>
</Grid>


+ 6
- 6
src/pages/Payment/Details_Public/index.js Ver fichero

@@ -59,9 +59,9 @@ const Index = () => {
React.useEffect(() => {
if (Object.keys(transactionData).length > 0) {
console.log(transactionData)
console.log(itemList)
console.log(record)
// console.log(transactionData)
// console.log(itemList)
// console.log(record)
setOnReady(true);
}
}, [transactionData]);
@@ -102,21 +102,21 @@ const Index = () => {
"paymentId": params.id
},
onSuccess: function(responseData2){
responseData2.data["transDateStr"] = DateUtils.dateFormat(responseData2.data.transDateTime, "DD/MM/YYYY");
responseData2.data["transDateStr"] = responseData2.data.transDateTime;
responseData2.data["transTimeStr"] = DateUtils.dateFormat(responseData2.data.transDateTime, "HH:mm:ss");
setResponeData(responseData2.transactionData)
setItemList(responseData2.paymentItemList)
setRecord(responseData2.data);
},
onError: function(){
responseData.data["transDateStr"] = DateUtils.dateFormat(responseData.data.transDateTime, "DD/MM/YYYY");
responseData.data["transDateStr"] = responseData.data.transDateTime;
responseData.data["transTimeStr"] = DateUtils.dateFormat(responseData.data.transDateTime, "HH:mm:ss");
setResponeData(responseData)

}
});
}else{
responseData.data["transDateStr"] = DateUtils.dateFormat(responseData.data.transDateTime, "DD/MM/YYYY");
responseData.data["transDateStr"] = responseData.data.transDateTime;
responseData.data["transTimeStr"] = DateUtils.dateFormat(responseData.data.transDateTime, "HH:mm:ss");
setResponeData(responseData)
setItemList(responseData.paymentItemList)


+ 38
- 26
src/pages/Payment/FPS/AckPage.js Ver fichero

@@ -104,7 +104,7 @@ const AckPage = () => {
onSuccess: function(responseData){
localStorage.removeItem("webtoken");
localStorage.removeItem("transactionid");
responseData.data["transDateStr"] = DateUtils.dateFormat(responseData.data.transDateTime, "DD/MM/YYYY");
responseData.data["transDateStr"] = DateUtils.dateFormat(responseData.data.transDateTime, intl.formatMessage({id: "dateStrFormat"}));
responseData.data["transTimeStr"] = DateUtils.dateFormat(responseData.data.transDateTime, "HH:mm:ss");
setResponeDataData(responseData.transactionData)
setItemList(responseData.paymentItemList)
@@ -202,7 +202,8 @@ const AckPage = () => {
{/*row 1*/}
<Grid item xs={12} md={12} spacing={2} sx={{ textAlign: "center" }}>
<Typography variant="h3" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "center" }}>
您的申請和付款已收到
{/* 您的申請和付款已收到 */}
<FormattedMessage id="MSG.paymentMsg"/>
</Typography>
<Grid container justifyContent="center" direction="column" spacing={2} sx={{ p: 2 }} alignitems="stretch" >
<Grid item className="printOrder" xs={12} md={12} sx={{ pt: 2 }} style={{ height: '100%', order: 1 }}>
@@ -253,21 +254,22 @@ const AckPage = () => {
<center>
<Grid item xs={12} md={8} >
<Typography variant="h5" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}>
付款取消訊息:
{/* 付款取消訊息: */}
<FormattedMessage id="MSG.paymentCancelMsg1"/>
<br /><br />
您的付款已被取消。我們收到了您的付款請求,但由於某些原因,付款無法完成。請注意以下事項:
<FormattedMessage id="MSG.paymentCancelMsg2"/>
<br /><br />
如果您主動取消了支付,請確認並確保取消是您的意願。
<FormattedMessage id="MSG.paymentCancelMsg3"/>
<br />
如果付款被取消是由於系統問題或其他原因,請您嘗試以下解決方法:
<FormattedMessage id="MSG.paymentCancelMsg4"/>
<br /><br />
檢查您的支付帳戶是否有任何異常或限制。
<FormattedMessage id="MSG.paymentCancelMsg5"/>
<br />
確保您的付款資訊準確無誤。
<FormattedMessage id="MSG.paymentCancelMsg6"/>
<br />
檢查您的網路連線是否正常。
<FormattedMessage id="MSG.paymentCancelMsg7"/>
<br /><br />
如果您需要進一步的協助或有任何疑問,請隨時與我們聯繫,我們將盡快解決您的付款問題。謝謝!
<FormattedMessage id="MSG.paymentCancelMsg8"/>
</Typography>
</Grid>
</center>
@@ -296,29 +298,39 @@ const AckPage = () => {
<Grid container justifyContent="flex-start" alignItems="center" >
<center>
<Grid item xs={12} md={8} >

<Typography variant="h5" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}>
付款失敗訊息:
<FormattedMessage id="MSG.paymentFailMsg1"/>
<br /><br />
親愛的用戶,很遺憾地告訴您,您的付款操作未成功。我們在處理您的付款時遇到了問題。請您仔細檢查以下事項:
<FormattedMessage id="MSG.paymentFailMsg2"/>
<br /><br />
您的支付帳戶餘額是否足夠。
<br />
您提供的付款資訊是否準確無誤。
<br />
請檢查您的網路連線是否正常。
<ul>
<li>
<FormattedMessage id="MSG.paymentFailMsg3"/>
</li>
<li>
<FormattedMessage id="MSG.paymentFailMsg4"/>
</li>
<li>
<FormattedMessage id="MSG.paymentFailMsg5"/>
</li>
</ul>
<br /><br />
如果您已確認以上問題無誤,但付款失敗,請您嘗試以下解決方法:
<FormattedMessage id="MSG.paymentFailMsg6"/>
<br /><br />
嘗試使用其他付款方式進行付款。
<br />
檢查您的支付帳戶是否有異常或限制。
<br />
聯絡我們的客服人員尋求協助。
<ul>
<li>
<FormattedMessage id="MSG.paymentFailMsg7"/>
</li>
<li>
<FormattedMessage id="MSG.paymentFailMsg8"/>
</li>
<li>
<FormattedMessage id="MSG.paymentFailMsg9"/>
</li>
</ul>
<br /><br />
如果您需要進一步的協助或有任何疑問,請隨時與我們聯繫。非常抱歉給您帶來不便,我們將盡快解決您的付款問題。謝謝!
<FormattedMessage id="MSG.paymentFailMsg10"/>
</Typography>

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


+ 129
- 68
src/pages/Payment/FPS/FPS.js Ver fichero

@@ -10,6 +10,9 @@ import * as HttpUtils from "utils/HttpUtils";
import * as UrlUtils from "utils/ApiPathConst";
import { useNavigate } from "react-router-dom";
import FpsIcon from "assets/images/icons/fps.svg";
import expiredQrcodeEN from "assets/images/icons/expiredQrcodeEN.png";
import expiredQrcodeZH from "assets/images/icons/expiredQrcodeZH.png";
import expiredQrcodeCN from "assets/images/icons/expiredQrcodeCN.png";
import { useLocation } from 'react-router-dom';
// import {paymentPath} from "auth/utils";
import {currencyFormat} from "utils/FormatUtils";
@@ -19,7 +22,7 @@ import Loadable from 'components/Loadable';
const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent')));

import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png'
import {FormattedMessage} from "react-intl";
import {FormattedMessage, useIntl} from "react-intl";
const BackgroundHead = {
backgroundImage: `url(${titleBackgroundImg})`,
width: '100%',
@@ -30,15 +33,21 @@ const BackgroundHead = {
backgroundPosition: 'right'
}


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

const Index = () => {
const navigate = useNavigate()
const location = useLocation();
const intl = useIntl();
const { locale } = intl;

const [locationData, setLocationData] = React.useState({});
const [paymentData, setPaymentData] = React.useState({});
const [onReady, setOnReady] = React.useState(false);
const [qrCodeTimeout, setqrCodeTimeout] = React.useState(false);
const [paymentStatusCode, setPaymentStatusCode] = React.useState("");
const [expiredQrcode, setExpiredQrcode] = React.useState(expiredQrcodeEN);
const [responeData, setResponeDataData] = React.useState({});
const [fpsTransctionData, setFpsTransctionData] = React.useState({});
@@ -49,6 +58,7 @@ const Index = () => {
const [fpsqrcodeurlPrd, setFpsqrcodeurlPrd] = React.useState("");
const [fpsqrcodeurlFps, setFpsqrcodeurlFps] = React.useState("");
const [browserType, setBrowserType] = React.useState("");
const [sysEnv, setSysEnv] = React.useState("");
const mobileBrowser = "Mobile";
const desktopBrowser = "Desktop";
@@ -69,12 +79,14 @@ const Index = () => {
if(Object.keys(location.state).length > 0){
// console.log (location.state)
setLocationData(location.state)
setBrowserType(desktopBrowser)

if (/Android|webOS|iPhone|iPad|iPod|Opera Mini/i.test(navigator.userAgent)) {
console.log('Mobile web browser');
// console.log('Mobile web browser');
setBrowserType(mobileBrowser)
// setFpsqrcodeurl(openPASGUrl)
} else {
console.log('Desktop web browser');
// console.log('Desktop web browser');
setBrowserType(desktopBrowser)
}
}
@@ -88,6 +100,17 @@ const Index = () => {
}
}, [locationData]);

React.useEffect(() => {
// console.log (locationData)
if (locale === 'zh-HK'){
setExpiredQrcode(expiredQrcodeZH)
} else if (locale === 'en'){
setExpiredQrcode(expiredQrcodeEN)
} else {
setExpiredQrcode(expiredQrcodeCN)
}
}, [locale]);

React.useEffect(() => {
// console.log (paymentData)
if (Object.keys(paymentData).length > 0){
@@ -159,6 +182,7 @@ const Index = () => {
*/
setResponeDataData(responseData)
const timeoutdatetime = responseData.fpsmerchanttimeoutdatetime
setSysEnv(responseData.sysEnv)
const searchString = "[UTC]";
let convertedDateString = "";
if ( timeoutdatetime.toString().includes(searchString) ){
@@ -175,12 +199,18 @@ const Index = () => {
console.log(fpsqrcodeurl)
console.log(fpsqrcodeurlwithFps)
const openPASGUrl = pasgPath + '?pay_req_obj=' + encodeURIComponent(fpsqrcodeurl) + '&callback='
+ encodeURIComponent("https://"+window.location.hostname+ '/paymentPage/fps/fpscallback?TRANSACTION_ID='+transactionid+"&WEB_TOKEN="+webtoken+"&PAYMENT_ID="+localStorage.getItem("paymentId"));
const openPASGUrlPrd = pasgPathPrd + '?pay_req_obj=' + encodeURIComponent(fpsqrcodeurl) + '&callback='
+ encodeURIComponent("https://"+window.location.hostname+ '/paymentPage/fps/fpscallback?TRANSACTION_ID='+transactionid+"&WEB_TOKEN="+webtoken+"&PAYMENT_ID="+localStorage.getItem("paymentId"));
const openPASGUrl = pasgPath + '?pay_req_obj=' + encodeURIComponent(fpsqrcodeurlwithFps) + '&callback='
+ encodeURIComponent("https://"+window.location.hostname+ '/paymentPage/fps/fpscallback?&PAYMENT_ID='+localStorage.getItem("paymentId"));
const openPASGUrlPrd = pasgPathPrd + '?pay_req_obj=' + encodeURIComponent(fpsqrcodeurlwithFps) + '&callback='
+ encodeURIComponent("https://"+window.location.hostname+ '/paymentPage/fps/fpscallback?&PAYMENT_ID='+localStorage.getItem("paymentId"));
const openPASGUrlPrdFps = pasgPath + '?pay_req_obj=' + encodeURIComponent(fpsqrcodeurlwithFps) + '&callback='
+ encodeURIComponent("https://"+window.location.hostname+ '/paymentPage/fps/fpscallback?TRANSACTION_ID='+transactionid+"&WEB_TOKEN="+webtoken+"&PAYMENT_ID="+localStorage.getItem("paymentId"));
+ encodeURIComponent("https://"+window.location.hostname+ '/paymentPage/fps/fpscallback?&PAYMENT_ID='+localStorage.getItem("paymentId"));
// const openPASGUrl = pasgPath + '?pay_req_obj=' + encodeURIComponent(fpsqrcodeurlwithFps) + '&callback='
// + encodeURIComponent("https://"+window.location.hostname+ '/paymentPage/fps/fpscallback?TRANSACTION_ID='+transactionid+"&WEB_TOKEN="+webtoken+"&PAYMENT_ID="+localStorage.getItem("paymentId"));
// const openPASGUrlPrd = pasgPathPrd + '?pay_req_obj=' + encodeURIComponent(fpsqrcodeurlwithFps) + '&callback='
// + encodeURIComponent("https://"+window.location.hostname+ '/paymentPage/fps/fpscallback?TRANSACTION_ID='+transactionid+"&WEB_TOKEN="+webtoken+"&PAYMENT_ID="+localStorage.getItem("paymentId"));
// const openPASGUrlPrdFps = pasgPath + '?pay_req_obj=' + encodeURIComponent(fpsqrcodeurlwithFps) + '&callback='
// + encodeURIComponent("https://"+window.location.hostname+ '/paymentPage/fps/fpscallback?TRANSACTION_ID='+transactionid+"&WEB_TOKEN="+webtoken+"&PAYMENT_ID="+localStorage.getItem("paymentId"));
setFpsqrcodeurl(openPASGUrl)
setFpsqrcodeurlPrd(openPASGUrlPrd)
setFpsqrcodeurlFps(openPASGUrlPrdFps)
@@ -188,7 +218,7 @@ const Index = () => {
});

//testing
// const timeoutdatetime = "2024-05-06T11:10:30Z[UTC]"
// const timeoutdatetime = "2024-11-18T07:04:35Z[UTC]"
// const convertedDateString = timeoutdatetime.replace("[UTC]", "");
// setFpsmerchanttimeoutdatetime(convertedDateString)
// setPaymentId("C202310268000681")
@@ -196,7 +226,7 @@ const Index = () => {
// {
// "paymentid": "C202310268000681",
// "paymentstatus": "INPR",
// "fpsmerchanttimeoutdatetime": "2024-05-06T11:10:30Z[UTC]",
// "fpsmerchanttimeoutdatetime": "2024-11-18T07:04:35Z[UTC]",
// "fpsqrcodeimgbase64": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAYAAAB5fY51AAAuyklEQVR4Xu3dfcy/d1nff2IAAAAASUVORK5CYII=",
// "fpsqrcodeurl": "http://127.0.0.1:8080/api/payment/wallet/fps/enquiryfpspayload/vm.JKDDlTOavR3ASviSwUnS1Lw4-"
// }
@@ -231,6 +261,7 @@ const Index = () => {
},
onSuccess: function(responseData){
const paymentstatuscode = responseData.paymentdetail.result.paymentstatuscode;
setPaymentStatusCode(paymentstatuscode)
if (paymentstatuscode != "" && paymentstatuscode != "INPR" ){
if (paymentstatuscode === 'APPR') {
// const timestamp = Date.now();
@@ -249,7 +280,8 @@ const Index = () => {
}
},
onError: function(){
cancelPayment()
alert("ERROR")
// cancelPayment()
// clearInterval(currentTimer.current);
}
});
@@ -260,35 +292,43 @@ const Index = () => {
const timeOutDate = new Date(fpsmerchanttimeoutdatetime);
const currentTime = new Date;
const timedowncount = Math.round((timeOutDate.getTime() - currentTime.getTime()) / 1000);
setTimeDownCount(timedowncount);
// console.log(time)
// console.log(timeOutDate)
// console.log(currentTime)
// console.log(timeOutDate.getTime()-currentTime.getTime())
getPaymentStatus();
if (timeOutDate.getTime()<currentTime.getTime()){
// console.log("stop");
clearInterval(currentTimer.current);
cancelPayment()
if (browserType === desktopBrowser){
getPaymentStatus();
if (timeOutDate.getTime()<currentTime.getTime()){
// console.log("stop");
clearInterval(currentTimer.current);
setqrCodeTimeout(true)
setTimeDownCount(0);
cancelPayment()
}else{
setTimeDownCount(timedowncount);
}
}
},[time])

const cancelPayment = ()=>{
if (Object.keys(paymentData).length>0){
HttpUtils.post({
url: UrlUtils.CANCEL_PAYMENT_URL,
params:{
"transactionid": paymentData.transactionid,
"webtoken": paymentData.webtoken,
"paymentid": fpsTransctionData.paymentid
},
onSuccess: function(){
// navigate('/paymentPage/fps/ackpage');
let page = '/paymentPage/fps/ackpage';
let stateParams = { state: { transactionid: paymentData.transactionid} }
navigate(page, stateParams);
}
});
getPaymentStatus()
if (paymentStatusCode === "INPR"){
HttpUtils.post({
url: UrlUtils.CANCEL_PAYMENT_URL,
params:{
"transactionid": paymentData.transactionid,
"webtoken": paymentData.webtoken,
"paymentid": fpsTransctionData.paymentid
},
onSuccess: function(){
navigate('/paymentPage/fps/ackpage');
let page = '/paymentPage/fps/ackpage';
let stateParams = { state: { transactionid: paymentData.transactionid} }
navigate(page, stateParams);
}
});
}
}
}

@@ -330,6 +370,8 @@ const Index = () => {
<Grid item xs={12} md={12} >

<Typography variant="h3" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "center" }}>
<FormattedMessage id="payAlert"/>
<br /><br />
<img src={FpsIcon} width="80" height="80" alt="FPS"></img>
<br />
<FormattedMessage id="payTotalDeatail"/>
@@ -338,50 +380,69 @@ const Index = () => {
</Typography>
{browserType==mobileBrowser?
<Typography variant="h3" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "center" }}>
<Button
component="span"
variant="contained"
size="large"
color="primary"
onClick={()=>{
mobliePayment();
}}
sx={{ m: 4 }}
>請選擇支付程式付款-Testing</Button>
<Button
component="span"
variant="contained"
size="large"
color="primary"
onClick={()=>{
mobliePaymentPrd();
}}
sx={{ m: 4 }}
>請選擇支付程式付款-PRD</Button>
<Button
component="span"
variant="contained"
size="large"
color="primary"
onClick={()=>{
mobliePaymentFps();
}}
sx={{ m: 4 }}
>請選擇支付程式付款-fps prefix</Button>
{
sysEnv=="prod"?
<Button
component="span"
variant="contained"
size="large"
color="primary"
onClick={()=>{
mobliePaymentPrd();
}}
sx={{ m: 4 }}
>請選擇支付程式付款</Button>
:
<>
<Button
component="span"
variant="contained"
size="large"
color="primary"
onClick={()=>{
mobliePayment();
}}
sx={{ m: 4 }}
>請選擇支付程式付款-Testing</Button>
<Button
component="span"
variant="contained"
size="large"
color="primary"
onClick={()=>{
mobliePaymentFps();
}}
sx={{ m: 4 }}
>請選擇支付程式付款-fps prefix</Button>
</>
}
</Typography>
:
<Typography variant="h3" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "center" }}>
請掃描以下二維碼
<FormattedMessage id="fpsQrcodeTitle1"/>
<br />
<img src={fpsTransctionData.fpsqrcodeimgbase64} alt="QR Code"/>
{
!qrCodeTimeout?
<img src={fpsTransctionData.fpsqrcodeimgbase64} alt="QR Code"/>
:<img src={expiredQrcode} alt="Expired QR Code"/>
}
<br />
{"["+paymentId+"]"}
<br/>
二維碼有效期限3分鐘
<br />
請在規定時間內完成付款流程
<br />
{"剩餘時間: "+timeDownCount+ "秒"}
{
timeDownCount<=0?
<FormattedMessage id="fpsQrcodeExpired"/>:
<>
<FormattedMessage id="fpsQrcodeTitle2"/>
<br />
<FormattedMessage id="fpsQrcodeTitle3"/>
<br />
<FormattedMessage id="fpsQrcodeTitle4"/>&nbsp;
{timeDownCount}&nbsp;
<FormattedMessage id="fpsQrcodeTitle5"/>
</>
}
</Typography>
}
<Typography variant="h3" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "center" }}>


+ 1
- 1
src/pages/Payment/FPS/FPSTest.js Ver fichero

@@ -312,7 +312,7 @@ const Index = () => {
<br/>
二維碼有效期限3分鐘
<br />
請在規定時間內完成付款流程
請在規定時間內完成付款流程
<br />
{"剩餘時間:"+timeDownCount}
</Typography>


+ 50
- 40
src/pages/Payment/FPS/fpscallback.js Ver fichero

@@ -76,22 +76,22 @@ const Fpscallback = () => {

const loadForm = () => {
const params = new URLSearchParams(window.location.search);
let transactionid = params.get("TRANSACTION_ID")
let webtoken = params.get("WEB_TOKEN")
// let transactionid = params.get("TRANSACTION_ID")
// let webtoken = params.get("WEB_TOKEN")
let paymentId = params.get("PAYMENT_ID")
paymentId = paymentId.split('?is_successful')[0];

console.log(transactionid)
console.log(webtoken)
// console.log(transactionid)
// console.log(webtoken)
console.log(paymentId)

HttpUtils.post({
url: UrlUtils.PAYMENT_CALLBACK_STATUS_API,
params:{
"apprefid": transactionid,
"webtoken": webtoken,
// "apprefid": transactionid,
// "webtoken": webtoken,
"paymentId": paymentId,
"transactionid":Number(transactionid)
// "transactionid":Number(transactionid)
},
onSuccess: function(responseData){
setResponeDataData(responseData)
@@ -99,7 +99,7 @@ const Fpscallback = () => {
localStorage.removeItem("webtoken");
localStorage.removeItem("transactionid");
}
responseData.data["transDateStr"] = DateUtils.dateFormat(responseData.data.transDateTime, "DD/MM/YYYY");
responseData.data["transDateStr"] = responseData.data.transDateTime;
responseData.data["transTimeStr"] = DateUtils.dateFormat(responseData.data.transDateTime, "HH:mm:ss");
setResponeDataData(responseData.transactionData)
setItemList(responseData.paymentItemList)
@@ -191,7 +191,7 @@ const Fpscallback = () => {
{/*row 1*/}
<Grid item xs={12} md={12} spacing={2} sx={{ textAlign: "center" }}>
<Typography variant="h3" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "center" }}>
您的申請和付款已收到
<FormattedMessage id="MSG.paymentMsg"/>
</Typography>
<Grid container justifyContent="center" direction="column" spacing={2} sx={{ p: 2 }} alignitems="stretch" >
<Grid item className="printOrder" xs={12} md={12} sx={{ pt: 2 }} style={{ height: '100%', order: 1 }}>
@@ -242,21 +242,21 @@ const Fpscallback = () => {
<center>
<Grid item xs={12} md={8} >
<Typography variant="h5" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}>
付款取消訊息:
<br /><br />
您的付款已被取消。我們收到了您的付款請求,但由於某些原因,付款無法完成。請注意以下事項:
<br /><br />
如果您主動取消了支付,請確認並確保取消是您的意願。
<br />
如果付款被取消是由於系統問題或其他原因,請您嘗試以下解決方法:
<br /><br />
檢查您的支付帳戶是否有任何異常或限制。
<br />
確保您的付款資訊準確無誤。
<br />
檢查您的網路連線是否正常。
<br /><br />
如果您需要進一步的協助或有任何疑問,請隨時與我們聯繫,我們將盡快解決您的付款問題。謝謝!
<FormattedMessage id="MSG.paymentCancelMsg1"/>
<br /><br />
<FormattedMessage id="MSG.paymentCancelMsg2"/>
<br /><br />
<FormattedMessage id="MSG.paymentCancelMsg3"/>
<br />
<FormattedMessage id="MSG.paymentCancelMsg4"/>
<br /><br />
<FormattedMessage id="MSG.paymentCancelMsg5"/>
<br />
<FormattedMessage id="MSG.paymentCancelMsg6"/>
<br />
<FormattedMessage id="MSG.paymentCancelMsg7"/>
<br /><br />
<FormattedMessage id="MSG.paymentCancelMsg8"/>
</Typography>
</Grid>
</center>
@@ -285,29 +285,39 @@ const Fpscallback = () => {
<Grid container justifyContent="flex-start" alignItems="center" >
<center>
<Grid item xs={12} md={8} >

<Typography variant="h5" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}>
付款失敗訊息:
<FormattedMessage id="MSG.paymentFailMsg1"/>
<br /><br />
親愛的用戶,很遺憾地告訴您,您的付款操作未成功。我們在處理您的付款時遇到了問題。請您仔細檢查以下事項:
<FormattedMessage id="MSG.paymentFailMsg2"/>
<br /><br />
您的支付帳戶餘額是否足夠。
<br />
您提供的付款資訊是否準確無誤。
<br />
請檢查您的網路連線是否正常。
<ul>
<li>
<FormattedMessage id="MSG.paymentFailMsg3"/>
</li>
<li>
<FormattedMessage id="MSG.paymentFailMsg4"/>
</li>
<li>
<FormattedMessage id="MSG.paymentFailMsg5"/>
</li>
</ul>
<br /><br />
如果您已確認以上問題無誤,但付款失敗,請您嘗試以下解決方法:
<FormattedMessage id="MSG.paymentFailMsg6"/>
<br /><br />
嘗試使用其他付款方式進行付款。
<br />
檢查您的支付帳戶是否有異常或限制。
<br />
聯絡我們的客服人員尋求協助。
<ul>
<li>
<FormattedMessage id="MSG.paymentFailMsg7"/>
</li>
<li>
<FormattedMessage id="MSG.paymentFailMsg8"/>
</li>
<li>
<FormattedMessage id="MSG.paymentFailMsg9"/>
</li>
</ul>
<br /><br />
如果您需要進一步的協助或有任何疑問,請隨時與我們聯繫。非常抱歉給您帶來不便,我們將盡快解決您的付款問題。謝謝!
<FormattedMessage id="MSG.paymentFailMsg10"/>
</Typography>

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


+ 7
- 7
src/pages/Payment/MultiPaymentWindow.js Ver fichero

@@ -64,7 +64,7 @@ const MultiPaymentWindow = (props) => {
// console.log(props.transactionData)
if(Object.keys(props.transactionData).length > 0){
setLoadtTransactionData(props.transactionData)
console.log(props.browserType)
// console.log(props.browserType)
}
}, [props.transactionData]);

@@ -292,7 +292,7 @@ const MultiPaymentWindow = (props) => {
<DialogContent>
<DialogContentText>
<FormLabel sx={{ fontSize: "20px", color: "#000000", textAlign: "left", ml:1}}>
<FormattedMessage id="paymentProcessLimited"/>
<FormattedMessage id="paymentProcessLimited"/>
</FormLabel>
<Grid item xs={12} md={12} sx={{ pt: 2 }} style={{ height: '100%' }} width="100%">
<Box xs={12} md={12} sx={{ p: 4, border: '3px solid #eee', borderRadius: '10px' }} >
@@ -304,7 +304,7 @@ const MultiPaymentWindow = (props) => {
</Typography>

{/* <Typography variant="h5" sx={{ textAlign: "left" }}>
付金額: HK$ {FormatUtils.currencyFormat(props.totalAmount)}
金額: HK$ {FormatUtils.currencyFormat(props.totalAmount)}
</Typography> */}
{!props.onReady ?
<LoadingComponent />
@@ -373,7 +373,7 @@ const MultiPaymentWindow = (props) => {
</Grid>:
<Grid container direction="row" justifyContent="center" alignItems="center">
<FormLabel sx={{ fontSize: "20px", color: "#000000", textAlign: "center"}}>
<FormattedMessage id="paymentMethodNotAvailable"/>
<FormattedMessage id="paymentMethodNotAvailable"/>
</FormLabel>
</Grid>
}
@@ -381,12 +381,12 @@ const MultiPaymentWindow = (props) => {
<Grid item xs={12} md={12}>
<Grid container >
<Grid item>
<Typography variant="pnspsFormParagraphBold" sx={{ color: "#000000", textAlign: "left" }}>
<FormattedMessage id="payTotal"/>(HK$):&nbsp;
<Typography variant="h5" sx={{ color: "#000000", textAlign: "left" }}>
<FormattedMessage id="payTotal"/>&nbsp;($):&nbsp;
</Typography>
</Grid>
<Grid item>
<Typography variant="pnspsFormParagraphBold" sx={{color: "#000000", textAlign: "left" }}>
<Typography variant="h5" sx={{color: "#000000", textAlign: "left" }}>
{" HK$ " + FormatUtils.currencyFormat(props.totalAmount)}
</Typography>
</Grid>


+ 24
- 14
src/pages/Payment/PaymentCallback.js Ver fichero

@@ -123,7 +123,7 @@ const Index = () => {
localStorage.removeItem("webtoken");
localStorage.removeItem("transactionid");
}
responseData.data["transDateStr"] = DateUtils.dateFormat(responseData.data.transDateTime, "DD/MM/YYYY");
responseData.data["transDateStr"] = responseData.data.transDateTime;
responseData.data["transTimeStr"] = DateUtils.dateFormat(responseData.data.transDateTime, "HH:mm:ss");
setResponeDataData(responseData.transactionData)
setItemList(responseData.paymentItemList)
@@ -294,29 +294,39 @@ const Index = () => {
<Grid container justifyContent="flex-start" alignItems="center" >
<center>
<Grid item xs={12} md={8} >

<Typography variant="h5" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}>
<FormattedMessage id="MSG.paymentFailMsg1"/>
<br /><br />
<FormattedMessage id="MSG.paymentFailMsg2"/>
<br /><br />
<FormattedMessage id="MSG.paymentFailMsg3"/>
<br />
<FormattedMessage id="MSG.paymentFailMsg4"/>
<br />
<FormattedMessage id="MSG.paymentFailMsg5"/>
<ul>
<li>
<FormattedMessage id="MSG.paymentFailMsg3"/>
</li>
<li>
<FormattedMessage id="MSG.paymentFailMsg4"/>
</li>
<li>
<FormattedMessage id="MSG.paymentFailMsg5"/>
</li>
</ul>
<br /><br />
<FormattedMessage id="MSG.paymentFailMsg6"/>
<br /><br />
<FormattedMessage id="MSG.paymentFailMsg7"/>
<br />
<FormattedMessage id="MSG.paymentFailMsg8"/>
<br />
<FormattedMessage id="MSG.paymentFailMsg9"/>
<ul>
<li>
<FormattedMessage id="MSG.paymentFailMsg7"/>
</li>
<li>
<FormattedMessage id="MSG.paymentFailMsg8"/>
</li>
<li>
<FormattedMessage id="MSG.paymentFailMsg9"/>
</li>
</ul>
<br /><br />
<FormattedMessage id="MSG.paymentFailMsg10"/>
</Typography>

</Typography>
</Grid>
</center>
</Grid>


+ 11
- 5
src/pages/Payment/Search_GLD/DataGrid.js Ver fichero

@@ -9,7 +9,7 @@ import { FiDataGrid } from "components/FiDataGrid";
import { clickableLink } from 'utils/CommonFunction';
// ==============================|| EVENT TABLE ||============================== //

export default function SearchPaymentTable({ searchCriteria }) {
export default function SearchPaymentTable({ searchCriteria, applyGridOnReady, applySearch}) {
const [_searchCriteria, set_searchCriteria] = React.useState(searchCriteria);
const navigate = useNavigate()

@@ -96,10 +96,16 @@ export default function SearchPaymentTable({ searchCriteria }) {
columns={columns}
customPageSize={10}
onRowDoubleClick={handleEditClick}
doLoad={{
url:PAYMENT_LIST,
params:_searchCriteria,
}}
applyGridOnReady={applyGridOnReady}
applySearch={applySearch}
// doLoad={{
// url:PAYMENT_LIST,
// params:_searchCriteria,
// }}
doLoad={React.useMemo(() => ({
url: PAYMENT_LIST,
params: _searchCriteria,
}), [_searchCriteria])}
/>
</div>
);


+ 18
- 2
src/pages/Payment/Search_GLD/SearchForm.js Ver fichero

@@ -19,7 +19,7 @@ import {DemoItem} from "@mui/x-date-pickers/internals/demo";
import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider";
import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs";
// ==============================|| DASHBOARD - DEFAULT ||============================== //
const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => {
const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady }) => {

const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom);
const [maxDate, setMaxDate] = React.useState(searchCriteria.dateTo);
@@ -31,6 +31,18 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => {
const [fromDateValue, setFromDateValue] = React.useState("dd / mm / yyyy");
const [toDateValue, setToDateValue] = React.useState("dd / mm / yyyy");

React.useEffect(() => {
if(searchCriteria.status!=undefined){
if(searchCriteria.status === ""){
ComboData.paymentStatus[0]
}else{
setStatus(ComboData.paymentStatus.find(item => item.type === searchCriteria.status))
}
}else{
setStatus(ComboData.paymentStatus[0])
}
}, [searchCriteria]);

React.useEffect(() => {
setFromDateValue(minDate);
}, [minDate]);
@@ -62,7 +74,10 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => {
setStatus(ComboData.paymentStatus[0]);
setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)))
setMaxDate(DateUtils.dateValue(new Date()))
reset();
reset({
code:"",
transNo:""
});
}


@@ -215,6 +230,7 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => {
<Button
variant="contained"
type="submit"
disabled={onGridReady}
>
Submit
</Button>


+ 26
- 6
src/pages/Payment/Search_GLD/index.js Ver fichero

@@ -7,6 +7,7 @@ import {
import MainCard from "components/MainCard";
import * as React from "react";
import * as DateUtils from "utils/DateUtils";
import { getSearchCriteria } from "auth/utils";

import Loadable from 'components/Loadable';
const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent')));
@@ -28,18 +29,34 @@ const BackgroundHead = {

const Index = () => {

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

React.useEffect(() => {
if (Object.keys(getSearchCriteria(window.location.pathname)).length>0){
setSearchCriteria(getSearchCriteria(window.location.pathname))
}else{
localStorage.setItem('searchCriteria',"")
setSearchCriteria({
dateTo: DateUtils.dateValue(new Date()),
dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)),
})
}
}, []);

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

function applySearch(input) {
setGridOnReady(true)
setSearchCriteria(input);
localStorage.setItem('searchCriteria', JSON.stringify({path:window.location.pathname,data:input}))
}

function applyGridOnReady(input) {
setGridOnReady(input);
}

return (
@@ -63,8 +80,9 @@ const Index = () => {
{/*row 1*/}
<Grid item xs={12} md={12} lg={12} sx={{mb:-1}}>
<SearchForm
applySearch={applySearch}
searchCriteria={searchCriteria}
applySearch={applySearch}
searchCriteria={searchCriteria}
onGridReady={onGridReady}
/>
</Grid>
{/*row 2*/}
@@ -76,6 +94,8 @@ const Index = () => {
>
<EventTable
searchCriteria={searchCriteria}
applyGridOnReady={applyGridOnReady}
applySearch={applySearch}
/>
</MainCard>
</Grid>


+ 10
- 4
src/pages/Payment/Search_Public/DataGrid.js Ver fichero

@@ -14,7 +14,7 @@ import { clickableLink } from 'utils/CommonFunction';
import {PAYMENT_LIST} from "utils/ApiPathConst";
// ==============================|| EVENT TABLE ||============================== //

export default function SearchPublicNoticeTable({ searchCriteria }) {
export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnReady, applySearch }) {
const navigate = useNavigate()
const theme = useTheme();
const isMdOrLg = useMediaQuery(theme.breakpoints.up('md'));
@@ -94,7 +94,7 @@ export default function SearchPublicNoticeTable({ searchCriteria }) {
{
id: 'payAmount',
field: 'payAmount',
headerName: intl.formatMessage({id: 'currencyAmount'}) + ' ($)',
headerName: intl.formatMessage({id: 'currencyAmount'}),
width: 150,
valueGetter: (params) => {
return (params?.value) ? "$ " + FormatUtils.currencyFormat(params?.value) : "";
@@ -110,10 +110,16 @@ export default function SearchPublicNoticeTable({ searchCriteria }) {
columns={columns}
customPageSize={10}
onRowDoubleClick={handleEditDoubleClick}
doLoad={{
applyGridOnReady={applyGridOnReady}
applySearch={applySearch}
// doLoad={{
// url: PAYMENT_LIST,
// params: _searchCriteria,
// }}
doLoad={React.useMemo(() => ({
url: PAYMENT_LIST,
params: _searchCriteria,
}}
}), [_searchCriteria])}
/>
</div>
);


+ 9
- 3
src/pages/Payment/Search_Public/SearchForm.js Ver fichero

@@ -21,11 +21,11 @@ import {DemoItem} from "@mui/x-date-pickers/internals/demo";
import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider";
import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs";
// ==============================|| DASHBOARD - DEFAULT ||============================== //
const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => {
const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady }) => {
const intl = useIntl();
const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom);
const [maxDate, setMaxDate] = React.useState(searchCriteria.dateTo);
const [status, setStatus] = React.useState(ComboData.paymentStatus[0]);
const [status, setStatus] = React.useState(searchCriteria.status!=undefined?ComboData.paymentStatus.find(item => item.type === searchCriteria.status):ComboData.paymentStatus[0]);

const [fromDateValue, setFromDateValue] = React.useState("dd / mm / yyyy");
const [toDateValue, setToDateValue] = React.useState("dd / mm / yyyy");
@@ -78,7 +78,11 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => {
setStatus(ComboData.paymentStatus[0]);
setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)))
setMaxDate(DateUtils.dateValue(new Date()))
reset();
reset({
code:"",
transNo:""
});
localStorage.setItem('searchCriteria',"")
}


@@ -181,6 +185,7 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => {
disablePortal={false}
id="status"
size="small"
disableClearable
filterOptions={(options) => options}
options={ComboData.paymentStatus}
value={status}
@@ -239,6 +244,7 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => {
variant="contained"
type="submit"
aria-label={intl.formatMessage({id: 'submit'})}
disabled={onGridReady}
>
<FormattedMessage id="submit"/>
</Button>


+ 28
- 3
src/pages/Payment/Search_Public/index.js Ver fichero

@@ -14,6 +14,7 @@ const SearchForm = Loadable(React.lazy(() => import('./SearchForm')));
const EventTable = Loadable(React.lazy(() => import('./DataGrid')));
import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png'
import {FormattedMessage} from "react-intl";
import { getSearchCriteria } from "auth/utils";

const BackgroundHead = {
backgroundImage: `url(${titleBackgroundImg})`,
@@ -33,13 +34,34 @@ const Index = () => {
dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)),
});
const [onReady, setOnReady] = React.useState(false);
const [onGridReady, setGridOnReady] = React.useState(false);

React.useEffect(() => {
setOnReady(true);
if (Object.keys(getSearchCriteria(window.location.pathname)).length>0){
setSearchCriteria(getSearchCriteria(window.location.pathname))
}else{
localStorage.setItem('searchCriteria',"")
setSearchCriteria({
dateTo: DateUtils.dateValue(new Date()),
dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)),
})
}
}, []);
React.useEffect(() => {
if(Object.keys(searchCriteria).length>0){
setOnReady(true);
}
}, [searchCriteria]);

function applySearch(input) {
setGridOnReady(true)
setSearchCriteria(input);
localStorage.setItem('searchCriteria', JSON.stringify({path:window.location.pathname,data:input}))
}

function applyGridOnReady(input) {
setGridOnReady(input);
}

return (
@@ -63,8 +85,9 @@ const Index = () => {
{/*row 1*/}
<Grid item xs={12} md={12} lg={12}>
<SearchForm
applySearch={applySearch}
searchCriteria={searchCriteria}
applySearch={applySearch}
searchCriteria={searchCriteria}
onGridReady={onGridReady}
/>
</Grid>
{/*row 2*/}
@@ -76,6 +99,8 @@ const Index = () => {
>
<EventTable
searchCriteria={searchCriteria}
applyGridOnReady={applyGridOnReady}
applySearch={applySearch}
/>
</MainCard>
</Grid>


+ 3
- 1
src/pages/Payment/index.js Ver fichero

@@ -520,7 +520,9 @@ const Index = () => {
}}
>
<DialogTitle></DialogTitle>
<Typography variant="h2" style={{ padding: '16px' }}>行動失敗</Typography>
<Typography variant="h2" style={{ padding: '16px' }}>
<FormattedMessage id ="MSG.actionFail"/>
</Typography>
<DialogContent style={{ display: 'flex', }}>
<Stack direction="column" justifyContent="space-between">
{


+ 53
- 22
src/pages/Proof/Create_FromApp/ApplicationDetails.js Ver fichero

@@ -27,26 +27,50 @@ const SearchPublicNoticeForm = ({ formData }) => {
initialValues: data,
});

const DisplayField = ({ name, width }) => {
return <TextField
fullWidth
disabled
size="small"
onChange={formik.handleChange}
id={name}
name={name}
value={formik.values[name]}
variant="outlined"
sx={
{
"& .MuiInputBase-input.Mui-disabled": {
WebkitTextFillColor: "#000000",
background: "#f8f8f8",
},
width: width ? width : '100%'
}
const DisplayField = ({ name, width, dummyUser }) => {
return <>
{dummyUser?
<TextField
fullWidth
disabled
size="small"
onChange={formik.handleChange}
id={name}
name={name}
value={"GLD: "+formik.values[name]}
variant="outlined"
sx={
{
"& .MuiInputBase-input.Mui-disabled": {
WebkitTextFillColor: "#000000",
background: "#f8f8f8",
},
width: width ? width : '100%'
}
}
/>
:
<TextField
fullWidth
disabled
size="small"
onChange={formik.handleChange}
id={name}
name={name}
value={formik.values[name]}
variant="outlined"
sx={
{
"& .MuiInputBase-input.Mui-disabled": {
WebkitTextFillColor: "#000000",
background: "#f8f8f8",
},
width: width ? width : '100%'
}
}
/>
}
/>;
</>
}


@@ -97,9 +121,16 @@ const SearchPublicNoticeForm = ({ formData }) => {
</Grid>

<Grid item xs={12} md={8} lg={8}>
<DisplayField
name={formik.values?.orgId ? 'enCompanyName' : 'contactPerson'}
/>
{
formik.values?.orgId?
<DisplayField
name={formik.values?.enCompanyName == "GLD" ? 'custName' : 'enCompanyName'}
dummyUser={true}
/>:
<DisplayField
name={'contactPerson'}
/>
}
</Grid>
</Grid>
</Grid>


+ 16
- 1
src/pages/Proof/Create_FromApp/ProofForm.js Ver fichero

@@ -131,6 +131,21 @@ const FormPanel = ({ formData }) => {
setSaving(false);
return;
}

if (!values.length|| values.length <= 0) {
setWarningText("Column should > 0");
setIsWarningPopUp(true);
setSaving(false);
return;
}
if(formik.values.groupType == "Private Bill" ){
if (!values.noOfPages || values.noOfPages <= 0) {
setWarningText("Page should > 0");
setIsWarningPopUp(true);
setSaving(false);
return;
}
}
// console.log(values);
HttpUtils.postWithFiles({
url: UrlUtils.CREATE_PROOF,
@@ -208,7 +223,7 @@ const FormPanel = ({ formData }) => {
<Grid item xs={12} md={12}>
<Stack direction="row" sx={{ display: 'flex', alignItems: 'center' }}>
<FormLabel sx={{ paddingRight: 2, textAlign: "center" }}>
<Typography variant="h5">Deadline for online proof with revision:</Typography>
<Typography variant="h5">Deadline for online manuscript revision:</Typography>
</FormLabel>
<TextField
fullWidth


+ 4
- 4
src/pages/Proof/Create_FromApp/UploadFileTable.js Ver fichero

@@ -59,10 +59,10 @@ export default function UploadFileTable({ recordList, setRecordList, showPageCol
...rowModesModel,
[id]: { mode: GridRowModes.View, ignoreModifications: true },
});
console.log("Starting Delete")
const editedRow = rows.find((row) => row.id === id);
console.log(editedRow)
console.log(editedRow.isNew)
// console.log("Starting Delete")
// const editedRow = rows.find((row) => row.id === id);
// console.log(editedRow)
// console.log(editedRow.isNew)
setRecordList(rows.filter((row) => row.id !== id));
setRows(rows.filter((row) => row.id !== id));
}


+ 1
- 1
src/pages/Proof/Payment/Pay.js Ver fichero

@@ -181,7 +181,7 @@ const Index = ({ record }) => {
<DialogContent style={{ display: 'flex', }}>
<Stack direction="column" justifyContent="space-between">
<Typography variant="h4">
<FormattedMessage id="totalAmount" /> (HK$): {FormatUtils.currencyFormat(record.fee)}
<FormattedMessage id="totalAmount" /> ($): {FormatUtils.currencyFormat(record.fee)}
</Typography>
</Stack>
</DialogContent>


+ 1
- 0
src/pages/Proof/Payment/Pay_Creditor.js Ver fichero

@@ -70,6 +70,7 @@ const Index = ({ record }) => {
navigate("/publicNotice");
}}
>
<FormattedMessage id="backToNoticePage" />
</Button>
</Typography>
</Grid>


+ 5
- 4
src/pages/Proof/Payment/Pay_DN.js Ver fichero

@@ -44,12 +44,12 @@ const Index = ({ record }) => {
<Grid container justifyContent="flex-start" alignItems="center" >
<center>
<Grid item xs={12} md={8} >
<Typography variant="h2" sx={{ textAlign: "left", ml: 4, mr: 4, mt: 4, borderBottom: "1px solid black" }}>
<Typography variant="h4" sx={{ textAlign: "left", ml: 4, mr: 4, mt: 4, borderBottom: "1px solid black" }}>
<FormattedMessage id="proofPaymentHeader_demandNote" />
</Typography>


<Typography variant="h3" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}>
<Typography variant="h5" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}>
<div dangerouslySetInnerHTML={{
__html: intl.formatMessage(
{
@@ -67,7 +67,7 @@ const Index = ({ record }) => {
id: 'proofPaymentBody_demandNote2'
},
{
closingDateOff: DateUtils.dateStr(record.closingDateOff),
closingDateOff: DateUtils.dateFormat(record?.closingDateOff, intl.formatMessage({id: "dateStrFormat"})),
email: record?.mail,
}
)
@@ -79,7 +79,7 @@ const Index = ({ record }) => {
id: 'proofPaymentBody_demandNote3'
},
{
paymentDeadline: DateUtils.dateStr(record?.closingDate),
paymentDeadline: DateUtils.dateFormat(record?.closingDate, intl.formatMessage({id: "dateStrFormat"})),
}
)
}} />
@@ -105,6 +105,7 @@ const Index = ({ record }) => {
navigate("/publicNotice");
}}
>
<FormattedMessage id="backToNoticePage" />
</Button>
</Typography>
</Grid>


+ 4
- 3
src/pages/Proof/Payment/Pay_Office.js Ver fichero

@@ -44,12 +44,12 @@ const Index = ({ record }) => {
<Grid container justifyContent="flex-start" alignItems="center" >
<center>
<Grid item xs={12} md={8} >
<Typography variant="h2" sx={{ textAlign: "left", ml: 4, mr: 4, mt: 4, borderBottom: "1px solid black" }}>
<Typography variant="h4" sx={{ textAlign: "left", ml: 4, mr: 4, mt: 4, borderBottom: "1px solid black" }}>
<FormattedMessage id="proofPaymentHeader_office" />
</Typography>


<Typography variant="h3" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}>
<Typography variant="h5" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}>
<div dangerouslySetInnerHTML={{
__html: intl.formatMessage(
{
@@ -91,7 +91,7 @@ const Index = ({ record }) => {
id: 'proofPaymentBody_office5'
},
{
paymentDeadline: DateUtils.dateStr(record?.closingDate),
paymentDeadline: DateUtils.dateFormat(record?.closingDate, intl.formatMessage({id: "dateStrFormat"})),
}
)
}} />
@@ -117,6 +117,7 @@ const Index = ({ record }) => {
navigate("/publicNotice");
}}
>
<FormattedMessage id="backToNoticePage" />
</Button>
</Typography>
</Grid>


+ 9
- 6
src/pages/Proof/Payment/Pay_Online.js Ver fichero

@@ -32,7 +32,9 @@ import {
// useEffect,
useState
} from "react";
import { PNSPS_BUTTON_THEME, PNSPS_LONG_BUTTON_THEME } from "../../../themes/buttonConst";
import { PNSPS_BUTTON_THEME,
// PNSPS_LONG_BUTTON_THEME
} from "../../../themes/buttonConst";
import { ThemeProvider } from "@emotion/react";
import { FormattedMessage, useIntl } from "react-intl";
// ==============================|| DASHBOARD - DEFAULT ||============================== //
@@ -145,11 +147,11 @@ const Index = () => {
<Grid container justifyContent="flex-start" alignItems="center" >
<center>
<Grid item xs={12} md={8} >
<Typography variant="h3" sx={{ textAlign: "left", ml: 4, mr: 4, mt: 4, borderBottom: "1px solid black" }}>
<Typography variant="h4" sx={{ textAlign: "left", ml: 4, mr: 4, mt: 4, borderBottom: "1px solid black" }}>
<FormattedMessage id="proofPaymentHeader_online" />
</Typography>

<Typography variant="h4" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}>
<Typography variant="h5" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}>
<div dangerouslySetInnerHTML={{
__html: intl.formatMessage(
{
@@ -167,7 +169,7 @@ const Index = () => {
id: 'proofPaymentBody_online2'
},
{
paymentDeadline: DateUtils.dateStr(record?.closingDate),
paymentDeadline: DateUtils.dateFormat(record?.closingDate, intl.formatMessage({id: "dateStrFormat"})),
}
)
}} />
@@ -175,10 +177,11 @@ const Index = () => {
</Typography>

<Typography variant="h4" sx={{ ml: 8, textAlign: "left" }}>
<ThemeProvider theme={PNSPS_LONG_BUTTON_THEME}>
<ThemeProvider theme={PNSPS_BUTTON_THEME}>
<Button
component="span"
variant="contained"
// sx={{ ml: { sm: 4, md: 4, lg: 4 }, mr: 4, mt: { xs: 2, sm: 2 }, mb: { xs: 2, sm: 2 } }}
sx={{mr: 4 }}
onClick={() => { setIsPopUp(true) }}
>
@@ -238,7 +241,7 @@ const Index = () => {
<DialogContent style={{ display: 'flex', }}>
<Stack direction="column" justifyContent="space-between">
<Typography variant="h4">
<FormattedMessage id="totalAmount" /> (HK$): {FormatUtils.currencyFormat(fee)}
<FormattedMessage id="totalAmount" /> ($): {FormatUtils.currencyFormat(fee)}
</Typography>
</Stack>
</DialogContent>


+ 60
- 25
src/pages/Proof/Reply_GLD/ApplicationDetails.js Ver fichero

@@ -34,9 +34,11 @@ const ApplicationDetailCard = ({

const [data, setData] = useState({});
const [cancelPopUp, setCancelPopUp] = useState(false);
const [onDownload, setOnDownload] = useState(false);

useEffect(() => {
if (formData) {
console.log(formData)
setData(formData);
}
}, [formData]);
@@ -46,26 +48,50 @@ const ApplicationDetailCard = ({
initialValues: data,
});

const DisplayField = ({ name, width }) => {
return <TextField
fullWidth
disabled
size="small"
onChange={formik.handleChange}
id={name}
name={name}
value={formik.values[name]}
variant="outlined"
sx={
{
"& .MuiInputBase-input.Mui-disabled": {
WebkitTextFillColor: "#000000",
background: "#f8f8f8",
},
width: width ? width : '100%'
}
const DisplayField = ({ name, width, dummyUser }) => {
return <>
{dummyUser?
<TextField
fullWidth
disabled
size="small"
onChange={formik.handleChange}
id={name}
name={name}
value={"GLD: "+formik.values[name]}
variant="outlined"
sx={
{
"& .MuiInputBase-input.Mui-disabled": {
WebkitTextFillColor: "#000000",
background: "#f8f8f8",
},
width: width ? width : '100%'
}
}
/>
:
<TextField
fullWidth
disabled
size="small"
onChange={formik.handleChange}
id={name}
name={name}
value={formik.values[name]}
variant="outlined"
sx={
{
"& .MuiInputBase-input.Mui-disabled": {
WebkitTextFillColor: "#000000",
background: "#f8f8f8",
},
width: width ? width : '100%'
}
}
/>
}
/>;
</>
}

const confirmCancel = () => {
@@ -83,8 +109,15 @@ const ApplicationDetailCard = ({
}

const genProof = () => {
setOnDownload(true)
HttpUtils.fileDownload({
url: UrlUtils.GEN_GAZETTE_PROOF + "/" + params.id
url: UrlUtils.GEN_GAZETTE_PROOF + "/" + params.id,
onResponse:()=>{
setOnDownload(false)
},
onError:()=>{
setOnDownload(false)
}
});
}

@@ -105,7 +138,7 @@ const ApplicationDetailCard = ({
component="span"
variant="contained"
size="large"
disabled={!showProofBtn}
disabled={!showProofBtn||onDownload}
onClick={genProof}
>
<Typography variant="h5">Proof Slip</Typography>
@@ -170,10 +203,12 @@ const ApplicationDetailCard = ({

<Grid item xs={12} md={9} lg={9}>
<FormControl variant="outlined" fullWidth disabled >
{data.orgId === null ?
<DisplayField name="contactPerson" />
{data?.orgId?
<DisplayField
name="applicant"
dummyUser={data?.enCompanyName == "GLD" ? true : false}/>
:
<DisplayField name="applicant" />
<DisplayField name="contactPerson" />
}
</FormControl>
</Grid>
@@ -270,7 +305,7 @@ const ApplicationDetailCard = ({
</Grid>
<Grid item xs={12} md={12} lg={12}
sx={{ display: 'flex', alignItems: 'center' }}>
<Typography variant="h5">Deadline for confirm proof and payment</Typography>
<Typography variant="h5">Deadline for confirm proof and payment</Typography>
</Grid>
<Grid item xs={12} md={12} lg={12} sx={{ mb: 4, display: 'flex', alignItems: 'center' }}>
<Typography variant="h5">Before {DateUtils.datetimeStr(data.proofPaymentDeadline)}</Typography>


+ 1
- 1
src/pages/Proof/Reply_GLD/ProofForm.js Ver fichero

@@ -76,7 +76,7 @@ const FormPanel = ({ formData, isOverTime }) => {
isOverTime ?
<Grid container direction="column" sx={{ paddingLeft: 4, paddingRight: 4 }} spacing={1}>
<Grid item xs={12} md={12} textAlign="left">
<Typography variant="h5">The response timed out, please apply again.</Typography>
<Typography variant="h5">Proofing timed out. Please apply again.</Typography>
</Grid>
</Grid>
:


+ 4
- 4
src/pages/Proof/Reply_GLD/UploadFileTable.js Ver fichero

@@ -44,10 +44,10 @@ export default function UploadFileTable({recordList, setRecordList,}) {
...rowModesModel,
[id]: { mode: GridRowModes.View, ignoreModifications: true },
});
console.log("Starting Delete")
const editedRow = rows.find((row) => row.id === id);
console.log(editedRow)
console.log(editedRow.isNew)
// console.log("Starting Delete")
// const editedRow = rows.find((row) => row.id === id);
// console.log(editedRow)
// console.log(editedRow.isNew)
setRecordList(rows.filter((row) => row.id !== id));
setRows(rows.filter((row) => row.id !== id));
}


+ 57
- 12
src/pages/Proof/Reply_Public/ApplicationDetails.js Ver fichero

@@ -18,6 +18,9 @@ const MainCard = Loadable(React.lazy(() => import('components/MainCard')));
import * as StatusUtils from "utils/statusUtils/PublicNoteStatusUtils";
import FileList from "components/FileList"
import { FormattedMessage, useIntl } from "react-intl";
import {
isORGLoggedIn,
} from "utils/Utils";
// ==============================|| DASHBOARD - DEFAULT ||============================== //
const ApplicationDetailCard = ({ formData, }) => {

@@ -175,6 +178,32 @@ const ApplicationDetailCard = ({ formData, }) => {
</Grid>
</Grid>
</Grid>
{isORGLoggedIn() ?
<>
<Grid container direction="row" justifyContent="space-between"
alignItems="center">
<Grid item xs={12} md={6} lg={6} sx={{ mb: 1, }}>
<Grid container alignItems="left">
<Grid item xs={12} md={3} lg={3}
sx={{ display: 'flex', alignItems: 'center' }}>
<FormLabel><Typography variant="pnspsFormParagraph">
<FormattedMessage id="careOf" />:
</Typography></FormLabel>
</Grid>

<Grid item xs={12} md={9} lg={9}>
<Stack direction="row">
<DisplayField name="careOf" />
</Stack>
</Grid>
</Grid>
</Grid>
</Grid>
</>
:
null

}
<Grid container direction="row" justifyContent="space-between"
alignItems="center">
<Grid item xs={12} md={6} lg={6} sx={{ mb: 1, }}>
@@ -205,9 +234,11 @@ const ApplicationDetailCard = ({ formData, }) => {
<Grid item xs={12} sm={12} md={6} lg={6} sx={{ mb: 1 }}>
<Grid container alignItems={"center"}>
<Grid item xs={12} sm={12} md={12} lg={12} sx={{ alignItems: 'center', wordBreak: 'break-word' }}>
<Typography><Typography variant="pnspsFormParagraph">
<FormattedMessage id="pleaseCheckReminder" />:
</Typography></Typography>
<Typography>
<Typography variant="pnspsFormParagraph">
<FormattedMessage id="pleaseCheckReminder" />:
</Typography>
</Typography>
</Grid>
<Grid item xs={12} sm={12} md={12} lg={12} sx={{ width: '95%', maxWidth: { xs: '70vw', sm: '72vw', md: '75vw', lg: '80vw' } }}>
<FileList
@@ -223,11 +254,14 @@ const ApplicationDetailCard = ({ formData, }) => {
/>
</Grid>
</Grid>

</Grid>

<Grid item xs={12} md={5} lg={5} sx={{ mb: 1, }}>
<Grid container alignItems={"center"}>
{
data.creditor == true ?
<>
<Grid item xs={12} md={12} lg={12}
sx={{ display: 'flex', alignItems: 'center' }}>
<Typography variant="h5" display="inline">
@@ -240,7 +274,7 @@ const ApplicationDetailCard = ({ formData, }) => {
{locale === 'en' ?
`${intl.formatMessage({ id: 'before' })} ${DateUtils.dateFormat(data?.reviseDeadline, intl.formatMessage({ id: "paymentMethodDatetimeStrFormat" }))?.replace("am", "a.m.")?.replace("pm", "p.m.")} `
:
`${DateUtils.dateFormat(data?.reviseDeadline, intl.formatMessage({ id: "paymentMethodDatetimeStrFormat" }))?.replace("am", "a.m.")?.replace("pm", "p.m.")} ${intl.formatMessage({ id: 'before' })}`
`${DateUtils.dateFormat(data?.reviseDeadline, intl.formatMessage({ id: "paymentMethodDatetimeStrFormat" }))?.replace("am", "上午")?.replace("pm", "下午")}${intl.formatMessage({ id: 'before' })}`
}
</Typography>
</Grid>
@@ -256,15 +290,21 @@ const ApplicationDetailCard = ({ formData, }) => {
{locale === 'en' ?
`${intl.formatMessage({ id: 'before' })} ${DateUtils.dateFormat(data?.proofPaymentDeadline, intl.formatMessage({ id: "paymentMethodDatetimeStrFormat" }))?.replace("am", "a.m.")?.replace("pm", "p.m.")} `
:
`${DateUtils.dateFormat(data?.proofPaymentDeadline, intl.formatMessage({ id: "paymentMethodDatetimeStrFormat" }))?.replace("am", "a.m.")?.replace("pm", "p.m.")} ${intl.formatMessage({ id: 'before' })}`
`${DateUtils.dateFormat(data?.proofPaymentDeadline, intl.formatMessage({ id: "paymentMethodDatetimeStrFormat" }))?.replace("am", "上午")?.replace("pm", "下午")}${intl.formatMessage({ id: 'before' })}`
}
</Typography>
</Grid>
</>
:
<></>
}

<Grid item xs={12} sm={3} md={3} lg={3}
sx={{ mb: 1, display: 'flex', alignItems: 'center' }}>
<Typography variant="pnspsFormParagraph">
<FormattedMessage id="payFeeFor" />:
<Typography>
<Typography variant="pnspsFormParagraph">
<FormattedMessage id="payFeeFor" />:
</Typography>
</Typography>
</Grid>
<Grid item xs={12} sm={9} md={9} lg={9} sx={{ mb: 1, display: 'flex', alignItems: 'center' }}>
@@ -274,11 +314,16 @@ const ApplicationDetailCard = ({ formData, }) => {
{
formik.values.groupType === "Private Bill"
?
<Typography variant="pnspsFormParagraph">( {data.noOfPages} {intl.formatMessage({ id: 'page' })} x $6,552 )</Typography>
<Typography>
<Typography variant="pnspsFormParagraph">( {data.noOfPages} {intl.formatMessage({ id: 'page' })} x $6,552 )</Typography>
</Typography>
:
<Typography variant="pnspsFormParagraph">( {data.length} cm x {data.colCount === 2 ?
"$364 " + intl.formatMessage({ id: 'doubleCol' }) :
"$182 " + intl.formatMessage({ id: 'singleCol' })} )</Typography>
<Typography>
<Typography variant="pnspsFormParagraph">( {data.length} cm x {data.colCount === 2 ?
"$364 " + intl.formatMessage({ id: 'doubleCol' }) :
"$182 " + intl.formatMessage({ id: 'singleCol' })} )
</Typography>
</Typography>
}
</Grid>
</Grid>


+ 187
- 142
src/pages/Proof/Reply_Public/ProofForm.js Ver fichero

@@ -26,7 +26,10 @@ import { notifyActionSuccess } from 'utils/CommonFunction';
import { PNSPS_BUTTON_THEME } from "themes/buttonConst";
import { ThemeProvider } from "@emotion/react";
import { FormattedMessage, useIntl } from "react-intl";
import { isDummyLoggedIn } from "utils/Utils"
import {
isDummyLoggedIn,
checkIsOnlyOnlinePaymentByIssueDate
} from "utils/Utils"

const UploadFileTable = Loadable(React.lazy(() => import('./UploadFileTable')));
//import * as ProofStatus from "utils/statusUtils/ProofStatus";
@@ -46,9 +49,11 @@ const FormPanel = ({ formData }) => {
const [warningTitle, setWarningTitle] = React.useState("");
const [isWarningPopUp, setIsWarningPopUp] = React.useState(false);
const [warningText, setWarningText] = React.useState("");
const [isOnlyOnlinePayment, setOnlyOnlinePayment] = React.useState();

const navigate = useNavigate()
const params = useParams();
const dft = locale === 'en' ? "DD MMMM YYYY" : "YYYY年MM月DD日";

const tabelStyle = {
border: "2px solid gray",
@@ -60,8 +65,11 @@ const FormPanel = ({ formData }) => {
React.useEffect(() => {
if (formData) {
setData(formData);
setOnlyOnlinePayment(checkIsOnlyOnlinePaymentByIssueDate(formData.issueDate))
if (isDummyLoggedIn()) {
set_paymentMethod("demandNote")
} else if (checkIsOnlyOnlinePaymentByIssueDate(formData.issueDate)){
set_paymentMethod("online")
}
}
}, [formData]);
@@ -120,7 +128,7 @@ const FormPanel = ({ formData }) => {
},
files: attachments ? attachments : [],
onSuccess: function (responseData) {
console.log(responseData)
// console.log(responseData)
if (responseData.success === false) {
navigate("/publicNotice/" + responseData.id);
} else {
@@ -236,7 +244,7 @@ const FormPanel = ({ formData }) => {
<FormattedMessage id="proofReplyDate" /> :&nbsp;
{
locale === 'en' ?
DateUtils.dateValue(formik.values.replyDate)
DateUtils.datetimeStr(formik.values.replyDate)
:
DateUtils.datetimeStr_Cht(formik.values.replyDate)
}
@@ -319,138 +327,29 @@ const FormPanel = ({ formData }) => {
isDummyLoggedIn() ?
<Grid item xs={12} sx={{ mb: 1, }}>
<table style={tabelStyle}>
<tr style={tabelStyle}>
<th style={tabelStyle} width="50" align="left"></th>
<th style={tabelStyle} width="300" align="left"><FormattedMessage id="paymentMeans" /></th>
<th style={tabelStyle} width="300" align="left"><FormattedMessage id="confirmingDealine" /></th>
<th style={tabelStyle} width="400" align="left"><FormattedMessage id="PaymentCoonpletDealine" /></th>
</tr>
<tr>
<td style={tabelStyle}>
<Checkbox
checked={paymentMethod == "demandNote"}
onChange={() => {
set_paymentMethod("demandNote")
}}
/>
</td>
<td style={tabelStyle}>
<FormattedMessage id="payDn" />
<br /><a href="#payOnlineDetails" color='#fff' onClick={() => {
setWarningTitle(intl.formatMessage({ id: "payDn" }))
setWarningText(
<><FormattedMessage id="paymentMethodMeans" />
<ul>
<li><FormattedMessage id="atm" /></li>
<li><FormattedMessage id="pps" /></li>
<li><FormattedMessage id="eBank" /></li>
<li><FormattedMessage id="phoneBank" /></li>
<li><FormattedMessage id="eCheque" /></li>
<li><FormattedMessage id="fps" /></li>
<li><FormattedMessage id="hkpo" /></li>
<li><FormattedMessage id="store" /></li>
<li><FormattedMessage id="post" /></li>
</ul>
</>
);
setIsWarningPopUp(true);
}}><FormattedMessage id="viewDetail" /></a>
</td>
<td style={tabelStyle}>{DateUtils.dateFormat(formData.closingDateOff, intl.formatMessage({ id: "dateStrFormat" }))} 5:00 p.m.</td>
<td style={tabelStyle}>
<FormattedMessage id="payDnRemark" values={{
date: DateUtils.dateFormat(formData.closingDate, intl.formatMessage({ id: "dateStrFormat" })) + " 12:00 p.m."
}} />
</td>
</tr>
<tr>
<td style={tabelStyle}>
<Checkbox
checked={paymentMethod == "office"}
onChange={() => {
set_paymentMethod("office")
}}
/>
</td>
<td style={tabelStyle}>
<FormattedMessage id="payNPGO" />
<br /><a href="#payOnlineDetails" color='#fff' onClick={() => {
setWarningTitle(intl.formatMessage({ id: "payNPGO" }))
setWarningText(
<><FormattedMessage id="paymentMethodMeans" />
<ul>
<li><FormattedMessage id="cheque" /></li>
<li><FormattedMessage id="cash" /></li>
</ul>
</>
);
setIsWarningPopUp(true);
}}><FormattedMessage id="viewDetail" /></a>
</td>
<td style={tabelStyle}>{DateUtils.dateFormat(formData.closingDate, intl.formatMessage({ id: "dateStrFormat" }))} 12:00 p.m.</td>
<td style={tabelStyle}>
<FormattedMessage id="payNPGORemark" values={{
date: DateUtils.dateFormat(formData.closingDate, intl.formatMessage({ id: "dateStrFormat" })) + " 12:30 p.m."
}} />
</td>
</tr>
</table>
</Grid> :
<>
<Grid item xs={12} sx={{ mb: 1, }}>
<table style={tabelStyle}>
<tbody>
<tr style={tabelStyle}>
<th style={tabelStyle} width="50" align="left"></th>
<th style={tabelStyle} width="300" align="left"><FormattedMessage id="paymentMeans" /></th>
<th style={tabelStyle} width="300" align="left"><FormattedMessage id="commentDeadline" /></th>
<th style={tabelStyle} width="300" align="left"><FormattedMessage id="confirmingDealine" /></th>
<th style={tabelStyle} width="400" align="left"><FormattedMessage id="PaymentCoonpletDealine" /></th>
</tr>
<tr>
<td style={tabelStyle}>
<Checkbox
checked={paymentMethod == "online"}
checked={paymentMethod == "demandNote"}
onChange={() => {
set_paymentMethod("online")
set_paymentMethod("demandNote")
}}
/>
</td>
<td style={tabelStyle}>
<FormattedMessage id="payOnline" />
<FormattedMessage id="paymentMeans" />: <FormattedMessage id="payDn" />
<br /><a href="#payOnlineDetails" color='#fff' onClick={() => {
setWarningTitle(intl.formatMessage({ id: "payOnline" }))
setWarningTitle(intl.formatMessage({ id: "paymentMeans" }) + ": " + intl.formatMessage({ id: "payDn" }))
setWarningText(
<><FormattedMessage id="paymentMethodMeans" />
<ul>
<li><FormattedMessage id="fps" /></li>
<li><FormattedMessage id="card" /></li>
<li><FormattedMessage id="pps" /></li>
</ul>
</>
);
setIsWarningPopUp(true);
}}><FormattedMessage id="viewDetail" /></a>
</td>
<td style={tabelStyle}>{DateUtils.dateFormat(formData.proofPaymentDeadline, intl.formatMessage({ id: "paymentMethodDatetimeStrFormat" }))?.replace("am", "a.m.")?.replace("pm", "p.m.")}</td>
<td style={tabelStyle}>{DateUtils.dateFormat(formData.expiryDate, intl.formatMessage({ id: "paymentMethodDatetimeStrFormat" }))?.replace("am", "a.m.")?.replace("pm", "p.m.")}</td>
</tr>
<tr>
<td style={tabelStyle}>
{isOverDnReviseDeadline() ?
<></> :
<Checkbox
checked={paymentMethod == "demandNote"}
onChange={() => {
set_paymentMethod("demandNote")
}}
/>
}
</td>
<td style={tabelStyle}>
<FormattedMessage id="payDn" />
<br /><a href="#payOnlineDetails" color='#fff' onClick={() => {
setWarningTitle(intl.formatMessage({ id: "payDn" }))
setWarningText(
<><FormattedMessage id="paymentMethodMeans" />
<><FormattedMessage id="paymentMethodMeans" />:
<ul>
<li><FormattedMessage id="atm" /></li>
<li><FormattedMessage id="pps" /></li>
@@ -462,64 +361,210 @@ const FormPanel = ({ formData }) => {
<li><FormattedMessage id="store" /></li>
<li><FormattedMessage id="post" /></li>
</ul>
<Typography variant="h6">
<div style={{ padding: 12 }} dangerouslySetInnerHTML={{ __html: intl.formatMessage({ id: "proofNote" }) }} />
</Typography>
</>
);
setIsWarningPopUp(true);
}}><FormattedMessage id="viewDetail" /></a>
}}><u><FormattedMessage id="viewDetail" /></u></a>
</td>
<td style={tabelStyle}>{DateUtils.dateFormat(formData.closingDateOff, intl.formatMessage({ id: "dateStrFormat" }))} 5:00 p.m.</td>
<td style={tabelStyle}>{DateUtils.dateFormat(formData.closingDateOff, intl.formatMessage({ id: "dateStrFormat" }))} 5:00 p.m.</td>
<td style={tabelStyle}>
<FormattedMessage id="payDnRemark" values={{
date: DateUtils.dateFormat(formData.closingDate, intl.formatMessage({ id: "dateStrFormat" })) + " 12:00 p.m."
date: DateUtils.dateFormat(formData.closingDate, intl.formatMessage({ id: "dateStrFormat" }))
}} />
</td>
</tr>

<tr>
<td style={tabelStyle}>
{
isOverNpgoReviseDeadline() ?
<></> :
<Checkbox
checked={paymentMethod == "office"}
onChange={() => {
set_paymentMethod("office")
}}
/>
}
<Checkbox
checked={paymentMethod == "office"}
onChange={() => {
set_paymentMethod("office")
}}
/>
</td>
<td style={tabelStyle}>
<FormattedMessage id="payNPGO" />
<br /><a href="#payOnlineDetails" color='#fff' onClick={() => {
setWarningTitle(intl.formatMessage({ id: "payNPGO" }))
setWarningTitle(intl.formatMessage({ id: "paymentMeans" }) + ": " + intl.formatMessage({ id: "payNPGOPopUpTitle" }))
setWarningText(
<><FormattedMessage id="paymentMethodMeans" />
<><FormattedMessage id="paymentMethodMeans" />:
<ul>
<li><FormattedMessage id="cheque" /></li>
<li><FormattedMessage id="drafts" /></li>
<li><FormattedMessage id="cashierOrders" /></li>
<li><FormattedMessage id="cash" /></li>
</ul>
</>
);
setIsWarningPopUp(true);
}}><FormattedMessage id="viewDetail" /></a>
}}><u><FormattedMessage id="viewDetail" /></u></a>
</td>
<td style={tabelStyle}>{DateUtils.dateFormat(formData.closingDate, intl.formatMessage({ id: "dateStrFormat" }))} 11:30 a.m.</td>
<td style={tabelStyle}>{DateUtils.dateFormat(formData.closingDate, intl.formatMessage({ id: "dateStrFormat" }))} 12:00 p.m.</td>
<td style={tabelStyle}>
<FormattedMessage id="payNPGORemark" values={{
date: DateUtils.dateFormat(formData.closingDate, intl.formatMessage({ id: "dateStrFormat" })) + " 12:30 p.m."
date: DateUtils.dateFormat(formData.closingDate, intl.formatMessage({ id: "dateStrFormat" }))
}} />
</td>
</tr>

</tbody>
</table>
</Grid> :
<>
<Grid item xs={12} sx={{ mb: 1, }}>
<table style={tabelStyle}>
<tbody>
<tr style={tabelStyle}>
<th style={tabelStyle} width="50" align="left"></th>
<th style={tabelStyle} width="300" align="left"><FormattedMessage id="paymentMeans" /></th>
<th style={tabelStyle} width="300" align="left"><FormattedMessage id="commentDeadline" /></th>
<th style={tabelStyle} width="300" align="left"><FormattedMessage id="confirmingDealine" /></th>
<th style={tabelStyle} width="400" align="left"><FormattedMessage id="PaymentCoonpletDealine" /></th>
</tr>
<tr>
<td style={tabelStyle}>
<Checkbox
checked={paymentMethod == "online"}
onChange={() => {
set_paymentMethod("online")
}}
/>
</td>
<td style={tabelStyle}>
<FormattedMessage id="payOnline" />
<br /><a href="#payOnlineDetails" color='#fff' onClick={() => {
setWarningTitle(intl.formatMessage({ id: "paymentMeans" }) + ": " + intl.formatMessage({ id: "payOnline" }))
setWarningText(
<><FormattedMessage id="paymentMethodMeans" />:
<ul>
<li><FormattedMessage id="fps" /></li>
<li><FormattedMessage id="card" /></li>
<li><FormattedMessage id="pps" /></li>
</ul>
</>
);
setIsWarningPopUp(true);
}}><u><FormattedMessage id="viewDetail" /></u></a>
</td>
<td style={tabelStyle}>{
locale === 'en' ?
`${DateUtils.dateFormat(formData.reviseDeadline, intl.formatMessage({ id: "datetimeFormate" }))?.replace("am", "a.m.")?.replace("pm", "p.m.")}`
:
`${DateUtils.dateFormat(formData.reviseDeadline, intl.formatMessage({ id: "datetimeFormate" }))?.replace("am", "上午")?.replace("pm", "下午").replace("00分", "")}`
}</td>
<td style={tabelStyle}>{
locale === 'en' ?
`${DateUtils.dateFormat(formData.proofPaymentDeadline, intl.formatMessage({ id: "datetimeFormate" }))?.replace("am", "a.m.")?.replace("pm", "p.m.")}`
:
`${DateUtils.dateFormat(formData.proofPaymentDeadline, intl.formatMessage({ id: "datetimeFormate" }))?.replace("am", "上午")?.replace("pm", "下午").replace("00分", "")}`
}</td>
<td style={tabelStyle}>
<FormattedMessage id="payOnlineRemark" values={{
date: DateUtils.dateFormat(formData.proofPaymentDeadline, dft)
}} />
</td>
</tr>
{!isOnlyOnlinePayment?
<>
<tr>
<td style={tabelStyle}>
{isOverDnReviseDeadline() ?
<></> :
<Checkbox
checked={paymentMethod == "demandNote"}
onChange={() => {
set_paymentMethod("demandNote")
}}
/>
}
</td>
<td style={tabelStyle}>
<FormattedMessage id="payDn" />
<br /><a href="#payOnlineDetails" color='#fff' onClick={() => {
setWarningTitle(intl.formatMessage({ id: "paymentMeans" }) + ": " + intl.formatMessage({ id: "payDn" }))
setWarningText(
<><FormattedMessage id="paymentMethodMeans" />:
<ul>
<li><FormattedMessage id="atm" /></li>
<li><FormattedMessage id="pps" /></li>
<li><FormattedMessage id="eBank" /></li>
<li><FormattedMessage id="phoneBank" /></li>
<li><FormattedMessage id="eCheque" /></li>
<li><FormattedMessage id="fps" /></li>
<li><FormattedMessage id="hkpo" /></li>
<li><FormattedMessage id="store" /></li>
<li><FormattedMessage id="post" /></li>
</ul>
<Typography variant="h6">
<div style={{ padding: 12 }} dangerouslySetInnerHTML={{ __html: intl.formatMessage({ id: "proofNote" }) }} />
</Typography>
</>
);
setIsWarningPopUp(true);
}}><u><FormattedMessage id="viewDetail" /></u></a>
</td>
<td style={tabelStyle}>{DateUtils.dateFormat(formData.closingDateOff, intl.formatMessage({ id: "dateStrFormat" }))} {locale ==='en'?"5:00 p.m.":"下午5時"}</td>
<td style={tabelStyle}>{DateUtils.dateFormat(formData.closingDateOff, intl.formatMessage({ id: "dateStrFormat" }))} {locale ==='en'?"5:00 p.m.":"下午5時"}</td>
<td style={tabelStyle}>
<FormattedMessage id="payDnRemark" values={{
date: DateUtils.dateFormat(formData.proofPaymentDeadline, intl.formatMessage({ id: "dateStrFormat" }))
}} />
</td>
</tr>

<tr>
<td style={tabelStyle}>
{
isOverNpgoReviseDeadline() ?
<></> :
<Checkbox
checked={paymentMethod == "office"}
onChange={() => {
set_paymentMethod("office")
}}
/>
}
</td>
<td style={tabelStyle}>
<FormattedMessage id="payNPGO" />
<br /><a href="#payOnlineDetails" color='#fff' onClick={() => {
setWarningTitle(intl.formatMessage({ id: "paymentMeans" }) + ": " + intl.formatMessage({ id: "payNPGOPopUpTitle" }))
setWarningText(
<><FormattedMessage id="paymentMethodMeans" />:
<ul>
<li><FormattedMessage id="cheque" /></li>
<li><FormattedMessage id="drafts" /></li>
<li><FormattedMessage id="cashierOrders" /></li>
<li><FormattedMessage id="cash" /></li>
</ul>
</>
);
setIsWarningPopUp(true);
}}><u><FormattedMessage id="viewDetail" /></u></a>
</td>
<td style={tabelStyle}>{DateUtils.dateFormat(formData.closingDate, intl.formatMessage({ id: "dateStrFormat" }))} {locale ==='en'?"11:30 a.m.":"上午11時30分"}</td>
<td style={tabelStyle}>{DateUtils.dateFormat(formData.closingDate, intl.formatMessage({ id: "dateStrFormat" }))} {locale ==='en'?"12:00 p.m.":"下午12時"}</td>
<td style={tabelStyle}>
<FormattedMessage id="payNPGORemark" values={{
date: DateUtils.dateFormat(formData.closingDate, intl.formatMessage({ id: "dateStrFormat" }))
}} />
</td>
</tr>
</>:null
}
</tbody>

</table>
</Grid>
<Grid item xs={12}>
{/* <Grid item xs={12}>
<Typography variant="h6" height="100%" >
<div style={{ padding: 12 }} dangerouslySetInnerHTML={{ __html: intl.formatMessage({ id: "proofNote" }) }} />
</Typography>
</Grid>
</Grid> */}

<Grid item xs={12}>
<Typography variant="h6" height="100%" >
@@ -662,10 +707,10 @@ const FormPanel = ({ formData }) => {
</DialogContent>
<DialogActions>
<Button
aria-label={intl.formatMessage({ id: 'ok' })}
aria-label={intl.formatMessage({ id: 'close' })}
onClick={() => setIsWarningPopUp(false)}
>
OK
<FormattedMessage id="close" />
</Button>
</DialogActions>
</Dialog>


+ 4
- 4
src/pages/Proof/Reply_Public/UploadFileTable.js Ver fichero

@@ -46,10 +46,10 @@ export default function UploadFileTable({recordList, setRecordList,}) {
...rowModesModel,
[id]: { mode: GridRowModes.View, ignoreModifications: true },
});
console.log("Starting Delete")
const editedRow = rows.find((row) => row.id === id);
console.log(editedRow)
console.log(editedRow.isNew)
// console.log("Starting Delete")
// const editedRow = rows.find((row) => row.id === id);
// console.log(editedRow)
// console.log(editedRow.isNew)
setRecordList(rows.filter((row) => row.id !== id));
setRows(rows.filter((row) => row.id !== id));
}


+ 14
- 5
src/pages/Proof/Search_GLD/DataGrid.js Ver fichero

@@ -9,11 +9,11 @@ import { FiDataGrid } from "components/FiDataGrid";
import { clickableLink } from 'utils/CommonFunction';
// ==============================|| EVENT TABLE ||============================== //

export default function SearchPublicNoticeTable({searchCriteria}) {
export default function SearchPublicNoticeTable({searchCriteria, applyGridOnReady,applySearch}) {

const navigate = useNavigate()

const [_searchCriteria, set_searchCriteria] = React.useState({});
const [_searchCriteria, set_searchCriteria] = React.useState({searchCriteria});

React.useEffect(() => {
set_searchCriteria(searchCriteria);
@@ -83,6 +83,9 @@ export default function SearchPublicNoticeTable({searchCriteria}) {
renderCell: (params) => {
let company = params.row.enCompanyName != null?params.row.enCompanyName: params.row.chCompanyName;
company = company != null ? company : "";
if (company == "GLD"){
company = company + ": " + params.row.appCustName
}
return (<>
{params?.value}<br />{company}
</>);
@@ -119,12 +122,18 @@ export default function SearchPublicNoticeTable({searchCriteria}) {
<FiDataGrid
columns={columns}
customPageSize={10}
onRowDoubleClick={handleRowDoubleClick}
getRowHeight={() => 'auto'}
doLoad={{
onRowDoubleClick={handleRowDoubleClick}
applyGridOnReady={applyGridOnReady}
applySearch = {applySearch}
// doLoad={{
// url: LIST_PROOF,
// params: _searchCriteria,
// }}
doLoad={React.useMemo(() => ({
url: LIST_PROOF,
params: _searchCriteria,
}}
}), [_searchCriteria])}
/>
</div>
);


+ 71
- 12
src/pages/Proof/Search_GLD/SearchForm.js Ver fichero

@@ -21,22 +21,34 @@ import {DemoItem} from "@mui/x-date-pickers/internals/demo";
import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider";
import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs";
// ==============================|| DASHBOARD - DEFAULT ||============================== //
const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, issueComboData
const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, issueComboData, onGridReady
}) => {

const [type, setType] = React.useState([]);
const [status, setStatus] = React.useState(ComboData.proofStatus[0]);
const [status, setStatus] = React.useState(searchCriteria.statusKey!=undefined?ComboData.proofStatus_GLD[searchCriteria.statusKey]:ComboData.proofStatus_GLD[0]);
const [orgSelected, setOrgSelected] = React.useState({});
const [orgCombo, setOrgCombo] = React.useState();
const [issueSelected, setIssueSelected] = React.useState({});
const [issueCombo, setIssueCombo] = React.useState([]);
const [groupSelected, setGroupSelected] = React.useState({});
const [groupSelected, setGroupSelected] = React.useState(searchCriteria.gazettGroup!=undefined?ComboData.groupTitle.find(item => item.code === searchCriteria.gazettGroup):{});

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

// React.useEffect(() => {
// if(searchCriteria.status!=undefined){
// if(searchCriteria.status === ""){
// ComboData.proofStatus_GLD[0]
// }else{
// setSelectedStatus(ComboData.proofStatus_GLD.find(item => item.type === searchCriteria.status))
// }
// }else{
// setSelectedStatus(ComboData.proofStatus_GLD[0])
// }
// }, [searchCriteria]);
React.useEffect(() => {
setFromDateValue(minDate);
}, [minDate]);
@@ -68,26 +80,56 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss
refNo: data.refNo,
code: data.code,
issueId: issueSelected?.id,
gazettGroup: groupSelected?.type,
gazettGroup: groupSelected?.code,
dateFrom: sentDateFrom,
dateTo: sentDateTo,
contact: data.contact,
replyed: (status?.type && status?.type != 'all') ? status?.type : "",
orgId: (orgSelected?.key && orgSelected?.key > 0) ? orgSelected?.key : "",
statusKey:status?.key,

};


if(status?.type && status?.type != 'all'){
if (status?.type == "Confirmed"){
temp["replyed"] = "T";
temp["action"] = true;
temp["cancelled"] = false;
}else if(status?.type == "Re-proofing"){
temp["replyed"] = "T";
temp["action"] = false;
temp["cancelled"] = false;
}else if(status?.type == "No Reply"){
temp["replyed"] = "F";
temp["timeOut"] = "T";
temp["cancelled"] = false;
}else if(status?.type == "Cancelled"){
temp["cancelled"] = true;
} else{
temp["replyed"] = "F";
temp["timeOut"] = "F";
temp["cancelled"] = false;
}
}

applySearch(temp);
};

React.useEffect(() => {
if (orgComboData && orgComboData.length > 0) {
setOrgCombo(orgComboData);
if(searchCriteria.orgId!=undefined){
setOrgSelected(orgComboData.find(item => item.key === searchCriteria.orgId))
}
}
}, [orgComboData]);

React.useEffect(() => {
if (issueComboData && issueComboData.length > 0) {
setIssueCombo(issueComboData);
if(searchCriteria.issueId!=undefined){
setIssueSelected(issueComboData.find(item => item.id === searchCriteria.issueId))
}
}
}, [issueComboData]);

@@ -99,7 +141,12 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss
setGroupSelected({});
setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)))
setMaxDate(DateUtils.dateValue(new Date()))
reset();
reset({
refNo:"",
code:"",
contact:""
});
localStorage.setItem('searchCriteria',"")
}

function getIssueLabel(data) {
@@ -299,9 +346,10 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss
id="status"
size="small"
filterOptions={(options) => options}
options={ComboData.proofStatus}
options={ComboData.proofStatus_GLD}
value={status}
inputValue={status?.label ? status?.label : ""}
getOptionLabel={(option) => option.type? intl.formatMessage({ id: option.i18nLabel }) : ""}
inputValue={status? intl.formatMessage({id: status.i18nLabel}):""}
onChange={(event, newValue) => {
if (newValue !== null) {
setStatus(newValue);
@@ -323,13 +371,15 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss
<Grid item xs={9} s={6} md={5} lg={3} sx={{ ml: 3, mr: 3, mb: 3 }}>
<Autocomplete
{...register("orgId")}
disablePortal={false}
disablePortal
id="orgId"
size="small"
options={orgCombo}
groupBy={(option) => option.groupType}
size="small"
value={orgSelected}
getOptionLabel={(option) => option.name? option.name : ""}
inputValue={orgSelected ? orgSelected.name : ""}
inputValue={orgSelected ? orgSelected.name!=undefined?orgSelected.name:"" : ""}

onChange={(event, newValue) => {
if (newValue !== null) {
setOrgSelected(newValue);
@@ -345,6 +395,14 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss
}}
/>
)}
renderGroup={(params) => (
<Grid item key={params.key}>
<Typography fontSize={20} fontStyle="italic" p={1}>
{params.group}
</Typography>
{params.children}
</Grid>
)}
/>
</Grid>
: <></>
@@ -371,7 +429,8 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss
<Button
variant="contained"
type="submit"
>
disabled={onGridReady}
>
Submit
</Button>
</Grid>


+ 22
- 5
src/pages/Proof/Search_GLD/index.js Ver fichero

@@ -10,6 +10,7 @@ import * as React from "react";
import * as HttpUtils from "utils/HttpUtils";
import * as DateUtils from "utils/DateUtils";
import {GET_ORG_COMBO, GET_ISSUE_COMBO} from "utils/ApiPathConst";
import { getSearchCriteria } from "auth/utils";

import Loadable from 'components/Loadable';
const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent')));
@@ -32,15 +33,22 @@ const BackgroundHead = {
const UserSearchPage_Individual = () => {
const [orgCombo, setOrgCombo] = React.useState([]);
const [issueCombo, setIssueCombo] = React.useState([]);
const [searchCriteria, setSearchCriteria] = React.useState({
dateTo: DateUtils.dateValue(new Date()),
dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate() - 14)),
});
const [searchCriteria, setSearchCriteria] = React.useState({});
const [onReady, setOnReady] = React.useState(false);
const [onGridReady, setGridOnReady] = React.useState(false);

React.useEffect(() => {
React.useEffect(() => {
getOrgCombo();
getIssueCombo();
if (Object.keys(getSearchCriteria(window.location.pathname)).length>0){
setSearchCriteria(getSearchCriteria(window.location.pathname))
}else{
localStorage.setItem('searchCriteria',"")
setSearchCriteria({
dateTo: DateUtils.dateValue(new Date()),
dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)),
})
}
}, []);

React.useEffect(() => {
@@ -69,7 +77,13 @@ const UserSearchPage_Individual = () => {
}

function applySearch(input) {
setGridOnReady(true)
setSearchCriteria(input);
localStorage.setItem('searchCriteria', JSON.stringify({path:window.location.pathname,data:input}))
}

function applyGridOnReady(input) {
setGridOnReady(input);
}

return (
@@ -95,6 +109,7 @@ const UserSearchPage_Individual = () => {
orgComboData={orgCombo}
issueComboData={issueCombo}
searchCriteria={searchCriteria}
onGridReady={onGridReady}
/>
</Grid>
{/*row 2*/}
@@ -107,6 +122,8 @@ const UserSearchPage_Individual = () => {
>
<EventTable
searchCriteria={searchCriteria}
applyGridOnReady={applyGridOnReady}
applySearch={applySearch}
/>
</MainCard>
</Grid>


+ 32
- 21
src/pages/Proof/Search_Public/DataGrid.js Ver fichero

@@ -11,13 +11,14 @@ import { useNavigate } from "react-router-dom";
import { FiDataGrid } from "components/FiDataGrid";
import {
isORGLoggedIn,
} from "utils/Utils";
import {useTheme} from "@emotion/react";
import {useIntl} from "react-intl";
isDummyLoggedIn,
} from "utils/Utils";
import { useTheme } from "@emotion/react";
import { useIntl } from "react-intl";
import { clickableLink } from 'utils/CommonFunction';
// ==============================|| EVENT TABLE ||============================== //

export default function SearchPublicNoticeTable({ searchCriteria }) {
export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnReady, applySearch }) {

const navigate = useNavigate()
const theme = useTheme();
@@ -44,7 +45,15 @@ export default function SearchPublicNoticeTable({ searchCriteria }) {
'& .MuiDataGrid-footerContainer': {
border: 1,
borderColor: "#EEE"
}
},
"& .MuiDataGrid-columnHeaderTitle": {
whiteSpace: "normal",
lineHeight: "normal"
},
"& .MuiDataGrid-columnHeader": {
// Forced to use important since overriding inline styles
height: "unset !important"
},
}


@@ -66,7 +75,7 @@ export default function SearchPublicNoticeTable({ searchCriteria }) {
}
}*/

const getIssueLabel=(data) =>{
const getIssueLabel = (data) => {
let issueYear = data.row.issueYear
let volume = data.row.issueVolume;
let issueNo = data.row.issueNo;
@@ -90,22 +99,22 @@ export default function SearchPublicNoticeTable({ searchCriteria }) {
+ ", " + DateUtils.dateFormat(issueDate, "D MMM YYYY (ddd)");
}

const columns = [
{
field: 'actions',
headerName: intl.formatMessage({id: 'proofId'}),
headerName: intl.formatMessage({ id: 'proofId' }),
width: isMdOrLg ? 'auto' : 200,
flex: isMdOrLg ? 1.5 : undefined,
cellClassName: 'actions',
renderCell: (params) => {
return clickableLink('/proof/reply/' + params.row.id,params.row.refNo);
return clickableLink('/proof/reply/' + params.row.id, params.row.refNo);
},
},
{
id: 'appId',
field: 'appId',
headerName: isORGLoggedIn()?intl.formatMessage({id: 'gazetteCount3'}):intl.formatMessage({id: 'gazetteCount2'}),
headerName: isORGLoggedIn() ? intl.formatMessage({ id: 'gazetteCount3' }) : intl.formatMessage({ id: 'gazetteCount2' }),
width: isMdOrLg ? 'auto' : 330,
flex: isMdOrLg ? 2 : undefined,
renderCell: (params) => {
@@ -114,13 +123,13 @@ export default function SearchPublicNoticeTable({ searchCriteria }) {
let isssue = getIssueLabel(params);

// return <div style={{ margin: 4 }}>{appNo}<br />{isssue}<br />{params.row.appRemarks}</div>
return <div style={{ margin: 4 }}>{isssue}<br />{isORGLoggedIn()?<>{params.row.appCareOf}<br /></>:null}{params.row.appRemarks}</div>
return <div style={{ margin: 4 }}>{isssue}<br />{isORGLoggedIn() ? isDummyLoggedIn()?<><>GLD: {params.row.applicant}<br /></><>{params.row.appCareOf}<br /></></>:<>{params.row.appCareOf}<br /></> : null}{params.row.appRemarks}</div>
},
},
{
id: 'created',
field: 'created',
headerName: intl.formatMessage({id: 'proofDate'}),
field: 'reviseDeadline',
headerName: intl.formatMessage({ id: 'proofDate' }),
width: isMdOrLg ? 'auto' : 200,
flex: isMdOrLg ? 1.5 : undefined,
valueGetter: (params) => {
@@ -130,7 +139,7 @@ export default function SearchPublicNoticeTable({ searchCriteria }) {
{
id: 'proofPaymentDeadline',
field: 'proofPaymentDeadline',
headerName: intl.formatMessage({id: 'replyBefore'}),
headerName: intl.formatMessage({ id: 'replyBefore' }),
width: isMdOrLg ? 'auto' : 200,
flex: isMdOrLg ? 1.5 : undefined,
valueGetter: (params) => {
@@ -142,7 +151,7 @@ export default function SearchPublicNoticeTable({ searchCriteria }) {
{
id: 'replyDate',
field: 'replyDate',
headerName: intl.formatMessage({id: 'replyDate'}),
headerName: intl.formatMessage({ id: 'replyDate' }),
width: isMdOrLg ? 'auto' : 200,
flex: isMdOrLg ? 1.5 : undefined,
valueGetter: (params) => {
@@ -151,17 +160,17 @@ export default function SearchPublicNoticeTable({ searchCriteria }) {
},
{
id: 'actions',
headerName: intl.formatMessage({id: 'status'}),
headerName: intl.formatMessage({ id: 'status' }),
width: isMdOrLg ? 'auto' : 160,
flex: isMdOrLg ? 1 : undefined,
renderCell: (params) => {
return locale === 'en' ? ProofStatus.getStatus_Eng(params) : ProofStatus.getStatus_Cht(params);
return locale === 'en' ? ProofStatus.getStatus_Eng(params) : locale === 'zh-HK' ? ProofStatus.getStatus_Cht(params) : ProofStatus.getStatus_Cn(params);
},
},
{
id: 'fee',
field: 'fee',
headerName: intl.formatMessage({id: 'fee'}),
headerName: intl.formatMessage({ id: 'fee' }),
width: isMdOrLg ? 'auto' : 160,
flex: isMdOrLg ? 1 : undefined,
valueGetter: (params) => {
@@ -175,7 +184,7 @@ export default function SearchPublicNoticeTable({ searchCriteria }) {
}

return (
<div style={{ width: '100%', overflowX: 'auto'}}>
<div style={{ width: '100%', overflowX: 'auto' }}>

<FiDataGrid
sx={_sx}
@@ -183,10 +192,12 @@ export default function SearchPublicNoticeTable({ searchCriteria }) {
customPageSize={10}
getRowHeight={() => "auto"}
onRowDoubleClick={handleRowDoubleClick}
doLoad={{
applyGridOnReady={applyGridOnReady}
applySearch={applySearch}
doLoad={React.useMemo(() => ({
url: LIST_PROOF,
params: _searchCriteria,
}}
}), [_searchCriteria])}
/>
</div>
);

+ 32
- 8
src/pages/Proof/Search_Public/SearchForm.js Ver fichero

@@ -22,16 +22,16 @@ import {DemoItem} from "@mui/x-date-pickers/internals/demo";
import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider";
import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs";
// ==============================|| DASHBOARD - DEFAULT ||============================== //
const SearchPublicNoticeForm = ({ applySearch, searchCriteria, issueComboData
const SearchPublicNoticeForm = ({ applySearch, searchCriteria, issueComboData, onGridReady
}) => {
const intl = useIntl();
const { locale } = intl;
const [type, setType] = React.useState([]);
const [status, setStatus] = React.useState(ComboData.proofStatus[0]);
const [status, setStatus] = React.useState(searchCriteria.statusKey!=undefined?ComboData.proofStatusFull[searchCriteria.statusKey]:ComboData.proofStatusFull[0]);
const [issueSelected, setIssueSelected] = React.useState({});
const [issueCombo, setIssueCombo] = React.useState([]);
const [groupSelected, setGroupSelected] = React.useState({});
const [groupSelected, setGroupSelected] = React.useState(searchCriteria.gazettGroup!=undefined?ComboData.groupTitle.find(item => item.code === searchCriteria.gazettGroup):{});

const [minDate, setMinDate] = React.useState(searchCriteria.dateFrom);
const [maxDate, setMaxDate] = React.useState(searchCriteria.dateTo);
@@ -84,9 +84,24 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, issueComboData
gazettGroup: groupSelected?.type,
dateFrom: sentDateFrom,
dateTo: sentDateTo,
//contact: data.contact,
replyed: (status?.type && status?.type != 'all') ? status?.type : "",
statusKey:status?.key,
};
if(status?.type && status?.type != 'all'){
if (status?.type == "Confirmed"){
temp["replyed"] = "T";
temp["action"] = true;
}else if(status?.type == "Re-proofing"){
temp["replyed"] = "T";
temp["action"] = false;
}else if(status?.type == "No Reply"){
temp["replyed"] = "F";
temp["timeOut"] = "T";
}else{
temp["replyed"] = "F";
temp["timeOut"] = "F";
}
}
applySearch(temp);
};

@@ -94,17 +109,24 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, issueComboData
React.useEffect(() => {
if (issueComboData && issueComboData.length > 0) {
setIssueCombo(issueComboData);
if(searchCriteria.issueId!=undefined){
setIssueSelected(issueComboData.find(item => item.id === searchCriteria.issueId))
}
}
}, [issueComboData]);

function resetForm() {
setType([]);
setStatus(ComboData.proofStatus[0]);
setStatus(ComboData.proofStatusFull[0]);
setIssueSelected({});
setGroupSelected({});
setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)))
setMaxDate(DateUtils.dateValue(new Date()))
reset();
reset({
refNo:"",
code:"",
});
localStorage.setItem('searchCriteria',"")
}

function getIssueLabel(data) {
@@ -300,8 +322,9 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, issueComboData
disablePortal={false}
size="small"
id="status"
disableClearable
filterOptions={(options) => options}
options={ComboData.proofStatus}
options={ComboData.proofStatusFull}
value={status}
getOptionLabel={(option) => option.type? intl.formatMessage({ id: option.i18nLabel }) : ""}
inputValue={status? intl.formatMessage({ id: status.i18nLabel }) : ""}
@@ -345,6 +368,7 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, issueComboData
variant="contained"
type="submit"
aria-label={intl.formatMessage({id: 'submit'})}
disabled={onGridReady}
>
<FormattedMessage id="submit"/>
</Button>


+ 20
- 4
src/pages/Proof/Search_Public/index.js Ver fichero

@@ -9,6 +9,7 @@ import * as UrlUtils from "utils/ApiPathConst";
import * as React from "react";
import * as HttpUtils from "utils/HttpUtils";
import * as DateUtils from "utils/DateUtils";
import { getSearchCriteria } from "auth/utils";

import Loadable from 'components/Loadable';
const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent')));
@@ -37,9 +38,15 @@ const UserSearchPage_Individual = () => {
dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)),
});
const [onReady, setOnReady] = React.useState(false);
const [onGridReady, setGridOnReady] = React.useState(false);

React.useEffect(() => {
getIssueCombo();
if (Object.keys(getSearchCriteria(window.location.pathname)).length>0){
setSearchCriteria(getSearchCriteria(window.location.pathname))
}else{
localStorage.setItem('searchCriteria',"")
}
}, []);

React.useEffect(() => {
@@ -59,7 +66,13 @@ const UserSearchPage_Individual = () => {

function applySearch(input) {
setGridOnReady(true)
setSearchCriteria(input);
localStorage.setItem('searchCriteria', JSON.stringify({path:window.location.pathname,data:input}))
}

function applyGridOnReady(input) {
setGridOnReady(input);
}

return (
@@ -83,9 +96,10 @@ const UserSearchPage_Individual = () => {
{/*row 1*/}
<Grid item xs={12} md={12} lg={12}>
<SearchForm
applySearch={applySearch}
issueComboData={issueCombo}
searchCriteria={searchCriteria}
applySearch={applySearch}
issueComboData={issueCombo}
searchCriteria={searchCriteria}
onGridReady={onGridReady}
/>
</Grid>
{/*row 2*/}
@@ -96,7 +110,9 @@ const UserSearchPage_Individual = () => {
sx={{width: "-webkit-fill-available"}}
>
<EventTable
searchCriteria={searchCriteria}
searchCriteria={searchCriteria}
applyGridOnReady={applyGridOnReady}
applySearch={applySearch}
/>
</MainCard>
</Grid>


Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio

Cargando…
Cancelar
Guardar