Files
beer-inventory/app/routes/admin/manage/inventory.tsx
T
kennyboy55 c816af19a5
Build dev docker image / build (push) Successful in 43s
Build dev docker image / release (push) Successful in 1s
AI Changes: new scan page, add inventory filter
2026-08-03 12:48:09 +02:00

91 lines
3.2 KiB
TypeScript

import type { ActionFunctionArgs, LoaderFunctionArgs } from "@remix-run/node";
import { json } from "@remix-run/node";
import { useMemo, useState } from "react";
import { useLoaderData } from "@remix-run/react";
import { Button, Form } from "react-bootstrap";
import { containerTypeToString } from "~/models/types";
import { volume } from '~/utils/conversions';
import { enhance } from "~/utils/db.server";
export async function loader({
params,
request
}: LoaderFunctionArgs) {
const { dbe } = await enhance(request);
const containers = await dbe.container.findMany({select: {id: true, drink: true, type: true, inventory: true, volume: true}, orderBy: {drink: {name: "asc"}}});
return json({ containers });
};
export async function action({
request,
}: ActionFunctionArgs) {
const { dbe } = await enhance(request);
const form = await request.formData();
const containerid = Number(form.get("id"));
let inventory = Number(form.get("inventory"));
if(inventory <= 0) inventory = 0;
const currentContainer = await dbe.container.findUnique({where: {id: containerid}, select: {inventory: true}});
const shouldSetLastAdded = currentContainer != null && inventory > currentContainer.inventory;
await dbe.container.update({
data: {
inventory: inventory,
lastAdded: shouldSetLastAdded ? new Date() : undefined,
},
where: {id: containerid}
});
return null;
};
export default function EditInventoryRoute() {
const lData = useLoaderData<typeof loader>();
const [search, setSearch] = useState("");
const filteredContainers = useMemo(() => {
const searchText = search.trim().toLowerCase();
if (!searchText) return lData.containers;
return lData.containers.filter((container) => {
const label = `${container.drink.name} ${containerTypeToString(container.type)} ${container.inventory}`.toLowerCase();
return label.includes(searchText);
});
}, [lData.containers, search]);
return (
<div>
<h2>Update inventory</h2>
<Form method="post">
<Form.Group className='mb-2'>
<Form.Label>Filter containers</Form.Label>
<Form.Control
type="search"
value={search}
onChange={(event) => setSearch(event.currentTarget.value)}
placeholder="Type drink name, type or inventory"
autoComplete="off"
/>
</Form.Group>
<Form.Group className='mb-2'>
<Form.Label>Drink container</Form.Label>
<Form.Select name="id">
{ filteredContainers.map((container) => (
<option key={container.id} value={container.id}>{container.drink.name} - {containerTypeToString(container.type)} - {volume(container.volume)} ({container.inventory})</option>
))}
</Form.Select>
</Form.Group>
<Form.Group className='mb-2'>
<Form.Label>New inventory amount</Form.Label>
<Form.Control name="inventory" type="number" min={0} max={50} step={1} />
</Form.Group>
<Button type="submit">Submit</Button>
</Form>
</div>
);
}