Skip to content

Instantly share code, notes, and snippets.

@arieltonglet
Last active March 11, 2023 20:59
Show Gist options
  • Select an option

  • Save arieltonglet/0fcec02b2df3cd92a2969b95f4a525b6 to your computer and use it in GitHub Desktop.

Select an option

Save arieltonglet/0fcec02b2df3cd92a2969b95f4a525b6 to your computer and use it in GitHub Desktop.
Incomplete batch uploader for Payload CMS
import React, { useEffect, useState } from "react";
import { Redirect } from "react-router-dom";
import { DefaultTemplate } from "payload/components/templates";
import { Button, Eyebrow, Gutter } from "payload/components/elements";
import { AdminView } from "payload/config";
import { useStepNav } from "payload/components/hooks";
import { useConfig, Meta } from "payload/components/utilities";
import Dropzone from "react-dropzone";
type Status = "IDLE" | "UPLOADING" | "DONE";
const BatchUploader: AdminView = ({ user, canAccessAdmin }) => {
const {
routes: { admin: adminRoute, api },
serverURL,
} = useConfig();
const { setStepNav } = useStepNav();
// The effect below will only run one time and will allow us
// to set the step nav to display our custom route name
useEffect(() => {
setStepNav([
{
label: "Bulk uploader",
},
]);
}, [setStepNav]);
// If an unauthorized user tries to navigate straight to this page,
// Boot 'em out
if (!user || (user && !canAccessAdmin)) {
return <Redirect to={`${adminRoute}/unauthorized`} />;
}
// Dropzone
const [files, setFiles] = useState([]);
const [status, setStatus] = useState<Status>("IDLE");
const [statusTexts, setStatusTexts] = useState<string[]>([]);
const onDrop = (acceptedFiles) => {
setFiles(acceptedFiles);
};
const uploadFile = async (file): Promise<string> => {
const formData = new FormData();
formData.append("file", file);
const response = await fetch(`${serverURL}${api}/media`, {
method: "POST",
body: formData,
});
return `${file.path} – ${response.status} ${response.statusText}`;
};
const onSubmit = () => {
setStatus("UPLOADING");
const promises = files.map((file) => uploadFile(file));
Promise.all(promises)
.then((values) => {
setStatus("DONE");
setFiles([]);
setStatusTexts(values);
})
.catch((err) => console.error(`Error in Promise ${err}`));
};
return (
<DefaultTemplate>
<Meta title="Media batch uploader" />
<Eyebrow />
<Gutter>
<h1>Media batch uploader</h1>
<Dropzone onDrop={onDrop}>
{({ getRootProps, getInputProps }) => (
<div
{...getRootProps()}
style={{ padding: 50, border: "2px dashed gray" }}
>
<input {...getInputProps()} />
<p style={{ margin: 0 }}>
Drag'n'drop some files here, or click to select files
</p>
</div>
)}
</Dropzone>
{/* Dropped files list */}
{files && (
<ol style={{ marginTop: "25px" }}>
{files.map((file) => (
<li key={file.path}>{file.path}</li>
))}
</ol>
)}
{/* Status text */}
{statusTexts && statusTexts.length > 0 && (
<ol style={{ marginTop: "25px" }}>
{statusTexts.map((status, i) => (
<li key={i}>{status}</li>
))}
</ol>
)}
<Button
buttonStyle="primary"
onClick={onSubmit}
disabled={status === "UPLOADING"}
>
Upload
</Button>
</Gutter>
</DefaultTemplate>
);
};
export default BatchUploader;
import { buildConfig } from "payload/config";
import BatchUploader from "./routes/BatchUploader";
export default buildConfig({
[...]
admin: {
components: {
routes: [
{
path: "/batch-uploader",
Component: BatchUploader,
},
],
},
},
[...]
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment