Compare commits

...

234 커밋

작성자 SHA1 메시지 날짜
  Jason Chuang 62c3a6bbfd FPS enable web-to-app 1 주 전
  Alex Cheung 32c3b256da update check page 3 주 전
  Alex Cheung fbd0a00b8b update db check page /databaseHealthCheck 4 주 전
  Alex Cheung 520de2f87c update recon download file btn 1 개월 전
  Alex Cheung 8a873414c6 update download btn disable 1 개월 전
  Alex Cheung 0347064423 add get jvm info 2 달 전
  Alex Cheung 3fdf6311bb update jvm page 2 달 전
  Alex Cheung 7777e520c4 FIx FPS cancel 2 달 전
  Alex Cheung f5e671ca7f fix public notes save search criteria 2 달 전
  Jason Chuang 985118ae10 fix audit log export 2 달 전
  Alex Cheung ad333c8621 update SearchCriteria save 2 달 전
  Alex Cheung ab6377db8c update save page number for data gird 2 달 전
  Alex Cheung afd6fe0242 update massage 2 달 전
  Alex Cheung 3cf55a0191 update message 2 달 전
  Alex Cheung 673229bbe5 update org register remove '()' checking 2 달 전
  Alex Cheung 3cc816b55c update org user faxNo and org faxNo and dashboard clear search 3 달 전
  Alex Cheung f85eb71007 fix clear combo 3 달 전
  Alex Cheung 923c8577f3 update gld view searching and gld user search page bug fix 3 달 전
  Alex Cheung c2fe95a1a6 update application and bug fix 3 달 전
  Alex Cheung 70e6943b4a update public search criteria save 3 달 전
  Alex Cheung 868e84838d update proof searchCriteria save 3 달 전
  Alex Cheung ef23ec8af9 layout fix 7 달 전
  Alex Cheung 75f4c51fff update home page message and about us 7 달 전
  Alex Cheung d849afb6fc update about us 7 달 전
  Alex Cheung b436ffa1d0 update application reset btn 7 달 전
  Alex Cheung fe84a6f046 add back FPS auto cancel 8 달 전
  Alex Cheung 6a07b6cc71 add careOf and org combo 9 달 전
  Jason Chuang 257526d37c emport phone no 9 달 전
  Alex Cheung 18a990b716 Merge branch 'New_Enhancement' into CR003 9 달 전
  Alex Cheung ebcccfc705 update proof combo 9 달 전
  Alex Cheung d66410f7ac fix table field for dummy user 9 달 전
  Alex Cheung d748c23f51 update fps web to app for testing 9 달 전
  Alex Cheung 68914b6406 updated contactPerson with empty string when user is dummy user 9 달 전
  Alex Cheung 71541441a5 update fps expired 9 달 전
  Alex Cheung a591027d29 update fps 9 달 전
  Alex Cheung 324548afbf update gen gdn 9 달 전
  Alex Cheung 50a22d0d69 handle dummy user client display 9 달 전
  Alex Cheung 48a88815c1 add search combo for gld views 9 달 전
  Alex Cheung ded2428881 combo update 10 달 전
  Alex Cheung 6015900f57 update audit log auth 10 달 전
  Alex Cheung 77efaee1da add application remark auth 10 달 전
  Alex Cheung c16e0af999 update group 10 달 전
  Alex Cheung 35daecbf33 add auth 10 달 전
  Alex Cheung 874aeeb2cc fix grid loading 11 달 전
  Alex Cheung 9d537b917c remove build 11 달 전
  Alex Cheung 4952fcab16 search button update 11 달 전
  Alex Cheung efa7c3933b fix datagrid error 11 달 전
  Alex Cheung 9d4ecf4390 fix datagird without search button 11 달 전
  Alex Cheung 20902d5305 fix disable button with error 11 달 전
  Alex Cheung 5b5589566a update search button 11 달 전
  Alex Cheung 9c5bd9ac95 fix double search api for data table 11 달 전
  Alex Cheung 50ddd841b4 add loading to datagird 11 달 전
  Alex Cheung 63738d8b6a add loading for iAmsmart loading data 11 달 전
  Anna Ho 44325ecc10 CriOS as iOS_Chrome 11 달 전
  Alex Cheung 3ef7e45af1 update FPS test 11 달 전
  Jason Chuang 46aa7177fe Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement 11 달 전
  Jason Chuang 6b9998fccc FPS 11 달 전
  Alex Cheung 3b0753f753 update user guide 11 달 전
  Jason Chuang 505554a408 update user guide label 1 년 전
  Jason Chuang 0e92a27d81 update label 1 년 전
  Jason Chuang 70b87c12db update user guide pub link 1 년 전
  Anna Ho 3adb028a51 add 1 년 전
  Jason Chuang 8b0caa2231 Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement 1 년 전
  Jason Chuang f971b01920 update about us 1 년 전
  Anna Ho ddad685252 cn use zh user guide file 1 년 전
  Anna Ho e91b67420c change path 1 년 전
  Anna Ho 6d4e1cd767 add header 1 년 전
  Jason Chuang 5548862d84 Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement 1 년 전
  Jason Chuang c98e2c0a83 fps and about us 1 년 전
  Anna Ho f9e43b23e7 user-guide-pub 1 년 전
  Alex Cheung 4d74c29810 date change 1 년 전
  Alex Cheung 53ac90879b fix pending payment deadline 1 년 전
  Alex Cheung c1c38cdb53 update wordings 1 년 전
  Alex Cheung dd3c15fe40 Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement 1 년 전
  Alex Cheung c74c956d76 disable console.log 1 년 전
  Anna Ho 561610a51d change folder name 1 년 전
  Alex Cheung b6d805afa5 Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement 1 년 전
  Alex Cheung 78e85c246f update uat title color change 1 년 전
  Anna Ho 47da9555d4 AboutUs, ImportantNotice, PrivacyPolicy 1 년 전
  Jason Chuang 6b81ba3544 enable FPS web to app 1 년 전
  Alex Cheung 33f312ce75 update fps disable check mobile 1 년 전
  Alex Cheung 40ef9d6fe3 update district 1 년 전
  Anna Ho 0460eae108 about us color 1 년 전
  Anna Ho cddce62251 About Us UI fix 1 년 전
  Anna Ho 1f07220334 about us 1 년 전
  Alex Cheung bd313899b5 update wordings and userprofile 1 년 전
  Alex Cheung 8091aaeb27 Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement 1 년 전
  Alex Cheung 1bdbd45897 update idNo check 1 년 전
  Jason Chuang 3dfc109d63 iam smart label update 1 년 전
  Alex Cheung b1e5a946c4 fix display detail 1 년 전
  Alex Cheung b284fd5ba2 wording update 1 년 전
  Anna Ho 524272274d update 1 년 전
  Alex Cheung c0b27730d8 fix date bug 1 년 전
  Alex Cheung 0b46126b8c add admin header display 1 년 전
  Alex Cheung 1ceebfdb87 update wordings 1 년 전
  Anna Ho 3761c1184e iamsmart and fix dn sendDate bug 1 년 전
  Anna Ho ceed5c5cec change header to "Deadline for online manuscript revision (Pay online via PNSPS)" 1 년 전
  Anna Ho bd9655c4d2 fix bug 1 년 전
  Anna Ho 6880ed72ba iAM Smart set brokerPage=true 1 년 전
  Alex Cheung 0ee39a7fde update ui layout 1 년 전
  Alex Cheung 96b7bc6ef5 update i18n 1 년 전
  Alex Cheung 4afb60358b update i18n 1 년 전
  Alex Cheung e8a24e7403 update comment from Matt 1 년 전
  Alex Cheung ed089e64d1 fix i18n bug 1 년 전
  Alex Cheung 724e79b2fe Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement 1 년 전
  Alex Cheung 505af12820 update i18n 1 년 전
  Anna Ho 783bf7ccc8 update UI 1 년 전
  Anna Ho 602c4b420b fix bug 1 년 전
  Anna Ho c0811a72df fix i18n 1 년 전
  Anna Ho b04f433b4d update i18n 1 년 전
  Anna Ho 0cee61df7d remove "pnspsdev.gld.gov.hk" 1 년 전
  Anna Ho 875458a76f update UI 1 년 전
  Anna Ho a322555297 update UI 1 년 전
  Anna Ho ffd3f166fa update i18n 1 년 전
  Anna Ho 26b3f9597b update string 1 년 전
  Jason Chuang f378e4f16d Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement 1 년 전
  Jason Chuang 858d9d727e update message 1 년 전
  Alex Cheung f02a69cb4d Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement 1 년 전
  Alex Cheung 6e97e779d8 update payment status 1 년 전
  Anna Ho 428abdc670 on iamsmart fail page 1 년 전
  Alex Cheung 0cb399846f update payment status display 1 년 전
  Alex Cheung 5219813c26 fix gns routes 1 년 전
  Jason Chuang 2de38844d0 update access right for GDN 1 년 전
  Anna Ho f952d2a7fc fix url 1 년 전
  Anna Ho c2dabf0d9f update i18n 1 년 전
  Anna Ho cd93eccdc8 update user guide ui 1 년 전
  Anna Ho 09eb8afdd3 add userGuide 1 년 전
  Anna Ho aa370d75ed add Important Notice 1 년 전
  Anna Ho 6c3aca90bf update check ID 1 년 전
  Alex Cheung 07a6f593b6 fix user profile 1 년 전
  Anna Ho c91f032a2d Login Routes re 1 년 전
  Alex Cheung ab3adaad33 Merge branch 'test_HKID' into New_Enhancement 1 년 전
  Alex Cheung f1af83023b fix cnid cannot save 1 년 전
  Anna Ho 1a632f2cad add SYS.ui.manage.allowRegistration 1 년 전
  Alex Cheung a640af8c79 update change password page add text 1 년 전
  Alex Cheung f8d82db96d update user HKid and checkdigi 1 년 전
  Alex Cheung 51e3209acc Merge branch 'New_Enhancement' into test_HKID 1 년 전
  Anna Ho dedcbf29bd move iAM Smart api path to properties 1 년 전
  Alex Cheung dda5735faf fix login with wrong username 1 년 전
  Alex Cheung cdbf342265 update index icon 1 년 전
  Jason Chuang a683d36674 update about us 1 년 전
  Anna Ho ef73acfeb3 fix create proof bug 1 년 전
  Anna Ho a3217e28c3 update forgot username 1 년 전
  Anna Ho 89dcb5cad8 update reply proof UI 1 년 전
  Jason Chuang 524be841e9 Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement 1 년 전
  Jason Chuang bfe26b8160 update label 1 년 전
  Alex Cheung 4506564ee0 update fps prod url 1 년 전
  Anna Ho 6d3f5550a4 add about us 1 년 전
  Alex Cheung fd8b5427bc update gdn 1 년 전
  Anna Ho 7a5d5e6ede address5 change update phone 1 년 전
  Anna Ho ea4d92337c check proof column should > 0 1 년 전
  Anna Ho ca0dca8c10 update words 1 년 전
  Alex Cheung 09bd2f5098 Merge branch 'New_Enhancement' into SRAA_Test 1 년 전
  Alex Cheung 8ec89dec0f sraa update 1 년 전
  Jason Chuang fe5d91e148 update locale 1 년 전
  Anna Ho 4f95510418 word 1 년 전
  Anna Ho 3c4e51ca35 update word 1 년 전
  Alex Cheung a5d16b54a6 update Axios version for Vulnerable JS Library 1 년 전
  Anna Ho 415c86d1b9 update word 1 년 전
  Jason Chuang e70b0cbf05 Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement 1 년 전
  Jason Chuang 5982711ad6 update label 1 년 전
  Anna Ho b727c5cb8f privacyPolicy 1 년 전
  Jason Chuang 1fcfcbe8ec update label 1 년 전
  Anna Ho 1db138f63e user group fix bug 1 년 전
  Anna Ho f43c78838d fix i am smart bug 1 년 전
  Alex Cheung 36ebdfce6f update fps mobile btn 1 년 전
  Jason Chuang bcf88deadd Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement 1 년 전
  Jason Chuang fa974d4856 update label 1 년 전
  Terence 51dce719c3 update route case sensitive 1 년 전
  Anna Ho 4dd1b26a02 update iAM Smart button 1 년 전
  Alex Cheung bf113662ee Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement 1 년 전
  Alex Cheung 414e5da675 update check pasword special character and update org btn auth and application Id i18n 1 년 전
  Anna Ho 6bfed621e7 update iAM Smart button text 1 년 전
  Alex Cheung cd687d6cb9 update hidle payment table for credit user 1 년 전
  Anna Ho 63400671a7 GLD proof search statue 1 년 전
  Jason Chuang cb28ce731c Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement 1 년 전
  Jason Chuang b4eb579409 update label 1 년 전
  Anna Ho b700fff6e2 iAM Smart & status i18n 1 년 전
  Anna Ho bdf58c0b2d "iAM Smart" update Login Success UI 1 년 전
  Anna Ho f6fbec0c45 "iAM Smart" from update 1 년 전
  Anna Ho 13bf252cdb "iAM Smart" update 1 년 전
  Alex Cheung a88c79deb8 update emailConfirm handle 1 년 전
  Alex Cheung 066ba60193 update Amendment zip 1 년 전
  Anna Ho 53e51f84c3 update gen O/S dn List 1 년 전
  Anna Ho 7b8b15398d status 1 년 전
  Anna Ho 6d76833cd4 iAm Smart fix typo 1 년 전
  Jason Chuang d36afa6ee9 Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement 1 년 전
  Jason Chuang 2999987498 update i18n 1 년 전
  Alex Cheung a91c53694e update check not accept btn checking and ui update 1 년 전
  Anna Ho 3aa8d99095 Proof Records Starus 1 년 전
  Anna Ho af54518f20 update status i18n 1 년 전
  Alex Cheung f120ab9edb update dummy user edit apply public notice fax and phone number 1 년 전
  Anna Ho 8fdc98276d fix bug 1 년 전
  Anna Ho 0c0b97456f GET_SEND_OVERDUE_CREDITOR_LIST 1 년 전
  Alex Cheung 99a229cf0c update setting 1 년 전
  Jason Chuang 646421d897 update label 1 년 전
  Jason Chuang a7b5878ecf update label 1 년 전
  Alex Cheung ad18ada2dc Merge branch 'master' into New_Enhancement 1 년 전
  Jason Chuang 1eed4d7f3d Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement 1 년 전
  Jason Chuang 55f53d384c update label 1 년 전
  Alex Cheung b8b843aae2 fix preferLocale and add orgPaymentRecord for org check online payment record 1 년 전
  Jason Chuang 922abf73ac Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement 1 년 전
  Jason Chuang 9234d74a74 label and layout update 1 년 전
  Alex Cheung 95e1b8c921 update 1 년 전
  Alex Cheung 13ec88f514 update fps second 1 년 전
  Alex Cheung e5614037b8 fix autoFocus 1 년 전
  Alex Cheung 51462e8283 fix eng name and cht name 1 년 전
  Alex Cheung 6ae8ba07a6 hidle error message without edit mode 1 년 전
  Alex Cheung 9e55135d38 update check captcha 1 년 전
  Alex Cheung 016ea6235d update check captcha 1 년 전
  Alex Cheung 39b150a58c update layout 1 년 전
  Alex Cheung e3cdffa2f5 update proof and payment page text 1 년 전
  Alex Cheung d7ae3c0ee1 update check name 1 년 전
  Anna Ho 4dca798a3a disable 15:00 Scheduled, add send mail Button 1 년 전
  Anna Ho 81639691e5 fix bug - reload after mark "published" 1 년 전
  Anna Ho ff0cbe1c05 Merge branch 'master' into New_Enhancement 1 년 전
  Anna Ho f13b166d63 Merge branch 'master' into New_Enhancement 1 년 전
  Alex Cheung cbc8eb2c90 update dashboard loading 1 년 전
  Alex Cheung 37a6b1f9e9 update 1 년 전
  Alex Cheung e9f2fdb852 update 1 년 전
  Alex Cheung b2a727ca61 add change password page 1 년 전
  Alex Cheung 55f9a1d78f Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement 1 년 전
  Alex Cheung bd40598a1d update password log 1 년 전
  Anna Ho da6bcd39fb fix bug 1 년 전
  Anna Ho 7af45e4e8d Merge branch 'master' into New_Enhancement 1 년 전
  Anna Ho c2e1d3a305 dn revoke paid 1 년 전
  Alex Cheung 630344cfc4 Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement 1 년 전
  Alex Cheung a78cdad254 add password remark 1 년 전
  Anna Ho 131b31f850 email and paid button at application 1 년 전
  Alex Cheung cb04b13088 Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement 1 년 전
  Alex Cheung b61dc7d04a update captcha 1 년 전
  Anna Ho a0d8c5f0db Merge branch 'master' into New_Enhancement 1 년 전
  Alex Cheung b7a919f44e Merge branch 'New_Enhancement' of https://git.2fi-solutions.com/alex/PNSPS-frontend-MaterialUI into New_Enhancement 1 년 전
  Alex Cheung ec5aa563e4 update gldRemarks for gld user 1 년 전
