add basic implementation of file upload

This commit is contained in:
Brandon Egger 2023-06-25 20:05:46 -05:00
parent 89a21707ec
commit 8f4ff71425
2 changed files with 51 additions and 25 deletions

View File

@ -41,7 +41,6 @@ import {
import Modal from "react-modal"; import Modal from "react-modal";
import { type RouterInputs } from "~/utils/api"; import { type RouterInputs } from "~/utils/api";
import { PlatformLinkButton } from "~/pages/resources/[id]"; import { PlatformLinkButton } from "~/pages/resources/[id]";
import axios from "axios";
// Required for accessibility // Required for accessibility
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
@ -55,36 +54,21 @@ export type ResourceUpdateInput = RouterInputs["auditoryResource"]["update"];
* File needs to be path relative to resource_logos/ * File needs to be path relative to resource_logos/
*/ */
const SelectImageInput = ({ file }: { file?: string }) => { const SelectImageInput = ({ file }: { file?: string }) => {
const onChange = async (event: ChangeEvent<HTMLInputElement>) => { const { getValues } = useFormContext<ResourceUpdateInput>();
console.log(event.target.files);
const onChange = async (event: ChangeEvent<HTMLInputElement>) => {
const data = new FormData(); const data = new FormData();
if (!event.target.files || !event.target.files[0]) { if (!event.target.files || !event.target.files[0]) {
return; return;
} }
const resourceId = getValues("id");
data.append("photo", event.target.files[0]); data.append("photo", event.target.files[0]);
const response = await axios.post( await fetch(`/api/resources/photo/${resourceId}`, {
"/api/resources/photo/645b1afc1905d6074dfcf17d",
data,
{
headers: {
"Content-Type": "multipart/form-data",
},
}
);
const ress = await fetch("/api/resources/photo/645b1afc1905d6074dfcf17d", {
method: "POST", method: "POST",
headers: {
Accept: "application/json",
},
body: data, body: data,
}); });
console.log("done");
console.log(response);
}; };
return ( return (
@ -105,7 +89,13 @@ const SelectImageInput = ({ file }: { file?: string }) => {
</div> </div>
</label> </label>
<input <input
onChange={onChange} onChange={(event) => {
onChange(event).catch(() => {
throw new Error(
"Unexpected error occured when selecting new file."
);
});
}}
accept="image/*" accept="image/*"
id="resource-image-file" id="resource-image-file"
type="file" type="file"

View File

@ -1,24 +1,60 @@
import { type NextApiHandler } from "next"; import { type NextApiHandler } from "next";
import formidable from "formidable"; import formidable from "formidable";
import * as path from "path";
import { prisma } from "~/server/db";
const handler: NextApiHandler = (req, res) => { /**
* Returns filename for a given filepath.
* @param filepath
*/
function getFileName(filepath: string) {
return filepath.split("/").at(-1) ?? "";
}
const handler: NextApiHandler = async (req, res) => {
if (req.method !== "POST") { if (req.method !== "POST") {
res.status(404).end(); res.status(404).end();
return; return;
} }
const { id } = req.query; const { id } = req.query;
console.log(id);
if (Array.isArray(id) || !id) {
res.writeHead(400, "Invalid resource ID provided").end();
return;
}
const form = formidable({ const form = formidable({
uploadDir: "./public/resource_logos/uploads", uploadDir: "./public/resource_logos/uploads",
keepExtensions: true, keepExtensions: true,
}); });
form.parse(req, (err, fields, files) => { const localUploadPath: Promise<string> = new Promise((resolve, reject) => {
console.log(JSON.stringify(files)); form.parse(req, (_err, _fields, files) => {
const photo = Array.isArray(files.photo) ? files.photo[0] : files.photo;
if (!photo) {
reject("Invalid file type sent (or none provided)");
return;
}
resolve(path.join("uploads", getFileName(photo.filepath)));
});
}); });
try {
await prisma.auditoryResource.update({
where: {
id,
},
data: {
icon: await localUploadPath,
},
});
} catch (error: unknown) {
res.writeHead(400, JSON.stringify((error as Error).message)).end();
return;
}
res.writeHead(200, { "Content-Type": "application/json" }).end(); res.writeHead(200, { "Content-Type": "application/json" }).end();
}; };