Wire up file upload form
This commit is contained in:
@@ -1,12 +1,29 @@
|
||||
import React from 'react';
|
||||
import { Button, Container, CssBaseline, Grid, Typography } from '@material-ui/core';
|
||||
import { DropzoneAreaBase } from 'material-ui-dropzone';
|
||||
import { useUserContext } from '../Contexts/UserContext';
|
||||
import useStyles from '../Styles';
|
||||
import React from "react";
|
||||
import { Button, Container, CssBaseline, Grid, Typography } from "@material-ui/core";
|
||||
import { DropzoneAreaBase } from "material-ui-dropzone";
|
||||
import { useUserContext } from "../Contexts/UserContext";
|
||||
import { useFileUploadContext, FileUploadProvider } from "../Contexts/FileUploadContext";
|
||||
import ModalProgressBar from "../ModalProgressBar";
|
||||
import useStyles from "../Styles";
|
||||
|
||||
const FileUploadZone = ({ classes }) => {
|
||||
const { uploading, progress, status, upload, cancel } = useFileUploadContext();
|
||||
|
||||
return (
|
||||
<form className={classes.form} noValidate>
|
||||
<DropzoneAreaBase
|
||||
maxFileSize={5e+7}
|
||||
showAlerts={false}
|
||||
onAdd={upload}
|
||||
/>
|
||||
<ModalProgressBar uploading={uploading} progress={progress} onCancel={cancel} status={status} />
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
||||
export default function FileUploadForm() {
|
||||
const classes = useStyles();
|
||||
const { signOut } = useUserContext();
|
||||
const classes = useStyles();
|
||||
|
||||
return (
|
||||
<Container component="main" maxWidth="xs">
|
||||
@@ -15,14 +32,14 @@ export default function FileUploadForm() {
|
||||
<Typography component="h1" variant="h5">
|
||||
Upload file
|
||||
</Typography>
|
||||
<form className={classes.form} noValidate>
|
||||
<DropzoneAreaBase />
|
||||
<Grid container>
|
||||
<Grid item >
|
||||
<Button onClick={signOut}>Sign Out</Button>
|
||||
</Grid>
|
||||
<FileUploadProvider>
|
||||
<FileUploadZone classes={classes} />
|
||||
</FileUploadProvider>
|
||||
<Grid container>
|
||||
<Grid item >
|
||||
<Button onClick={signOut}>Sign Out</Button>
|
||||
</Grid>
|
||||
</form>
|
||||
</Grid>
|
||||
</div>
|
||||
</Container>
|
||||
);
|
||||
|
||||
44
src/components/ModalProgressBar/index.jsx
Normal file
44
src/components/ModalProgressBar/index.jsx
Normal file
@@ -0,0 +1,44 @@
|
||||
import React from "react";
|
||||
import Modal from '@material-ui/core/Modal';
|
||||
|
||||
import { Button, LinearProgress } from "@material-ui/core";
|
||||
|
||||
const getModalStyle = () => {
|
||||
const top = 30;
|
||||
const left = 50;
|
||||
|
||||
return {
|
||||
width: `350px`,
|
||||
top: `${top}%`,
|
||||
left: `${left}%`,
|
||||
transform: `translate(-${left}%, -${top}%)`,
|
||||
backgroundColor: `white`,
|
||||
border: `none`,
|
||||
position: `absolute`,
|
||||
margin: `1em`,
|
||||
padding: `1em`,
|
||||
textAlign: `center`,
|
||||
};
|
||||
};
|
||||
|
||||
const ModalProgressBar = ({ onCancel, uploading, progress, status }) => {
|
||||
const modalStyle = getModalStyle();
|
||||
const onClickCancel = () => {
|
||||
if (onCancel) onCancel();
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal open={uploading}>
|
||||
<div style={modalStyle}>
|
||||
{status && <p>{status}</p>}
|
||||
<LinearProgress variant="determinate" value={progress} />
|
||||
<Button onClick={onClickCancel}>
|
||||
{ progress < 101 ? "Cancel" : "Done" }
|
||||
</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
export default ModalProgressBar;
|
||||
@@ -21,7 +21,7 @@ const SiteRoutes = () => {
|
||||
<Switch>
|
||||
<AuthRoute path="/" exact render={() => <SignInForm />} type={TYPES.GUEST} token={token} />
|
||||
<AuthRoute path="/signup" exact render={() => <SignUpForm />} type={TYPES.GUEST} token={token} />
|
||||
<AuthRoute path="/home" render={() => <FileUploadForm />} type={TYPES.PROTECTED} token={token} />
|
||||
<AuthRoute path="/home" render={() => <FileUploadForm />} type={TYPES.PUBLIC} token={token} />
|
||||
</Switch>
|
||||
</BrowserRouter>
|
||||
</Suspense>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import React, { useContext, useEffect, useState } from 'react';
|
||||
import React, { useContext, useEffect, useState } from "react";
|
||||
import { uploadFile, getCancelToken } from "../../services/uploadFile";
|
||||
|
||||
const FileUploadContext = React.createContext();
|
||||
|
||||
@@ -6,16 +7,45 @@ export const FileUploadProvider = ({ children }) => {
|
||||
const [file, setFile] = useState(null);
|
||||
const [uploading, setUploading] = useState(false);
|
||||
const [progress, setProgress] = useState(0);
|
||||
const [status, setStatus] = useState(null);
|
||||
const [cancelUpload, setCancelUpload] = useState(null);
|
||||
|
||||
const upload = (file) => {
|
||||
const cancel = async () => {
|
||||
console.log(`cancel`);
|
||||
if (cancelUpload) cancelUpload.cancel();
|
||||
setCancelUpload(null);
|
||||
setUploading(false);
|
||||
};
|
||||
|
||||
const upload = async (files) => {
|
||||
if (files.length === 0) return;
|
||||
|
||||
const file = files[0].file;
|
||||
const filename = file.name;
|
||||
|
||||
setUploading(true);
|
||||
setProgress(0);
|
||||
setStatus(`Uploading ${filename}`);
|
||||
setCancelUpload(getCancelToken());
|
||||
try {
|
||||
const result = await uploadFile(file, setProgress, cancelUpload);
|
||||
console.log(result);
|
||||
setStatus(`Uploaded ${filename}`);
|
||||
setCancelUpload(null);
|
||||
setProgress(101);
|
||||
}
|
||||
catch (e) {
|
||||
setStatus(`Error occured ${e.message}`);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<FileUploadContext.Provider value={{
|
||||
uploading,
|
||||
progress,
|
||||
status,
|
||||
upload,
|
||||
cancel,
|
||||
}}>
|
||||
{children}
|
||||
</FileUploadContext.Provider>
|
||||
|
||||
29
src/services/uploadFile.js
Normal file
29
src/services/uploadFile.js
Normal file
@@ -0,0 +1,29 @@
|
||||
import axios from 'axios';
|
||||
|
||||
const UPLOAD_ENDPOINT = 'http://localhost:8080/api/upload';
|
||||
|
||||
export const getCancelToken = () => {
|
||||
const token = axios.CancelToken;
|
||||
return token.source();
|
||||
}
|
||||
|
||||
export const uploadFile = (file, onProgress, cancelToken) => {
|
||||
const form = new FormData();
|
||||
let options = {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
cancelToken,
|
||||
};
|
||||
if (onProgress) {
|
||||
options = {
|
||||
...options,
|
||||
onUploadProgress: (event) => {
|
||||
onProgress(Math.floor((event.loaded / event.total) * 100));
|
||||
}
|
||||
}
|
||||
}
|
||||
form.append('file', file);
|
||||
return axios.post(UPLOAD_ENDPOINT, form, options);
|
||||
};
|
||||
Reference in New Issue
Block a user