diff --git a/src/pages/ProofCreate_FromApp/DataGrid.js b/src/pages/ProofCreate_FromApp/DataGrid.js deleted file mode 100644 index 7f0fc11..0000000 --- a/src/pages/ProofCreate_FromApp/DataGrid.js +++ /dev/null @@ -1,136 +0,0 @@ -// 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('/application/'+ params.id); - }; - - - 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 = ""; - let code = ""; - 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 [appNo+" ("+code+")"+isssue] - }, - }, - { - id: 'created', - field: 'created', - headerName: 'Proof Date', - flex: 1, - valueGetter: (params) => { - return DateUtils.datetimeStr(params?.value); - } - }, - { - id: 'created', - field: 'created', - headerName: 'Confirmed/Return Date', - flex: 1, - valueGetter: (params) => { - return 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: 'groupNo', - field: 'groupNo', - 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)?(params?.value):""; - } - }, - ]; - - 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/ProofCreate_FromApp/GazetteDetails.js b/src/pages/ProofCreate_FromApp/GazetteDetails.js index c6cba0f..118b626 100644 --- a/src/pages/ProofCreate_FromApp/GazetteDetails.js +++ b/src/pages/ProofCreate_FromApp/GazetteDetails.js @@ -78,7 +78,7 @@ const GazetteDetails = ({ formData }) => { @@ -93,7 +93,7 @@ const GazetteDetails = ({ formData }) => { diff --git a/src/pages/ProofCreate_FromApp/ProofForm.js b/src/pages/ProofCreate_FromApp/ProofForm.js new file mode 100644 index 0000000..442cf2d --- /dev/null +++ b/src/pages/ProofCreate_FromApp/ProofForm.js @@ -0,0 +1,311 @@ +// material-ui +import { + Dialog, DialogTitle, DialogContent, DialogActions, + Typography, + Autocomplete, + CardContent, + Grid, + Stack, + TextField, + FormLabel, + Button +} from '@mui/material'; +import * as UrlUtils from "utils/ApiPathConst"; +import * as HttpUtils from "utils/HttpUtils"; +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 Loadable from 'components/Loadable'; +const UploadFileTable = Loadable(React.lazy(() => import('./UploadFileTable'))); +// ==============================|| DASHBOARD - DEFAULT ||============================== // + + +const FormPanel = ({ formData }) => { + + const [data, setData] = React.useState({}); + const [columnPrice, setColumnPrice] = React.useState(ComboData.proofPrice[0]); + const [attachments, setAttachments] = React.useState([]); + + const [isWarningPopUp, setIsWarningPopUp] = React.useState(false); + const [warningText, setWarningText] = React.useState(""); + + const navigate = useNavigate() + + React.useEffect(() => { + if (formData) + setData(formData); + }, [formData]); + + const formik = useFormik({ + enableReinitialize: true, + initialValues: data, + onSubmit: values => { + if (!attachments || attachments.length<=0) { + setWarningText("請選擇上傳檔案"); + setIsWarningPopUp(true); + return; + } + // console.log(values); + HttpUtils.postWithFiles({ + url: UrlUtils.CREATE_PROOF, + params: { + appId: values.id, + fee: values.fee, + length: values.length, + colCount: columnPrice.colCount, + noOfPages: values.noOfPages, + }, + files: attachments, + onSuccess: function () { + navigate("/proof/search"); + } + }); + } + }); + + 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 ( + + +
+ {/*row 1*/} + + + Proof + + + + {/*row 2*/} + + + = (formik.values.groupType == "A" ? 2 : 1)} + onChange={(event) => { + readFile(event) + }} + /> + + + + + + + + + + + + + { + formik.values.groupType == "A" ? + + + + + pages + + + x + + + ${formik.values.price ? formik.values.price : 0} + + + + : + + + { + const value = event.target.value; + formik.setFieldValue("length", value); + formik.setFieldValue("fee", columnPrice.value*value); + }} + name="length" + value={formik.values["length"]} + variant="outlined" + sx={ + { + "& .MuiInputBase-input.Mui-disabled": { + WebkitTextFillColor: "#000000", + background: "#f8f8f8", + }, + width: '15%' + } + } + /> + + cm + + + + x + + + option.label ? option.label : ""} + onChange={(event, newValue) => { + setColumnPrice(newValue) + formik.values["fee"] = newValue.value*formik.values.length; + }} + renderInput={(params) => ( + + )} + /> + + + } + + + + + + + + + Necessary fee: + + + $ + + + + + + + + + + + + + + +
+
+ setIsWarningPopUp(false)} > + 注意 + + {warningText} + + + + + +
+
+ ); +}; + +export default FormPanel; diff --git a/src/pages/ProofCreate_FromApp/UploadFileTable.js b/src/pages/ProofCreate_FromApp/UploadFileTable.js new file mode 100644 index 0000000..5dcbbf8 --- /dev/null +++ b/src/pages/ProofCreate_FromApp/UploadFileTable.js @@ -0,0 +1,109 @@ +// 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: 'File Name', + flex: 1, + }, + { + id: 'size', + field: 'size', + headerName: 'File Size', + valueGetter: (params) => { + // console.log(params) + return Math.ceil(params.value/1024)+" KB"; + }, + flex: 1, + }, + ]; + + return ( + + + + ); +} diff --git a/src/pages/ProofCreate_FromApp/index.js b/src/pages/ProofCreate_FromApp/index.js index 87a75be..af1a6d1 100644 --- a/src/pages/ProofCreate_FromApp/index.js +++ b/src/pages/ProofCreate_FromApp/index.js @@ -6,13 +6,14 @@ 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 { 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 GazetteDetails = Loadable(React.lazy(() => import('./GazetteDetails'))); -const EventTable = Loadable(React.lazy(() => import('./DataGrid'))); +const ProofForm = Loadable(React.lazy(() => import('./ProofForm'))); // ==============================|| DASHBOARD - DEFAULT ||============================== // @@ -42,6 +43,9 @@ const Index = () => { responseData.data["faxNumber"] = JSON.parse(responseData.data.contactFaxNo).faxNumber; responseData.data["fax_countryCode"] = JSON.parse(responseData.data.contactFaxNo).countryCode; + + responseData.data["issueNoStr"] = responseData.data.issueVolume+"/"+responseData.data.issueYear+" No. "+responseData.data.issueNo + responseData.data["issueDate"] = DateUtils.dateStr(responseData.data.issueDate); setRecord(responseData.data); } }); @@ -84,8 +88,8 @@ const Index = () => { border={false} content={false} > - diff --git a/src/pages/ProofSearch/DataGrid.js b/src/pages/ProofSearch/DataGrid.js index 7f0fc11..5a6ff79 100644 --- a/src/pages/ProofSearch/DataGrid.js +++ b/src/pages/ProofSearch/DataGrid.js @@ -37,14 +37,14 @@ export default function SearchPublicNoticeTable({ recordList }) { headerName: 'Application No./ Gazette Code/ Gazette Issue', flex: 1, renderCell: (params) => { - let appNo = ""; - let code = ""; + 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 [appNo+" ("+code+")"+isssue] + return
App No: {appNo}
Gazette Code: {code}
Issue: {isssue}
}, }, { @@ -57,12 +57,12 @@ export default function SearchPublicNoticeTable({ recordList }) { } }, { - id: 'created', - field: 'created', + id: 'replyDate', + field: 'replyDate', headerName: 'Confirmed/Return Date', flex: 1, valueGetter: (params) => { - return DateUtils.datetimeStr(params?.value); + return params?.value?DateUtils.datetimeStr(params?.value):""; } }, { @@ -94,8 +94,8 @@ export default function SearchPublicNoticeTable({ recordList }) { } }, { - id: 'groupNo', - field: 'groupNo', + id: 'groupTitle', + field: 'groupTitle', headerName: 'Gazette Group', flex: 1, valueGetter: (params) => { @@ -108,11 +108,18 @@ export default function SearchPublicNoticeTable({ recordList }) { headerName: 'Fee', flex: 1, valueGetter: (params) => { - return (params?.value)?(params?.value):""; + 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; @@ -123,6 +130,7 @@ export default function SearchPublicNoticeTable({ recordList }) {
0) ? orgSelected?.key : "", }; @@ -234,9 +234,9 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria,issu disablePortal id="status" filterOptions={(options) => options} - options={ComboData.publicNoticeStaticEng} + options={ComboData.proofStatus} value={status} - inputValue={status?.label} + inputValue={status?.label?status?.label:""} onChange={(event, newValue) => { if (newValue !== null) { setStatus(newValue); diff --git a/src/pages/ProofSearch/index.js b/src/pages/ProofSearch/index.js index 883e0e5..dde3b21 100644 --- a/src/pages/ProofSearch/index.js +++ b/src/pages/ProofSearch/index.js @@ -55,7 +55,7 @@ const UserSearchPage_Individual = () => { function getUserList(){ HttpUtils.get({ - url: UrlUtils.GET_PUBLIC_NOTICE_LIST, + url: UrlUtils.LIST_PROOF, params: searchCriteria, onSuccess: function(responseData){ setRecord(responseData); diff --git a/src/pages/PublicNotice/ApplyForm/PublicNoticeApplyForm.js b/src/pages/PublicNotice/ApplyForm/PublicNoticeApplyForm.js index 244b50c..c15fa3f 100644 --- a/src/pages/PublicNotice/ApplyForm/PublicNoticeApplyForm.js +++ b/src/pages/PublicNotice/ApplyForm/PublicNoticeApplyForm.js @@ -1,7 +1,7 @@ // material-ui import { - Grid, - Typography, + Grid, + Typography, Button, RadioGroup, Dialog, DialogTitle, DialogContent, DialogActions, @@ -16,21 +16,21 @@ import * as FieldUtils from "utils/FieldUtils"; import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' -import {useNavigate} from "react-router-dom"; +import { useNavigate } from "react-router-dom"; // ==============================|| DASHBOARD - DEFAULT ||============================== // -const PublicNoticeApplyForm = ({loadedData, selections}) => { +const PublicNoticeApplyForm = ({ loadedData, selections }) => { const [isWarningPopUp, setIsWarningPopUp] = React.useState(false); const [warningText, setWarningText] = React.useState(""); - const [attachment, setAttachment] = React.useState({}); - const navigate=useNavigate(); + const [attachment, setAttachment] = React.useState({}); + const navigate = useNavigate(); const BackgroundHead = { backgroundImage: `url(${titleBackgroundImg})`, width: 'auto', height: 'auto', - backgroundSize:'contain', + backgroundSize: 'contain', backgroundRepeat: 'no-repeat', backgroundColor: '#0C489E', backgroundPosition: 'right' @@ -40,31 +40,31 @@ const PublicNoticeApplyForm = ({loadedData, selections}) => { // },[]); const formik = useFormik({ - enableReinitialize:true, - initialValues:loadedData, - validationSchema:yup.object().shape({ + enableReinitialize: true, + initialValues: loadedData, + validationSchema: yup.object().shape({ contactPerson: yup.string().max(40, "不得超過 40 個字符").required('請輸入聯絡人'), - tel_countryCode: yup.string().min(3,'請輸入3位數字').required('請輸入國際區號'), - fax_countryCode: yup.string().min(3,'請輸入3位數字'), - phoneNumber: yup.string().min(8,'請輸入8位數字').required('請輸入聯絡電話'), - faxNumber: yup.string().min(8,'請輸入8位數字'), + tel_countryCode: yup.string().min(3, '請輸入3位數字').required('請輸入國際區號'), + fax_countryCode: yup.string().min(3, '請輸入3位數字'), + phoneNumber: yup.string().min(8, '請輸入8位數字').required('請輸入聯絡電話'), + faxNumber: yup.string().min(8, '請輸入8位數字'), remarks: yup.string().max(255, "不得超過 255 個字符").nullable(), }), - onSubmit:values=>{ - if(!values.issueId){ + onSubmit: values => { + if (!values.issueId) { setWarningText("請選擇目標期數"); setIsWarningPopUp(true); return; } - if(!attachment){ + if (!attachment) { setWarningText("請選擇上傳檔案"); setIsWarningPopUp(true); return; - }else if(!attachment.size || attachment.size <=0){ + } else if (!attachment.size || attachment.size <= 0) { setWarningText("請上傳有效檔案"); setIsWarningPopUp(true); return; - }else if(attachment.size >= (10*1024*1034)){ + } else if (attachment.size >= (10 * 1024 * 1034)) { setWarningText("上傳檔案大小應<10MB"); setIsWarningPopUp(true); return; @@ -79,15 +79,15 @@ const PublicNoticeApplyForm = ({loadedData, selections}) => { countryCode: values.tel_countryCode, phoneNumber: values.phoneNumber }, - contactFaxNo:{ + contactFaxNo: { countryCode: values.fax_countryCode, faxNumber: values.faxNumber }, - issueId:values.issueId, - remarks:values.remarks?values.remarks:"", + issueId: values.issueId, + remarks: values.remarks ? values.remarks : "", }, files: [attachment], - onSuccess: function(){ + onSuccess: function () { navigate("/publicNotice"); // location.reload(); } @@ -95,16 +95,16 @@ const PublicNoticeApplyForm = ({loadedData, selections}) => { } }); - const readFile=(event)=>{ + const readFile = (event) => { let file = event.target.files[0]; - if(file){ - if(file.name.toLowerCase().substr(file.name.length - 4).includes(".doc") - || file.name.toLowerCase().substr(file.name.length - 5).includes(".docx") - || file.name.toLowerCase().substr(file.name.length - 4).includes(".xls") - || file.name.toLowerCase().substr(file.name.length - 5).includes(".xlsx") - ){ + if (file) { + if (file.name.toLowerCase().substr(file.name.length - 4).includes(".doc") + || file.name.toLowerCase().substr(file.name.length - 5).includes(".docx") + || file.name.toLowerCase().substr(file.name.length - 4).includes(".xls") + || file.name.toLowerCase().substr(file.name.length - 5).includes(".xlsx") + ) { setAttachment(event.target.files[0]); - }else{ + } else { setWarningText("請上傳有效檔案 (檔案格式: .doc, .docx, .xls, .xlsx)"); setIsWarningPopUp(true); setAttachment({}); @@ -116,135 +116,135 @@ const PublicNoticeApplyForm = ({loadedData, selections}) => { return ( - - -
- - 申請公共啟事 - -
-
- {/* + + +
+ + 申請公共啟事 + +
+
+ {/* 申請公共啟事 */} - - -
- - - {FieldUtils.getTextField({ - label:"聯絡人:", - valueName:"contactPerson", - form: formik, - disabled:true - })} - - - {FieldUtils.getPhoneField({ - label:"聯繫電話:", - disabled:true, - valueName:{ - code: "tel_countryCode", - num:"phoneNumber", - }, - form: formik - })} - - - {FieldUtils.getPhoneField({ - label:"聯繫傳真:", - disabled:true, - valueName:{ - code: "fax_countryCode", - num:"faxNumber", - }, - form: formik - })} - - - + + + + + + {FieldUtils.getTextField({ + label: "聯絡人:", + valueName: "contactPerson", + form: formik, + disabled: true + })} + + + {FieldUtils.getPhoneField({ + label: "聯繫電話:", + disabled: true, + valueName: { + code: "tel_countryCode", + num: "phoneNumber", + }, + form: formik + })} + + + {FieldUtils.getPhoneField({ + label: "聯繫傳真:", + disabled: true, + valueName: { + code: "fax_countryCode", + num: "faxNumber", + }, + form: formik + })} + + + - 目標期數: - - - - { - selections - } - - + sx={{ display: 'flex', alignItems: 'center' }}> + 目標期數: + + + + { + selections + } + - - + + + - 稿件檔案 ({"檔案大小應<10MB"}): - - - { - readFile(event) - }} - /> - {attachment.name} - - + sx={{ display: 'flex', alignItems: 'center' }}> + 稿件檔案 ({"檔案大小應<10MB"}): + + + { + readFile(event) + }} + /> + {attachment.name} + + - - + + + - - {FieldUtils.getTextArea({ - label:"備註:", - valueName:"remarks", - form: formik, - inputProps:{maxLength: 255} - })} - - -
- -
-
- -
-
-
- setIsWarningPopUp(false)} > - 注意 - - {warningText} - - - - - -
+ + {FieldUtils.getTextArea({ + label: "備註:", + valueName: "remarks", + form: formik, + inputProps: { maxLength: 255 } + })} + + +
+ +
+
+
+ +
+
+ setIsWarningPopUp(false)} > + 注意 + + {warningText} + + + + + +
+
); }; diff --git a/src/utils/ApiPathConst.js b/src/utils/ApiPathConst.js index 86f06ad..5848ccb 100644 --- a/src/utils/ApiPathConst.js +++ b/src/utils/ApiPathConst.js @@ -69,8 +69,9 @@ export const UPDATE_PUBLIC_NOTICE_APPLY_DETAIL = apiPath+'/application/save'; export const GET_ISSUE_COMBO = apiPath+'/gazette-issue/combo'; -export const GET_PROOF_APP = apiPath+'/proof/create-from-app'; -export const GET_LIST_PROOF = apiPath+'/proof/create-from-app'; +export const LIST_PROOF = apiPath+'/proof/list';//GET +export const GET_PROOF_APP = apiPath+'/proof/create-from-app';//GET +export const CREATE_PROOF = apiPath+'/proof/create';//POST //User Group export const POST_AND_UPDATE_USER_GROUP = apiPath+'/group/save'; \ No newline at end of file diff --git a/src/utils/ComboData.js b/src/utils/ComboData.js index c92e73b..9b5b3bc 100644 --- a/src/utils/ComboData.js +++ b/src/utils/ComboData.js @@ -80,4 +80,15 @@ export const groupTitle = [ { 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' }, +]; + +export const proofPrice = [ + { label: 'Single Column $182', value: 182, colCount:1}, + { label: 'Double Column $364', value: 364, colCount:2}, +]; + +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' }, ]; \ No newline at end of file