100개의 변경된 파일4015개의 추가작업 그리고 2815개의 파일을 삭제
분할 보기
  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. +419
    -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. +113
    -62
      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. +175
    -141
      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 파일 보기

@@ -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
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
파일 보기


+ 1
- 1
package.json 파일 보기

@@ -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 파일 보기

Before After
Width: 180  |  Height: 180  |  Size: 6.4 KiB

BIN
public/favicon-16x16.png 파일 보기

Before After
Width: 16  |  Height: 16  |  Size: 1.1 KiB

BIN
public/favicon-32x32.png 파일 보기

Before After
Width: 32  |  Height: 32  |  Size: 1.7 KiB

+ 9
- 38
public/index.html 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

Before After
Width: 300  |  Height: 300  |  Size: 6.8 KiB

BIN
src/assets/images/icons/expiredQrcodeEN.png 파일 보기

Before After
Width: 300  |  Height: 300  |  Size: 8.8 KiB

BIN
src/assets/images/icons/expiredQrcodeZH.png 파일 보기

Before After
Width: 300  |  Height: 300  |  Size: 6.9 KiB

+ 2
- 0
src/auth/index.js 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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>
);


+ 419
- 293
src/layout/MainLayout/Header/index.js 파일 보기

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

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

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

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

await navigate('/login');
};

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

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

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

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

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

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

