@@ -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}> | <Grid item xs={12} md={9} lg={9}> | ||||
<DisplayField | <DisplayField | ||||
name="issueNum" | |||||
name="issueNoStr" | |||||
/> | /> | ||||
</Grid> | </Grid> | ||||
@@ -93,7 +93,7 @@ const GazetteDetails = ({ formData }) => { | |||||
<Grid item xs={12} md={9} lg={9}> | <Grid item xs={12} md={9} lg={9}> | ||||
<DisplayField | <DisplayField | ||||
name="gazetteCode" | |||||
name="groupNo" | |||||
/> | /> | ||||
</Grid> | </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 UrlUtils from "utils/ApiPathConst"; | ||||
import * as React from "react"; | import * as React from "react"; | ||||
import * as HttpUtils from "utils/HttpUtils"; | import * as HttpUtils from "utils/HttpUtils"; | ||||
import * as DateUtils from "utils/DateUtils"; | |||||
import { useParams } from "react-router-dom"; | import { useParams } from "react-router-dom"; | ||||
import Loadable from 'components/Loadable'; | import Loadable from 'components/Loadable'; | ||||
const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | ||||
const ApplicationDetails = Loadable(React.lazy(() => import('./ApplicationDetails'))); | const ApplicationDetails = Loadable(React.lazy(() => import('./ApplicationDetails'))); | ||||
const GazetteDetails = Loadable(React.lazy(() => import('./GazetteDetails'))); | const GazetteDetails = Loadable(React.lazy(() => import('./GazetteDetails'))); | ||||
const EventTable = Loadable(React.lazy(() => import('./DataGrid'))); | |||||
const ProofForm = Loadable(React.lazy(() => import('./ProofForm'))); | |||||
// ==============================|| DASHBOARD - DEFAULT ||============================== // | // ==============================|| DASHBOARD - DEFAULT ||============================== // | ||||
@@ -42,6 +43,9 @@ const Index = () => { | |||||
responseData.data["faxNumber"] = JSON.parse(responseData.data.contactFaxNo).faxNumber; | responseData.data["faxNumber"] = JSON.parse(responseData.data.contactFaxNo).faxNumber; | ||||
responseData.data["fax_countryCode"] = JSON.parse(responseData.data.contactFaxNo).countryCode; | 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); | setRecord(responseData.data); | ||||
} | } | ||||
}); | }); | ||||
@@ -84,8 +88,8 @@ const Index = () => { | |||||
border={false} | border={false} | ||||
content={false} | content={false} | ||||
> | > | ||||
<EventTable | |||||
recordList={record} | |||||
<ProofForm | |||||
formData={record} | |||||
/> | /> | ||||
</MainCard> | </MainCard> | ||||
</Grid> | </Grid> | ||||
@@ -37,14 +37,14 @@ export default function SearchPublicNoticeTable({ recordList }) { | |||||
headerName: 'Application No./ Gazette Code/ Gazette Issue', | headerName: 'Application No./ Gazette Code/ Gazette Issue', | ||||
flex: 1, | flex: 1, | ||||
renderCell: (params) => { | renderCell: (params) => { | ||||
let appNo = ""; | |||||
let code = ""; | |||||
let appNo = params.row.appNo; | |||||
let code = params.row.groupNo; | |||||
let isssue = params.row.issueYear | let isssue = params.row.issueYear | ||||
+" Vol. "+zeroPad(params.row.issueVolume,3) | +" Vol. "+zeroPad(params.row.issueVolume,3) | ||||
+", No. "+zeroPad(params.row.issueNo,2) | +", No. "+zeroPad(params.row.issueNo,2) | ||||
+", "+DateUtils.dateFormat(params.row.issueDate, "D MMM YYYY (ddd)"); | +", "+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', | headerName: 'Confirmed/Return Date', | ||||
flex: 1, | flex: 1, | ||||
valueGetter: (params) => { | 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', | headerName: 'Gazette Group', | ||||
flex: 1, | flex: 1, | ||||
valueGetter: (params) => { | valueGetter: (params) => { | ||||
@@ -108,11 +108,18 @@ export default function SearchPublicNoticeTable({ recordList }) { | |||||
headerName: 'Fee', | headerName: 'Fee', | ||||
flex: 1, | flex: 1, | ||||
valueGetter: (params) => { | 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) { | function zeroPad(num, places) { | ||||
num=num?num:0; | num=num?num:0; | ||||
var zero = places - num.toString().length + 1; | var zero = places - num.toString().length + 1; | ||||
@@ -123,6 +130,7 @@ export default function SearchPublicNoticeTable({ recordList }) { | |||||
<div style={{ height: 400, width: '100%' }}> | <div style={{ height: 400, width: '100%' }}> | ||||
<FiDataGrid | <FiDataGrid | ||||
rowHeight={80} | |||||
rows={rows} | rows={rows} | ||||
columns={columns} | columns={columns} | ||||
initialState={{ | initialState={{ | ||||
@@ -45,7 +45,7 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria,issu | |||||
dateFrom: data.dateFrom, | dateFrom: data.dateFrom, | ||||
dateTo: data.dateTo, | dateTo: data.dateTo, | ||||
contact: data.contact, | 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 : "", | orgId: (orgSelected?.key && orgSelected?.key > 0) ? orgSelected?.key : "", | ||||
}; | }; | ||||
@@ -234,9 +234,9 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria,issu | |||||
disablePortal | disablePortal | ||||
id="status" | id="status" | ||||
filterOptions={(options) => options} | filterOptions={(options) => options} | ||||
options={ComboData.publicNoticeStaticEng} | |||||
options={ComboData.proofStatus} | |||||
value={status} | value={status} | ||||
inputValue={status?.label} | |||||
inputValue={status?.label?status?.label:""} | |||||
onChange={(event, newValue) => { | onChange={(event, newValue) => { | ||||
if (newValue !== null) { | if (newValue !== null) { | ||||
setStatus(newValue); | setStatus(newValue); | ||||
@@ -55,7 +55,7 @@ const UserSearchPage_Individual = () => { | |||||
function getUserList(){ | function getUserList(){ | ||||
HttpUtils.get({ | HttpUtils.get({ | ||||
url: UrlUtils.GET_PUBLIC_NOTICE_LIST, | |||||
url: UrlUtils.LIST_PROOF, | |||||
params: searchCriteria, | params: searchCriteria, | ||||
onSuccess: function(responseData){ | onSuccess: function(responseData){ | ||||
setRecord(responseData); | setRecord(responseData); | ||||
@@ -1,7 +1,7 @@ | |||||
// material-ui | // material-ui | ||||
import { | import { | ||||
Grid, | |||||
Typography, | |||||
Grid, | |||||
Typography, | |||||
Button, | Button, | ||||
RadioGroup, | RadioGroup, | ||||
Dialog, DialogTitle, DialogContent, DialogActions, | Dialog, DialogTitle, DialogContent, DialogActions, | ||||
@@ -16,21 +16,21 @@ import * as FieldUtils from "utils/FieldUtils"; | |||||
import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' | import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' | ||||
import {useNavigate} from "react-router-dom"; | |||||
import { useNavigate } from "react-router-dom"; | |||||
// ==============================|| DASHBOARD - DEFAULT ||============================== // | // ==============================|| DASHBOARD - DEFAULT ||============================== // | ||||
const PublicNoticeApplyForm = ({loadedData, selections}) => { | |||||
const PublicNoticeApplyForm = ({ loadedData, selections }) => { | |||||
const [isWarningPopUp, setIsWarningPopUp] = React.useState(false); | const [isWarningPopUp, setIsWarningPopUp] = React.useState(false); | ||||
const [warningText, setWarningText] = React.useState(""); | const [warningText, setWarningText] = React.useState(""); | ||||
const [attachment, setAttachment] = React.useState({}); | |||||
const navigate=useNavigate(); | |||||
const [attachment, setAttachment] = React.useState({}); | |||||
const navigate = useNavigate(); | |||||
const BackgroundHead = { | const BackgroundHead = { | ||||
backgroundImage: `url(${titleBackgroundImg})`, | backgroundImage: `url(${titleBackgroundImg})`, | ||||
width: 'auto', | width: 'auto', | ||||
height: 'auto', | height: 'auto', | ||||
backgroundSize:'contain', | |||||
backgroundSize: 'contain', | |||||
backgroundRepeat: 'no-repeat', | backgroundRepeat: 'no-repeat', | ||||
backgroundColor: '#0C489E', | backgroundColor: '#0C489E', | ||||
backgroundPosition: 'right' | backgroundPosition: 'right' | ||||
@@ -40,31 +40,31 @@ const PublicNoticeApplyForm = ({loadedData, selections}) => { | |||||
// },[]); | // },[]); | ||||
const formik = useFormik({ | 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('請輸入聯絡人'), | 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(), | remarks: yup.string().max(255, "不得超過 255 個字符").nullable(), | ||||
}), | }), | ||||
onSubmit:values=>{ | |||||
if(!values.issueId){ | |||||
onSubmit: values => { | |||||
if (!values.issueId) { | |||||
setWarningText("請選擇目標期數"); | setWarningText("請選擇目標期數"); | ||||
setIsWarningPopUp(true); | setIsWarningPopUp(true); | ||||
return; | return; | ||||
} | } | ||||
if(!attachment){ | |||||
if (!attachment) { | |||||
setWarningText("請選擇上傳檔案"); | setWarningText("請選擇上傳檔案"); | ||||
setIsWarningPopUp(true); | setIsWarningPopUp(true); | ||||
return; | return; | ||||
}else if(!attachment.size || attachment.size <=0){ | |||||
} else if (!attachment.size || attachment.size <= 0) { | |||||
setWarningText("請上傳有效檔案"); | setWarningText("請上傳有效檔案"); | ||||
setIsWarningPopUp(true); | setIsWarningPopUp(true); | ||||
return; | return; | ||||
}else if(attachment.size >= (10*1024*1034)){ | |||||
} else if (attachment.size >= (10 * 1024 * 1034)) { | |||||
setWarningText("上傳檔案大小應<10MB"); | setWarningText("上傳檔案大小應<10MB"); | ||||
setIsWarningPopUp(true); | setIsWarningPopUp(true); | ||||
return; | return; | ||||
@@ -79,15 +79,15 @@ const PublicNoticeApplyForm = ({loadedData, selections}) => { | |||||
countryCode: values.tel_countryCode, | countryCode: values.tel_countryCode, | ||||
phoneNumber: values.phoneNumber | phoneNumber: values.phoneNumber | ||||
}, | }, | ||||
contactFaxNo:{ | |||||
contactFaxNo: { | |||||
countryCode: values.fax_countryCode, | countryCode: values.fax_countryCode, | ||||
faxNumber: values.faxNumber | faxNumber: values.faxNumber | ||||
}, | }, | ||||
issueId:values.issueId, | |||||
remarks:values.remarks?values.remarks:"", | |||||
issueId: values.issueId, | |||||
remarks: values.remarks ? values.remarks : "", | |||||
}, | }, | ||||
files: [attachment], | files: [attachment], | ||||
onSuccess: function(){ | |||||
onSuccess: function () { | |||||
navigate("/publicNotice"); | navigate("/publicNotice"); | ||||
// location.reload(); | // location.reload(); | ||||
} | } | ||||
@@ -95,16 +95,16 @@ const PublicNoticeApplyForm = ({loadedData, selections}) => { | |||||
} | } | ||||
}); | }); | ||||
const readFile=(event)=>{ | |||||
const readFile = (event) => { | |||||
let file = event.target.files[0]; | 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]); | setAttachment(event.target.files[0]); | ||||
}else{ | |||||
} else { | |||||
setWarningText("請上傳有效檔案 (檔案格式: .doc, .docx, .xls, .xlsx)"); | setWarningText("請上傳有效檔案 (檔案格式: .doc, .docx, .xls, .xlsx)"); | ||||
setIsWarningPopUp(true); | setIsWarningPopUp(true); | ||||
setAttachment({}); | setAttachment({}); | ||||
@@ -116,135 +116,135 @@ const PublicNoticeApplyForm = ({loadedData, selections}) => { | |||||
return ( | 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> | <Typography variant="h5">申請公共啟事</Typography> | ||||
</Grid> */} | </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} | <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> | </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} | <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"> | <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> | </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> | </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> | </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_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 | //User Group | ||||
export const POST_AND_UPDATE_USER_GROUP = apiPath+'/group/save'; | 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: 3, label: 'C - High Court', title: 'High Court', type: 'C' }, | ||||
{ key: 4, label: 'D - Notices', title: 'Notices', type: 'D' }, | { key: 4, label: 'D - Notices', title: 'Notices', type: 'D' }, | ||||
{ key: 5, label: 'E - Miscellaneous (Companies)', title: 'Miscellaneous (Companies)', type: 'E' }, | { 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' }, | |||||
]; | ]; |