| @@ -53,11 +53,11 @@ const MainLayout = () => { | |||||
| <Box sx={{ display: 'flex', width: '100%', flexDirection: "column", paddingTop: { xs: "5px", sm: "43px" }}}> | <Box sx={{ display: 'flex', width: '100%', flexDirection: "column", paddingTop: { xs: "5px", sm: "43px" }}}> | ||||
| <Header/> | <Header/> | ||||
| {/* <Drawer open={open} handleDrawerToggle={handleDrawerToggle} /> */} | {/* <Drawer open={open} handleDrawerToggle={handleDrawerToggle} /> */} | ||||
| <Box component="main" sx={{ width: '100%', flexGrow: 1, p: { xs: 2, sm: 3 } }}> | |||||
| <div style={{ width: '100%', flexGrow: 1, p: { xs: 2, sm: 3 } }}> | |||||
| <Toolbar /> | <Toolbar /> | ||||
| {/* <Breadcrumbs navigation={navigation} title /> */} | {/* <Breadcrumbs navigation={navigation} title /> */} | ||||
| <Outlet /> | <Outlet /> | ||||
| </Box> | |||||
| </div> | |||||
| <Box sx={{borderTop: "3px solid #0C489E"}}> | <Box sx={{borderTop: "3px solid #0C489E"}}> | ||||
| <Footer/> | <Footer/> | ||||
| </Box> | </Box> | ||||
| @@ -25,7 +25,7 @@ const BackgroundHead = { | |||||
| // ==============================|| AUTHENTICATION - WRAPPER ||============================== // | // ==============================|| AUTHENTICATION - WRAPPER ||============================== // | ||||
| const AuthWrapper = ({ children }) => ( | const AuthWrapper = ({ children }) => ( | ||||
| <Box sx={{ minHeight: '100vh' }}> | |||||
| <Box sx={{ minHeight: '80vh' }}> | |||||
| {/* <AuthBackground /> */} | {/* <AuthBackground /> */} | ||||
| {/* <img src={banner} alt="banner" width="100%" /> */} | {/* <img src={banner} alt="banner" width="100%" /> */} | ||||
| <div style={BackgroundHead}> | <div style={BackgroundHead}> | ||||
| @@ -35,7 +35,7 @@ const AuthWrapper = ({ children }) => ( | |||||
| justifyContent="space-between" | justifyContent="space-between" | ||||
| alignItems="center" | alignItems="center" | ||||
| sx={{ | sx={{ | ||||
| minHeight: '100vh' | |||||
| minHeight: '80vh' | |||||
| }} | }} | ||||
| > | > | ||||
| <Grid item xs={12}> | <Grid item xs={12}> | ||||
| @@ -43,17 +43,18 @@ const AuthWrapper = ({ children }) => ( | |||||
| justifyContent="space-between" | justifyContent="space-between" | ||||
| alignItems="center" | alignItems="center" | ||||
| spacing={2}> | spacing={2}> | ||||
| <Grid item xs={12} sx={{ ml: 4, mt: 3 ,display: { xs: 'none', sm: 'block' }}}> | |||||
| <Grid item xs={12} md={8} sx={{ ml: 4, mt: 3 ,display: { xs: 'none', sm: 'block' }}}> | |||||
| <Typography style={{textAlign: "center",fontFamily: "微軟正黑體",fontSize: "1.6rem"}}>香港特別行政區政府</Typography> | <Typography style={{textAlign: "center",fontFamily: "微軟正黑體",fontSize: "1.6rem"}}>香港特別行政區政府</Typography> | ||||
| <Typography style={{textAlign: "center",fontFamily: "微軟正黑體",fontSize: "1.6rem",fontWeight:"bold"}}>憲報</Typography> | <Typography style={{textAlign: "center",fontFamily: "微軟正黑體",fontSize: "1.6rem",fontWeight:"bold"}}>憲報</Typography> | ||||
| </Grid> | </Grid> | ||||
| <Grid | <Grid | ||||
| item | item | ||||
| xs={12} | xs={12} | ||||
| md={3} | |||||
| container | container | ||||
| justifyContent="right" | justifyContent="right" | ||||
| alignItems="center" | alignItems="center" | ||||
| sx={{ minHeight: { xs: 'calc(100vh - 134px)', md: 'calc(100vh - 112px)' } }} | |||||
| sx={{ minHeight: { xs: 'calc(80vh - 134px)', md: 'calc(80vh - 112px)' } }} | |||||
| > | > | ||||
| <Grid item> | <Grid item> | ||||
| <AuthCard>{children}</AuthCard> | <AuthCard>{children}</AuthCard> | ||||
| @@ -98,6 +98,7 @@ const AuthLoginCustom = () => { | |||||
| }), | }), | ||||
| validationSchema:yup.object().shape({ | validationSchema:yup.object().shape({ | ||||
| // username: yup.string().min(6,'用戶名稱最少6位').required('請輸入用戶名稱'), | // username: yup.string().min(6,'用戶名稱最少6位').required('請輸入用戶名稱'), | ||||
| username: yup.string().required('請輸入用戶名稱'), | |||||
| password: yup.string().min(8,'請輸入最少8位密碼').required('請輸入密碼') | password: yup.string().min(8,'請輸入最少8位密碼').required('請輸入密碼') | ||||
| .matches(/^(?=.*[a-z])/, '請包括最少1個小寫字母') | .matches(/^(?=.*[a-z])/, '請包括最少1個小寫字母') | ||||
| .matches(/^(?=.*[A-Z])/, '請包括最少1個大寫字母') | .matches(/^(?=.*[A-Z])/, '請包括最少1個大寫字母') | ||||
| @@ -58,6 +58,7 @@ const CustomFormWizard = (props) => { | |||||
| const [fileList, setFileList] = useState([]); | const [fileList, setFileList] = useState([]); | ||||
| const [fileListData, setFileListData] = useState([]); | const [fileListData, setFileListData] = useState([]); | ||||
| const [checkUpload, setCheckUpload] = useState(false); | const [checkUpload, setCheckUpload] = useState(false); | ||||
| const [updateRows, setUpdateRows] = useState([]); | |||||
| const handleClickShowPassword = () => { | const handleClickShowPassword = () => { | ||||
| setShowPassword(!showPassword); | setShowPassword(!showPassword); | ||||
| @@ -141,6 +142,22 @@ const CustomFormWizard = (props) => { | |||||
| } | } | ||||
| }; | }; | ||||
| useEffect(() => { | |||||
| console.log(updateRows); | |||||
| let updateRowList = new DataTransfer(); | |||||
| var updateRowsIndex = updateRows.length; | |||||
| if (updateRowsIndex!=null){ | |||||
| for (let i = 0; i < updateRowsIndex; i++){ | |||||
| const file = updateRows[i] | |||||
| updateRowList.items.add(file); | |||||
| } | |||||
| let updatedFileList = updateRowList.files; | |||||
| setFileList(updatedFileList); | |||||
| } | |||||
| }, [updateRows]); | |||||
| const handleFileUpload = (event)=>{ | const handleFileUpload = (event)=>{ | ||||
| let updateList = new DataTransfer(); | let updateList = new DataTransfer(); | ||||
| let currentFileList = fileListData; | let currentFileList = fileListData; | ||||
| @@ -263,7 +280,7 @@ const CustomFormWizard = (props) => { | |||||
| { | { | ||||
| refType:"identification", | refType:"identification", | ||||
| refId: response.data.id, | refId: response.data.id, | ||||
| file: fileList[0], | |||||
| file: fileList, | |||||
| onSuccess: (response)=>{ | onSuccess: (response)=>{ | ||||
| console.log(response); | console.log(response); | ||||
| // setOpen(true); | // setOpen(true); | ||||
| @@ -1050,7 +1067,7 @@ const CustomFormWizard = (props) => { | |||||
| <Typography display="inline" variant="h6" sx={{ fontSize: 12, color: 'primary.primary'}}>如: 香港身份證; 護照; 中國內地身份證等</Typography> | <Typography display="inline" variant="h6" sx={{ fontSize: 12, color: 'primary.primary'}}>如: 香港身份證; 護照; 中國內地身份證等</Typography> | ||||
| </Stack> | </Stack> | ||||
| {fileList !=null? | {fileList !=null? | ||||
| <UploadFileTable recordList={fileListData} />:null} | |||||
| <UploadFileTable recordList={fileListData} setUpdateRows={setUpdateRows} />:null} | |||||
| {/* <Stack mt={1} direction="row" justifyContent="flex-start" alignItems="center" spacing={2}> | {/* <Stack mt={1} direction="row" justifyContent="flex-start" alignItems="center" spacing={2}> | ||||
| <Button variant="contained" type="submit" sx={{ fontSize: 12,height:'25px'}}>Submit</Button> | <Button variant="contained" type="submit" sx={{ fontSize: 12,height:'25px'}}>Submit</Button> | ||||
| <Button disabled={!formik.isValid} variant="contained" type="submit" sx={{ fontSize: 12,height:'25px'}}>Submit</Button> | <Button disabled={!formik.isValid} variant="contained" type="submit" sx={{ fontSize: 12,height:'25px'}}>Submit</Button> | ||||
| @@ -1271,7 +1288,7 @@ const CustomFormWizard = (props) => { | |||||
| <Stack spacing={1} direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}> | <Stack spacing={1} direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}> | ||||
| <Typography display="inline" variant="h4" sx={{ color: 'primary.primary'}}>身份證明文件</Typography> | <Typography display="inline" variant="h4" sx={{ color: 'primary.primary'}}>身份證明文件</Typography> | ||||
| {fileList !=null? | {fileList !=null? | ||||
| <UploadFileTable recordList={fileListData} />:null} | |||||
| <UploadFileTable recordList={fileListData} updateRows={updateRows} />:null} | |||||
| </Stack> | </Stack> | ||||
| </Grid> | </Grid> | ||||
| </Grid> | </Grid> | ||||
| @@ -3,20 +3,22 @@ import * as React from 'react'; | |||||
| import { | import { | ||||
| DataGrid, | DataGrid, | ||||
| GridActionsCellItem, | GridActionsCellItem, | ||||
| GridRowModes | |||||
| } from "@mui/x-data-grid"; | } from "@mui/x-data-grid"; | ||||
| import RemoveCircleOutlineIcon from '@mui/icons-material/RemoveCircleOutline'; | import RemoveCircleOutlineIcon from '@mui/icons-material/RemoveCircleOutline'; | ||||
| import {useEffect} from "react"; | import {useEffect} from "react"; | ||||
| // import {useNavigate} from "react-router-dom"; | // import {useNavigate} from "react-router-dom"; | ||||
| // import { useTheme } from '@mui/material/styles'; | // import { useTheme } from '@mui/material/styles'; | ||||
| import { | import { | ||||
| // Box, | |||||
| Box, | |||||
| Stack | Stack | ||||
| } from '@mui/material'; | } from '@mui/material'; | ||||
| // ==============================|| EVENT TABLE ||============================== // | // ==============================|| EVENT TABLE ||============================== // | ||||
| export default function UploadFileTable({recordList}) { | |||||
| export default function UploadFileTable({recordList, setUpdateRows}) { | |||||
| const [rows, setRows] = React.useState(recordList); | const [rows, setRows] = React.useState(recordList); | ||||
| const [rowModesModel] = React.useState({}); | |||||
| const [rowModesModel,setRowModesModel] = React.useState({}); | |||||
| // const theme = useTheme(); | // const theme = useTheme(); | ||||
| // const navigate = useNavigate() | // const navigate = useNavigate() | ||||
| @@ -25,6 +27,10 @@ export default function UploadFileTable({recordList}) { | |||||
| setRows(recordList); | setRows(recordList); | ||||
| }, [recordList]); | }, [recordList]); | ||||
| // useEffect(() => { | |||||
| // console.log(updateRows); | |||||
| // }, [updateRows]); | |||||
| function NoRowsOverlay() { | function NoRowsOverlay() { | ||||
| return ( | return ( | ||||
| <Stack height="100%" alignItems="center" justifyContent="center"> | <Stack height="100%" alignItems="center" justifyContent="center"> | ||||
| @@ -34,9 +40,18 @@ export default function UploadFileTable({recordList}) { | |||||
| ); | ); | ||||
| } | } | ||||
| const handleEditClick = () => () => { | |||||
| // navigate('/user/'+ id); | |||||
| }; | |||||
| const handleCancelClick = (id) => () => { | |||||
| setRowModesModel({ | |||||
| ...rowModesModel, | |||||
| [id]: { mode: GridRowModes.View, ignoreModifications: true }, | |||||
| }); | |||||
| console.log("test123") | |||||
| const editedRow = rows.find((row) => row.id === id); | |||||
| console.log(editedRow) | |||||
| console.log(editedRow.isNew) | |||||
| setUpdateRows(rows.filter((row) => row.id !== id)); | |||||
| setRows(rows.filter((row) => row.id !== id)); | |||||
| } | |||||
| const columns = [ | const columns = [ | ||||
| { | { | ||||
| @@ -52,7 +67,7 @@ export default function UploadFileTable({recordList}) { | |||||
| icon={<RemoveCircleOutlineIcon/>} | icon={<RemoveCircleOutlineIcon/>} | ||||
| label="delete" | label="delete" | ||||
| className="textPrimary" | className="textPrimary" | ||||
| onClick={handleEditClick(id)} | |||||
| onClick={handleCancelClick(id)} | |||||
| color="error" | color="error" | ||||
| />] | />] | ||||
| }, | }, | ||||
| @@ -76,7 +91,7 @@ export default function UploadFileTable({recordList}) { | |||||
| ]; | ]; | ||||
| return ( | return ( | ||||
| <div style={{ height: 200, width: '100%' }}> | |||||
| <Box style={{ height: '200px', width: '100%' }}> | |||||
| <DataGrid | <DataGrid | ||||
| rows={rows} | rows={rows} | ||||
| columns={columns} | columns={columns} | ||||
| @@ -85,18 +100,12 @@ export default function UploadFileTable({recordList}) { | |||||
| rowModesModel={rowModesModel} | rowModesModel={rowModesModel} | ||||
| disablePagination | disablePagination | ||||
| components={{ NoRowsOverlay, }} | components={{ NoRowsOverlay, }} | ||||
| initialState={{ | |||||
| pagination: { | |||||
| paginationModel: {}, | |||||
| }, | |||||
| }} | |||||
| // hideFooterPagination={true} | // hideFooterPagination={true} | ||||
| disableSelectionOnClick | disableSelectionOnClick | ||||
| disableColumnMenu | disableColumnMenu | ||||
| disableColumnSelector | disableColumnSelector | ||||
| hideFooter | hideFooter | ||||
| //autoHeight = {true} | |||||
| /> | /> | ||||
| </div> | |||||
| </Box> | |||||
| ); | ); | ||||
| } | } | ||||
| @@ -56,22 +56,26 @@ export const fileDownload = ({fileId, skey, filename, onError}) =>{ | |||||
| export const fileUpload = ({ refType, refId, file,refCode, onSuccess, onFail, onError}) =>{ | export const fileUpload = ({ refType, refId, file,refCode, onSuccess, onFail, onError}) =>{ | ||||
| var formData = new FormData(); | var formData = new FormData(); | ||||
| for (let i = 0; i < file.length; i++){ | |||||
| const file = file[i] | |||||
| formData.append("multipartFile", file); | formData.append("multipartFile", file); | ||||
| formData.append("refType", refType); | |||||
| formData.append("refId", refId); | |||||
| if(refCode){ | |||||
| formData.append("refCode", refCode); | |||||
| } | |||||
| // formData.append("multipartFile", file); | |||||
| formData.append("refType", refType); | |||||
| formData.append("refId", refId); | |||||
| if(refCode){ | |||||
| formData.append("refCode", refCode); | |||||
| } | |||||
| console.log(formData) | |||||
| axios.post(FILE_UP_POST,formData,{ | |||||
| headers: { | |||||
| "Content-Type":"multipart/form-data" | |||||
| } | } | ||||
| console.log(formData) | |||||
| axios.post(FILE_UP_POST,formData,{ | |||||
| headers: { | |||||
| "Content-Type":"multipart/form-data" | |||||
| } | |||||
| }).then( | |||||
| (response)=>{ | |||||
| onResponse(response,onSuccess,onFail); | |||||
| } | |||||
| ).catch(error => { return handleError(error, onError); }); | |||||
| }).then( | |||||
| (response)=>{ | |||||
| onResponse(response,onSuccess,onFail); | |||||
| } | |||||
| ).catch(error => { return handleError(error, onError); }); | |||||
| }; | }; | ||||