| @@ -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 <Button onClick={handleEditClick(params)}><u>{params.row.refNo}</u></Button>; | |||
| }, | |||
| }, | |||
| { | |||
| 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}<br /> | |||
| {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 ( | |||
| <div style={{ height: 400, width: '100%' }}> | |||
| <FiDataGrid | |||
| rows={rows} | |||
| columns={columns} | |||
| initialState={{ | |||
| pagination: { | |||
| paginationModel: { page: 0, pageSize: 5 }, | |||
| }, | |||
| }} | |||
| /> | |||
| </div> | |||
| ); | |||
| } | |||
| @@ -78,7 +78,7 @@ const GazetteDetails = ({ formData }) => { | |||
| <Grid item xs={12} md={9} lg={9}> | |||
| <DisplayField | |||
| name="issueNum" | |||
| name="issueNoStr" | |||
| /> | |||
| </Grid> | |||
| @@ -93,7 +93,7 @@ const GazetteDetails = ({ formData }) => { | |||
| <Grid item xs={12} md={9} lg={9}> | |||
| <DisplayField | |||
| name="gazetteCode" | |||
| name="groupNo" | |||
| /> | |||
| </Grid> | |||
| @@ -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 ( | |||
| <MainCard xs={12} md={12} lg={12} | |||
| border={false} | |||
| content={false}> | |||
| <form onSubmit={formik.handleSubmit}> | |||
| {/*row 1*/} | |||
| <CardContent sx={{ px: 2.5, pt: 3 }}> | |||
| <Grid item justifyContent="space-between" alignItems="center"> | |||
| Proof | |||
| </Grid> | |||
| </CardContent> | |||
| {/*row 2*/} | |||
| <Grid container direction="column" sx={{ paddingLeft: 4, paddingRight: 4 }} spacing={1}> | |||
| <Grid item xs={12} md={12}> | |||
| <input | |||
| id="uploadFileBtn" | |||
| name="file" | |||
| type="file" | |||
| accept=".pdf" | |||
| style={{ display: 'none' }} | |||
| disabled={attachments.length >= (formik.values.groupType == "A" ? 2 : 1)} | |||
| onChange={(event) => { | |||
| readFile(event) | |||
| }} | |||
| /> | |||
| <label htmlFor="uploadFileBtn"> | |||
| <Button | |||
| component="span" | |||
| variant="contained" | |||
| size="large" | |||
| disabled={attachments.length >= (formik.values.groupType == "A" ? 2 : 1)} | |||
| > Upload Files</Button> | |||
| </label> | |||
| </Grid> | |||
| <Grid item xs={12} md={12}> | |||
| <UploadFileTable key="uploadTable" recordList={attachments} setRecordList={setAttachments} /> | |||
| </Grid> | |||
| <Grid item xs={12} md={12}> | |||
| <Button | |||
| size="large" | |||
| variant="contained" | |||
| sx={{ | |||
| textTransform: 'capitalize', | |||
| alignItems: 'end' | |||
| }}> | |||
| Calculate | |||
| </Button> | |||
| </Grid> | |||
| { | |||
| formik.values.groupType == "A" ? | |||
| <Grid item xs={12} md={12}> | |||
| <Stack direction="row" sx={{ display: 'flex', alignItems: 'center' }}> | |||
| <TextField | |||
| fullWidth | |||
| size="small" | |||
| type="text" | |||
| onChange={formik.handleChange} | |||
| name="noOfPages" | |||
| value={formik.values["noOfPages"]} | |||
| variant="outlined" | |||
| sx={ | |||
| { | |||
| "& .MuiInputBase-input.Mui-disabled": { | |||
| WebkitTextFillColor: "#000000", | |||
| background: "#f8f8f8", | |||
| }, | |||
| width: '15%' | |||
| } | |||
| } | |||
| /> | |||
| <FormLabel sx={{ paddingLeft: 2, paddingRight: 2, textAlign: "center" }}> | |||
| pages | |||
| </FormLabel> | |||
| <FormLabel sx={{ paddingLeft: 2, paddingRight: 2, textAlign: "center" }}> | |||
| x | |||
| </FormLabel> | |||
| <FormLabel sx={{ paddingLeft: 2, paddingRight: 2, textAlign: "center" }}> | |||
| ${formik.values.price ? formik.values.price : 0} | |||
| </FormLabel> | |||
| </Stack> | |||
| </Grid> | |||
| : | |||
| <Grid item xs={12} md={12}> | |||
| <Stack direction="row" sx={{ display: 'flex', alignItems: 'center' }}> | |||
| <TextField | |||
| fullWidth | |||
| size="small" | |||
| type="text" | |||
| onChange={(event)=>{ | |||
| 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%' | |||
| } | |||
| } | |||
| /> | |||
| <FormLabel sx={{ paddingLeft: 2, paddingRight: 2, textAlign: "center" }}> | |||
| cm | |||
| </FormLabel> | |||
| <FormLabel sx={{ paddingLeft: 2, paddingRight: 4, textAlign: "center" }}> | |||
| x | |||
| </FormLabel> | |||
| <Autocomplete | |||
| sx={{ | |||
| width: "15%" | |||
| }} | |||
| disablePortal | |||
| id="price" | |||
| options={ComboData.proofPrice} | |||
| value={columnPrice} | |||
| inputValue={(columnPrice?.label) ? columnPrice?.label : ""} | |||
| getOptionLabel={(option) => option.label ? option.label : ""} | |||
| onChange={(event, newValue) => { | |||
| setColumnPrice(newValue) | |||
| formik.values["fee"] = newValue.value*formik.values.length; | |||
| }} | |||
| renderInput={(params) => ( | |||
| <TextField {...params} | |||
| InputLabelProps={{ | |||
| shrink: true | |||
| }} | |||
| sx={{ | |||
| width: "100%" | |||
| }} | |||
| /> | |||
| )} | |||
| /> | |||
| </Stack> | |||
| </Grid> | |||
| } | |||
| <Grid item xs={12} md={12}> | |||
| <Stack direction="row" sx={{ display: 'flex', alignItems: 'center' }}> | |||
| <FormLabel sx={{ paddingRight: 2, textAlign: "center" }}> | |||
| Necessary fee: | |||
| </FormLabel> | |||
| <FormLabel sx={{ paddingLeft: 2, paddingRight: 2, textAlign: "center" }}> | |||
| $ | |||
| </FormLabel> | |||
| <TextField | |||
| fullWidth | |||
| size="small" | |||
| type="text" | |||
| onChange={formik.handleChange} | |||
| name="fee" | |||
| value={formik.values["fee"]} | |||
| variant="outlined" | |||
| sx={ | |||
| { | |||
| "& .MuiInputBase-input.Mui-disabled": { | |||
| WebkitTextFillColor: "#000000", | |||
| background: "#f8f8f8", | |||
| }, | |||
| width: '15%' | |||
| } | |||
| } | |||
| /> | |||
| </Stack> | |||
| </Grid> | |||
| <Grid item xs={12} md={12}> | |||
| <Button | |||
| size="large" | |||
| variant="contained" | |||
| color="success" | |||
| type="submit" | |||
| sx={{ | |||
| textTransform: 'capitalize', | |||
| alignItems: 'end' | |||
| }}> | |||
| Save | |||
| </Button> | |||
| </Grid> | |||
| </Grid> | |||
| </form> | |||
| <div> | |||
| <Dialog open={isWarningPopUp} onClose={() => setIsWarningPopUp(false)} > | |||
| <DialogTitle>注意</DialogTitle> | |||
| <DialogContent style={{ display: 'flex', }}> | |||
| <Typography variant="h3" style={{ padding: '16px' }}>{warningText}</Typography> | |||
| </DialogContent> | |||
| <DialogActions> | |||
| <Button onClick={() => setIsWarningPopUp(false)}>OK</Button> | |||
| </DialogActions> | |||
| </Dialog> | |||
| </div> | |||
| </MainCard> | |||
| ); | |||
| }; | |||
| export default FormPanel; | |||
| @@ -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 ( | |||
| <Stack height="100%" alignItems="center" justifyContent="center"> | |||
| No File Record | |||
| {/* <pre>(rows={[]})</pre> */} | |||
| </Stack> | |||
| ); | |||
| } | |||
| 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 [ | |||
| <GridActionsCellItem | |||
| key="OutSave" | |||
| icon={<RemoveCircleOutlineIcon/>} | |||
| 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 ( | |||
| <Box style={{ height: '200px', width: '100%' }}> | |||
| <DataGrid | |||
| rows={rows} | |||
| columns={columns} | |||
| editMode="row" | |||
| sx={{border:1}} | |||
| rowModesModel={rowModesModel} | |||
| disablePagination | |||
| components={{ NoRowsOverlay, }} | |||
| // hideFooterPagination={true} | |||
| disableSelectionOnClick | |||
| disableColumnMenu | |||
| disableColumnSelector | |||
| hideFooter | |||
| /> | |||
| </Box> | |||
| ); | |||
| } | |||
| @@ -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} | |||
| > | |||
| <EventTable | |||
| recordList={record} | |||
| <ProofForm | |||
| formData={record} | |||
| /> | |||
| </MainCard> | |||
| </Grid> | |||
| @@ -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 <div style={{margin: 4}}>App No: {appNo}<br/>Gazette Code: {code}<br/>Issue: {isssue}</div> | |||
| }, | |||
| }, | |||
| { | |||
| @@ -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 }) { | |||
| <div style={{ height: 400, width: '100%' }}> | |||
| <FiDataGrid | |||
| rowHeight={80} | |||
| rows={rows} | |||
| columns={columns} | |||
| initialState={{ | |||
| @@ -45,7 +45,7 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria,issu | |||
| dateFrom: data.dateFrom, | |||
| dateTo: data.dateTo, | |||
| contact: data.contact, | |||
| status: (status?.type && status?.type != 'all') ? status?.type : "", | |||
| replyed: (status?.type && status?.type != 'all') ? status?.type : "", | |||
| orgId: (orgSelected?.key && orgSelected?.key > 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); | |||
| @@ -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); | |||
| @@ -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 ( | |||
| <Grid container sx={{minHeight: '95vh',backgroundColor:'#ffffff'}} direction="column" alignItems="center"> | |||
| <Grid item xs={12} md={12} width="100%" > | |||
| <div style={BackgroundHead}> | |||
| <Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center"> | |||
| <Typography ml={15} color='#FFF' variant="h4">申請公共啟事</Typography> | |||
| </Stack> | |||
| </div> | |||
| </Grid> | |||
| {/* <Grid item xs={12}> | |||
| <Grid container sx={{ minHeight: '95vh', backgroundColor: '#ffffff' }} direction="column" alignItems="center"> | |||
| <Grid item xs={12} md={12} width="100%" > | |||
| <div style={BackgroundHead}> | |||
| <Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center"> | |||
| <Typography ml={15} color='#FFF' variant="h4">申請公共啟事</Typography> | |||
| </Stack> | |||
| </div> | |||
| </Grid> | |||
| {/* <Grid item xs={12}> | |||
| <Typography variant="h5">申請公共啟事</Typography> | |||
| </Grid> */} | |||
| <Grid item xs={12} md={12} width={{md:"60%",xs:"90%"}}> | |||
| <Box xs={12} mt={1} sx={{ p: 2, border: '3px groove grey', borderRadius: '10px'}}> | |||
| <form onSubmit={formik.handleSubmit}> | |||
| <Grid container spacing={1} sx={{minHeight: '80vh'}} direction="row" justifyContent="flex-start" alignItems="center"> | |||
| <Grid item xs={12} md={12} lg={12} sx={{ mb: 1 }}> | |||
| {FieldUtils.getTextField({ | |||
| label:"聯絡人:", | |||
| valueName:"contactPerson", | |||
| form: formik, | |||
| disabled:true | |||
| })} | |||
| </Grid> | |||
| <Grid item xs={12} md={12}> | |||
| {FieldUtils.getPhoneField({ | |||
| label:"聯繫電話:", | |||
| disabled:true, | |||
| valueName:{ | |||
| code: "tel_countryCode", | |||
| num:"phoneNumber", | |||
| }, | |||
| form: formik | |||
| })} | |||
| </Grid> | |||
| <Grid item xs={12} md={12}> | |||
| {FieldUtils.getPhoneField({ | |||
| label:"聯繫傳真:", | |||
| disabled:true, | |||
| valueName:{ | |||
| code: "fax_countryCode", | |||
| num:"faxNumber", | |||
| }, | |||
| form: formik | |||
| })} | |||
| </Grid> | |||
| <Grid item xs={12} lg={12}> | |||
| <Grid container alignItems={"center"}> | |||
| <Grid item xs={12} md={12} width={{ md: "60%", xs: "90%" }}> | |||
| <Box xs={12} mt={1} sx={{ p: 2, border: '3px groove grey', borderRadius: '10px' }}> | |||
| <form onSubmit={formik.handleSubmit}> | |||
| <Grid container spacing={1} sx={{ minHeight: '80vh' }} direction="row" justifyContent="flex-start" alignItems="center"> | |||
| <Grid item xs={12} md={12} lg={12} sx={{ mb: 1 }}> | |||
| {FieldUtils.getTextField({ | |||
| label: "聯絡人:", | |||
| valueName: "contactPerson", | |||
| form: formik, | |||
| disabled: true | |||
| })} | |||
| </Grid> | |||
| <Grid item xs={12} md={12}> | |||
| {FieldUtils.getPhoneField({ | |||
| label: "聯繫電話:", | |||
| disabled: true, | |||
| valueName: { | |||
| code: "tel_countryCode", | |||
| num: "phoneNumber", | |||
| }, | |||
| form: formik | |||
| })} | |||
| </Grid> | |||
| <Grid item xs={12} md={12}> | |||
| {FieldUtils.getPhoneField({ | |||
| label: "聯繫傳真:", | |||
| disabled: true, | |||
| valueName: { | |||
| code: "fax_countryCode", | |||
| num: "faxNumber", | |||
| }, | |||
| form: formik | |||
| })} | |||
| </Grid> | |||
| <Grid item xs={12} lg={12}> | |||
| <Grid container alignItems={"center"}> | |||
| <Grid item xs={12} md={3} lg={3} | |||
| sx={{display: 'flex', alignItems: 'center'}}> | |||
| 目標期數: | |||
| </Grid> | |||
| <Grid item xs={12} md={6} lg={6}> | |||
| <RadioGroup | |||
| aria-labelledby="demo-radio-buttons-group-label" | |||
| id="issueId" | |||
| name="issueId" | |||
| defaultValue={formik.values.issueId} | |||
| > | |||
| { | |||
| selections | |||
| } | |||
| </RadioGroup> | |||
| </Grid> | |||
| sx={{ display: 'flex', alignItems: 'center' }}> | |||
| 目標期數: | |||
| </Grid> | |||
| <Grid item xs={12} md={6} lg={6}> | |||
| <RadioGroup | |||
| aria-labelledby="demo-radio-buttons-group-label" | |||
| id="issueId" | |||
| name="issueId" | |||
| defaultValue={formik.values.issueId} | |||
| > | |||
| { | |||
| selections | |||
| } | |||
| </RadioGroup> | |||
| </Grid> | |||
| </Grid> | |||
| <Grid item xs={12} md={12} lg={12}> | |||
| <Grid container direction="row" justifyContent="flex-start" alignItems="center"> | |||
| </Grid> | |||
| <Grid item xs={12} md={12} lg={12}> | |||
| <Grid container direction="row" justifyContent="flex-start" alignItems="center"> | |||
| <Grid item xs={12} md={3} lg={3} | |||
| sx={{display: 'flex', alignItems: 'center'}}> | |||
| 稿件檔案 ({"檔案大小應<10MB"}): | |||
| </Grid> | |||
| <Grid item xs={12} md={3} lg={3}> | |||
| <input | |||
| id="uploadFileBtn" | |||
| name="file" | |||
| type="file" | |||
| accept=".doc,.docx,.xls,.xlsx" | |||
| style={{ display: 'none' }} | |||
| onChange={(event)=> { | |||
| readFile(event) | |||
| }} | |||
| /> | |||
| {attachment.name} | |||
| </Grid> | |||
| <Grid item xs={12} md={3} lg={3}> | |||
| sx={{ display: 'flex', alignItems: 'center' }}> | |||
| 稿件檔案 ({"檔案大小應<10MB"}): | |||
| </Grid> | |||
| <Grid item xs={12} md={3} lg={3}> | |||
| <input | |||
| id="uploadFileBtn" | |||
| name="file" | |||
| type="file" | |||
| accept=".doc,.docx,.xls,.xlsx" | |||
| style={{ display: 'none' }} | |||
| onChange={(event) => { | |||
| readFile(event) | |||
| }} | |||
| /> | |||
| {attachment.name} | |||
| </Grid> | |||
| <Grid item xs={12} md={3} lg={3}> | |||
| <label htmlFor="uploadFileBtn"> | |||
| <Button | |||
| component="span" | |||
| variant="outlined" | |||
| size="large" | |||
| >{attachment?"上傳檔案":"重新上傳"}</Button> | |||
| </label> | |||
| </Grid> | |||
| <Button | |||
| component="span" | |||
| variant="outlined" | |||
| size="large" | |||
| >{attachment ? "上傳檔案" : "重新上傳"}</Button> | |||
| </label> | |||
| </Grid> | |||
| </Grid> | |||
| <Grid item xs={12} md={12} lg={12}> | |||
| {FieldUtils.getTextArea({ | |||
| label:"備註:", | |||
| valueName:"remarks", | |||
| form: formik, | |||
| inputProps:{maxLength: 255} | |||
| })} | |||
| </Grid> | |||
| <Grid item xs={12}> | |||
| <center> | |||
| <Button | |||
| variant="contained" | |||
| type="submit" | |||
| size="large" | |||
| >申請公共啟事</Button> | |||
| </center> | |||
| </Grid> | |||
| </Grid> | |||
| </form> | |||
| </Box> | |||
| </Grid> | |||
| <div> | |||
| <Dialog open={isWarningPopUp} onClose={() => setIsWarningPopUp(false)} > | |||
| <DialogTitle>注意</DialogTitle> | |||
| <DialogContent style={{ display: 'flex', }}> | |||
| <Typography variant="h3" style={{ padding: '16px' }}>{warningText}</Typography> | |||
| </DialogContent> | |||
| <DialogActions> | |||
| <Button onClick={() => setIsWarningPopUp(false)}>OK</Button> | |||
| </DialogActions> | |||
| </Dialog> | |||
| </div> | |||
| <Grid item xs={12} md={12} lg={12}> | |||
| {FieldUtils.getTextArea({ | |||
| label: "備註:", | |||
| valueName: "remarks", | |||
| form: formik, | |||
| inputProps: { maxLength: 255 } | |||
| })} | |||
| </Grid> | |||
| <Grid item xs={12}> | |||
| <center> | |||
| <Button | |||
| variant="contained" | |||
| type="submit" | |||
| size="large" | |||
| >申請公共啟事</Button> | |||
| </center> | |||
| </Grid> | |||
| </Grid> | |||
| </form> | |||
| </Box> | |||
| </Grid> | |||
| <div> | |||
| <Dialog open={isWarningPopUp} onClose={() => setIsWarningPopUp(false)} > | |||
| <DialogTitle>注意</DialogTitle> | |||
| <DialogContent style={{ display: 'flex', }}> | |||
| <Typography variant="h3" style={{ padding: '16px' }}>{warningText}</Typography> | |||
| </DialogContent> | |||
| <DialogActions> | |||
| <Button onClick={() => setIsWarningPopUp(false)}>OK</Button> | |||
| </DialogActions> | |||
| </Dialog> | |||
| </div> | |||
| </Grid> | |||
| ); | |||
| }; | |||
| @@ -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'; | |||
| @@ -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' }, | |||
| ]; | |||