Skip to content

Commit 374078f

Browse files
author
Jovert Lota Palonpon
committed
wip - Dropzone Component #23
1 parent 4c853db commit 374078f

File tree

6 files changed

+209
-2
lines changed

6 files changed

+209
-2
lines changed

package-lock.json

Lines changed: 50 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"prop-types": "^15.6.2",
2727
"react": "^16.8.1",
2828
"react-dom": "^16.8.1",
29+
"react-dropzone": "^10.1.0",
2930
"react-loading-skeleton": "^1.1.1",
3031
"react-router-dom": "^4.3.1",
3132
"yup": "^0.26.10"

resources/js/ui/Dropzone.js

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
import React, { useState, useEffect } from 'react';
2+
import PropTypes from 'prop-types';
3+
import { useDropzone } from 'react-dropzone';
4+
5+
import { Grid, RootRef, Typography, withStyles } from '@material-ui/core';
6+
import classNames from 'classnames';
7+
8+
function Dropzone(props) {
9+
const { classes } = props;
10+
11+
const [files, setFiles] = useState([]);
12+
const { getRootProps, getInputProps, isDragActive } = useDropzone({
13+
accept: 'image/*',
14+
maxSize: 1 * 1000 * 1000,
15+
onDrop: acceptedFiles => {
16+
setFiles(
17+
files.concat(
18+
acceptedFiles.map(file =>
19+
Object.assign(file, {
20+
url: URL.createObjectURL(file),
21+
}),
22+
),
23+
),
24+
);
25+
},
26+
});
27+
28+
const { ref, ...rootProps } = getRootProps();
29+
30+
useEffect(
31+
() => () => {
32+
// Make sure to revoke the data uris to avoid memory leaks.
33+
files.forEach(file => URL.revokeObjectURL(file.preview));
34+
},
35+
[files],
36+
);
37+
38+
return (
39+
<RootRef rootRef={ref}>
40+
<Grid
41+
{...rootProps}
42+
container
43+
spacing={8}
44+
justify="center"
45+
alignItems="center"
46+
className={classes.root}
47+
>
48+
<input {...getInputProps()} />
49+
50+
{files.length > 0 ? (
51+
files
52+
.map((file, key) => (
53+
<Grid item key={key}>
54+
<img
55+
src={file.url}
56+
className={classNames(
57+
classes.file,
58+
classes.image,
59+
)}
60+
/>
61+
62+
<Typography
63+
color="primary"
64+
className={classes.removeLink}
65+
>
66+
Remove File
67+
</Typography>
68+
</Grid>
69+
))
70+
.concat([
71+
<Grid item key="addFile">
72+
<div
73+
className={classNames(
74+
classes.file,
75+
classes.addFile,
76+
)}
77+
>
78+
<Typography
79+
className={classNames(
80+
classes.text,
81+
classes.textIcon,
82+
)}
83+
>
84+
+
85+
</Typography>
86+
</div>
87+
88+
<Typography>&nbsp;</Typography>
89+
</Grid>,
90+
])
91+
) : (
92+
<Grid item>
93+
<Typography className={classes.text}>
94+
{isDragActive
95+
? `Drag files here`
96+
: `Drag 'n' drop some files here, or click to select files`}
97+
</Typography>
98+
</Grid>
99+
)}
100+
</Grid>
101+
</RootRef>
102+
);
103+
}
104+
105+
Dropzone.propTypes = {
106+
onDrop: PropTypes.func,
107+
};
108+
109+
const styles = theme => ({
110+
root: {
111+
border: `2px dashed ${theme.palette.grey[500]}`,
112+
backgroundColor: theme.palette.grey[200],
113+
minHeight: 250,
114+
},
115+
116+
text: {
117+
color: theme.palette.grey[500],
118+
},
119+
120+
textIcon: {
121+
fontSize: 75,
122+
fontWeight: 'bold',
123+
textAlign: 'center',
124+
},
125+
126+
removeLink: {
127+
textAlign: 'center',
128+
'&:hover': {
129+
cursor: 'pointer',
130+
},
131+
},
132+
133+
file: {
134+
border: `3px solid ${theme.palette.grey[500]}`,
135+
borderRadius: '5%',
136+
width: 120,
137+
height: 120,
138+
},
139+
140+
image: {
141+
'&:hover': {
142+
filter: 'blur(4px)',
143+
},
144+
},
145+
146+
addFile: {
147+
'&:hover': {
148+
cursor: 'pointer',
149+
},
150+
},
151+
});
152+
153+
export default withStyles(styles)(Dropzone);

resources/js/ui/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import loadable from '@loadable/component';
22

3+
export const Dropzone = loadable(() => import('./Dropzone'));
34
export const Modal = loadable(() => import('./Modal'));
45
export const Skeleton = loadable(() => import('./Skeleton'));
56
export const Snackbar = loadable(() => import('./Snackbar'));

resources/js/views/__backoffice/users/Create.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { Profile, Account, Avatar } from './Forms';
1919
class Create extends Component {
2020
state = {
2121
loading: false,
22-
activeStep: 0,
22+
activeStep: 2,
2323
formValues: [],
2424
errors: {},
2525
message: {},

resources/js/views/__backoffice/users/Forms/Avatar.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import PropTypes from 'prop-types';
33

44
import { Button, Grid, Typography, withStyles } from '@material-ui/core';
55

6+
import { Dropzone } from '../../../../ui';
7+
68
const Avatar = props => {
79
const { classes, values, errors, handleSubmit, handleSkip } = props;
810

@@ -12,7 +14,7 @@ const Avatar = props => {
1214
Avatar Upload
1315
</Typography>
1416

15-
<div className={classes.root} />
17+
<Dropzone />
1618

1719
<div className={classes.sectionSpacer} />
1820

0 commit comments

Comments
 (0)