Files
beer-inventory/app/routes/admin/new/manufacturer.tsx
T

119 lines
3.9 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 { useActionData, useLoaderData } from "@remix-run/react";
import { Container, Row, Button, Form, Col, ListGroup } from "react-bootstrap";
import { enhance } from "~/utils/db.server";
export const action = async ({
request,
}: ActionFunctionArgs) => {
const { dbe } = await enhance(request);
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 country = String(parsedForm.get("country"));
const name = String(parsedForm.get("name"));
const description = String(parsedForm.get("description"));
const image = parsedForm.get("image") as NodeOnDiskFile;
var newFilename = null;
if(image.size > 0)
newFilename = "/manufacturers/" + name.toLowerCase().replaceAll(" ", "_") + "." + image.name.split('.').pop();
try{
// Move the file to the manufacturers folder with the slug as name
if(newFilename)
{
// Copy is required for docker container to work
copyFileSync(image.getFilePath(), "public" + newFilename);
rmSync(image.getFilePath(), {force: true});
}
const createdManufacturer = await dbe.manufacturer.create({ data: {name: name, description: description, image: newFilename, country: {connect: {code: country}}} });
return redirect("/inventory/manufacturer/" + createdManufacturer.id);
}
catch(e){
console.log(e);
rmSync(image.getFilePath(), {force: true});
rmSync("public" + newFilename, {force: true});
}
return null;
};
export const loader = async ({
request,
} : LoaderFunctionArgs) => {
const { dbe } = await enhance(request);
const countries = await dbe.country.findMany({orderBy: {name: "asc"}});
const manufacturers = await dbe.manufacturer.findMany({orderBy: {name: "asc"}});
return json({countries, manufacturers});
}
export default function NewManufacturerRoute() {
var loaderData = useLoaderData<typeof loader>();
var actionData = useActionData<typeof action>();
return (
<Container>
<Row>
<h1>Add Manufacturer</h1>
<Form method="POST" encType="multipart/form-data">
<Form.Group className="mb-3">
<Form.Label>Country</Form.Label>
<Form.Select name="country" required>
{loaderData.countries.map((country) => (
<option value={country.code}>
{country.name}
</option>
))}
</Form.Select>
</Form.Group>
<Form.Group className="mb-3">
<Form.Label>Name</Form.Label>
<Form.Control type="text" placeholder="Manufacturer" name="name" required/>
</Form.Group>
<Form.Group className="mb-3">
<Form.Label>Description</Form.Label>
<Form.Control as="textarea" type="text" name="description"/>
</Form.Group>
<Form.Group className="mb-3">
<Form.Label>Image</Form.Label>
<Form.Control type="file" name="image" accept="image/*"/>
</Form.Group>
<Button variant="primary" type="submit">
Submit
</Button>
</Form>
</Row>
<Row className="mt-5">
<Col>
<ListGroup>
{loaderData.manufacturers.map((manu) => (
<ListGroup.Item key={manu.id}>
{manu.name} ({manu.country_id})
</ListGroup.Item>
))}
</ListGroup>
</Col>
</Row>
</Container>
);
}