:
<></>
}

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

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

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

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

:
<></>
}

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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


+ 23
- 13
src/layout/MainLayout/index.js 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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>


+ 113
- 62
src/pages/Organization/DetailPage/OrganizationCard.js 파일 보기

@@ -24,18 +24,20 @@ import { PNSPS_BUTTON_THEME } from "themes/buttonConst";
import { ThemeProvider } from "@emotion/react";
import { isGrantedAny } from "auth/utils";

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

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

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

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

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

return (
<MainCard elevation={0}
border={false}
@@ -311,17 +324,32 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => {
</ThemeProvider>
</Grid>
:
<Grid item sx={{ ml: 3, mr: 3 }}>
<ThemeProvider theme={PNSPS_BUTTON_THEME}>
<Button
variant="contained"
color="orange"
onClick={() => setCreditorConfirmPopUp(true)}
>
Mark as Credit Client
</Button>
</ThemeProvider>
</Grid>
<>
<Grid item sx={{ ml: 3, mr: 3 }}>
<ThemeProvider theme={PNSPS_BUTTON_THEME}>
<Button
variant="contained"
color="orange"
onClick={() => setCreditorConfirmPopUp(true)}
>
Mark as Credit Client
</Button>
</ThemeProvider>
</Grid>
{ isGrantedAny("MAINTAIN_DEMANDNOTE")?
<Grid item sx={{ ml: 3, mr: 3 }}>
<ThemeProvider theme={PNSPS_BUTTON_THEME}>
<Button
variant="contained"
color="primary"
onClick={() => sendDn_Overdue(true)}
>
Generate O&#47;S DN List
</Button>
</ThemeProvider>
</Grid> : null
}
</>
}
</>
}
@@ -396,18 +424,18 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => {
<Typography variant="pnspsFormParagraphBold">{FieldUtils.notNullFieldLabel("Expiry Date:")}</Typography>
</Grid>
<Grid item xs={12} md={6} lg={6}>
{(!editMode && !createMode)?
{(!editMode && !createMode) ?
<TextField
fullWidth
id="currentExDate"
// error={(fromDate===null)}
// type="date"
name="currentExDate"
value={fromDate!=null?DateUtils.dateStr(fromDate):DateUtils.dateStr(currentFromDate)}
value={fromDate != null ? DateUtils.dateStr(fromDate) : DateUtils.dateStr(currentFromDate)}
disabled={true}
/>:
/> :
<LocalizationProvider dateAdapter={AdapterDayjs}>
<DemoItem components={['DatePicker']}>
<DemoItem components={['DatePicker']}>
<DatePicker
id="brExpiryDate"
name="brExpiryDate"
@@ -426,9 +454,9 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => {
onChange={(newValue) => {
// console.log(newValue)
// setErrorMsg("")
if(DateUtils.dateValue(newValue)>DateUtils.dateValue(new Date())){
if (DateUtils.dateValue(newValue) > DateUtils.dateValue(new Date())) {
setFromDate(newValue);
}else{
} else {
// setErrorMsg("Please select a date after today.")
}
}}
@@ -438,19 +466,20 @@ const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => {
}
</Grid>
{
fromDate==null?
(!editMode && !createMode)?
<FormHelperText error id="helper-text-date">
Please select a date after today.
</FormHelperText>
:
fromDate == null ?
(!editMode && !createMode) ?
// <FormHelperText error id="helper-text-date">
// Please select a date after today.
// </FormHelperText>
null
:
<FormHelperText error id="helper-text-date">
{intl.formatMessage({ id: 'pleaseFillInBusinessRegCertValidityDate' })}
</FormHelperText>
:
:
null
}
}
</Grid>

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

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

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

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

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

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

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


+ 51
- 55
src/pages/Organization/DetailPage/OrganizationPubCard.js 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

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


+ 50
- 40
src/pages/Payment/FPS/fpscallback.js 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

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


+ 5
- 4
src/pages/Proof/Payment/Pay_DN.js 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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>


+ 175
- 141
src/pages/Proof/Reply_Public/ProofForm.js 파일 보기

@@ -49,6 +49,7 @@ const FormPanel = ({ formData }) => {

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

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

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

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

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

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

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


+ 4
- 4
src/pages/Proof/Reply_Public/UploadFileTable.js 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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 파일 보기

@@ -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>


이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.

불러오는 중...
취소
저장