From 5be3d301aa72ff158d3cd225e2c7dead1259cdcb Mon Sep 17 00:00:00 2001 From: anna Date: Tue, 10 Oct 2023 17:26:01 +0800 Subject: [PATCH 01/12] proof --- src/components/FileList.js | 211 +++++++----- src/layout/MainLayout/Header/index.js | 2 +- src/pages/ManageOrgUserPage/index.js | 125 +++---- .../ProofReply_Public/ApplicationDetails.js | 245 +++++++++++++ src/pages/ProofReply_Public/ProofForm.js | 256 ++++++++++++++ .../ProofReply_Public/UploadFileTable.js | 111 ++++++ src/pages/ProofReply_Public/index.js | 122 +++++++ src/pages/ProofSearch_Public/DataGrid.js | 144 ++++++++ src/pages/ProofSearch_Public/SearchForm.js | 322 ++++++++++++++++++ src/pages/ProofSearch_Public/index.js | 127 +++++++ .../UserInformationCard_Individual.js | 2 + src/routes/PublicUserRoutes.js | 10 + src/utils/ApiPathConst.js | 4 +- src/utils/DateUtils.js | 8 + 14 files changed, 1541 insertions(+), 148 deletions(-) create mode 100644 src/pages/ProofReply_Public/ApplicationDetails.js create mode 100644 src/pages/ProofReply_Public/ProofForm.js create mode 100644 src/pages/ProofReply_Public/UploadFileTable.js create mode 100644 src/pages/ProofReply_Public/index.js create mode 100644 src/pages/ProofSearch_Public/DataGrid.js create mode 100644 src/pages/ProofSearch_Public/SearchForm.js create mode 100644 src/pages/ProofSearch_Public/index.js diff --git a/src/components/FileList.js b/src/components/FileList.js index 8aa648c..b44d711 100644 --- a/src/components/FileList.js +++ b/src/components/FileList.js @@ -1,16 +1,16 @@ // material-ui import * as React from 'react'; import { - DataGrid, GridActionsCellItem, } from "@mui/x-data-grid"; import * as Icon from '../utils/IconUtils'; import * as HttpUtils from "../utils/HttpUtils" import * as UrlUtils from "../utils/ApiPathConst" import * as DateUtils from "../utils/DateUtils" +import { FiDataGrid } from './FiDataGrid'; // ==============================|| EVENT TABLE ||============================== // -export default function FileList({refType, refId, allowDelete, sx}) { +export default function FileList({ refType, refId, allowDelete, sx, dateHideable, ...props }) { const [rows, setRows] = React.useState([]); const [rowModesModel] = React.useState({}); @@ -22,12 +22,12 @@ export default function FileList({refType, refId, allowDelete, sx}) { HttpUtils.get( { url: UrlUtils.GET_FILE_DELETE, - params:{ + params: { fileId: fileId, - skey:skey, + skey: skey, filename: filename }, - onSuccess: function(){ + onSuccess: function () { loadData(); } } @@ -36,84 +36,124 @@ export default function FileList({refType, refId, allowDelete, sx}) { const onDownloadClick = (fileId, skey, filename) => () => { HttpUtils.fileDownload({ - fileId:fileId, - skey:skey, - filename:filename, + fileId: fileId, + skey: skey, + filename: filename, }); }; - const loadData = ()=>{ - HttpUtils.post( - { - url: UrlUtils.POST_FILE_LIST, - params:{ - refType: refType, - refId: refId, - }, - onSuccess: function(responseData){ - setRows(responseData.records); + const loadData = () => { + + HttpUtils.post( + { + url: UrlUtils.POST_FILE_LIST, + params: { + refType: refType, + refId:refId, + }, + onSuccess: function (responseData) { + setRows(responseData.records); + } } - } - ); + ); }; - const convertToStr=(bytes,decimals)=>{ - if(bytes == 0) return '0 Bytes'; + const convertToStr = (bytes, decimals) => { + if (bytes == 0) return '0 Bytes'; var dm = decimals || 2, sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; - let i = 0; - i = Math.floor(Math.log(bytes) / Math.log(1024)); + let i = 0; + i = Math.floor(Math.log(bytes) / Math.log(1024)); return parseFloat((bytes / Math.pow(1024, i)).toFixed(dm)) + ' ' + sizes[i]; } - const columns = [ - { - id: 'created', - field: 'created', - headerName: 'created', - flex: 1, - valueGetter:(params)=>{ - return DateUtils.datetimeStr(params.value); - } - }, - { - field: 'actions', - type: 'actions', - headerName: '', - width: 50, - cellClassName: 'actions', - getActions: (params) => { - return [ - } - label="Download" - className="textPrimary" - onClick={onDownloadClick(params.id, params.row.skey, params.row.filename)} - color="primary" - />] + const columns = (dateHideable ? + [ + { + field: 'actions', + type: 'actions', + headerName: '', + width: 50, + cellClassName: 'actions', + getActions: (params) => { + return [ + } + label="Download" + className="textPrimary" + onClick={onDownloadClick(params.id, params.row.skey, params.row.filename)} + color="primary" + />] + }, }, - },{ - id: 'filename', - field: 'filename', - headerName: 'filename', - flex: 3, - }, - { - id: 'filesize', - field: 'filesize', - headerName: 'filesize', - flex: 1, - valueGetter:(params)=>{ - return convertToStr(params.value); + { + id: 'filename', + field: 'filename', + headerName: 'filename', + flex: 3, + }, + { + id: 'filesize', + field: 'filesize', + headerName: 'filesize', + flex: 1, + valueGetter: (params) => { + return convertToStr(params.value); + } } - }, - ]; + ] + : + [ + { + id: 'created', + field: 'created', + headerName: 'created', + flex: 1, + valueGetter: (params) => { + return DateUtils.datetimeStr(params.value); + } + }, + { + field: 'actions', + type: 'actions', + headerName: '', + width: 50, + cellClassName: 'actions', + getActions: (params) => { + return [ + } + label="Download" + className="textPrimary" + onClick={onDownloadClick(params.id, params.row.skey, params.row.filename)} + color="primary" + />] + }, + }, + { + id: 'filename', + field: 'filename', + headerName: 'filename', + flex: 3, + }, + { + id: 'filesize', + field: 'filesize', + headerName: 'filesize', + flex: 1, + valueGetter: (params) => { + return convertToStr(params.value); + } + }, + ] + ); + - - if(allowDelete){ + if (allowDelete) { columns.push({ field: 'actions', type: 'actions', @@ -124,7 +164,7 @@ export default function FileList({refType, refId, allowDelete, sx}) { return [ } + icon={} label="Delete" className="textPrimary" onClick={onDeleteClick(params.id, params.row.skey, params.row.filename)} @@ -135,22 +175,23 @@ export default function FileList({refType, refId, allowDelete, sx}) { } return ( -
- -
+ //
+ + //
); } diff --git a/src/layout/MainLayout/Header/index.js b/src/layout/MainLayout/Header/index.js index f97636d..2fbc26f 100644 --- a/src/layout/MainLayout/Header/index.js +++ b/src/layout/MainLayout/Header/index.js @@ -118,7 +118,7 @@ function Header(props) { 我的公共啟事
  • - 校對記錄 + 校對記錄
  • 付款記錄 diff --git a/src/pages/ManageOrgUserPage/index.js b/src/pages/ManageOrgUserPage/index.js index 4a47da4..698ddfb 100644 --- a/src/pages/ManageOrgUserPage/index.js +++ b/src/pages/ManageOrgUserPage/index.js @@ -1,13 +1,11 @@ // material-ui -import { - DataGrid, - //GridActionsCellItem -} from "@mui/x-data-grid"; +import {FiDataGrid} from "components/FiDataGrid"; import { - Typography, Button, Grid -}from '@mui/material'; + Typography, Button, Grid, Stack +} from '@mui/material'; +import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' import Checkbox from '@mui/material/Checkbox'; import MainCard from "../../components/MainCard"; @@ -17,6 +15,15 @@ import * as HttpUtils from "../../utils/HttpUtils"; import * as UrlUtils from "../../utils/ApiPathConst"; import * as DateUtils from "../../utils/DateUtils"; +const BackgroundHead = { + backgroundImage: `url(${titleBackgroundImg})`, + width: '100%', + height: '100%', + backgroundSize: 'contain', + backgroundRepeat: 'no-repeat', + backgroundColor: '#0C489E', + backgroundPosition: 'right' +} // ==============================|| DASHBOARD - DEFAULT ||============================== // @@ -24,65 +31,64 @@ import * as DateUtils from "../../utils/DateUtils"; const ManageOrgUserPage = () => { const [rows, setRows] = React.useState([]); - const [rowModesModel] = React.useState({}); React.useEffect(() => { loadData(); }, []); - function loadData(){ + function loadData() { HttpUtils.get( { url: UrlUtils.GET_PUBLIC_ORG_USER_LIST, - onSuccess: function(responseData){ + onSuccess: function (responseData) { setRows(responseData); } } ); } - function onActiveClick(params){ + function onActiveClick(params) { HttpUtils.get({ - url: UrlUtils.GET_USER_UNLOCK+"/"+params.row.id, - onSuccess:()=>{ - loadData(); + url: UrlUtils.GET_USER_UNLOCK + "/" + params.row.id, + onSuccess: () => { + loadData(); } }); } - function getHeader(headerStr){ + function getHeader(headerStr) { return {headerStr}; } - function getStatus(params){ - if(params.row.locked){ + function getStatus(params) { + if (params.row.locked) { return ( <> - {getStatusTag({color:"#525150", text: "鎖定"})} - + {getStatusTag({ color: "#525150", text: "鎖定" })} + - ) - }else if(!params.row.verifiedBy){ - return getStatusTag({color:"#fca503", text: "待批核"}) - }else if(params.row.status == "active"){ - return getStatusTag({color:"#73AD21", text: "生效中"}) + ) + } else if (!params.row.verifiedBy) { + return getStatusTag({ color: "#fca503", text: "待批核" }) + } else if (params.row.status == "active") { + return getStatusTag({ color: "#73AD21", text: "生效中" }) } - return getStatusTag({text: params.row.status}) + return getStatusTag({ text: params.row.status }) } - function getStatusTag({color="#000", textColor="#FFF",text=""}){ - return ( -
    {text}
    + function getStatusTag({ color = "#000", textColor = "#FFF", text = "" }) { + return ( +
    {text}
    ) } - const setPrimaryUser=(params)=>{ + const setPrimaryUser = (params) => { HttpUtils.get( { - url: (!params.row.primaryUser?UrlUtils.GET_SET_PRIMARY_USER:UrlUtils.GET_SET_UN_PRIMARY_USER)+"/"+params.row.id, - onSuccess:function(){ + url: (!params.row.primaryUser ? UrlUtils.GET_SET_PRIMARY_USER : UrlUtils.GET_SET_UN_PRIMARY_USER) + "/" + params.row.id, + onSuccess: function () { loadData(); } } @@ -97,23 +103,23 @@ const ManageOrgUserPage = () => { field: 'username', headerName: getHeader('登錄名稱'), flex: 1, - + }, { id: 'contactPerson', field: 'contactPerson', headerName: getHeader('用戶名稱'), flex: 1, - + }, { id: 'contactTel', field: 'contactTel', headerName: getHeader('聯絡電話'), flex: 1, - valueGetter:(params)=>{ + valueGetter: (params) => { let contactTel = JSON.parse(params.value) - return contactTel?.countryCode+" "+contactTel?.phoneNumber; + return contactTel?.countryCode + " " + contactTel?.phoneNumber; } }, { @@ -127,7 +133,7 @@ const ManageOrgUserPage = () => { field: 'lastLogin', headerName: getHeader('最後登入日期'), flex: 1, - valueGetter:(params)=>{ + valueGetter: (params) => { return DateUtils.datetimeStr(params.value); } }, @@ -136,7 +142,7 @@ const ManageOrgUserPage = () => { field: 'lastApply', headerName: getHeader('最後提交申請日期'), flex: 1, - valueGetter:()=>{ + valueGetter: () => { return "--"; } }, @@ -159,9 +165,9 @@ const ManageOrgUserPage = () => { renderCell: (params) => { console.log(params); return ( - {setPrimaryUser(params)}} - checked={params.row.primaryUser} + { setPrimaryUser(params) }} + checked={params.row.primaryUser} /> ); }, @@ -169,30 +175,27 @@ const ManageOrgUserPage = () => { ]; return ( - - - Setting - - - 公司/機構用戶記錄 - + + + +
    + + 公司/機構用戶記錄 + +
    - - - + + +
    ); diff --git a/src/pages/ProofReply_Public/ApplicationDetails.js b/src/pages/ProofReply_Public/ApplicationDetails.js new file mode 100644 index 0000000..fed44a5 --- /dev/null +++ b/src/pages/ProofReply_Public/ApplicationDetails.js @@ -0,0 +1,245 @@ +// material-ui +import { + FormControl, + Grid, + Typography, + FormLabel, + TextField, + Stack +} from '@mui/material'; + +import { useFormik } from 'formik'; +import * as React from "react"; +import * as DateUtils from "utils/DateUtils" +import { useParams } from "react-router-dom"; +import Loadable from 'components/Loadable'; +const MainCard = Loadable(React.lazy(() => import('components/MainCard'))); +import * as StatusUtils from "../PublicNotice/ListPanel/PublicNoteStatusUtils"; +import FileList from "components/FileList" +// ==============================|| DASHBOARD - DEFAULT ||============================== // +const ApplicationDetailCard = ({ formData,}) => { + + const params = useParams(); + + const [data, setData] = React.useState({}); + //const [proofId, setProofId] = React.useState(); + + React.useEffect(() => { + if (formData){ + setData(formData); + //setProofId(formData.id); + } + }, [formData]); + + const formik = useFormik({ + enableReinitialize: true, + initialValues: data, + }); + + const DisplayField = ({ name, width }) => { + return ; + } + + function currencyFormat(num) { + let val = num?num:0; + return val.toLocaleString('en-US', { + minimumFractionDigits: 2 + }); + } + + + return ( + + + 公共啟事:校對資料 + +
    + + + + + + + 申請編號: + + + + + + + + + + + 申請狀態: + + + + + {StatusUtils.getStatusByText(data.appStatus)} + + + + + + + + + + 申請人: + + + + + {data.orgId === null ? + + : + + } + + + + + + + + 憲報期數: + + + + + + + + + + + + + 聯絡人: + + + + + + + + + + + + 刊出日期: + + + + + + + + + + + + + 我的備注: + + + + + + + + + + + + + + + + + 請下載下列印刷稿檔案,並仔細校對: + + + + + + + + + 繳費及返稿最後限期: + + + {DateUtils.dateStr_Cht(data.returnBeforeDate)} 下午 2:00前 + + + 應繳費用: + + + {currencyFormat(data.fee)} + + + { + formik.values.groupType == "A" + ? + ( {data.length} 頁 x $6,552 ) + : + ( {data.length} cm x {data.colCount==2?"$364 二格位":"$182 一格位"} ) + } + + + + + + + +
    +
    + ); +}; + +export default ApplicationDetailCard; diff --git a/src/pages/ProofReply_Public/ProofForm.js b/src/pages/ProofReply_Public/ProofForm.js new file mode 100644 index 0000000..42b89ab --- /dev/null +++ b/src/pages/ProofReply_Public/ProofForm.js @@ -0,0 +1,256 @@ +// material-ui +import { + Dialog, DialogTitle, DialogContent, DialogActions, + Typography, + Grid, + Stack, + TextField, + FormLabel, + Button, + RadioGroup, Radio, + FormControlLabel +} from '@mui/material'; +import * as UrlUtils from "utils/ApiPathConst"; +import * as HttpUtils from "utils/HttpUtils"; +import FileList from "components/FileList" +import MainCard from "components/MainCard"; +import * as React from "react"; +import * as yup from 'yup'; +import { useParams } from "react-router-dom"; +import { useFormik } from 'formik'; +import { useNavigate } from "react-router-dom"; +import * as DateUtils from "utils/DateUtils" +import Loadable from 'components/Loadable'; +const UploadFileTable = Loadable(React.lazy(() => import('./UploadFileTable'))); + +// ==============================|| DASHBOARD - DEFAULT ||============================== // + + +const FormPanel = ({ formData }) => { + + const [data, setData] = React.useState({}); + const [attachments, setAttachments] = React.useState([]); + + const [isWarningPopUp, setIsWarningPopUp] = React.useState(false); + const [warningText, setWarningText] = React.useState(""); + + const navigate = useNavigate() + const params = useParams(); + + React.useEffect(() => { + if (formData) { + setData(formData); + } + }, [formData]); + + const formik = useFormik({ + enableReinitialize: true, + initialValues: data, + validationSchema: yup.object().shape({ + vaild: yup.string().max(255, "請輸入你的登入密碼").required('請輸入你的登入密碼'), + }), + onSubmit: values => { + if (!values.action) { + if (!attachments || attachments.length <= 0) { + setWarningText("請選擇上傳檔案"); + setIsWarningPopUp(true); + return; + } + } + // console.log(values); + HttpUtils.postWithFiles({ + url: UrlUtils.REPLY_PROOF, + params: { + id: data.id, + action: values.action, + vaild: values.vaild, + }, + files: attachments ? attachments : [], + onSuccess: function () { + navigate("/proof/search"); + }, + onFail: function (response) { + setWarningText("行動失敗: 請檢查內容並再次提交回覆"); + setIsWarningPopUp(true); + console.log(response); + }, + onError: function (error) { + setWarningText("行動失敗: 請檢查內容並再次提交回覆"); + setIsWarningPopUp(true); + console.log(error); + } + }); + } + }); + + const readFile = (event) => { + let file = event.target.files[0]; + if (file) { + if (!file.name.toLowerCase().substr(file.name.length - 4).includes(".pdf")) { + setWarningText("請上傳有效檔案 (檔案格式: .pdf)"); + setIsWarningPopUp(true); + document.getElementById("uploadFileBtn").value = ""; + return; + } + if (file.size >= (10 * 1024 * 1034)) { + setWarningText("上傳檔案大小應<10MB"); + setIsWarningPopUp(true); + return; + } + + file['id'] = attachments.length; + setAttachments([ + ...attachments, + file + ]); + document.getElementById("uploadFileBtn").value = ""; + } + } + + + + return ( + + + + 公共啟事:校對回覆 + + +
    + + { + formik.values.replyDate ? + + + 校對回覆日期: {DateUtils.datetimeStr_Cht(formik.values.replyDate)} + + + 校對回覆: {formik.values.action? "可以付印(稿件正確)":"未能付印(需要修改)"} + + + + + + : + + + + + } label="可以付印(稿件正確)" /> + } label="未能付印(需要修改)" /> + + + + + 請上載稿件修改的檔案: + + + + = (formik.values.groupType == "A" ? 2 : 1)} + onChange={(event) => { + readFile(event) + }} + /> + + + + + + + + + + + + + 簽署: + + + + + + + + + + + + + } + + + +
    +
    + setIsWarningPopUp(false)} > + 注意 + + {warningText} + + + + + +
    +
    + ); +}; + +export default FormPanel; diff --git a/src/pages/ProofReply_Public/UploadFileTable.js b/src/pages/ProofReply_Public/UploadFileTable.js new file mode 100644 index 0000000..9090721 --- /dev/null +++ b/src/pages/ProofReply_Public/UploadFileTable.js @@ -0,0 +1,111 @@ +// material-ui +import * as React from 'react'; +import { + DataGrid, + GridActionsCellItem, + GridRowModes +} from "@mui/x-data-grid"; +import RemoveCircleOutlineIcon from '@mui/icons-material/RemoveCircleOutline'; +import {useEffect} from "react"; +// import {useNavigate} from "react-router-dom"; +// import { useTheme } from '@mui/material/styles'; +import { + Box, + Stack +} from '@mui/material'; +// ==============================|| EVENT TABLE ||============================== // + +export default function UploadFileTable({recordList, setRecordList,}) { + + const [rows, setRows] = React.useState(recordList); + const [rowModesModel,setRowModesModel] = React.useState({}); + // const theme = useTheme(); + + // const navigate = useNavigate() + + useEffect(() => { + setRows(recordList); + // console.log(disableDelete); + }, [recordList]); + + function NoRowsOverlay() { + return ( + + No File Record + {/*
    (rows={[]})
    */} +
    + ); + } + + const handleCancelClick = (id) => () => { + setRowModesModel({ + ...rowModesModel, + [id]: { mode: GridRowModes.View, ignoreModifications: true }, + }); + console.log("Starting Delete") + const editedRow = rows.find((row) => row.id === id); + console.log(editedRow) + console.log(editedRow.isNew) + setRecordList(rows.filter((row) => row.id !== id)); + setRows(rows.filter((row) => row.id !== id)); + } + + const columns = [ + { + field: 'actions', + type: 'actions', + headerName: '', + width: 30, + cellClassName: 'actions', + // hide:true, + getActions: ({id}) => { + return [ + } + label="delete" + className="textPrimary" + onClick={handleCancelClick(id)} + color="error" + />] + }, + }, + { + id: 'name', + field: 'name', + headerName: '檔案名稱', + flex: 1, + }, + { + id: 'size', + field: 'size', + headerName: '檔案大小', + valueGetter: (params) => { + // console.log(params) + return Math.ceil(params.value/1024)+" KB"; + }, + flex: 1, + }, + ]; + + return ( + + + + ); +} diff --git a/src/pages/ProofReply_Public/index.js b/src/pages/ProofReply_Public/index.js new file mode 100644 index 0000000..de29ffd --- /dev/null +++ b/src/pages/ProofReply_Public/index.js @@ -0,0 +1,122 @@ +// material-ui +import { + Grid, + Typography, + Stack, + Box +} from '@mui/material'; +import * as UrlUtils from "utils/ApiPathConst"; +import * as React from "react"; +import * as HttpUtils from "utils/HttpUtils"; +import * as DateUtils from "utils/DateUtils"; +import { useParams } from "react-router-dom"; + +import Loadable from 'components/Loadable'; +const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); +const ApplicationDetails = Loadable(React.lazy(() => import('./ApplicationDetails'))); +const ProofForm = Loadable(React.lazy(() => import('./ProofForm'))); +import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' +const BackgroundHead = { + backgroundImage: `url(${titleBackgroundImg})`, + width: '100%', + height: '100%', + backgroundSize: 'contain', + backgroundRepeat: 'no-repeat', + backgroundColor: '#0C489E', + backgroundPosition: 'right' +} + +// ==============================|| DASHBOARD - DEFAULT ||============================== // + +const Index = () => { + const params = useParams(); + + const [record, setRecord] = React.useState(); + const [onReady, setOnReady] = React.useState(false); + + React.useEffect(() => { + loadForm(); + }, []); + + React.useEffect(() => { + setOnReady(true); + }, [record]); + + + const loadForm = () => { + if (params.id > 0) { + + HttpUtils.get({ + url: UrlUtils.GET_PROOF + "/" + params.id, + onSuccess: (responseData) => { + responseData.data["phoneNumber"] = JSON.parse(responseData.data.contactTelNo).phoneNumber; + responseData.data["tel_countryCode"] = JSON.parse(responseData.data.contactTelNo).countryCode; + + responseData.data["faxNumber"] = JSON.parse(responseData.data.contactFaxNo).faxNumber; + responseData.data["fax_countryCode"] = JSON.parse(responseData.data.contactFaxNo).countryCode; + + responseData.data["issueNoStr"] = responseData.data.issueYear + +" Vol. "+zeroPad(responseData.data.issueVolume,3) + +", No. "+zeroPad(responseData.data.issueNo,2); + + responseData.data["issueDate"] = DateUtils.dateFormat(responseData.data.issueDate, "D MMM YYYY (ddd)"); + + responseData.data["groupType"] = responseData.data.groupNo.charAt(0); + responseData.data["action"] = responseData.data.replyDate?responseData.data.action:true; + setRecord(responseData.data); + } + }); + } + } + + function zeroPad(num, places) { + num=num?num:0; + var zero = places - num.toString().length + 1; + return Array(+(zero > 0 && zero)).join("0") + num; + } + + + return ( + !onReady ? + + : + + +
    + + 校對記錄 + +
    +
    + {/*row 1*/} + + +
    + + + + + + + + + + +
    +
    +
    + {/*row 2*/} +
    + ); +}; + +export default Index; diff --git a/src/pages/ProofSearch_Public/DataGrid.js b/src/pages/ProofSearch_Public/DataGrid.js new file mode 100644 index 0000000..b70343b --- /dev/null +++ b/src/pages/ProofSearch_Public/DataGrid.js @@ -0,0 +1,144 @@ +// material-ui +import * as React from 'react'; +import { + Button +} from '@mui/material'; +import * as DateUtils from "utils/DateUtils"; +import {useNavigate} from "react-router-dom"; +import {FiDataGrid} from "components/FiDataGrid"; +// ==============================|| EVENT TABLE ||============================== // + +export default function SearchPublicNoticeTable({ recordList }) { + const [rows, setRows] = React.useState(recordList); + const navigate = useNavigate() + + React.useEffect(() => { + setRows(recordList); + }, [recordList]); + + const handleEditClick = (params) => () => { + navigate('/proof/reply/'+ params.row.appId); + }; + + + const columns = [ + { + field: 'actions', + headerName: 'Proof No.', + width: 150, + cellClassName: 'actions', + renderCell: (params) => { + return ; + }, + }, + { + id: 'appId', + field: 'appId', + headerName: 'Application No./ Gazette Code/ Gazette Issue', + flex: 1, + renderCell: (params) => { + let appNo = params.row.appNo; + let code = params.row.groupNo; + let isssue = params.row.issueYear + +" Vol. "+zeroPad(params.row.issueVolume,3) + +", No. "+zeroPad(params.row.issueNo,2) + +", "+DateUtils.dateFormat(params.row.issueDate, "D MMM YYYY (ddd)"); + + return
    App No: {appNo}
    Gazette Code: {code}
    Issue: {isssue}
    + }, + }, + { + id: 'created', + field: 'created', + headerName: 'Proof Date', + flex: 1, + valueGetter: (params) => { + return DateUtils.datetimeStr(params?.value); + } + }, + { + id: 'replyDate', + field: 'replyDate', + headerName: 'Confirmed/Return Date', + flex: 1, + valueGetter: (params) => { + return params?.value?DateUtils.datetimeStr(params?.value):""; + } + }, + { + id: 'contactPerson', + field: 'contactPerson', + headerName: 'Contact Person', + flex: 1, + renderCell: (params) => { + let company = params.row.enCompanyName!= null ?" ("+(params.row.enCompanyName)+")":""; + + let phone = JSON.parse(params.row.contactTelNo); + let faxNo = JSON.parse(params.row.contactFaxNo); + + let contact = ""; + if (phone) { + contact = "Phone No.: " + phone?.countryCode + " " + phone?.phoneNumber + } + + if (faxNo && faxNo?.faxNumber) { + if (contact != "") + contact = contact + ", " + contact = contact + "Fax No.:" + faxNo?.countryCode + " " + faxNo?.faxNumber + } + + return (<> + {params?.value + company}
    + {contact} + ); + } + }, + { + id: 'groupTitle', + field: 'groupTitle', + headerName: 'Gazette Group', + flex: 1, + valueGetter: (params) => { + return (params?.value)?(params?.value):""; + } + }, + { + id: 'fee', + field: 'fee', + headerName: 'Fee', + flex: 1, + valueGetter: (params) => { + return (params?.value)?"$ "+currencyFormat(params?.value):""; + } + }, + ]; + + function currencyFormat(num) { + return num.toLocaleString('en-US', { + minimumFractionDigits: 2 + }); + } + + + function zeroPad(num, places) { + num=num?num:0; + var zero = places - num.toString().length + 1; + return Array(+(zero > 0 && zero)).join("0") + num; + } + + return ( +
    + + +
    + ); +} diff --git a/src/pages/ProofSearch_Public/SearchForm.js b/src/pages/ProofSearch_Public/SearchForm.js new file mode 100644 index 0000000..706191c --- /dev/null +++ b/src/pages/ProofSearch_Public/SearchForm.js @@ -0,0 +1,322 @@ +// material-ui +import { + Button, + CardContent, + Grid, TextField, + Autocomplete +} from '@mui/material'; +import MainCard from "components/MainCard"; +import { useForm } from "react-hook-form"; +import * as React from "react"; +import * as ComboData from "utils/ComboData"; +import * as DateUtils from "utils/DateUtils"; +// ==============================|| DASHBOARD - DEFAULT ||============================== // + + +const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria,issueComboData + }) => { + + const [type, setType] = React.useState([]); + const [status, setStatus] = React.useState({ key: 0, label: 'All', type: 'all' }); + 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 [minDate, setMinDate] = React.useState(searchCriteria.dateFrom); + const [maxDate, setMaxDate] = React.useState(searchCriteria.dateTo); + + + const { reset, register, handleSubmit } = useForm() + const onSubmit = (data) => { + + let typeArray = []; + + for (let i = 0; i < type.length; i++) { + typeArray.push(type[i].label); + } + + const temp = { + refNo: data.refNo, + code: data.code, + issueId: issueSelected?.id, + gazettGroup: groupSelected?.type, + dateFrom: data.dateFrom, + dateTo: data.dateTo, + contact: data.contact, + replyed: (status?.type && status?.type != 'all') ? status?.type : "", + orgId: (orgSelected?.key && orgSelected?.key > 0) ? orgSelected?.key : "", + + }; + applySearch(temp); + }; + + React.useEffect(() => { + if (orgComboData && orgComboData.length > 0) { + setOrgCombo(orgComboData); + } + }, [orgComboData]); + + React.useEffect(() => { + if (issueComboData && issueComboData.length > 0) { + setIssueCombo(issueComboData); + } + }, [issueComboData]); + + function resetForm() { + setType([]); + setStatus({ key: 0, label: 'All', type: 'all' }); + setOrgSelected({}); + setIssueSelected({}); + setGroupSelected({}); + reset(); + } + + function getIssueLabel(data){ + if(data=={}) return ""; + return data.year + +" Vol. "+zeroPad(data.volume,3) + +", No. "+zeroPad(data.issueNo,2) + +", "+DateUtils.dateFormat(data.issueDate, "D MMM YYYY (ddd)"); + } + + function zeroPad(num, places) { + num=num?num:0; + var zero = places - num.toString().length + 1; + return Array(+(zero > 0 && zero)).join("0") + num; + } + + return ( + + +
    + {/*row 1*/} + + + 搜尋 + + + + {/*row 2*/} + + + + + + + + + + + getIssueLabel(option)} + onChange={(event, newValue) => { + if (newValue !== null) { + setIssueSelected(newValue); + } + }} + renderInput={(params) => ( + + )} + /> + + + + option.label} + onChange={(event, newValue) => { + if (newValue !== null) { + setGroupSelected(newValue); + } + }} + renderInput={(params) => ( + + )} + /> + + + + { + setMinDate(DateUtils.dateStr(newValue)); + }} + InputLabelProps={{ + shrink: true + }} + /> + + + + { + setMaxDate(DateUtils.dateStr(newValue)); + }} + id="dateTo" + type="date" + label="校對日期(To)" + defaultValue={searchCriteria.dateTo} + /> + + + + + + + + + options} + options={ComboData.proofStatus} + value={status} + inputValue={status?.label?status?.label:""} + onChange={(event, newValue) => { + if (newValue !== null) { + setStatus(newValue); + } + }} + renderInput={(params) => ( + + )} + InputLabelProps={{ + shrink: true + }} + /> + + + { + orgCombo ? + + { + if (newValue !== null) { + setOrgSelected(newValue); + } + }} + renderInput={(params) => ( + + )} + /> + + : <> + } + + + + + + {/*last row*/} + + + + + + + + + + +
    +
    + ); +}; + +export default SearchPublicNoticeForm; diff --git a/src/pages/ProofSearch_Public/index.js b/src/pages/ProofSearch_Public/index.js new file mode 100644 index 0000000..95082e4 --- /dev/null +++ b/src/pages/ProofSearch_Public/index.js @@ -0,0 +1,127 @@ +// material-ui +import { + Grid, + Typography, + Stack +} from '@mui/material'; +import MainCard from "components/MainCard"; +import * as UrlUtils from "utils/ApiPathConst"; +import * as React from "react"; +import * as HttpUtils from "utils/HttpUtils"; +import * as DateUtils from "utils/DateUtils"; + +import Loadable from 'components/Loadable'; +const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); +const SearchForm = Loadable(React.lazy(() => import('./SearchForm'))); +const EventTable = Loadable(React.lazy(() => import('./DataGrid'))); +import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' + +const BackgroundHead = { + backgroundImage: `url(${titleBackgroundImg})`, + width: '100%', + height: '100%', + backgroundSize:'contain', + backgroundRepeat: 'no-repeat', + backgroundColor: '#0C489E', + backgroundPosition: 'right' +} + +// ==============================|| DASHBOARD - DEFAULT ||============================== // + +const UserSearchPage_Individual = () => { + + const [record,setRecord] = React.useState([]); + const [orgCombo,setOrgCombo] = React.useState([]); + const [issueCombo,setIssueCombo] = React.useState([]); + const [searchCriteria, setSearchCriteria] = React.useState({ + dateTo: DateUtils.dateStr(new Date()), + dateFrom: DateUtils.dateStr(new Date().setDate(new Date().getDate()-14)), + }); + const [onReady, setOnReady] = React.useState(false); + + React.useEffect(() => { + getUserList(); + getOrgCombo(); + getIssueCombo(); + }, []); + + React.useEffect(() => { + setOnReady(true); + }, [record]); + + React.useEffect(() => { + getUserList(); + }, [searchCriteria]); + + function getUserList(){ + HttpUtils.get({ + url: UrlUtils.LIST_PROOF, + params: searchCriteria, + onSuccess: function(responseData){ + setRecord(responseData); + } + }); + } + + function getOrgCombo(){ + HttpUtils.get({ + url: UrlUtils.GET_ORG_COMBO, + onSuccess: function(responseData){ + let combo = responseData; + setOrgCombo(combo); + } + }); + } + + function getIssueCombo(){ + HttpUtils.get({ + url: UrlUtils.GET_ISSUE_COMBO, + onSuccess: function(responseData){ + let combo = responseData; + setIssueCombo(combo); + } + }); + } + + + function applySearch(input) { + setSearchCriteria(input); + } + + return ( + !onReady ? + + : + + +
    + + 校對記錄 + +
    +
    + {/*row 1*/} + + + + {/*row 2*/} + + + + + +
    + ); +}; + +export default UserSearchPage_Individual; diff --git a/src/pages/pnspsUserDetailPage_Individual/UserInformationCard_Individual.js b/src/pages/pnspsUserDetailPage_Individual/UserInformationCard_Individual.js index 3087526..c7f3191 100644 --- a/src/pages/pnspsUserDetailPage_Individual/UserInformationCard_Individual.js +++ b/src/pages/pnspsUserDetailPage_Individual/UserInformationCard_Individual.js @@ -390,6 +390,7 @@ const UserInformationCard_Individual = ({ formData, loadDataFun }) => {
    + {FieldUtils.getComboField({ label: "Country:", valueName: "country", @@ -479,6 +480,7 @@ const UserInformationCard_Individual = ({ formData, loadDataFun }) => { + {FieldUtils.getComboField({ label: "District:", valueName: "district", diff --git a/src/routes/PublicUserRoutes.js b/src/routes/PublicUserRoutes.js index 9e3aa05..27aba9b 100644 --- a/src/routes/PublicUserRoutes.js +++ b/src/routes/PublicUserRoutes.js @@ -11,6 +11,8 @@ const ManageOrgUser = Loadable(lazy(() => import('pages/ManageOrgUserPage'))); const PublicNotice = Loadable(lazy(() => import('pages/PublicNotice/ListPanel'))); const PublicNoticeApplyForm = Loadable(lazy(() => import('pages/PublicNotice/ApplyForm'))); const PublicNoticeDetail = Loadable(lazy(() => import('pages/PublicNoticeDetail'))); +const ProofReply = Loadable(lazy(() => import('pages/ProofReply_Public'))); +const ProofSearch = Loadable(lazy(() => import('pages/ProofSearch_Public'))); // ==============================|| MAIN ROUTING ||============================== // @@ -45,6 +47,14 @@ const PublicDashboard = { path: 'publicNotice/:id', element: }, + { + path: 'proof/reply/:id', + element: + }, + { + path: 'proof/search', + element: + }, ] }, ] diff --git a/src/utils/ApiPathConst.js b/src/utils/ApiPathConst.js index 5848ccb..e22e4bc 100644 --- a/src/utils/ApiPathConst.js +++ b/src/utils/ApiPathConst.js @@ -70,8 +70,10 @@ export const UPDATE_PUBLIC_NOTICE_APPLY_DETAIL = apiPath+'/application/save'; export const GET_ISSUE_COMBO = apiPath+'/gazette-issue/combo'; export const LIST_PROOF = apiPath+'/proof/list';//GET -export const GET_PROOF_APP = apiPath+'/proof/create-from-app';//GET +export const GET_PROOF_APP = apiPath+'/proof/create-from-app';//GLD export const CREATE_PROOF = apiPath+'/proof/create';//POST +export const GET_PROOF = apiPath+'/proof/details';//GET +export const REPLY_PROOF = apiPath+'/proof/reply';//GET //User Group export const POST_AND_UPDATE_USER_GROUP = apiPath+'/group/save'; \ No newline at end of file diff --git a/src/utils/DateUtils.js b/src/utils/DateUtils.js index 52d55e0..9ec9e2d 100644 --- a/src/utils/DateUtils.js +++ b/src/utils/DateUtils.js @@ -9,6 +9,14 @@ export const dateStr = (date) =>{ return dateFormat(date,"YYYY-MM-DD") }; +export const datetimeStr_Cht = (date) =>{ + return dateFormat(date,"YYYY年MM月DD日 HH:mm:ss") +}; + +export const dateStr_Cht = (date) =>{ + return dateFormat(date,"YYYY年MM月DD日") +}; + export const convertToDate = (date)=>{ if(typeof date == 'number'){ return dayjs(date); From 3f565e5fba8c02ada1eff0d4af39723be198bcac Mon Sep 17 00:00:00 2001 From: anna Date: Wed, 11 Oct 2023 12:13:34 +0800 Subject: [PATCH 02/12] update ui and combo --- src/components/FileList.js | 12 +- .../ProofReply_Public/ApplicationDetails.js | 29 +-- src/pages/ProofReply_Public/ProofForm.js | 188 ++++++++++-------- src/pages/ProofReply_Public/index.js | 93 +++++---- src/pages/ProofSearch_Public/DataGrid.js | 77 +++---- src/pages/ProofSearch_Public/SearchForm.js | 59 +----- src/pages/ProofSearch_Public/index.js | 18 +- .../ListPanel/SearchPublicNoticeForm.js | 3 +- src/utils/ComboData.js | 75 +++---- src/utils/DateUtils.js | 2 +- 10 files changed, 250 insertions(+), 306 deletions(-) diff --git a/src/components/FileList.js b/src/components/FileList.js index b44d711..045f3fe 100644 --- a/src/components/FileList.js +++ b/src/components/FileList.js @@ -10,7 +10,7 @@ import * as DateUtils from "../utils/DateUtils" import { FiDataGrid } from './FiDataGrid'; // ==============================|| EVENT TABLE ||============================== // -export default function FileList({ refType, refId, allowDelete, sx, dateHideable, ...props }) { +export default function FileList({ refType, refId, allowDelete, sx, dateHideable,lang, ...props }) { const [rows, setRows] = React.useState([]); const [rowModesModel] = React.useState({}); @@ -91,13 +91,13 @@ export default function FileList({ refType, refId, allowDelete, sx, dateHideable { id: 'filename', field: 'filename', - headerName: 'filename', + headerName: lang=="ch"?"檔案名稱":'File Name', flex: 3, }, { id: 'filesize', field: 'filesize', - headerName: 'filesize', + headerName: lang=="ch"?"檔案大小":'File Size', flex: 1, valueGetter: (params) => { return convertToStr(params.value); @@ -109,7 +109,7 @@ export default function FileList({ refType, refId, allowDelete, sx, dateHideable { id: 'created', field: 'created', - headerName: 'created', + headerName: lang=="ch"?"日期":'Created', flex: 1, valueGetter: (params) => { return DateUtils.datetimeStr(params.value); @@ -136,13 +136,13 @@ export default function FileList({ refType, refId, allowDelete, sx, dateHideable { id: 'filename', field: 'filename', - headerName: 'filename', + headerName: lang=="ch"?"檔案名稱":'File Name', flex: 3, }, { id: 'filesize', field: 'filesize', - headerName: 'filesize', + headerName: lang=="ch"?"檔案大小":'File Size', flex: 1, valueGetter: (params) => { return convertToStr(params.value); diff --git a/src/pages/ProofReply_Public/ApplicationDetails.js b/src/pages/ProofReply_Public/ApplicationDetails.js index fed44a5..8a263a0 100644 --- a/src/pages/ProofReply_Public/ApplicationDetails.js +++ b/src/pages/ProofReply_Public/ApplicationDetails.js @@ -17,7 +17,7 @@ const MainCard = Loadable(React.lazy(() => import('components/MainCard'))); import * as StatusUtils from "../PublicNotice/ListPanel/PublicNoteStatusUtils"; import FileList from "components/FileList" // ==============================|| DASHBOARD - DEFAULT ||============================== // -const ApplicationDetailCard = ({ formData,}) => { +const ApplicationDetailCard = ({ formData, }) => { const params = useParams(); @@ -25,7 +25,7 @@ const ApplicationDetailCard = ({ formData,}) => { //const [proofId, setProofId] = React.useState(); React.useEffect(() => { - if (formData){ + if (formData) { setData(formData); //setProofId(formData.id); } @@ -59,10 +59,10 @@ const ApplicationDetailCard = ({ formData,}) => { } function currencyFormat(num) { - let val = num?num:0; + let val = num ? num : 0; return val.toLocaleString('en-US', { - minimumFractionDigits: 2 - }); + minimumFractionDigits: 2 + }); } @@ -71,7 +71,7 @@ const ApplicationDetailCard = ({ formData,}) => { border={false} content={false} > - + 公共啟事:校對資料
    @@ -162,7 +162,7 @@ const ApplicationDetailCard = ({ formData,}) => { - + @@ -195,6 +195,7 @@ const ApplicationDetailCard = ({ formData,}) => { { sx={{ display: 'flex', alignItems: 'center' }}> 繳費及返稿最後限期: - + {DateUtils.dateStr_Cht(data.returnBeforeDate)} 下午 2:00前 { 應繳費用: - {currencyFormat(data.fee)} + {currencyFormat(data.fee)} - + { formik.values.groupType == "A" - ? - ( {data.length} 頁 x $6,552 ) - : - ( {data.length} cm x {data.colCount==2?"$364 二格位":"$182 一格位"} ) + ? + ( {data.length} 頁 x $6,552 ) + : + ( {data.length} cm x {data.colCount == 2 ? "$364 二格位" : "$182 一格位"} ) } diff --git a/src/pages/ProofReply_Public/ProofForm.js b/src/pages/ProofReply_Public/ProofForm.js index 42b89ab..eb9e6b2 100644 --- a/src/pages/ProofReply_Public/ProofForm.js +++ b/src/pages/ProofReply_Public/ProofForm.js @@ -107,6 +107,15 @@ const FormPanel = ({ formData }) => { } } + const isOverTime = () => { + let returnBeforeDate = DateUtils.convertToDate(formik.values?.returnBeforeDate); + if (!returnBeforeDate) return true; + returnBeforeDate = returnBeforeDate.setHours(14, 0, 0, 0); + + let current = new Date(); + return current.getTime() > returnBeforeDate; + } + return ( @@ -127,10 +136,11 @@ const FormPanel = ({ formData }) => { 校對回覆日期: {DateUtils.datetimeStr_Cht(formik.values.replyDate)} - 校對回覆: {formik.values.action? "可以付印(稿件正確)":"未能付印(需要修改)"} + 校對回覆: {formik.values.action ? "可以付印(稿件正確)" : "未能付印(需要修改)"} - { disableColumnSelector hideFooter /> - + : - + ( + isOverTime() ? + + + 回覆逾時,請重新申請。 + + + : + - - - } label="可以付印(稿件正確)" /> - } label="未能付印(需要修改)" /> - - + + + } label="可以付印(稿件正確)" /> + } label="未能付印(需要修改)" /> + + - - 請上載稿件修改的檔案: - + + 請上載稿件修改的檔案: + - - = (formik.values.groupType == "A" ? 2 : 1)} - onChange={(event) => { - readFile(event) - }} - /> - - + + = (formik.values.groupType == "A" ? 2 : 1)} + onChange={(event) => { + readFile(event) + }} + /> + + - - - + + + - - - - 簽署: - - - - - + + + + 簽署: + + + + + + + + + + + + + ) - - - - } diff --git a/src/pages/ProofReply_Public/index.js b/src/pages/ProofReply_Public/index.js index de29ffd..d2604d4 100644 --- a/src/pages/ProofReply_Public/index.js +++ b/src/pages/ProofReply_Public/index.js @@ -10,6 +10,7 @@ import * as React from "react"; import * as HttpUtils from "utils/HttpUtils"; import * as DateUtils from "utils/DateUtils"; import { useParams } from "react-router-dom"; +import { useNavigate } from "react-router-dom"; import Loadable from 'components/Loadable'; const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); @@ -30,6 +31,7 @@ const BackgroundHead = { const Index = () => { const params = useParams(); + const navigate = useNavigate() const [record, setRecord] = React.useState(); const [onReady, setOnReady] = React.useState(false); @@ -49,6 +51,9 @@ const Index = () => { HttpUtils.get({ url: UrlUtils.GET_PROOF + "/" + params.id, onSuccess: (responseData) => { + if(!responseData.data?.id){ + navigate("/proof/search"); + } responseData.data["phoneNumber"] = JSON.parse(responseData.data.contactTelNo).phoneNumber; responseData.data["tel_countryCode"] = JSON.parse(responseData.data.contactTelNo).countryCode; @@ -56,13 +61,13 @@ const Index = () => { responseData.data["fax_countryCode"] = JSON.parse(responseData.data.contactFaxNo).countryCode; responseData.data["issueNoStr"] = responseData.data.issueYear - +" Vol. "+zeroPad(responseData.data.issueVolume,3) - +", No. "+zeroPad(responseData.data.issueNo,2); - - responseData.data["issueDate"] = DateUtils.dateFormat(responseData.data.issueDate, "D MMM YYYY (ddd)"); + + " Vol. " + zeroPad(responseData.data.issueVolume, 3) + + ", No. " + zeroPad(responseData.data.issueNo, 2); + + responseData.data["issueDateStr"] = DateUtils.dateFormat(responseData.data.issueDate, "D MMM YYYY (ddd)"); responseData.data["groupType"] = responseData.data.groupNo.charAt(0); - responseData.data["action"] = responseData.data.replyDate?responseData.data.action:true; + responseData.data["action"] = responseData.data.replyDate ? responseData.data.action : true; setRecord(responseData.data); } }); @@ -70,7 +75,7 @@ const Index = () => { } function zeroPad(num, places) { - num=num?num:0; + num = num ? num : 0; var zero = places - num.toString().length + 1; return Array(+(zero > 0 && zero)).join("0") + num; } @@ -80,42 +85,48 @@ const Index = () => { !onReady ? : - - -
    - - 校對記錄 - -
    -
    - {/*row 1*/} - - -
    - - - - - - - - - + ( + + +
    + + 校對記錄 + +
    +
    + {/*row 1*/} + + +
    + + + + + + + + + + +
    -
    -
    -
    - {/*row 2*/} -
    + + {/*row 2*/} + + + + ) + + ); }; diff --git a/src/pages/ProofSearch_Public/DataGrid.js b/src/pages/ProofSearch_Public/DataGrid.js index b70343b..6776836 100644 --- a/src/pages/ProofSearch_Public/DataGrid.js +++ b/src/pages/ProofSearch_Public/DataGrid.js @@ -4,8 +4,8 @@ import { Button } from '@mui/material'; import * as DateUtils from "utils/DateUtils"; -import {useNavigate} from "react-router-dom"; -import {FiDataGrid} from "components/FiDataGrid"; +import { useNavigate } from "react-router-dom"; +import { FiDataGrid } from "components/FiDataGrid"; // ==============================|| EVENT TABLE ||============================== // export default function SearchPublicNoticeTable({ recordList }) { @@ -17,14 +17,14 @@ export default function SearchPublicNoticeTable({ recordList }) { }, [recordList]); const handleEditClick = (params) => () => { - navigate('/proof/reply/'+ params.row.appId); + navigate('/proof/reply/' + params.row.appId); }; const columns = [ { field: 'actions', - headerName: 'Proof No.', + headerName: '校對編號', width: 150, cellClassName: 'actions', renderCell: (params) => { @@ -34,23 +34,34 @@ export default function SearchPublicNoticeTable({ recordList }) { { id: 'appId', field: 'appId', - headerName: 'Application No./ Gazette Code/ Gazette Issue', + headerName: '申請編號/憲報編號/憲報期數', flex: 1, renderCell: (params) => { let appNo = params.row.appNo; let code = params.row.groupNo; let isssue = params.row.issueYear - +" Vol. "+zeroPad(params.row.issueVolume,3) - +", No. "+zeroPad(params.row.issueNo,2) - +", "+DateUtils.dateFormat(params.row.issueDate, "D MMM YYYY (ddd)"); + + " Vol. " + zeroPad(params.row.issueVolume, 3) + + ", No. " + zeroPad(params.row.issueNo, 2) + + ", " + DateUtils.dateFormat(params.row.issueDate, "D MMM YYYY (ddd)"); - return
    App No: {appNo}
    Gazette Code: {code}
    Issue: {isssue}
    + return
    申請編號: {appNo}
    憲報編號: {code}
    憲報期數: {isssue}
    }, }, + { + id: 'returnBeforeDate', + field: 'returnBeforeDate', + headerName: '此日期前回覆', + flex: 1, + valueGetter: (params) => { + let returnBeforeDate = DateUtils.convertToDate(params?.value); + returnBeforeDate = returnBeforeDate.setHours(14, 0, 0, 0); + return DateUtils.datetimeStr_Cht(returnBeforeDate); + } + }, { id: 'created', field: 'created', - headerName: 'Proof Date', + headerName: '校對日期', flex: 1, valueGetter: (params) => { return DateUtils.datetimeStr(params?.value); @@ -59,69 +70,41 @@ export default function SearchPublicNoticeTable({ recordList }) { { id: 'replyDate', field: 'replyDate', - headerName: 'Confirmed/Return Date', + headerName: '回覆日期', flex: 1, valueGetter: (params) => { - return params?.value?DateUtils.datetimeStr(params?.value):""; - } - }, - { - id: 'contactPerson', - field: 'contactPerson', - headerName: 'Contact Person', - flex: 1, - renderCell: (params) => { - let company = params.row.enCompanyName!= null ?" ("+(params.row.enCompanyName)+")":""; - - let phone = JSON.parse(params.row.contactTelNo); - let faxNo = JSON.parse(params.row.contactFaxNo); - - let contact = ""; - if (phone) { - contact = "Phone No.: " + phone?.countryCode + " " + phone?.phoneNumber - } - - if (faxNo && faxNo?.faxNumber) { - if (contact != "") - contact = contact + ", " - contact = contact + "Fax No.:" + faxNo?.countryCode + " " + faxNo?.faxNumber - } - - return (<> - {params?.value + company}
    - {contact} - ); + return params?.value ? DateUtils.datetimeStr(params?.value) : ""; } }, { id: 'groupTitle', field: 'groupTitle', - headerName: 'Gazette Group', + headerName: '憲報類型', flex: 1, valueGetter: (params) => { - return (params?.value)?(params?.value):""; + return (params?.value) ? (params?.value) : ""; } }, { id: 'fee', field: 'fee', - headerName: 'Fee', + headerName: '費用', flex: 1, valueGetter: (params) => { - return (params?.value)?"$ "+currencyFormat(params?.value):""; + return (params?.value) ? "$ " + currencyFormat(params?.value) : ""; } }, ]; function currencyFormat(num) { return num.toLocaleString('en-US', { - minimumFractionDigits: 2 - }); + minimumFractionDigits: 2 + }); } function zeroPad(num, places) { - num=num?num:0; + num = num ? num : 0; var zero = places - num.toString().length + 1; return Array(+(zero > 0 && zero)).join("0") + num; } diff --git a/src/pages/ProofSearch_Public/SearchForm.js b/src/pages/ProofSearch_Public/SearchForm.js index 706191c..d4bb4d2 100644 --- a/src/pages/ProofSearch_Public/SearchForm.js +++ b/src/pages/ProofSearch_Public/SearchForm.js @@ -13,13 +13,11 @@ import * as DateUtils from "utils/DateUtils"; // ==============================|| DASHBOARD - DEFAULT ||============================== // -const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria,issueComboData +const SearchPublicNoticeForm = ({ applySearch, searchCriteria,issueComboData }) => { const [type, setType] = React.useState([]); const [status, setStatus] = React.useState({ key: 0, label: 'All', type: 'all' }); - 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({}); @@ -46,17 +44,10 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria,issu dateTo: data.dateTo, contact: data.contact, replyed: (status?.type && status?.type != 'all') ? status?.type : "", - orgId: (orgSelected?.key && orgSelected?.key > 0) ? orgSelected?.key : "", - }; applySearch(temp); }; - React.useEffect(() => { - if (orgComboData && orgComboData.length > 0) { - setOrgCombo(orgComboData); - } - }, [orgComboData]); React.useEffect(() => { if (issueComboData && issueComboData.length > 0) { @@ -144,7 +135,7 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria,issu }} renderInput={(params) => ( option.label} + inputValue={(groupSelected?.labelCht)?groupSelected?.labelCht:""} + getOptionLabel={(option)=>option.labelCht} onChange={(event, newValue) => { if (newValue !== null) { setGroupSelected(newValue); @@ -169,7 +160,7 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria,issu }} renderInput={(params) => ( { @@ -209,7 +200,7 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria,issu }} id="dateTo" type="date" - label="校對日期(To)" + label="校對日期(到)" defaultValue={searchCriteria.dateTo} /> @@ -236,7 +227,8 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria,issu filterOptions={(options) => options} options={ComboData.proofStatus} value={status} - inputValue={status?.label?status?.label:""} + getOptionLabel={(option)=>option.labelCht} + inputValue={status?.labelCht?status?.labelCht:""} onChange={(event, newValue) => { if (newValue !== null) { setStatus(newValue); @@ -253,35 +245,6 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria,issu /> - { - orgCombo ? - - { - if (newValue !== null) { - setOrgSelected(newValue); - } - }} - renderInput={(params) => ( - - )} - /> - - : <> - } - - @@ -297,7 +260,7 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria,issu textTransform: 'capitalize', alignItems: 'end' }}> - Clear + 重置 @@ -310,7 +273,7 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria,issu textTransform: 'capitalize', alignItems: 'end' }}> - Submit + 提交 diff --git a/src/pages/ProofSearch_Public/index.js b/src/pages/ProofSearch_Public/index.js index 95082e4..ab51859 100644 --- a/src/pages/ProofSearch_Public/index.js +++ b/src/pages/ProofSearch_Public/index.js @@ -31,7 +31,6 @@ const BackgroundHead = { const UserSearchPage_Individual = () => { const [record,setRecord] = React.useState([]); - const [orgCombo,setOrgCombo] = React.useState([]); const [issueCombo,setIssueCombo] = React.useState([]); const [searchCriteria, setSearchCriteria] = React.useState({ dateTo: DateUtils.dateStr(new Date()), @@ -40,8 +39,6 @@ const UserSearchPage_Individual = () => { const [onReady, setOnReady] = React.useState(false); React.useEffect(() => { - getUserList(); - getOrgCombo(); getIssueCombo(); }, []); @@ -50,10 +47,10 @@ const UserSearchPage_Individual = () => { }, [record]); React.useEffect(() => { - getUserList(); + loadGrid(); }, [searchCriteria]); - function getUserList(){ + function loadGrid(){ HttpUtils.get({ url: UrlUtils.LIST_PROOF, params: searchCriteria, @@ -63,16 +60,6 @@ const UserSearchPage_Individual = () => { }); } - function getOrgCombo(){ - HttpUtils.get({ - url: UrlUtils.GET_ORG_COMBO, - onSuccess: function(responseData){ - let combo = responseData; - setOrgCombo(combo); - } - }); - } - function getIssueCombo(){ HttpUtils.get({ url: UrlUtils.GET_ISSUE_COMBO, @@ -104,7 +91,6 @@ const UserSearchPage_Individual = () => { diff --git a/src/pages/PublicNotice/ListPanel/SearchPublicNoticeForm.js b/src/pages/PublicNotice/ListPanel/SearchPublicNoticeForm.js index 6a8fadc..f86b13f 100644 --- a/src/pages/PublicNotice/ListPanel/SearchPublicNoticeForm.js +++ b/src/pages/PublicNotice/ListPanel/SearchPublicNoticeForm.js @@ -135,7 +135,8 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria }) => { ComboData.publicNoticeStatic } values={status} - inputValue={status?.label} + inputValue={status?.labelCht} + getOptionLabel={(option)=>option.labelCht} onChange={(event, newValue) => { if (newValue !== null) { setStatus(newValue); diff --git a/src/utils/ComboData.js b/src/utils/ComboData.js index 9b5b3bc..8796103 100644 --- a/src/utils/ComboData.js +++ b/src/utils/ComboData.js @@ -12,52 +12,29 @@ export const country = ["香港","內地","澳門"]; export const accountFilter = [{ id: 1, key: 1, label: 'Active', type: 'active' }, { id: 2, key: 2, label: 'Locked', type: 'locked' }, { id: 3, key: 3, label: 'Not verified', type: 'notVerified' }]; export const publicNoticeStatic = [ - { key: 0, label: '全部', type: 'all' }, - { key: 1, label: '處理中', type: 'processing' }, // submitted and reviewed - { key: 2, label: '待付款', type: 'confirmed' }, - { key: 3, label: '待發布', type: 'paid' }, - { key: 4, label: '已完成', type: 'completed' }, - { key: 5, label: '不接受', type: 'notAccepted' }, - { key: 6, label: '需重新提交', type: 'resubmit' }, - { key: 7, label: '已取消', type: 'cancelled' }, - { key: 8, label: '已撤銷', type: 'withdrawn' }, + { key: 0, labelCht: '全部', label: 'All', type: 'all' }, + { key: 1, labelCht: '處理中', label: 'Processing', type: 'processing' }, // submitted and reviewed + { key: 2, labelCht: '待付款', label: 'Pending Payment', type: 'confirmed' }, + { key: 3, labelCht: '待發布', label: 'To be published', type: 'paid' }, + { key: 4, labelCht: '已完成', label: 'Completed', type: 'completed' }, + { key: 5, labelCht: '不接受', label: 'Not accepted', type: 'notAccepted' }, + { key: 6, labelCht: '需重新提交', label: 'Re-submit Required', type: 'resubmit' }, + { key: 7, labelCht: '已取消', label: 'Cancelled', type: 'cancelled' }, + { key: 8, labelCht: '已撤銷', label: 'Withdrawn', type: 'withdrawn' }, ]; export const publicNoticeStatic_Creditor = [ - { key: 0, label: '全部', type: 'all' }, - { key: 1, label: '處理中', type: 'processing' }, // submitted and reviewed - { key: 2, label: '待發布', type: 'confirmed' }, - { key: 3, label: '待付款', type: 'published' }, - { key: 4, label: '已完成', type: 'completed' }, - { key: 5, label: '不接受', type: 'notAccepted' }, - { key: 6, label: '需重新提交', type: 'resubmit' }, - { key: 7, label: '已取消', type: 'cancelled' }, - { key: 8, label: '已撤銷', type: 'withdrawn' }, + { key: 0, labelCht: '全部', label: 'All', type: 'all' }, + { key: 1, labelCht: '處理中', label: 'Processing', type: 'processing' }, // submitted and reviewed + { key: 2, labelCht: '待發布', label: 'To be published', type: 'confirmed' }, + { key: 3, labelCht: '待付款', label: 'Pending Payment', type: 'published' }, + { key: 4, labelCht: '已完成', label: 'Completed', type: 'completed' }, + { key: 5, labelCht: '不接受', label: 'Not accepted', type: 'notAccepted' }, + { key: 6, labelCht: '需重新提交', label: 'Re-submit Required', type: 'resubmit' }, + { key: 7, labelCht: '已取消', label: 'Cancelled', type: 'cancelled' }, + { key: 8, labelCht: '已撤銷', label: 'Withdrawn', type: 'withdrawn' }, ]; -export const publicNoticeStaticEng = [ - { key: 0, label: 'All', type: 'all' }, - { key: 1, label: 'Processing', type: 'processing' }, // submitted and reviewed - { key: 2, label: 'Pending Payment', type: 'confirmed' }, - { key: 3, label: 'To be published', type: 'paid' }, - { key: 4, label: 'Completed', type: 'completed' }, - { key: 5, label: 'Not accepted', type: 'notAccepted' }, - { key: 6, label: 'Re-submit Required', type: 'resubmit' }, - { key: 7, label: 'Cancelled', type: 'cancelled' }, - { key: 8, label: 'Withdrawn', type: 'withdrawn' }, -]; - -export const publicNoticeStaticEng_Creditor = [ - { key: 0, label: 'All', type: 'all' }, - { key: 1, label: 'Processing', type: 'processing' }, // submitted and reviewed - { key: 2, label: 'To be published', type: 'confirmed' }, - { key: 3, label: 'Pending Payment', type: 'published' }, - { key: 4, label: 'Completed', type: 'completed' }, - { key: 5, label: 'Not accepted', type: 'notAccepted' }, - { key: 6, label: 'Re-submit Required', type: 'resubmit' }, - { key: 7, label: 'Cancelled', type: 'cancelled' }, - { key: 8, label: 'Withdrawn', type: 'withdrawn' }, -]; export const publicNoticeStatic_GLD = [ { key: 0, label: 'All', type: 'all' }, @@ -75,11 +52,11 @@ export const publicNoticeStatic_GLD = [ export const groupTitle = [ - { key: 1, label: 'A - Private Bill', title: 'Private Bill', type: 'A'}, - { key: 2, label: 'B - Companies Ordinance', title: 'Companies Ordinance', type: 'B' }, - { key: 3, label: 'C - High Court', title: 'High Court', type: 'C' }, - { key: 4, label: 'D - Notices', title: 'Notices', type: 'D' }, - { key: 5, label: 'E - Miscellaneous (Companies)', title: 'Miscellaneous  (Companies)', type: 'E' }, + { key: 1, labelCht: 'A - 私人帳單', label: 'A - Private Bill', title: 'Private Bill', type: 'A'}, + { key: 2, labelCht: 'B - 公司條例', label: 'B - Companies Ordinance', title: 'Companies Ordinance', type: 'B' }, + { key: 3, labelCht: 'C - 高等法院', label: 'C - High Court', title: 'High Court', type: 'C' }, + { key: 4, labelCht: 'D - 通知', label: 'D - Notices', title: 'Notices', type: 'D' }, + { key: 5, labelCht: 'E - 其他', label: 'E - Miscellaneous (Companies)', title: 'Miscellaneous  (Companies)', type: 'E' }, ]; export const proofPrice = [ @@ -88,7 +65,7 @@ export const proofPrice = [ ]; export const proofStatus = [ - { key: 0, label: 'All', type: 'all' }, - { key: 1, label: 'Replyed', type: 'T' }, // submitted and reviewed - { key: 2, label: 'Not reply yet', type: 'F' }, + { key: 0, labelCht: '全部', label: 'All', type: 'all' }, + { key: 1, labelCht: '已回覆', label:'Replyed', type: 'T' }, // submitted and reviewed + { key: 2, labelCht: '未回覆', label:'Not reply yet', type: 'F' }, ]; \ No newline at end of file diff --git a/src/utils/DateUtils.js b/src/utils/DateUtils.js index 9ec9e2d..a03e646 100644 --- a/src/utils/DateUtils.js +++ b/src/utils/DateUtils.js @@ -19,7 +19,7 @@ export const dateStr_Cht = (date) =>{ export const convertToDate = (date)=>{ if(typeof date == 'number'){ - return dayjs(date); + return dayjs(date).toDate(); }else if(Array.isArray(date)){ if(date.length==3){ return new Date(date[0],date[1]-1,date[2],0,0,0); From d09cd4c9f336641e8f6a7fde825ffe6d1a81d25e Mon Sep 17 00:00:00 2001 From: anna Date: Wed, 11 Oct 2023 12:33:42 +0800 Subject: [PATCH 03/12] generate Gazette Code before Create Proof --- .../ApplicationDetailCard.js | 31 ++++++++++++++++--- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/src/pages/PublicNoticeDetail_GLD/ApplicationDetailCard.js b/src/pages/PublicNoticeDetail_GLD/ApplicationDetailCard.js index bb7e4cd..e1ebaec 100644 --- a/src/pages/PublicNoticeDetail_GLD/ApplicationDetailCard.js +++ b/src/pages/PublicNoticeDetail_GLD/ApplicationDetailCard.js @@ -5,7 +5,8 @@ import { Grid, Typography, FormLabel, OutlinedInput, - Stack + Stack, + Dialog, DialogTitle, DialogContent, DialogActions, } from '@mui/material'; const MainCard = Loadable(lazy(() => import('components/MainCard'))); import { useForm } from "react-hook-form"; @@ -43,6 +44,9 @@ const ApplicationDetailCard = ( const { register } = useForm() + const [isWarningPopUp, setIsWarningPopUp] = useState(false); + const [warningText, setWarningText] = useState(""); + useEffect(() => { //if user data from parent are not null // console.log(applicationDetailData) @@ -94,8 +98,14 @@ const ApplicationDetailCard = ( }; const onProofClick = () => { - window.open("/proof/create/" + currentApplicationDetailData.id, "_blank", "noreferrer"); - window.addEventListener("focus", onFocus) + if (applicationDetailData.data.groupNo) { + window.open("/proof/create/" + currentApplicationDetailData.id, "_blank", "noreferrer"); + window.addEventListener("focus", onFocus) + }else{ + setWarningText("Please generate Gazette Code before Create Proof."); + setIsWarningPopUp(true); + } + } const onFocus = () => { @@ -145,14 +155,14 @@ const ApplicationDetailCard = ( spacing={2} mb={2} > - {currentApplicationDetailData.status == "submitted"||currentApplicationDetailData.status == "reviewed" ? + {currentApplicationDetailData.status == "submitted" || currentApplicationDetailData.status == "reviewed" ? <> @@ -481,6 +491,17 @@ const ApplicationDetailCard = ( +
    + setIsWarningPopUp(false)} > + Warning + + {warningText} + + + + + +
    ); }; From 22304ca6be08d9290f3f793a5a494da3467b9e70 Mon Sep 17 00:00:00 2001 From: anna Date: Wed, 11 Oct 2023 17:29:15 +0800 Subject: [PATCH 04/12] update proof --- src/pages/ProofCreate_FromApp/ProofForm.js | 64 ++++++++++++++++++---- src/utils/ApiPathConst.js | 1 + 2 files changed, 54 insertions(+), 11 deletions(-) diff --git a/src/pages/ProofCreate_FromApp/ProofForm.js b/src/pages/ProofCreate_FromApp/ProofForm.js index f74c9b7..022da46 100644 --- a/src/pages/ProofCreate_FromApp/ProofForm.js +++ b/src/pages/ProofCreate_FromApp/ProofForm.js @@ -16,7 +16,7 @@ import MainCard from "components/MainCard"; import * as ComboData from "utils/ComboData"; import * as React from "react"; import { useFormik } from 'formik'; -import {useNavigate} from "react-router-dom"; +import { useNavigate } from "react-router-dom"; import Loadable from 'components/Loadable'; const UploadFileTable = Loadable(React.lazy(() => import('./UploadFileTable'))); // ==============================|| DASHBOARD - DEFAULT ||============================== // @@ -34,20 +34,61 @@ const FormPanel = ({ formData }) => { const navigate = useNavigate() React.useEffect(() => { - if (formData){ + if (formData) { setData(formData); - if(formData.groupType == "A"){ + if (formData.groupType == "A") { setColumnPrice(ComboData.proofPrice[1]) formData['length'] = 18; } } }, [formData]); + + React.useEffect(() => { + if (!attachments || attachments.length <= 0){ + formik.setFieldValue("length",0); + formik.setFieldValue("noOfPages",0); + formik.setFieldValue("fee",0); + return; + } + + doCalculate(); + + }, [attachments]); + + const doCalculate=()=>{ + if (!attachments || attachments.length <= 0){ + setWarningText("無法計算,請上傳有效文件。"); + setIsWarningPopUp(true); + return; + } + HttpUtils.postWithFiles({ + url: UrlUtils.PROOF_CHECK_PRICE, + params: { + appId: data.id, + }, + files: attachments, + onSuccess: function (responseData) { + if(responseData.data.detail){ + setWarningText("無法計算,請上傳有效文件或手動輸入。"); + setIsWarningPopUp(true); + return; + } + formik.setFieldValue("length",responseData.data.length); + setColumnPrice(ComboData.proofPrice.find(obj=>{ + return obj.colCount === responseData.data.column + })); + formik.setFieldValue("noOfPages",responseData.data.no_of_page); + formik.setFieldValue("fee",columnPrice.value * (data.groupType == "A"?responseData.data.no_of_page*responseData.data.length:responseData.data.length)); + } + }); + } + const formik = useFormik({ enableReinitialize: true, initialValues: data, onSubmit: values => { - if (!attachments || attachments.length<=0) { + if (!attachments || attachments.length <= 0) { setWarningText("請選擇上傳檔案"); setIsWarningPopUp(true); return; @@ -79,12 +120,12 @@ const FormPanel = ({ formData }) => { document.getElementById("uploadFileBtn").value = ""; return; } - if(file.size >= (10 * 1024 * 1034)){ + if (file.size >= (10 * 1024 * 1034)) { setWarningText("上傳檔案大小應<10MB"); setIsWarningPopUp(true); return; } - + file['id'] = attachments.length; setAttachments([ ...attachments, @@ -96,6 +137,7 @@ const FormPanel = ({ formData }) => { + return ( { fullWidth size="small" type="text" - onChange={(event)=>{ + onChange={(event) => { const value = event.target.value; formik.setFieldValue("length", value); - formik.setFieldValue("fee", columnPrice.value*value); + formik.setFieldValue("fee", columnPrice.value* 18 * value); }} name="noOfPages" value={formik.values["noOfPages"]} @@ -194,10 +236,10 @@ const FormPanel = ({ formData }) => { fullWidth size="small" type="text" - onChange={(event)=>{ + onChange={(event) => { const value = event.target.value; formik.setFieldValue("length", value); - formik.setFieldValue("fee", columnPrice.value*value); + formik.setFieldValue("fee", columnPrice.value * value); }} name="length" value={formik.values["length"]} @@ -232,7 +274,7 @@ const FormPanel = ({ formData }) => { getOptionLabel={(option) => option.label ? option.label : ""} onChange={(event, newValue) => { setColumnPrice(newValue) - formik.values["fee"] = newValue.value*formik.values.length; + formik.values["fee"] = newValue.value * formik.values.length; }} renderInput={(params) => ( Date: Wed, 11 Oct 2023 17:31:31 +0800 Subject: [PATCH 05/12] update error popup --- src/pages/ProofCreate_FromApp/ProofForm.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pages/ProofCreate_FromApp/ProofForm.js b/src/pages/ProofCreate_FromApp/ProofForm.js index 022da46..95e6e2f 100644 --- a/src/pages/ProofCreate_FromApp/ProofForm.js +++ b/src/pages/ProofCreate_FromApp/ProofForm.js @@ -80,6 +80,10 @@ const FormPanel = ({ formData }) => { })); formik.setFieldValue("noOfPages",responseData.data.no_of_page); formik.setFieldValue("fee",columnPrice.value * (data.groupType == "A"?responseData.data.no_of_page*responseData.data.length:responseData.data.length)); + }, + onError: function(){ + setWarningText("無法計算,請手動輸入。"); + setIsWarningPopUp(true); } }); } From 1e832e9c62be7412249cf13b22f7019aada7850e Mon Sep 17 00:00:00 2001 From: anna Date: Wed, 11 Oct 2023 17:44:26 +0800 Subject: [PATCH 06/12] fix bug --- src/pages/ProofCreate_FromApp/ProofForm.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/pages/ProofCreate_FromApp/ProofForm.js b/src/pages/ProofCreate_FromApp/ProofForm.js index 95e6e2f..ec36c0e 100644 --- a/src/pages/ProofCreate_FromApp/ProofForm.js +++ b/src/pages/ProofCreate_FromApp/ProofForm.js @@ -75,11 +75,13 @@ const FormPanel = ({ formData }) => { return; } formik.setFieldValue("length",responseData.data.length); + let colValue = 0; setColumnPrice(ComboData.proofPrice.find(obj=>{ + colValue = obj.value; return obj.colCount === responseData.data.column })); formik.setFieldValue("noOfPages",responseData.data.no_of_page); - formik.setFieldValue("fee",columnPrice.value * (data.groupType == "A"?responseData.data.no_of_page*responseData.data.length:responseData.data.length)); + formik.setFieldValue("fee",(data.groupType == "A"?6552*responseData.data.no_of_page :responseData.data.length*colValue)); }, onError: function(){ setWarningText("無法計算,請手動輸入。"); @@ -207,7 +209,7 @@ const FormPanel = ({ formData }) => { onChange={(event) => { const value = event.target.value; formik.setFieldValue("length", value); - formik.setFieldValue("fee", columnPrice.value* 18 * value); + formik.setFieldValue("fee", 6552 * value); }} name="noOfPages" value={formik.values["noOfPages"]} @@ -229,7 +231,7 @@ const FormPanel = ({ formData }) => { x - ${formik.values.price ? formik.values.price : 0} + ${formik.values.price ? formik.values.price : "6,552"} From b2f6d2fd1f00d32df0cabaf00ae0e9554dd6d871 Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 12 Oct 2023 09:54:02 +0800 Subject: [PATCH 07/12] fiix bug --- src/pages/ProofSearch_Public/DataGrid.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/ProofSearch_Public/DataGrid.js b/src/pages/ProofSearch_Public/DataGrid.js index 6776836..ccbc690 100644 --- a/src/pages/ProofSearch_Public/DataGrid.js +++ b/src/pages/ProofSearch_Public/DataGrid.js @@ -17,7 +17,7 @@ export default function SearchPublicNoticeTable({ recordList }) { }, [recordList]); const handleEditClick = (params) => () => { - navigate('/proof/reply/' + params.row.appId); + navigate('/proof/reply/' + params.row.id); }; From dedccf32171b6ac2b0a06bc08f197b779bc58018 Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 12 Oct 2023 11:28:07 +0800 Subject: [PATCH 08/12] status align, hidden uploadBtn when confirm --- .../ProofReply_Public/ApplicationDetails.js | 18 +-- src/pages/ProofReply_Public/ProofForm.js | 120 +++++++++++------- 2 files changed, 81 insertions(+), 57 deletions(-) diff --git a/src/pages/ProofReply_Public/ApplicationDetails.js b/src/pages/ProofReply_Public/ApplicationDetails.js index 8a263a0..d1797c9 100644 --- a/src/pages/ProofReply_Public/ApplicationDetails.js +++ b/src/pages/ProofReply_Public/ApplicationDetails.js @@ -92,13 +92,13 @@ const ApplicationDetailCard = ({ formData, }) => { - + 申請狀態: - + {StatusUtils.getStatusByText(data.appStatus)} @@ -191,7 +191,7 @@ const ApplicationDetailCard = ({ formData, }) => { - 請下載下列印刷稿檔案,並仔細校對: + 請下載下列印刷稿檔案,並仔細校對: { - 繳費及返稿最後限期: + 繳費及返稿最後限期: - {DateUtils.dateStr_Cht(data.returnBeforeDate)} 下午 2:00前 + {DateUtils.dateStr_Cht(data.returnBeforeDate)} 下午 2:00前 - 應繳費用: + 應繳費用: - {currencyFormat(data.fee)} + {currencyFormat(data.fee)} { formik.values.groupType == "A" ? - ( {data.length} 頁 x $6,552 ) + ( {data.noOfPages} 頁 x $6,552 ) : - ( {data.length} cm x {data.colCount == 2 ? "$364 二格位" : "$182 一格位"} ) + ( {data.length} cm x {data.colCount == 2 ? "$364 二格位" : "$182 一格位"} ) } diff --git a/src/pages/ProofReply_Public/ProofForm.js b/src/pages/ProofReply_Public/ProofForm.js index eb9e6b2..0b318bc 100644 --- a/src/pages/ProofReply_Public/ProofForm.js +++ b/src/pages/ProofReply_Public/ProofForm.js @@ -31,6 +31,8 @@ const FormPanel = ({ formData }) => { const [data, setData] = React.useState({}); const [attachments, setAttachments] = React.useState([]); + const [actionValue, setActionValue] = React.useState(true); + const [isWarningPopUp, setIsWarningPopUp] = React.useState(false); const [warningText, setWarningText] = React.useState(""); @@ -50,19 +52,25 @@ const FormPanel = ({ formData }) => { vaild: yup.string().max(255, "請輸入你的登入密碼").required('請輸入你的登入密碼'), }), onSubmit: values => { - if (!values.action) { + if (!actionValue) { if (!attachments || attachments.length <= 0) { setWarningText("請選擇上傳檔案"); setIsWarningPopUp(true); return; } } + + if(isOverTime()){ + setWarningText("回覆逾時,請重新申請。"); + setIsWarningPopUp(true); + return; + } // console.log(values); HttpUtils.postWithFiles({ url: UrlUtils.REPLY_PROOF, params: { id: data.id, - action: values.action, + action: actionValue, vaild: values.vaild, }, files: attachments ? attachments : [], @@ -138,19 +146,25 @@ const FormPanel = ({ formData }) => { 校對回覆: {formik.values.action ? "可以付印(稿件正確)" : "未能付印(需要修改)"} - - - + { + formik.values.action ? + null + : + + + + } + : ( @@ -169,57 +183,67 @@ const FormPanel = ({ formData }) => { id="action" name="action" defaultValue={true} + onChange={(event)=>{ + setActionValue(event.target.value=="true"?true:false); + }} > } label="可以付印(稿件正確)" /> } label="未能付印(需要修改)" /> - - 請上載稿件修改的檔案: - - - - = (formik.values.groupType == "A" ? 2 : 1)} - onChange={(event) => { - readFile(event) - }} - /> - - - - - - - + { + actionValue ? + null + : + <> + + 請上載稿件修改的檔案: + + + + = (formik.values.groupType == "A" ? 2 : 1)} + onChange={(event) => { + readFile(event) + }} + /> + + + + + + + + + } - + 簽署: Date: Thu, 12 Oct 2023 11:45:56 +0800 Subject: [PATCH 09/12] fix bugs --- src/pages/ProofSearch_Public/DataGrid.js | 19 ++++++++++++++++++- src/pages/ProofSearch_Public/SearchForm.js | 19 +++++++------------ 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/pages/ProofSearch_Public/DataGrid.js b/src/pages/ProofSearch_Public/DataGrid.js index ccbc690..4ce0b02 100644 --- a/src/pages/ProofSearch_Public/DataGrid.js +++ b/src/pages/ProofSearch_Public/DataGrid.js @@ -20,6 +20,23 @@ export default function SearchPublicNoticeTable({ recordList }) { navigate('/proof/reply/' + params.row.id); }; + const getGroupTitle = (title) => { + switch (title) { + case 'Private Bill': + return "私人帳單"; + case 'Companies Ordinance': + return "公司條例"; + case 'High Court': + return "高等法院"; + case 'Notices': + return "通知"; + case 'Miscellaneous (Companies)': + return "其他"; + default: + return title; + } + } + const columns = [ { @@ -82,7 +99,7 @@ export default function SearchPublicNoticeTable({ recordList }) { headerName: '憲報類型', flex: 1, valueGetter: (params) => { - return (params?.value) ? (params?.value) : ""; + return getGroupTitle(params?.value); } }, { diff --git a/src/pages/ProofSearch_Public/SearchForm.js b/src/pages/ProofSearch_Public/SearchForm.js index d4bb4d2..60248c9 100644 --- a/src/pages/ProofSearch_Public/SearchForm.js +++ b/src/pages/ProofSearch_Public/SearchForm.js @@ -17,7 +17,7 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria,issueComboData }) => { const [type, setType] = React.useState([]); - const [status, setStatus] = React.useState({ key: 0, label: 'All', type: 'all' }); + const [status, setStatus] = React.useState(ComboData.proofStatus[0]); const [issueSelected, setIssueSelected] = React.useState({}); const [issueCombo, setIssueCombo] = React.useState([]); const [groupSelected, setGroupSelected] = React.useState({}); @@ -42,7 +42,7 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria,issueComboData gazettGroup: groupSelected?.type, dateFrom: data.dateFrom, dateTo: data.dateTo, - contact: data.contact, + //contact: data.contact, replyed: (status?.type && status?.type != 'all') ? status?.type : "", }; applySearch(temp); @@ -57,8 +57,7 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria,issueComboData function resetForm() { setType([]); - setStatus({ key: 0, label: 'All', type: 'all' }); - setOrgSelected({}); + setStatus(ComboData.proofStatus[0]); setIssueSelected({}); setGroupSelected({}); reset(); @@ -129,9 +128,7 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria,issueComboData inputValue={(issueSelected?.id) ? getIssueLabel(issueSelected) : ""} getOptionLabel={(option)=>getIssueLabel(option)} onChange={(event, newValue) => { - if (newValue !== null) { - setIssueSelected(newValue); - } + setIssueSelected(newValue); }} renderInput={(params) => ( option.labelCht} onChange={(event, newValue) => { - if (newValue !== null) { - setGroupSelected(newValue); - } + setGroupSelected(newValue); }} renderInput={(params) => ( - + {/* - + */} Date: Thu, 12 Oct 2023 11:49:34 +0800 Subject: [PATCH 10/12] fix bugs --- src/pages/ProofSearch/SearchForm.js | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/pages/ProofSearch/SearchForm.js b/src/pages/ProofSearch/SearchForm.js index 569bc91..1aab6af 100644 --- a/src/pages/ProofSearch/SearchForm.js +++ b/src/pages/ProofSearch/SearchForm.js @@ -17,7 +17,7 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria,issu }) => { const [type, setType] = React.useState([]); - const [status, setStatus] = React.useState({ key: 0, label: 'All', type: 'all' }); + const [status, setStatus] = React.useState(ComboData.proofStatus[0]); const [orgSelected, setOrgSelected] = React.useState({}); const [orgCombo, setOrgCombo] = React.useState(); const [issueSelected, setIssueSelected] = React.useState({}); @@ -66,7 +66,7 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria,issu function resetForm() { setType([]); - setStatus({ key: 0, label: 'All', type: 'all' }); + setStatus(ComboData.proofStatus[0]); setOrgSelected({}); setIssueSelected({}); setGroupSelected({}); @@ -138,9 +138,7 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria,issu inputValue={(issueSelected?.id) ? getIssueLabel(issueSelected) : ""} getOptionLabel={(option)=>getIssueLabel(option)} onChange={(event, newValue) => { - if (newValue !== null) { - setIssueSelected(newValue); - } + setIssueSelected(newValue); }} renderInput={(params) => ( option.label} onChange={(event, newValue) => { - if (newValue !== null) { - setGroupSelected(newValue); - } + setGroupSelected(newValue); }} renderInput={(params) => ( { - if (newValue !== null) { - setOrgSelected(newValue); - } + setOrgSelected(newValue); }} renderInput={(params) => ( Date: Thu, 12 Oct 2023 12:08:02 +0800 Subject: [PATCH 11/12] update proof UI --- src/pages/ProofCreate_FromApp/ProofForm.js | 76 +++++++++++++--------- 1 file changed, 46 insertions(+), 30 deletions(-) diff --git a/src/pages/ProofCreate_FromApp/ProofForm.js b/src/pages/ProofCreate_FromApp/ProofForm.js index ec36c0e..1fbb0af 100644 --- a/src/pages/ProofCreate_FromApp/ProofForm.js +++ b/src/pages/ProofCreate_FromApp/ProofForm.js @@ -28,6 +28,8 @@ const FormPanel = ({ formData }) => { const [columnPrice, setColumnPrice] = React.useState(ComboData.proofPrice[0]); const [attachments, setAttachments] = React.useState([]); + const [wait, setWait] = React.useState(false); + const [isWarningPopUp, setIsWarningPopUp] = React.useState(false); const [warningText, setWarningText] = React.useState(""); @@ -45,10 +47,10 @@ const FormPanel = ({ formData }) => { React.useEffect(() => { - if (!attachments || attachments.length <= 0){ - formik.setFieldValue("length",0); - formik.setFieldValue("noOfPages",0); - formik.setFieldValue("fee",0); + if (!attachments || attachments.length <= 0) { + formik.setFieldValue("length", 0); + formik.setFieldValue("noOfPages", 0); + formik.setFieldValue("fee", 0); return; } @@ -56,10 +58,12 @@ const FormPanel = ({ formData }) => { }, [attachments]); - const doCalculate=()=>{ - if (!attachments || attachments.length <= 0){ - setWarningText("無法計算,請上傳有效文件。"); + const doCalculate = () => { + setWait(true); + if (!attachments || attachments.length <= 0) { + setWarningText("Unable to calculate, please upload a valid document."); setIsWarningPopUp(true); + setWait(false); return; } HttpUtils.postWithFiles({ @@ -69,23 +73,25 @@ const FormPanel = ({ formData }) => { }, files: attachments, onSuccess: function (responseData) { - if(responseData.data.detail){ - setWarningText("無法計算,請上傳有效文件或手動輸入。"); + if (responseData.data.detail) { + setWarningText("Unable to calculate, please upload a valid document or input manually."); setIsWarningPopUp(true); return; } - formik.setFieldValue("length",responseData.data.length); + formik.setFieldValue("length", responseData.data.length); let colValue = 0; - setColumnPrice(ComboData.proofPrice.find(obj=>{ + setColumnPrice(ComboData.proofPrice.find(obj => { colValue = obj.value; return obj.colCount === responseData.data.column })); - formik.setFieldValue("noOfPages",responseData.data.no_of_page); - formik.setFieldValue("fee",(data.groupType == "A"?6552*responseData.data.no_of_page :responseData.data.length*colValue)); + formik.setFieldValue("noOfPages", responseData.data.no_of_page); + formik.setFieldValue("fee", (data.groupType == "A" ? 6552 * responseData.data.no_of_page : responseData.data.length * colValue)); + setWait(false); }, - onError: function(){ - setWarningText("無法計算,請手動輸入。"); + onError: function () { + setWarningText("Unable to calculate, please input manually."); setIsWarningPopUp(true); + setWait(false); } }); } @@ -95,7 +101,7 @@ const FormPanel = ({ formData }) => { initialValues: data, onSubmit: values => { if (!attachments || attachments.length <= 0) { - setWarningText("請選擇上傳檔案"); + setWarningText("Please upload file."); setIsWarningPopUp(true); return; } @@ -121,13 +127,13 @@ const FormPanel = ({ formData }) => { let file = event.target.files[0]; if (file) { if (!file.name.toLowerCase().substr(file.name.length - 4).includes(".pdf")) { - setWarningText("請上傳有效檔案 (檔案格式: .pdf)"); + setWarningText("Please upload a valid file (File format: .pdf)."); setIsWarningPopUp(true); document.getElementById("uploadFileBtn").value = ""; return; } if (file.size >= (10 * 1024 * 1034)) { - setWarningText("上傳檔案大小應<10MB"); + setWarningText("The file size for uploading should be less than 10MB"); setIsWarningPopUp(true); return; } @@ -186,17 +192,27 @@ const FormPanel = ({ formData }) => { - - - + { + wait ? + + Doing calculate, please wait ... + + : + + + + } + + { formik.values.groupType == "A" ? @@ -352,7 +368,7 @@ const FormPanel = ({ formData }) => {
    setIsWarningPopUp(false)} > - 注意 + Warning {warningText} From 9a86bc4e89ea5d31636d622883009d6c573330d4 Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 12 Oct 2023 14:41:31 +0800 Subject: [PATCH 12/12] update ui --- src/pages/PublicNoticeDetail_GLD/index.js | 19 +++--- .../tabTableDetail/ProofTab.js | 59 +++++++++---------- .../tabTableDetail/TabTable.js | 21 +++---- 3 files changed, 50 insertions(+), 49 deletions(-) diff --git a/src/pages/PublicNoticeDetail_GLD/index.js b/src/pages/PublicNoticeDetail_GLD/index.js index 14cdb32..5158c5e 100644 --- a/src/pages/PublicNoticeDetail_GLD/index.js +++ b/src/pages/PublicNoticeDetail_GLD/index.js @@ -43,6 +43,7 @@ const PublicNoticeDetail_GLD = () => { const params = useParams(); // const navigate = useNavigate() const [applicationDetailData, setApplicationDetailData] = useState({}); + const [proofList, setProofList] = useState([]); // const [refApplicationDetailData, setRefApplicationDetailData] = React.useState({}); const [isLoading, setLoading] = useState(false); const LoadingComponent = Loadable(lazy(() => import('../extra-pages/LoadingComponent'))); @@ -83,7 +84,7 @@ const PublicNoticeDetail_GLD = () => { const title = groupNo != null ? ("Application / " + appNo + ", " + gazetteIssue + ", " + issueNum + " , " + groupNo) : ("Application / " + appNo + ", " + gazetteIssue + ", " + issueNum) useEffect(() => { - loadApplicationDetail() + loadApplicationDetail(); }, []); // useEffect(() => { @@ -110,6 +111,7 @@ const PublicNoticeDetail_GLD = () => { setIssueNum(" No. " + gazetteIssueDetail.issueNo); setIssueDate(DateUtils.dateFormat(gazetteIssueDetail.issueDate, "D MMM YYYY (ddd)")); setGroupNo(response.data.data.groupNo); + setProofList(response.data.proofList); setLoading(false); } }) @@ -171,9 +173,9 @@ const PublicNoticeDetail_GLD = () => { onComplatedClick() } else if (getStatus == "withdraw") { onWithdrawnClick() - } else if (getStatus == "notAccepted"){ + } else if (getStatus == "notAccepted") { onNotAcceptClick(getReason); - } else if (getStatus == "resubmit"){ + } else if (getStatus == "resubmit") { onReSubmitClick(); } } @@ -266,8 +268,8 @@ const PublicNoticeDetail_GLD = () => { }; useEffect(() => { - const status = applicationDetailData.data!=undefined?applicationDetailData.data.status:"" - if(status === "submitted" && params.id > 0 && getUploadStatus){ + const status = applicationDetailData.data != undefined ? applicationDetailData.data.status : "" + if (status === "submitted" && params.id > 0 && getUploadStatus) { axios.get(`${SET_PUBLIC_NOTICE_STATUS_REVIEWED}/${params.id}`) .then((response) => { if (response.status === 204) { @@ -279,7 +281,7 @@ const PublicNoticeDetail_GLD = () => { console.log(error); return false; }); - }else{ + } else { setUploadStatus(false); } }, [getUploadStatus]); @@ -346,7 +348,10 @@ const PublicNoticeDetail_GLD = () => { - + diff --git a/src/pages/PublicNoticeDetail_GLD/tabTableDetail/ProofTab.js b/src/pages/PublicNoticeDetail_GLD/tabTableDetail/ProofTab.js index 2a72449..be855f0 100644 --- a/src/pages/PublicNoticeDetail_GLD/tabTableDetail/ProofTab.js +++ b/src/pages/PublicNoticeDetail_GLD/tabTableDetail/ProofTab.js @@ -1,54 +1,53 @@ // material-ui import * as React from 'react'; +import * as DateUtils from "utils/DateUtils"; import {FiDataGrid} from "components/FiDataGrid"; -import { - Button -} from '@mui/material'; // ==============================|| EVENT TABLE ||============================== // export default function ProofTab({rows}) { + function currencyFormat(num) { + return num.toLocaleString('en-US', { + minimumFractionDigits: 2 + }); + } + + const columns = [ { - id: 'proofRef', - field: 'proofRef', - headerName: 'Proof Ref.', + + id: 'refNo', + field: 'refNo', + headerName: 'Proof No.', flex: 1, }, { - id: 'proofSent', - field: 'proofSent', - headerName: 'Proof Return', + id: 'created', + field: 'created', + headerName: 'Proof Date', flex: 1, + valueGetter: (params) => { + return DateUtils.datetimeStr(params?.value); + } }, { - id: 'proofReturn', - field: 'proofReturn', - headerName: 'Proof Return', - flex: 1, - }, - { - id: 'status', - field: 'status', - headerName: 'Status', + id: 'replyDate', + field: 'replyDate', + headerName: 'Confirmed/Return Date', flex: 1, + valueGetter: (params) => { + return params?.value?DateUtils.datetimeStr(params?.value):""; + } }, { id: 'fee', field: 'fee', - headerName: 'Fee (HKD)', - flex: 2, + headerName: 'Fee', + flex: 1, + valueGetter: (params) => { + return (params?.value)?"$ "+currencyFormat(params?.value):""; + } }, - { - field: 'detail', - type: 'actions', - headerName: '', - width: 50, - cellClassName: 'actions', - renderCell: () => { - return ; - }, - } ]; return ( diff --git a/src/pages/PublicNoticeDetail_GLD/tabTableDetail/TabTable.js b/src/pages/PublicNoticeDetail_GLD/tabTableDetail/TabTable.js index 942636b..f05f539 100644 --- a/src/pages/PublicNoticeDetail_GLD/tabTableDetail/TabTable.js +++ b/src/pages/PublicNoticeDetail_GLD/tabTableDetail/TabTable.js @@ -21,31 +21,28 @@ const ProofTab = Loadable(lazy(() => import('./ProofTab'))); // ==============================|| DASHBOARD - DEFAULT ||============================== // -const PublicNotice = ({applicationDetailData}) => { - const [submittedList, ] = React.useState([]); - const [inProgressList, ] = React.useState([]); +const PublicNotice = ({applicationDetailData, proofList}) => { + const [_proofList, setProofList] = React.useState([]); + const [inProgressList,] = React.useState([]); const [onReady,setOnReady] = React.useState(false); const [selectedTab, setSelectedTab] = React.useState("1"); // const navigate = useNavigate(); const [statusHistoryList, setStatusHistoryList] = React.useState([]); - - // useEffect(() => { - // loadData(); - // }, []); - const reloadPage = () => { window.location.reload(false); } React.useEffect(() => { - //if user data from parent are not null - // console.log(applicationDetailData) if (Object.keys(applicationDetailData).length > 0) { setStatusHistoryList(applicationDetailData.statusHistoryList); } }, [applicationDetailData]); + React.useEffect(() => { + setProofList(proofList); + }, [proofList]); + React.useEffect(() => { //if state data are ready and assign to different field if (statusHistoryList.length > 0) { @@ -75,14 +72,14 @@ const PublicNotice = ({applicationDetailData}) => { - +