react-dropzone#useDropzone JavaScript Examples
The following examples show how to use
react-dropzone#useDropzone.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: DragNDrop.jsx From ResoBin with MIT License | 6 votes |
DragNDrop = ({ onDrop, children }) => {
const { getRootProps, getInputProps, isDragActive, isDragReject } =
useDropzone({ onDrop, ...dropzoneProps })
let message = null
if (!isDragActive)
message = (
<h2>
Drag & drop to upload
<br />
or click to browse files
</h2>
)
else if (isDragReject) message = <h2>Invalid upload format</h2>
else message = <h2>Drop files here</h2>
return (
<UploadBox {...getRootProps()} error={isDragReject}>
<input {...getInputProps()} />
<CloudUpload size="60" />
{message}
<span>
Accepted formats: .pdf, .doc, .ppt
<br />
Maximum upload file size: 30MB
</span>
</UploadBox>
)
}
Example #2
Source File: index.js From NFT-Marketplace with MIT License | 6 votes |
DropZone = ({ onFileUploaded }) => {
const classes = useStyles();
const [selectedFileUrl, setSelectedFileUrl] = useState('');
const onDrop = useCallback(acceptedFiles => {
const file = acceptedFiles[0];
const fileUrl = URL.createObjectURL(file);
setSelectedFileUrl(fileUrl);
onFileUploaded(file);
}, [onFileUploaded]);
const { getRootProps, getInputProps } = useDropzone({
onDrop,
accept: 'image/*'
});
return (
<div className={classes.dropzone} {...getRootProps()}>
<input {...getInputProps()} accept='image/*' />
{ selectedFileUrl
? <img src={selectedFileUrl} alt="Point thumbnail"/>
: (
<p>
<CloudUploadIcon />
NFT image
</p>
)
}
</div>
);
}
Example #3
Source File: image-upload-previewContainer.js From horondi_admin with MIT License | 6 votes |
ImageUploadPreviewContainer = ({ handler, src, id }) => {
const style = useStyles();
const { getRootProps, getInputProps } = useDropzone({
accept: 'image/*',
onDrop: (acceptedFiles) => {
handler(
acceptedFiles.map((file) =>
Object.assign(file, {
preview: URL.createObjectURL(file)
})
)
);
}
});
return (
<section className='container'>
<div {...getRootProps({ className: 'dropzone' })}>
<input
style={{ height: '300px', width: '200px' }}
{...getInputProps()}
/>
<label
className={src ? style.labelWithoutBack : style.labelWithBack}
htmlFor={id}
data-cy={utils.dataCy.preview}
>
{src && (
<img className={style.image} src={src} alt={utils.alt.preview} />
)}
</label>
</div>
</section>
);
}
Example #4
Source File: image-upload-container.js From horondi_admin with MIT License | 6 votes |
ImageUploadContainer = ({ handler, src, id }) => {
const style = useStyles();
const { getRootProps, getInputProps } = useDropzone({
accept: 'image/*',
onDrop: (acceptedFiles) => {
handler(
acceptedFiles.map((file) =>
Object.assign(file, {
preview: URL.createObjectURL(file)
})
)
);
}
});
return (
<section className='container'>
<div {...getRootProps({ className: 'dropzone' })}>
<input
style={{ height: '300px', width: '200px' }}
{...getInputProps()}
/>
<label
className={src ? style.labelWithoutBack : style.labelWithBack}
htmlFor={id}
data-cy={utils.dataCy.preview}
>
{src && (
<img className={style.image} src={src} alt={utils.alt.preview} />
)}
</label>
</div>
</section>
);
}
Example #5
Source File: BoxDropzone.js From eosio-components with MIT License | 6 votes |
Dropzone = ({ onSubmit }) => {
const classes = useStyles()
const { acceptedFiles, getRootProps, getInputProps } = useDropzone({
maxFiles: 1,
accept: 'application/json'
})
useEffect(() => {
if (!!!acceptedFiles.length) return
const reader = new FileReader()
reader.onload = (e) => {
onSubmit(JSON.parse(e.target.result))
}
reader.readAsText(acceptedFiles[0])
}, [acceptedFiles, onSubmit])
return (
<section>
<div {...getRootProps({ className: classes.dropzoneArea })}>
<input {...getInputProps()} />
<p>Drop your BP json file here</p>
</div>
</section>
)
}
Example #6
Source File: Dropzone.js From react-saas-template with MIT License | 6 votes |
function Dropzone(props) {
const { onDrop, accept, fullHeight, children, classes, style, theme } = props;
const {
getRootProps,
getInputProps,
isDragAccept,
isDragReject
} = useDropzone({
accept: accept,
onDrop: onDrop
});
return (
<Box {...getRootProps()} height="100%">
<input {...getInputProps()} />
<ColoredButton
fullWidth
className={classNames(
fullHeight ? classes.fullHeight : null,
classes.button
)}
variant="outlined"
color={getColor(isDragAccept, isDragReject, theme)}
style={style}
>
{children}
</ColoredButton>
</Box>
);
}
Example #7
Source File: UploadDragAndDrop.js From EDAViewer with MIT License | 6 votes |
export default function UploadDragAndDrop(props) {
const classes = useStyles();
const { onFilesAdded } = props;
const onDrop = React.useCallback(onFilesAdded, []);
const { getRootProps, getInputProps } = useDropzone({
onDrop,
maxSize: 100 * 1024 * 1024, //100MBs
});
return (
<div className={classes.dropzone} {...getRootProps()} style={{}}>
<input {...getInputProps()} />
<CloudUpload
className={classes.dropzoneIcon}
style={{
fontSize: "8rem",
}}
/>
<div className={classes.dropzoneText}>
Drag and drop design LEF/DEF files or <br />{" "}
<b>click to choose from your computer</b>
</div>
</div>
);
}
Example #8
Source File: Dropzone.js From verapdf-webapp-gui with GNU General Public License v3.0 | 6 votes |
function Dropzone(props) {
const { files, onFileDrop } = props;
// NOTE: will be adjusted with multiple files in future
const onDrop = useCallback(
acceptedFiles => {
if (!acceptedFiles.length) return;
onFileDrop(acceptedFiles[0]);
},
[onFileDrop]
);
const { getRootProps, getInputProps, isDragActive } = useDropzone({
onDrop,
...DROPZONE_OPTIONS,
});
return (
<section className="dropzone">
<div
{...getRootProps({
className: classNames('dropzone__container', {
_focused: isDragActive,
_filled: files.length,
}),
})}
>
<input {...getInputProps()} />
<DropzoneText files={files} />
</div>
</section>
);
}
Example #9
Source File: DropzoneWrapper.js From verapdf-webapp-gui with GNU General Public License v3.0 | 6 votes |
function DropzoneWrapper(props) {
const { onFileDrop, children } = props;
// NOTE: will be adjusted with multiple files in future
const onDrop = useCallback(
acceptedFiles => {
if (!acceptedFiles.length) return;
onFileDrop(acceptedFiles);
},
[onFileDrop]
);
const { getRootProps, getInputProps, isDragActive } = useDropzone({
onDrop,
...DROPZONE_OPTIONS,
noClick: true,
});
return (
<section
{...getRootProps({
className: 'dropzone-wrapper',
})}
>
{children}
<input {...getInputProps()} />
<div
className={classNames('dropzone-wrapper__fade', {
_visible: isDragActive,
})}
>
{DROPZONE_TEXT}
</div>
</section>
);
}
Example #10
Source File: DragNDrop.jsx From ResoBin with MIT License | 6 votes |
DragNDropSub = ({ onDrop, children }) => {
const { getRootProps, getInputProps, isDragActive, isDragReject } =
useDropzone({ maxFiles: 1, onDrop, ...dropzoneProps })
let message = children
if (isDragActive) {
if (isDragReject) message = <h2>File too large or invalid upload format</h2>
else message = <h2>Drop files here</h2>
}
return (
<UploadBoxSub {...getRootProps()} error={isDragReject}>
<input {...getInputProps()} />
{message}
</UploadBoxSub>
)
}
Example #11
Source File: GraphImporter.js From aws-perspective with Apache License 2.0 | 5 votes |
export function GraphImporter({setImportedGraph}) {
const onDrop = useCallback(acceptedFiles => {
acceptedFiles.forEach(file => {
const reader = new FileReader();
reader.onabort = () => console.error('file reading was aborted');
reader.onerror = () => console.error('file reading has failed');
reader.onload = () => {
const binaryStr = reader.result;
setImportedGraph({name: file.name, graph: JSON.parse(binaryStr)})
};
reader.readAsText(file);
});
}, [setImportedGraph]);
const { getRootProps, getInputProps } = useDropzone({ onDrop });
const { ref, ...rootProps } = getRootProps();
const useStyles = makeStyles(theme => ({
root: {
width: '100%',
textAlign: 'center',
border: '2px dashed #fafafa',
marginBottom: '2%',
'&:focus': {
outline: 'none'
},
},
text: {
fontFamily: 'Amazon Ember, Helvetica, Arial, sans-serif',
fontSize: '1rem',
padding: '5%',
color: '#AAB7B8'
}
}));
const classes = useStyles();
return (
<div>
<RootRef rootRef={ref}>
<Paper className={classes.root} {...rootProps}>
<input {...getInputProps()} />
<Typography className={classes.text}>
Drop JSON graph files here, or click to select files
</Typography>
</Paper>
</RootRef>
</div>
);
}
Example #12
Source File: Dropzone.js From web-client with Apache License 2.0 | 5 votes |
AttachmentsDropzone = ({ parentType, parentId, onUploadFinished = null, attachmentId = null }) => {
const onFileDrop = (newFiles) => {
setAcceptedFiles(newFiles);
};
const {
getRootProps, getInputProps,
isDragActive, isDragAccept, isDragReject
} = useDropzone({ onDrop: onFileDrop });
const [acceptedFiles, setAcceptedFiles] = useState([]);
const onUploadButtonClick = ev => {
const formData = new FormData();
formData.append('parentType', parentType);
formData.append('parentId', parentId);
acceptedFiles.forEach(file => {
formData.append('attachment[]', file);
})
let uri = '/attachments';
if (attachmentId) {
formData.append('attachmentId', attachmentId);
uri = `/attachments/${attachmentId}`;
}
secureApiFetch(uri, {
method: 'POST',
body: formData
})
.then(() => {
setAcceptedFiles([]);
if (onUploadFinished) onUploadFinished();
})
.catch(err => console.error(err));
}
const style = useMemo(() => ({
...baseStyle,
...(isDragActive ? activeStyle : {}),
...(isDragAccept ? acceptStyle : {}),
...(isDragReject ? rejectStyle : {})
}), [
isDragActive,
isDragAccept,
isDragReject
]);
return (
<div className="container">
<div {...getRootProps({ style })}>
<input {...getInputProps()} />
<p>Drag and drop some files here, or click to select files</p>
</div>
<aside>
{acceptedFiles.length === 0 && <div>(upload list empty)</div>}
{acceptedFiles.length > 0 && <List spacing={3}>{acceptedFiles.map(file => (
<ListItem key={file.path}>
<FontAwesomeIcon color='var(--primary-color)' icon={faUpload} /> {file.path} - {file.size} bytes
</ListItem>
))}</List>}
</aside>
<hr />
<PrimaryButton onClick={onUploadButtonClick} disabled={acceptedFiles.length === 0}>Upload file(s)</PrimaryButton>
</div>
);
}
Example #13
Source File: LibraryBlockAssets.jsx From frontend-app-library-authoring with GNU Affero General Public License v3.0 | 5 votes |
LibraryBlockAssets = (props) => {
const onDrop = useCallback(props.onDropFiles, []);
const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop });
if (props.assets.value === null) {
return <LoadingPage loadingMessage="Loading..." />;
}
const assets = props.assets.value || [];
return (
<>
<h1 className="float-right"><span className="sr-only">Static Assets</span></h1>
<p>There are {assets.length} static asset files for this XBlock:</p>
<ul>
{
assets.map(assetFile => (
<li key={assetFile.path}>
<a href={assetFile.url}>/static/{assetFile.path}</a> {' '}
({Math.round(assetFile.size / 1024.0)} KB)
(<Button variant="link" onClick={() => props.onDeleteFile(assetFile.path)} className="p-0" title="Delete this file">x</Button>)
</li>
))
}
</ul>
<div
{...getRootProps()}
style={{
lineHeight: '150px',
border: '3px solid #ddd',
textAlign: 'center',
backgroundColor: isDragActive ? '#90ee90' : '#fbfbfb',
marginBottom: '1em',
}}
>
<input {...getInputProps()} />
{
isDragActive
? <span> Drop the files here ...</span>
: <span> Drag and drop some files here to upload them, or click here to select files.</span>
}
</div>
<p>Tip: set the filenames carefully <em>before</em> uploading, as there is no rename tool.</p>
<p>
Within OLX or when using the "Edit" tab, always reference assets using /static/filename, e.g.
<code><img src="/static/jamie.jpg" alt="Picture of Jamie"/></code>
</p>
</>
);
}
Example #14
Source File: index.js From dashboard-reactjs with MIT License | 5 votes |
Dropzone = ({file, onFileUploaded }) => {
const [selectedFiles, setSelectedFiles] = useState('');
const onDrop = useCallback(acceptedFiles => {
const file = acceptedFiles[0];
const fileUrl = URL.createObjectURL(file);
setSelectedFiles(fileUrl);
onFileUploaded(file);
}, [onFileUploaded])
const {getRootProps, getInputProps, isDragActive} = useDropzone({
onDrop,
accept: 'image/*'
})
return (
<DropBackground {...getRootProps()}>
<input {...getInputProps()} accept="image/*" />
{/* {
isDragActive ?
<p>Drop the files here ...</p> :
<p>Drag 'n' drop some files here, or click to select files</p>
} */}
{ selectedFiles || file
?
<div className="image">
<img src={!selectedFiles ? `${process.env.REACT_APP_API_URL}/uploads/business/${file}` : selectedFiles
} alt="Point File" />
<span><FontAwesomeIcon icon={faPencilAlt} /> Alterar</span>
</div>
:
<div className="image-default">
<img src={Profile} alt="Point File" />
<span><FontAwesomeIcon icon={faUpload} /> Carregar</span>
</div>
}
</DropBackground>
)
}
Example #15
Source File: index.js From conectadev with MIT License | 5 votes |
function PostEditor() {
const classes = useStyles();
const ctx = usePost();
const { image, setImage, tags, setTags, markdownText, setMarkdownText } = ctx;
const onDrop = useCallback(
(acceptedFiles) => {
const file = acceptedFiles[0];
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onloadend = () => {
const base64data = reader.result;
setImage(base64data);
};
},
[setImage],
);
const { getRootProps, getInputProps } = useDropzone({
onDrop,
multiple: false,
accept: 'image/*',
});
return (
<>
<Box {...getRootProps()} mb={1}>
<input {...getInputProps()} />
<Button>Carregar imagem</Button>
</Box>
{image && (
<Box mb={2}>
<img className={classes.image} src={image} alt="background" />
</Box>
)}
<Box mb={2}>
<Title />
</Box>
<Box mb={2}>
<Autocomplete
multiple
id="tags-standard"
options={arrayTags}
getOptionLabel={(option) => option.title}
value={tags}
onChange={setTags}
renderInput={(params) => (
<TextField {...params} variant="standard" placeholder="tags" />
)}
/>
</Box>
<textarea
onChange={setMarkdownText}
value={markdownText}
className={classes.textArea}
>
editor markdown
</textarea>
</>
);
}
Example #16
Source File: VidDropzone.js From youtube-clone with MIT License | 5 votes |
function StyledDropzone() {
const dispatch = useDispatch();
const classes = useStyles();
const onDrop = ([videoFile]) => {
if (videoFile) {
dispatch(uploadVideo(videoFile));
}
};
const {
getRootProps,
getInputProps,
open,
isDragAccept,
isDragReject,
} = useDropzone({
noClick: true,
noKeyboard: true,
accept: "video/mp4",
maxSize: 25 * 1024 * 1024,
onDrop,
});
return (
<div className={classes.root}>
<div
{...getRootProps({
className: clsx(classes.content, {
[classes.acceptStyle]: isDragAccept,
[classes.rejectStyle]: isDragReject,
}),
})}
>
<input {...getInputProps()} />
<Fab className={clsx(classes.button, classes.uploadBtn)} onClick={open}>
<PublishIcon className={classes.uploadIcon} />
</Fab>
<Typography variant="body1">
Drag and drop a <strong>.mp4 </strong> file to upload
</Typography>
<Typography variant="body2" gutterBottom>
Your videos will be private until you publish them.
</Typography>
<Typography variant="caption" gutterBottom>
* Video Uploads are limited to 25 MB.
</Typography>
<Button
className={classes.button}
variant="contained"
color="primary"
onClick={open}
>
Select File
</Button>
</div>
</div>
);
}
Example #17
Source File: LoadData.jsx From airboardgame with MIT License | 5 votes |
LoadGame = ({ onLoad = () => {} }) => {
const { t } = useTranslation();
const onDrop = React.useCallback(
(acceptedFiles) => {
acceptedFiles.forEach((file) => {
const reader = new FileReader();
reader.onabort = () => console.log("file reading was aborted");
reader.onerror = () => console.log("file reading has failed");
reader.onload = () => {
try {
const result = JSON.parse(reader.result);
onLoad(result);
} catch (e) {
console.log("File parsing failed", e);
}
};
reader.readAsText(file);
});
},
[onLoad]
);
const { getRootProps, getInputProps } = useDropzone({ onDrop });
return (
<div
{...getRootProps()}
style={{
border: "1px dashed white",
padding: "0.5em",
cursor: "pointer",
fontSize: "1.5em",
}}
>
<input {...getInputProps()} />
<p style={{ textAlign: "center", margin: "1em" }}>
{t("Dragn drop file here")}
</p>
</div>
);
}
Example #18
Source File: ImageDropNPaste.jsx From airboardgame with MIT License | 5 votes |
ImageDropNPaste = ({ children }) => {
const { t } = useTranslation();
const [uploading, setUploading] = React.useState(false);
const { pushItem } = useItemActions();
const { addMedia, libraries } = useMediaLibrary();
const addImageItem = React.useCallback(
async (media) => {
pushItem({
type: "image",
id: uid(),
content: media,
});
},
[pushItem]
);
const onDrop = React.useCallback(
async (acceptedFiles) => {
setUploading(true);
await Promise.all(
acceptedFiles.map(async (file) => {
const media = await addMedia(libraries[0], file);
await addImageItem(media);
})
);
setUploading(false);
},
[addImageItem, addMedia, libraries]
);
const { getRootProps } = useDropzone({ onDrop });
const onPaste = React.useCallback(
async (e) => {
const { items } = e.clipboardData;
setUploading(true);
// eslint-disable-next-line no-plusplus
for (let i = 0; i < items.length; i++) {
const item = items[i];
if (item.type.indexOf("image") !== -1) {
const file = item.getAsFile();
// eslint-disable-next-line no-await-in-loop
const location = await addMedia(libraries[0], file);
// eslint-disable-next-line no-await-in-loop
await addImageItem(location);
}
}
setUploading(false);
},
[addImageItem, addMedia, libraries]
);
React.useEffect(() => {
window.addEventListener("paste", onPaste, false);
return () => {
window.removeEventListener("paste", onPaste);
};
}, [onPaste]);
return (
<div {...getRootProps()}>
{children}
{uploading && <Waiter message={t("Uploading image(s)...")} />}
</div>
);
}
Example #19
Source File: index.js From website with MIT License | 5 votes |
ChatImageUpload = ({ postType, postId, setAlertMessage, onCloseAlert }) => {
const router = useRouter();
const { state, dispatch } = useContext(ChatContext);
const isNewChat = getIsNewChat(state);
const selectedChatId = getSelectedChatId(state);
const sendFirstImageMessages = async (images) => {
const method = postType === donations ? 'sendInitialImageMessagesForDonation' : 'sendInitialImageMessagesForWish';
const [rawChat, rawFirstMessage] = await api.chats[method](postId, images);
const chatId = rawChat.data().chatId;
dispatch(setIsNewChat(false));
dispatch(setSelectedChatId(chatId));
router.push(`/chat`, `/chat?chatId=${chatId}`, { shallow: true });
};
const handleImageUploadError = (err) => {
if (err instanceof ChatError) {
setAlertMessage(err.message);
setTimeout(() => {
onCloseAlert(); // hide alert message after 5 seconds
}, 5000);
}
};
const handleImageExceedSizeLimitError = (message) => {
setAlertMessage(message);
setTimeout(() => {
onCloseAlert(); // hide alert message after 5 seconds
}, 5000);
};
const onUpload = useCallback((uploadedFiles, isNewChat, selectedChatId) => {
// check if file is more than 25 mb
if (uploadedFiles.some((file) => file.size > MAXIMUM_FILE_SIZE_LIMIT)) {
handleImageExceedSizeLimitError('Unable to upload files that are more than 25mb');
uploadedFiles = uploadedFiles.filter((file) => file.size <= MAXIMUM_FILE_SIZE_LIMIT);
}
if (uploadedFiles.length === 0) {
return;
}
if (isNewChat) {
sendFirstImageMessages(uploadedFiles)
.then(() => {
uploadedFiles = [];
})
.catch((err) => handleImageUploadError(err));
} else {
api.chats.sendImageMessages(selectedChatId, uploadedFiles).catch((err) => handleImageUploadError(err));
}
}, []);
const { getRootProps, getInputProps } = useDropzone({
onDrop: (files) => onUpload(files, isNewChat, selectedChatId),
accept: '.jpeg, .png, .jpg',
});
return (
<div {...getRootProps()}>
<input {...getInputProps()} />
<Gallery size="normal" />
</div>
);
}
Example #20
Source File: ImageSection.js From nextjs-ic-starter with MIT License | 5 votes |
ImageSection = () => {
const [imageId, setImageId] = useState(null)
const [loading, setLoading] = useState("")
const [file, setFile] = useState(null)
const imgSrc = useImageObject(imageId)
const { getRootProps, getInputProps } = useDropzone({
maxFiles: 1,
accept: "image/*",
onDrop: async acceptedFiles => {
if (acceptedFiles.length > 0) {
try {
const firstFile = acceptedFiles[0]
const newFile = await resizeImage(firstFile, ImageMaxWidth)
setFile(newFile)
} catch (error) {
console.error(error)
}
}
}
})
async function submitImage() {
if (file == null) {
return
}
setLoading("Submitting...")
setImageId(null)
const fileArray = await fileToCanisterBinaryStoreFormat(file)
const imageActor = makeImageActor()
const newImageId = await imageActor.create(fileArray)
setImageId(newImageId)
setLoading("")
}
return (
<div>
<section>
<h2>Image</h2>
<label htmlFor="name">Upload Image: </label>
<button {...getRootProps({ className: "dropzone" })}>
Pick a Image
<input {...getInputProps()} />
</button>
<button onClick={submitImage}>Submit</button>
</section>
<section>
<div>{loading}</div>
<label>Image loaded from canister: </label>
{imgSrc && <img src={imgSrc} alt="canister-image" />}
</section>
</div>
)
}
Example #21
Source File: DropZone.js From sailplane-web with GNU General Public License v3.0 | 5 votes |
export function DropZone({children, sharedFs, currentDirectory}, ref) {
const styles = {
container: {
cursor: 'pointer',
textAlign: 'center',
color: primary5,
fontSize: 16,
fontWeight: 200,
fontFamily: 'Open Sans',
outline: 0,
userSelect: 'none',
height: '100%',
},
};
const dispatch = useDispatch();
const onDrop = useCallback(
async (acceptedFiles) => {
dispatch(setStatus({message: 'Uploading'}));
const listSource = fileListSource(acceptedFiles, {preserveMtime: true});
const totalSize = acceptedFiles.reduce((prev, cur) => cur.size + prev, 0);
try {
await sharedFs.current.upload(currentDirectory, listSource, {
progress: (length) => {
dispatch(
setStatus({
message: `[${getPercent(length, totalSize)}%] Uploading files`,
}),
);
},
});
dispatch(setStatus({}));
} catch (e) {
// will add sharedFs.canWrite method later for richer ux
dispatch(
setStatus({
message: `Missing write permissions.`,
isError: true,
}),
);
delay(4000).then(() => dispatch(setStatus({})));
}
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[currentDirectory],
);
const {getRootProps, getInputProps, isDragActive, open} = useDropzone({
onDrop,
noClick: true,
});
useImperativeHandle(ref, () => ({
openUpload: () => {
open();
},
}));
return (
<div {...getRootProps()} style={styles.container} id={'dropZone'}>
<input {...getInputProps()} id={'fileUpload'} />
{isDragActive ? <FileDragBlock isActive={true} /> : <div>{children}</div>}
</div>
);
}
Example #22
Source File: images-upload-container.js From horondi_admin with MIT License | 5 votes |
ImagesUploadContainer = ({ handler, multiple, maxFiles, length }) => {
const style = useStyles();
const dispatch = useDispatch();
const availableCount = length ? maxFiles - length : maxFiles;
const validate = (file) => {
if (file.size > 15000000)
return {
code: 'size-too-large',
message: 'Максимальний розмір фото 15Mb'
};
if (length >= maxFiles)
return {
code: 'max files',
message: `Завантажте до ${maxFiles} фотографій`
};
return null;
};
const options = {
accept: 'image/*',
multiple,
maxFiles: availableCount,
noClick: true,
noKeyboard: true,
validator: validate,
onDrop: (acceptedFiles, fileRejections) => {
const files = acceptedFiles.map((file) =>
Object.assign(file, {
preview: URL.createObjectURL(file)
})
);
handler(files);
if (fileRejections.length) {
const { message } = fileRejections[0].errors[0];
dispatch(showErrorSnackbar(message));
}
}
};
const { getRootProps, getInputProps, open } = useDropzone(options);
return (
<Grid container>
<div {...getRootProps({ className: style.dropzone })}>
<input {...getInputProps()} />
<span>
<CloudUploadRounded />
</span>
<p>Перетягніть фото сюди або</p>
<button type='button' className={style.dropButton} onClick={open}>
Обрати
</button>
</div>
<p className={style.description}>
Завантажте до {maxFiles} зображень. Максимальний розмір фото - 15MB.
Дозволені формати: jpeg, jpg, png.
</p>
</Grid>
);
}
Example #23
Source File: dropSection.js From open-jobboard with Apache License 2.0 | 4 votes |
DropSection = (props) => {
const [isShownRight, setIsShownRight] = useState(true)
const [isShownLeft, setIsShownLeft] = useState(true)
const [modalIsOpen, setModalIsOpen] = useState(false)
const [profileFile, setProfileFile] = useState("");
const [device, setDevice] = useState("mobile")
useEffect(() => {
if(props.profile?.s) {
setModalIsOpen(false)
swal({
title: "Title success",
text: "Message success!",
icon: "success",
});
// Swal.fire({
// title: 'Vérifie ta boite mail.',
// html: 'Tu viens de recevoir un message de la part d\'ENGIE.',
// type: 'success',
// confirmButtonColor: '#00aaff',
// });
}
if(props.profile.f) {
swal(
{
type: 'error',
title: 'Oops...',
text: 'Message error',
}
)
}
}, [props.profile])
const onDrop = useCallback((acceptedFiles) => {
acceptedFiles.forEach((file) => {
setModalIsOpen(true)
const reader = new FileReader()
reader.onabort = () => console.log('file reading was aborted')
reader.onerror = () => console.log('file reading has failed')
reader.onload = () => {
// Do whatever you want with the file contents
const binaryStr = reader.result
console.log(binaryStr)
}
reader.readAsArrayBuffer(file)
setProfileFile(file)
})
}, [])
const {getRootProps, getInputProps} = useDropzone({onDrop})
const postProfile = (consentController) => {
props.addProfile({file: profileFile, consent: consentController, redirect: true})
}
const leftClassContent = isShownLeft ? [clippedStyles.left__content, clippedStyles.content__shown] : [clippedStyles.left__content]
const leftClassHover = isShownLeft ? [clippedStyles.left__content] : [clippedStyles.left__content_hovered, clippedStyles.hover__shown]
return (
<>
<section className={clippedStyles.clipped}>
<Media
queries={{ large: "(min-width: 1200px)" }}
defaultMatches={{ large: device === 'desktop' && props.isDesktopOrLaptop === 'desktop' }}
render={() =>
<div className={clippedStyles.bridge}>
<img src={bridgeImg} />
</div>
}
/>
<Media
queries={{ mobile: "(max-width: 1200px)" }}
defaultMatches={{ mobile: device === 'mobile' && props.isDesktopOrLaptop === 'mobile' }}
render={() =>
<div className={clippedStyles.heading_mobile}>
<div className="text-extra-large"><span className="text-bold-600">BPI group</span> vous accompagne</div>
<div className="text-extra-large text-bold-600">vers un nouvel avenir professionnel</div>
<div className={clippedStyles.bridge_mobile}>
<img src={bridgeImg} className={clippedStyles.bridge_mobile_img} />
</div>
</div>
}
/>
<Media
queries={{ large: "(min-width: 1200px)" }}
defaultMatches={{ large: device === 'desktop' && props.isDesktopOrLaptop === 'desktop' }}
render={() =>
<div className={clippedStyles.left}
onMouseEnter={() => setIsShownLeft(false)}
onMouseLeave={() => setIsShownLeft(true)}
role="textbox"
tabIndex="-1"
>
<div className={leftClassContent.join(' ')}>
<div className={clippedStyles.heading}>
<div className="text-extra-large">Dolore occaecat dolore consequat deserunt mollit deserunt laboris </div>
<div className="text-medium">Ut Lorem anim minim consectetur aliquip nulla est anim </div>
</div>
<div className={[clippedStyles.shape,clippedStyles.shape__justified].join(' ')}>
<img src={girlImg} alt="Jumping girl" />
<span className={clippedStyles.shape__text}>With Resume</span>
</div>
</div>
<div className={leftClassHover.join(' ')} {...getRootProps()}>
<input {...getInputProps()} />
<div className={clippedStyles.dropping}>
<div className={clippedStyles.cloud_row}>
<img src={cloudLogo} />
<img src={cloudLogo} />
<img src={cloudLogo} />
<img src={cloudLogo} />
</div>
<div className={clippedStyles.cloud_row}>
<div className={clippedStyles.cloud_col}>
<img src={cloudLogo} />
<img src={cloudLogo} />
</div>
<div className={clippedStyles.dropzone} >
<span className="text-large bold">
Glisse ton CV
</span>
<div id="dropzone">
</div>
<div className={clippedStyles.dashed}>
<div className={clippedStyles.logo_wrapper}>
<img src={plusLogo} alt="plus" />
</div>
</div>
</div>
<img src={cloudLogo} />
</div>
<div className="drop-message">et laisse la magie opérer</div>
<div className={clippedStyles.cloud_row}>
<img src={cloudLogo} />
<img src={cloudLogo} />
<img src={cloudLogo} />
</div>
</div>
</div>
</div>
}/>
<Media
queries={{ mobile: "(max-width: 1200px)" }}
defaultMatches={{ mobile: device === 'mobile' && props.isDesktopOrLaptop === 'mobile' }}
render={() =>
<div className={clippedStyles.left}
onMouseEnter={() => setIsShownLeft(false)}
onMouseLeave={() => setIsShownLeft(true)}
role="textbox"
tabIndex="-1"
>
<div className={[clippedStyles.left__content_hovered, clippedStyles.hover__shown].join(' ')} {...getRootProps()}>
<input {...getInputProps()} />
<div className={clippedStyles.dropping}>
<div className={clippedStyles.cloud_row_mobile}>
<div className={clippedStyles.dropzone} >
<span className="text-large text-bold-600">
Glissez votre CV
</span>
<div id="dropzone">
</div>
<div className={clippedStyles.dashed}>
<div className={clippedStyles.logo_wrapper}>
<img src={plusLogo} alt="plus" />
</div>
</div>
</div>
</div>
<div className="drop-message text-large text-bold-600">et le tour est joué</div>
</div>
</div>
</div>
}
/>
<Media
queries={{ large: "(min-width: 1200px)" }}
defaultMatches={{ large: device === 'desktop' && props.isDesktopOrLaptop === 'desktop'}}
render={() =>
<div
className={clippedStyles.right}
onMouseEnter={() => setIsShownRight(false)}
onMouseLeave={() => setIsShownRight(true)}
role="textbox"
tabIndex="-2"
>
{ isShownRight ? (
<div className={clippedStyles.right__content}>
<div className={clippedStyles.heading}>
</div>
<div className={clippedStyles.shape}>
<img src={boyImg} alt="Jumping boy" />
<span className={clippedStyles.shape__text}>Without Resume</span>
</div>
</div>
)
:
(
<Link to="/jobs" className={clippedStyles.right__content_hovered}>
<span className={clippedStyles.row}>
<img src={times} alt="times 1" />
<img src={times} alt="times 2" />
<img src={times} alt="times 3" />
</span>
<span className={`${clippedStyles.row} text-large text-bold-700 text-right`}>
Trop pressé
</span>
<span className={clippedStyles.row}>
<img src={times} alt="times 4" />
<img src={times} alt="times 5" />
<img src={times} alt="times 6" />
<img src={times} alt="times 7" />
</span>
<span className={`${clippedStyles.row} text-large text-right`}>
Accède à nos offres <FontAwesomeIcon className="icon-right" icon={faLongArrowAltRight} />
</span>
<span className={clippedStyles.row}>
<img src={times} alt="times 8" />
<img src={times} alt="times 9" />
<img src={times} alt="times 10" />
<img src={times} alt="times 11" />
</span>
</Link>
)
}
</div>
}
/>
<Media
queries={{ mobile: "(max-width: 1200px)" }}
defaultMatches={{ mobile: device === 'mobile' && props.isDesktopOrLaptop === 'mobile' }}
render={() =>
<div className={clippedStyles.content_mobile}>
<div className="text-extra-large"><span className="text-bold-600">Trop pressé</span></div>
<Link to="/jobs" className="button button-large">Accédez à nos offres <FontAwesomeIcon className="icon-right" icon={faLongArrowAltRight} /></Link>
</div>
}
/>
<Modal
toggleModal={setModalIsOpen}
modalIsOpen={modalIsOpen}
postProfile={postProfile}
profile={props.profile}
/>
</section>
</>
)
}
Example #24
Source File: index.js From Artion-Client with GNU General Public License v3.0 | 4 votes |
PaintBoard = () => {
const dispatch = useDispatch();
const history = useHistory();
const {
explorerUrl,
apiUrl,
fetchMintableCollections,
getNonce,
addUnlockableContent,
checkBan,
} = useApi();
const { registerRoyalty } = useSalesContract();
const { loadContract } = useContract();
const { account, chainId } = useWeb3React();
const imageRef = useRef();
const [selected, setSelected] = useState([]);
const [collections, setCollections] = useState([]);
const [nft, setNft] = useState();
const [type, setType] = useState();
const [image, setImage] = useState(null);
const [fee, setFee] = useState(null);
const [name, setName] = useState('');
const [symbol, setSymbol] = useState('');
const [description, setDescription] = useState('');
const [royalty, setRoyalty] = useState('');
const [xtra, setXtra] = useState('');
const [supply, setSupply] = useState(0);
const [hasUnlockableContent, setHasUnlockableContent] = useState(false);
const [unlockableContent, setUnlockableContent] = useState('');
const [currentMintingStep, setCurrentMintingStep] = useState(0);
const [isMinting, setIsMinting] = useState(false);
const [lastMintedTnxId, setLastMintedTnxId] = useState('');
const authToken = useSelector(state => state.ConnectWallet.authToken);
const getFee = async () => {
setFee(null);
try {
const contract = await loadContract(nft, FEE_ABI);
const _fee = await contract.platformFee();
setFee(parseFloat(_fee.toString()) / 10 ** 18);
} catch {
setFee(0);
}
};
const getCollections = async () => {
try {
const { data } = await fetchMintableCollections(authToken);
setCollections(data);
if (data.length) {
setSelected([data[0]]);
}
} catch (err) {
console.log(err);
}
};
useEffect(() => {
if (authToken) {
getCollections();
}
}, [authToken]);
useEffect(() => {
if (!nft) return;
getFee();
}, [nft]);
useEffect(() => {
dispatch(HeaderActions.toggleSearchbar(true));
}, []);
const onDrop = useCallback(acceptedFiles => {
setImage(acceptedFiles[0]);
}, []);
const { getRootProps, getInputProps } = useDropzone({
accept: accept.join(', '),
multiple: false,
onDrop,
maxSize: 15728640,
});
const removeImage = () => {
setImage(null);
if (imageRef.current) {
imageRef.current.value = '';
}
};
const imageToBase64 = () => {
return new Promise((resolve, reject) => {
let reader = new FileReader();
reader.readAsDataURL(image);
reader.onload = () => {
resolve(reader.result);
};
reader.onerror = err => {
reject(err);
};
});
};
const validateMetadata = () => {
return name !== '' && account !== '' && image;
};
const resetMintingStatus = () => {
setTimeout(() => {
setIsMinting(false);
setCurrentMintingStep(0);
}, 1000);
};
const mintNFT = async () => {
if (!account) {
showToast('info', 'Connect your wallet first');
return;
}
if (chainId !== ChainId.FANTOM && chainId !== ChainId.FANTOM_TESTNET) {
showToast('info', 'You are not connected to Fantom Opera Network');
return;
}
const balance = await WalletUtils.checkBalance(account);
if (balance < fee) {
showToast(
'custom',
`Your balance should be at least ${fee} FTM to mint an NFT`
);
return;
}
let isBanned = await checkBan(account, authToken);
if (isBanned) {
showToast('error', 'You are banned from minting');
return;
}
setLastMintedTnxId('');
// show stepper
setIsMinting(true);
console.log('created from ', account);
if (!validateMetadata()) {
resetMintingStatus();
return;
}
let signature;
let addr;
if (hasUnlockableContent && unlockableContent.length > 0) {
const { data: nonce } = await getNonce(account, authToken);
try {
const signer = await getSigner();
const msg = `Approve Signature on Artion.io with nonce ${nonce}`;
signature = await signer.signMessage(msg);
addr = ethers.utils.verifyMessage(msg, signature);
} catch (err) {
showToast(
'error',
'You need to sign the message to be able to update account settings.'
);
resetMintingStatus();
return;
}
}
let formData = new FormData();
const base64 = await imageToBase64();
formData.append('image', base64);
formData.append('name', name);
formData.append('account', account);
formData.append('description', description);
formData.append('symbol', symbol);
formData.append('xtra', xtra);
const _royalty = parseInt(royalty) * 100;
formData.append('royalty', isNaN(_royalty) ? 0 : _royalty);
try {
let result = await axios({
method: 'post',
url: `${apiUrl}/ipfs/uploadImage2Server`,
data: formData,
headers: {
'Content-Type': 'multipart/form-data',
Authorization: 'Bearer ' + authToken,
},
});
console.log('upload image result is ');
const jsonHash = result.data.jsonHash;
const contract = await loadContract(
nft,
type === 721 ? SINGLE_NFT_ABI : MULTI_NFT_ABI
);
try {
const args =
type === 721 ? [account, jsonHash] : [account, supply, jsonHash];
let tx;
if (!fee) {
tx = await contract.mint(...args);
} else {
const options = {
value: ethers.utils.parseEther(fee.toString()),
gasPrice: getHigherGWEI(),
};
const gasEstimate = await contract.estimateGas.mint(...args, options);
options.gasLimit = calculateGasMargin(gasEstimate);
tx = await contract.mint(...args, options);
}
setCurrentMintingStep(1);
setLastMintedTnxId(tx.hash);
setCurrentMintingStep(2);
const confirmedTnx = await tx.wait();
setCurrentMintingStep(3);
let mintedTkId;
if (type === 721) {
const evtCaught = confirmedTnx.logs[0].topics;
mintedTkId = BigNumber.from(evtCaught[3]);
} else {
mintedTkId = BigNumber.from(
ethers.utils.hexDataSlice(confirmedTnx.logs[1].data, 0, 32)
);
}
const royaltyTx = await registerRoyalty(
nft,
mintedTkId.toNumber(),
isNaN(_royalty) ? 0 : _royalty
);
await royaltyTx.wait();
// save unlockable content
if (hasUnlockableContent && unlockableContent.length > 0) {
await addUnlockableContent(
nft,
mintedTkId.toNumber(),
unlockableContent,
signature,
addr,
authToken
);
}
showToast('success', 'New NFT item minted!');
removeImage();
setName('');
setSymbol('');
setDescription('');
setTimeout(() => {
history.push(`/explore/${nft}/${mintedTkId.toNumber()}`);
}, 1000 + Math.random() * 2000);
} catch (error) {
showToast('error', formatError(error));
}
} catch (error) {
showToast('error', error.message);
}
resetMintingStatus();
};
return (
<div className={styles.container}>
<Header border />
<div className={styles.body}>
<div className={styles.board}>
<div {...getRootProps({ className: styles.uploadCont })}>
<input {...getInputProps()} ref={imageRef} />
{image ? (
<>
<img
className={styles.image}
src={URL.createObjectURL(image)}
/>
<div className={styles.overlay}>
<CloseIcon className={styles.remove} onClick={removeImage} />
</div>
</>
) : (
<>
<div className={styles.uploadtitle}>
Drop files here or
<span
className={styles.browse}
onClick={() => imageRef.current?.click()}
>
browse
</span>
</div>
<div className={styles.uploadsubtitle}>
JPG, PNG, BMP, GIF Max 15mb.
</div>
</>
)}
</div>
</div>
<div className={styles.panel}>
<div className={styles.panelInputs}>
<div className={styles.panelLeft}>
<div className={styles.formGroup}>
<p className={styles.formLabel}>Collection</p>
<Select
options={collections}
disabled={isMinting}
values={selected}
onChange={([col]) => {
setSelected([col]);
setNft(col.erc721Address);
setType(col.type);
}}
className={styles.select}
placeholder="Choose Collection"
itemRenderer={({ item, methods }) => (
<div
key={item.erc721Address}
className={styles.collection}
onClick={() => {
methods.clearAll();
methods.addItem(item);
}}
>
<img
src={`https://cloudflare-ipfs.com/ipfs/${item.logoImageHash}`}
className={styles.collectionLogo}
/>
<div className={styles.collectionName}>
{item.collectionName}
</div>
</div>
)}
contentRenderer={({ props: { values } }) =>
values.length > 0 ? (
<div className={styles.collection}>
<img
src={`https://cloudflare-ipfs.com/ipfs/${values[0].logoImageHash}`}
className={styles.collectionLogo}
/>
<div className={styles.collectionName}>
{values[0].collectionName}
</div>
</div>
) : (
<div className={styles.collection} />
)
}
/>
</div>
<div className={styles.formGroup}>
<p className={styles.formLabel}>Name</p>
<input
className={styles.formInput}
maxLength={40}
placeholder="Name"
value={name}
onChange={e => setName(e.target.value)}
disabled={isMinting}
/>
<div className={styles.lengthIndicator}>{name.length}/40</div>
</div>
<div className={styles.formGroup}>
<p className={styles.formLabel}>Symbol</p>
<input
className={styles.formInput}
maxLength={20}
placeholder="Symbol"
value={symbol}
onChange={e => setSymbol(e.target.value)}
disabled={isMinting}
/>
<div className={styles.lengthIndicator}>{symbol.length}/20</div>
</div>
<div className={styles.formGroup}>
<p className={styles.formLabel}>Description</p>
<textarea
className={cx(styles.formInput, styles.longInput)}
maxLength={120}
placeholder="Description"
value={description}
onChange={e => setDescription(e.target.value)}
disabled={isMinting}
/>
<div className={styles.lengthIndicator}>
{description.length}/120
</div>
</div>
</div>
<div className={styles.panelRight}>
{type === 1155 && (
<div className={styles.formGroup}>
<p className={styles.formLabel}>Supply</p>
<PriceInput
className={styles.formInput}
placeholder="Supply"
decimals={0}
value={'' + supply}
onChange={setSupply}
disabled={isMinting}
/>
</div>
)}
<div className={styles.formGroup}>
<p className={styles.formLabel}>
Royalty (%)
<BootstrapTooltip
title="If you set a royalty here, you will get X percent of sales price each time an NFT is sold on our platform."
placement="top"
>
<HelpOutlineIcon />
</BootstrapTooltip>
</p>
<PriceInput
className={styles.formInput}
placeholder="Royalty"
decimals={2}
value={'' + royalty}
onChange={val =>
val[val.length - 1] === '.'
? setRoyalty(val)
: setRoyalty(Math.min(100, +val))
}
disabled={isMinting}
/>
</div>
<div className={styles.formGroup}>
<p className={styles.formLabel}>
Link to IP Rights Document (Optional)
<BootstrapTooltip
title="Link to the document which proves your ownership of this image."
placement="top"
>
<HelpOutlineIcon />
</BootstrapTooltip>
</p>
<input
className={styles.formInput}
placeholder="Enter Link"
value={xtra}
onChange={e => setXtra(e.target.value)}
disabled={isMinting}
/>
</div>
<div className={styles.formGroup}>
<p className={styles.formLabel}>
Unlockable Content
<PurpleSwitch
checked={hasUnlockableContent}
onChange={e => {
setHasUnlockableContent(e.target.checked);
setUnlockableContent('');
}}
name="unlockableContent"
/>
</p>
{hasUnlockableContent && (
<textarea
className={cx(styles.formInput, styles.longInput)}
maxLength={500}
placeholder="Unlockable Content"
value={unlockableContent}
onChange={e => setUnlockableContent(e.target.value)}
disabled={isMinting}
/>
)}
</div>
</div>
</div>
{isMinting && (
<div>
<Stepper activeStep={currentMintingStep} alternativeLabel>
{mintSteps.map(label => (
<Step key={label}>
<StepLabel>{label}</StepLabel>
</Step>
))}
</Stepper>
</div>
)}
<div
className={cx(
styles.button,
(isMinting || !account || !validateMetadata()) && styles.disabled
)}
onClick={
isMinting || !account || !validateMetadata() ? null : mintNFT
}
>
{isMinting ? (
<ClipLoader size="16" color="white"></ClipLoader>
) : (
'Mint'
)}
</div>
<div className={styles.fee}>
{fee !== null ? (
<>
<InfoIcon />
{fee} FTM are charged to create a new NFT.
</>
) : (
<Skeleton width={330} height={22} />
)}
</div>
<div className={styles.mintStatusContainer}>
{lastMintedTnxId !== '' && (
<a
className={styles.tnxAnchor}
target="_blank"
rel="noopener noreferrer"
href={`${explorerUrl}/tx/${lastMintedTnxId}`}
>
You can track the last transaction here ...
</a>
)}
</div>
</div>
</div>
</div>
);
}
Example #25
Source File: Data.js From vria with MIT License | 4 votes |
function FileUploader(props) {
const { editorConfig, actions } = props;
const [currentFile, setCurrentFile] = useState(null);
const [readError, setReadError] = useState(null);
const onDrop = useCallback((acceptedFiles) => {
acceptedFiles.forEach((file) => {
const reader = new FileReader();
reader.onabort = () => setReadError('File read was aborted');
reader.onerror = () => setReadError('File read has failed');
reader.onload = () => setCurrentFile(reader.result);
reader.readAsText(file);
});
}, []);
const history = useHistory();
const {
acceptedFiles,
fileRejections,
isDragActive,
isDragAccept,
isDragReject,
getRootProps,
getInputProps
} = useDropzone({
onDrop,
accept: 'text/csv, application/json',
multiple: false
});
const importDataset = () => {
console.log('editorConfig', editorConfig);
try {
let c = JSON.parse(editorConfig);
console.log(c);
if (currentFile !== null) {
if (isJSON(currentFile)) {
// File is JSON
c.data = {
values: JSON.parse(currentFile)
};
} else {
// File is CSV
c.data = {
values: Papa.parse(currentFile, {
header: true,
dynamicTyping: true,
skipEmptyLines: true
}).data
};
}
actions.setEditorConfig(JSON.stringify(c, null, 2));
history.push('/editor');
}
} catch {
setReadError('Cannot import dataset: Vis-config contains invalid JSON');
}
};
const files = acceptedFiles.map((file) => (
<li key={file.path}>
{file.path} - {(file.size / 1000).toFixed(2)} KB -{' '}
<button onClick={importDataset}>Use Dataset</button>
</li>
));
return (
<section className='container'>
<DropArea {...getRootProps({ isDragActive, isDragAccept, isDragReject })}>
<input {...getInputProps()} />
<p>Drag a CSV or JSON file here or click to upload.</p>
</DropArea>
{files.length !== 0 ? (
<aside>
<h3>Uploaded file:</h3>
<ul>{files}</ul>
</aside>
) : null}
{fileRejections.length !== 0 ? (
<aside>
<p>{fileRejections[0].errors[0].message}</p>
</aside>
) : null}
<div>{readError}</div>
</section>
);
}
Example #26
Source File: index.js From website with MIT License | 4 votes |
DragNDropInputField = ({ onChange, error, initialImages = null }) => {
const [selectedImages, setSelectedImages] = useState([]);
const [alertMessage, setAlertMessage] = useState('');
const { getRootProps, getInputProps, isDragActive, isDragAccept, isDragReject } = useDropzone({
onDrop: (files) => onUpload(files, selectedImages),
accept: '.jpeg, .png, .jpg',
});
const onCloseAlert = () => setAlertMessage('');
const displayUploadFileAlert = (message) => {
setAlertMessage(message);
setTimeout(() => {
onCloseAlert(); // hide alert message after 5 seconds
}, 5000);
};
const onUpload = useCallback((acceptedFiles, selectedImages) => {
if (acceptedFiles.some((file) => file.size > MAXIMUM_FILE_SIZE_LIMIT)) {
displayUploadFileAlert('Unable to upload images that are more than 25mb');
acceptedFiles = acceptedFiles.filter((file) => file.size <= MAXIMUM_FILE_SIZE_LIMIT);
}
const allowedRemainingImages = MAXIMUM_ALLOWED_PHOTOS - selectedImages.length;
if (allowedRemainingImages < acceptedFiles.length) {
displayUploadFileAlert('Unable to upload more than 4 images');
}
// Only take maximum 4 images.
if (acceptedFiles.length > 0 && selectedImages.length <= MAXIMUM_ALLOWED_PHOTOS - 1) {
const acceptedImages = acceptedFiles.map((file) => {
return Object.assign(file, {
preview: URL.createObjectURL(file),
id: uuidv4(),
});
});
if (allowedRemainingImages > 0) {
const allowedImages = acceptedImages.splice(0, allowedRemainingImages);
setSelectedImages((prevSelectedImages) => [...prevSelectedImages, ...allowedImages]);
}
}
}, []);
useEffect(() => {
onChange(selectedImages);
}, [selectedImages]);
useEffect(() => {
if (initialImages) {
let initial = initialImages.map((imageUrl) => ({
preview: imageUrl,
id: uuidv4(),
}));
setSelectedImages(initial);
}
}, [initialImages]);
const onDragEnd = (result) => {
if (!result.destination) {
// dropped outside the list
return;
}
const items = reorder(selectedImages, result.source.index, result.destination.index);
setSelectedImages(items);
};
// a little function to help us with reordering the result
const reorder = (list, startIndex, endIndex) => {
const result = Array.from(list);
const [removed] = result.splice(startIndex, 1);
result.splice(endIndex, 0, removed);
return result;
};
const onDeleteClick = (index) => {
let cloneSelectedImages = [...selectedImages];
cloneSelectedImages.splice(index, 1);
setSelectedImages(cloneSelectedImages);
};
return (
<Container>
<DragNDropContainer {...getRootProps({ isDragActive, isDragAccept, isDragReject })}>
<input {...getInputProps()} />
<p>Drag 'n' drop up to {MAXIMUM_ALLOWED_PHOTOS} photos, or click to select photos</p>
</DragNDropContainer>
{error && <Error>{error}</Error>}
<DragDropContext onDragEnd={onDragEnd}>
<Droppable droppableId="droppable" direction="horizontal">
{(provided, snapshot) => (
<HorizontalImagesContainer ref={provided.innerRef} {...provided.droppableProps}>
{selectedImages.map((item, index) => (
<Draggable key={item.id} draggableId={item.id} index={index}>
{(provided, snapshot) => (
<DraggableImageContainer
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
isDragging={snapshot.isDragging}
draggableStyle={provided.draggableProps.style}
>
<Image src={item.preview} onDeleteClick={() => onDeleteClick(index)} />
</DraggableImageContainer>
)}
</Draggable>
))}
{provided.placeholder}
</HorizontalImagesContainer>
)}
</Droppable>
</DragDropContext>
{selectedImages.length > 0 ? (
<CoverTextWrapper>
<Text type="white" align="center">
Cover
</Text>
</CoverTextWrapper>
) : null}
{alertMessage.length > 0 && (
<AlertContainer>
<Alert icon type="critical" title="Something has gone wrong" closable onClose={onCloseAlert}>
{alertMessage}
</Alert>
</AlertContainer>
)}
</Container>
);
}
Example #27
Source File: file-upload.js From proof-of-humanity-web with MIT License | 4 votes |
export default function FileUpload({
value,
onChange: _onChange,
name,
accept,
acceptLabel,
maxSize,
maxSizeLabel,
multiple = false,
onBlur,
placeholder = `Drag your file${multiple ? "s" : ""}`,
photo = false,
video = false,
...rest
}) {
const [files, setFiles] = useState(value);
const [popupOpen, setPopupOpen] = useState(false);
const onChange = (_files, ...args) => {
if (_files)
for (const file of Array.isArray(_files) ? _files : [_files])
file.toJSON = () => ({
isSerializedFile: true,
type: file.type,
name: file.name,
content: bufferToString(file.content),
});
return _onChange
? _onChange({ target: { name, value: _files } })
: setFiles(_files, ...args);
};
const { getRootProps, getInputProps, open } = useDropzone({
noClick: true,
async onDrop(acceptedFiles) {
const readFiles = await Promise.all(
acceptedFiles.map(async (file) => {
const buffer = await file.arrayBuffer();
file.preview = URL.createObjectURL(file);
file.content = buffer;
return file;
})
);
const _files = readFiles.length === 1 ? readFiles[0] : readFiles;
onChange(_files);
},
multiple,
accept,
maxSize,
...rest,
});
useEffect(() => {
if (value) {
const _files = Array.isArray(value) ? value : [value];
if (_files.some((file) => file.isSerializedFile)) {
const parsedFiles = _files.map((file) => {
if (!file.isSerializedFile) return file;
const buffer = stringToBuffer(file.content);
file = new File([buffer], file.name, { type: file.type });
file.preview = URL.createObjectURL(file);
file.content = buffer;
file.toJSON = () => ({
isSerializedFile: true,
type: file.type,
name: file.name,
content: bufferToString(file.content),
});
return file;
});
_onChange({ target: { name, value: parsedFiles } });
}
}
}, [value, _onChange, name]);
useEffect(() => {
if (value !== undefined && value !== files) setFiles(value);
}, [value, files]);
useEffect(
() => () => {
if (files)
(Array.isArray(files) ? files : [files]).forEach((file) =>
URL.revokeObjectURL(file.preview)
);
},
[files]
);
return (
<Box
sx={{ position: "relative" }}
onClick={(event) => {
event.stopPropagation();
event.preventDefault();
}}
>
<Box
{...getRootProps({
onClick: (event) => {
event.preventDefault();
event.stopPropagation();
},
variant: "forms.fileUpload",
onBlur() {
if (onBlur) onBlur({ target: { name } });
},
...rest,
})}
>
<Input {...getInputProps({ name })} />
{maxSizeLabel && acceptLabel ? (
<Text sx={{ fontStyle: "italic" }}>
(Max Size: {maxSizeLabel} | {acceptLabel})
</Text>
) : maxSizeLabel ? (
<Text sx={{ fontStyle: "italic" }}>(Max Size: {maxSizeLabel})</Text>
) : acceptLabel ? (
<Text sx={{ fontStyle: "italic" }}>{acceptLabel}</Text>
) : null}
<Text>
{placeholder}
{photo || video ? ", " : " or "}
<Button variant="secondary" onClick={open}>
click here to browse files
</Button>
{photo || video ? (
<>
{" or "}
<Button
variant="secondary"
onClick={(event) => {
event.stopPropagation();
event.preventDefault();
setPopupOpen(true);
}}
>
click here to use your webcam
</Button>
<Webcam
open={popupOpen}
setPopupOpen={setPopupOpen}
photo={photo}
video={video}
onChange={(file) =>
onChange(multiple ? [...files, file] : file)
}
mirrored={false}
/>
</>
) : null}
</Text>
</Box>
<Flex sx={{ marginTop: 1 }}>
{files &&
(Array.isArray(files) ? files : [files])
.filter((file) => !file.isSerializedFile)
.map((file) => (
<Box
key={file.path || file.name}
sx={{
marginTop: 1,
position: "relative",
width: "fit-content",
}}
>
{file.type.startsWith("video") ? (
<Video variant="thumbnail" url={file.preview} />
) : file.type.startsWith("image") ? (
<Image variant="thumbnail" src={file.preview} />
) : (
<Text>{file.name}</Text>
)}
<Trash
sx={{
fill: "text",
position: "absolute",
right: -1,
top: -1,
}}
onClick={(event) => {
event.stopPropagation();
event.preventDefault();
onChange(
multiple ? files.filter((_file) => _file !== file) : null
);
}}
/>
</Box>
))}
</Flex>
</Box>
);
}
Example #28
Source File: Editor.jsx From locked.fyi with MIT License | 4 votes |
Editor = ({ thread: threadId, note: noteId }) => {
const { account } = useWeb3React()
const {
setNoteAttribute,
setNoteBody,
note,
noteThread,
loading,
save,
destroy,
uploadFile,
} = useOwnerThread(account, threadId, noteId)
const onDrop = async (acceptedFiles) => {
const { body } = note // keeping track of body, as-is
// TODO: support multiple file uploads at once!
const file = acceptedFiles[0]
const textArea = document.querySelector(".mde-text")
const insertAt = textArea.selectionStart
const uploadPlaceholder = "\nUploading file..."
setNoteBody(
body.slice(0, insertAt) + uploadPlaceholder + body.slice(insertAt)
)
const url = await uploadFile(file)
// We should look at the mimetype for files an respond accordingly
// If it is an image, embed as is
// if it is an mp3 use an audio player
// if it is an mp4, use a video player...
let markdown = `\n${url}\n`
if (file.type.match("image/*")) {
markdown = `![](${url})`
} else {
// Link to the file
markdown = `\n[${file.name}](${url})\n`
}
setNoteBody(`${body.slice(0, insertAt)}${markdown}${body.slice(insertAt)}`)
// WARNING: what happens if the body was changed?
// Restore the position
textArea.setSelectionRange(
insertAt + markdown.length + 1,
insertAt + markdown.length + 1
)
}
const { getRootProps, getInputProps, isDragActive } = useDropzone({
onDrop,
noClick: true,
noKeyboard: true,
})
const history = useHistory()
const [selectedTab, setSelectedTab] = useState("write")
const [saving, setSaving] = useState(false)
if (loading) {
return <Loading />
}
const onSave = async (event) => {
event.preventDefault()
setSaving(true)
await save()
setSaving(false)
return false
}
const onDestroy = async () => {
setSaving(true)
await destroy()
setSaving(false)
history.push(writePath())
return false
}
const onLockChange = (selected) => {
setNoteAttribute(
"locks",
(selected || []).map((option) => option.value)
)
}
const draftToggle = () => {
setNoteAttribute("draft", !note.attributes.draft)
}
const isDraft = note.attributes.draft
return (
<form className="container" onSubmit={onSave}>
<LockPicker
identity={account}
onLockChange={onLockChange}
currentLocks={note.attributes.locks}
>
<p>
Your note will use the{" "}
<a target="_blank" rel="noopener noreferrer" href="/#community-lock">
community lock
</a>
... but you can also{" "}
<a
target="_blank"
rel="noopener noreferrer"
href="https://app.unlock-protocol.com/dashboard"
>
deploy your own lock
</a>{" "}
if you want to monetize your own notes.
</p>
</LockPicker>
<div {...getRootProps()}>
<input {...getInputProps()} />
{/* Source: https://github.com/andrerpena/react-mde */}
<MarkDownEditor
isDragActive={isDragActive}
value={note.body}
onChange={setNoteBody}
selectedTab={selectedTab}
onTabChange={setSelectedTab}
generateMarkdownPreview={(markdown) =>
Promise.resolve(converter.makeHtml(markdown))
}
/>
</div>
<Checkbox
name="draft"
checked={isDraft}
onChange={draftToggle}
label="Draft"
/>
<Actions>
<nav>
<Button type="submit" disabled={saving}>
Save
</Button>
</nav>
<nav>
<Button type="button" disabled={saving} onClick={onDestroy}>
Destroy
</Button>
</nav>
{saving && <Loading />}
</Actions>
<div>
{note.attributes.id && note.attributes.id > 0 && (
<>
➡{" "}
<Link to={notePath(account, noteThread, note.attributes.id)}>
{note.attributes.title}
</Link>
</>
)}
</div>
</form>
)
}
Example #29
Source File: index.js From plataforma-sabia with MIT License | 4 votes |
EditServiceModal = ({
closeModal,
id,
name,
thumbnail,
keywords,
description,
measure_unit,
price,
type,
revalidateServices,
revalidateKeywords,
keywordsOptions,
}) => {
const [isSubmitting, setIsSubmitting] = useState(false);
const [uploadError, setUploadError] = useState(null);
const form = useForm({
defaultValues: {
name,
keywords,
thumbnail: { id: thumbnail?.id, url: thumbnail?.url },
description,
measure_unit,
price,
type,
},
});
const formThumbnail = form.watch('thumbnail');
const onSubmit = async (values) => {
setIsSubmitting(true);
const serviceToEdit = {
...values,
measure_unit: values.measure_unit.value,
thumbnail_id: values.thumbnail.id,
type: values.type.value,
keywords: values.keywords?.map((item) => item.value) ?? [],
price: formatCurrencyToInt(values.price),
};
const result = await updateService(id, serviceToEdit);
if (result.success) {
toast.success('Serviço atualizado com sucesso');
revalidateServices();
revalidateKeywords();
closeModal();
} else {
toast.error(result.error);
}
setIsSubmitting(false);
};
const onDropAttachment = async (acceptedFiles) => {
if (!acceptedFiles) return null;
setUploadError(false);
const formData = new FormData();
if (acceptedFiles.length !== 0) {
formData.append(`files[0]`, acceptedFiles[0], acceptedFiles[0].name);
}
const response = await upload(formData);
if (response.status === 200) {
const { id: uploadId, url } = response.data[0];
form.setValue('thumbnail.id', uploadId);
form.setValue('thumbnail.url', url);
} else {
setUploadError(response.data?.error?.message[0]?.message);
}
return true;
};
const handleRemoveAttachment = async () => {
const response = await deleteUpload(formThumbnail.id);
if (response?.success) {
form.setValue('thumbnail.id', '');
form.setValue('thumbnail.url', '');
} else {
toast.error(response.data?.error?.message[0]?.message);
}
};
const { getRootProps, getInputProps } = useDropzone({
accept: 'image/*',
onDrop: onDropAttachment,
});
const onCreateTerm = async (inputValue) => {
const term = await createTerm(inputValue, 'KEYWORDS');
revalidateKeywords();
return { label: term.term, value: `${term.id}` };
};
return (
<S.Modal onSubmit={form.handleSubmit(onSubmit)} noValidate>
<Title>Editar serviço</Title>
<Row>
<S.Column noPadding mr={1.2} noMarginMobile>
<InputField
form={form}
name="name"
label="Nome do serviço"
variant="gray"
fullWidth
/>
<SelectField
form={form}
name="keywords"
placeholder="Busque por palavras chaves (pode adicionar mais de um)"
label="Palavras-chave"
isMulti
creatable
onCreate={(inputValue) => onCreateTerm(inputValue)}
options={mapArrayOfObjectToSelect(keywordsOptions, 'term', 'id')}
variant="gray"
/>
<TextField
form={form}
name="description"
label="Descrição do serviço"
resize="none"
variant="gray"
/>
</S.Column>
<Column noPadding ml={1.2} noMarginMobile>
<S.Row mb={1.6}>
<InputHiddenField form={form} name="thumbnail.id" />
<InputHiddenField form={form} name="thumbnail.url" />
<S.ImageContainer>
<Image
src={formThumbnail?.url || '/card-image.jpg'}
alt={name}
layout="fill"
objectFit="cover"
/>
</S.ImageContainer>
<S.ImageActions>
<S.UploadBox {...getRootProps()}>
<input {...getInputProps()} />
<RectangularButton colorVariant="green">
<FiUpload fontSize={14} strokeWidth={4} />
Alterar imagem
</RectangularButton>
</S.UploadBox>
<RectangularButton
colorVariant="red"
onClick={handleRemoveAttachment}
disabled={!formThumbnail?.id}
>
<FiTrash2 fontSize={14} strokeWidth={3} />
Remover
</RectangularButton>
</S.ImageActions>
</S.Row>
{!!uploadError && (
<Row>
<S.UploadError>{uploadError}</S.UploadError>
</Row>
)}
<S.Row mb={1.6}>
<SelectField
form={form}
name="measure_unit"
label="Unidade de medida"
placeholder="Escolha a unidade de medida"
options={measureUnitOptions}
variant="rounded"
/>
<CurrencyInputField form={form} name="price" label="Preço" variant="gray" />
</S.Row>
<SelectField
form={form}
name="type"
label="Tipo"
placeholder="Escolha um tipo"
options={typeOptions}
variant="rounded"
/>
</Column>
</Row>
<S.Actions>
<RectangularButton variant="outlined" colorVariant="red" onClick={closeModal}>
Cancelar
</RectangularButton>
<RectangularButton
type="submit"
variant="filled"
colorVariant="green"
disabled={isSubmitting}
>
Editar Serviço
</RectangularButton>
</S.Actions>
</S.Modal>
);
}