103 lines
3.0 KiB
TypeScript
103 lines
3.0 KiB
TypeScript
import type { ActionFunctionArgs } from "@remix-run/node";
|
|
import { LoaderFunctionArgs, NodeOnDiskFile, json, redirect, unstable_composeUploadHandlers, unstable_createFileUploadHandler, unstable_createMemoryUploadHandler, unstable_parseMultipartFormData } from "@remix-run/node";
|
|
import { copyFileSync, rmSync } from "node:fs";
|
|
import { useLoaderData } from "@remix-run/react";
|
|
import { Container, Row, Button, Form, Image } from "react-bootstrap";
|
|
|
|
import { enhance } from "~/utils/db.server";
|
|
|
|
export const action = async ({
|
|
request,
|
|
params
|
|
}: ActionFunctionArgs) => {
|
|
const { dbe } = await enhance(request);
|
|
|
|
const id = Number(params.id);
|
|
|
|
const uploadHandler = unstable_composeUploadHandlers(
|
|
unstable_createFileUploadHandler({
|
|
file: ({ filename }) => filename.toLowerCase().replaceAll(" ", "_")
|
|
}),
|
|
// parse everything else into memory
|
|
unstable_createMemoryUploadHandler()
|
|
);
|
|
const parsedForm = await unstable_parseMultipartFormData(
|
|
request,
|
|
uploadHandler
|
|
);
|
|
|
|
const image = parsedForm.get("image") as NodeOnDiskFile;
|
|
|
|
const cocktail = await dbe.cocktail.findUnique({select: {image: true, name: true}, where: {id: id}});
|
|
|
|
if(!cocktail) return redirect("/admin/edit/cocktail");
|
|
|
|
const newFilename = "/cocktails/" + cocktail.name.toLowerCase().replaceAll(" ", "_") + "." + image.name.split('.').pop();
|
|
|
|
try{
|
|
// Remove old image
|
|
if(cocktail.image) rmSync("public"+ cocktail.image, {force: true});
|
|
|
|
// Copy the file to the cocktails folder with the slug as name
|
|
copyFileSync(image.getFilePath(), "public" + newFilename);
|
|
rmSync(image.getFilePath(), {force: true});
|
|
|
|
await dbe.cocktail.update({data: {image: newFilename}, where: {id: id}});
|
|
|
|
return redirect("/inventory/cocktail/" + id);
|
|
}
|
|
catch(e){
|
|
console.log(e);
|
|
rmSync(image.getFilePath(), {force: true});
|
|
}
|
|
|
|
return null;
|
|
};
|
|
|
|
export const loader = async ({
|
|
request,
|
|
params
|
|
} : LoaderFunctionArgs) => {
|
|
const { dbe } = await enhance(request);
|
|
|
|
const id = Number(params.id);
|
|
|
|
const cocktail = await dbe.cocktail.findUnique({select: {image: true, name: true}, where: {id: id}});
|
|
|
|
if(!cocktail) return redirect("/admin/edit/cocktail");
|
|
|
|
return json({cocktail});
|
|
}
|
|
|
|
export default function EditCocktailImageRoute() {
|
|
var loaderData = useLoaderData<typeof loader>();
|
|
|
|
return (
|
|
<Container>
|
|
<Row>
|
|
<h1>Edit cocktail image ({loaderData.cocktail.name})</h1>
|
|
|
|
<Form method="POST" encType="multipart/form-data">
|
|
|
|
<Form.Group className="mb-3">
|
|
<Form.Label>Image</Form.Label>
|
|
<Form.Control type="file" name="image" accept="image/*" required/>
|
|
</Form.Group>
|
|
|
|
<Button variant="primary" type="submit">
|
|
Submit
|
|
</Button>
|
|
</Form>
|
|
</Row>
|
|
<Row className="mt-3">
|
|
<h3>Current image</h3>
|
|
{ loaderData.cocktail.image ? (
|
|
<>
|
|
<p>{loaderData.cocktail.image}</p>
|
|
<Image src={loaderData.cocktail.image}></Image>
|
|
</>
|
|
) : "No current image" }
|
|
</Row>
|
|
</Container>
|
|
);
|
|
} |