Added warehouse edit api call and image displaying

This commit is contained in:
Tim Howitz 2025-06-06 18:18:49 +01:00
parent 4df13145eb
commit 127c69cb1e

View File

@ -1,4 +1,5 @@
"use client";
import Image from "next/image";
import axios from "axios";
import useSWR from "swr";
import { Dispatch, SetStateAction, useMemo, useState } from "react";
@ -80,7 +81,7 @@ function FilterInput({
// Modal Component for Bulk Logging
function BulkLogModal({ onClose }: { onClose: () => void }) {
const [palletNote, setPalletNote] = useState("");
const [warehouseLocation, setWarehouseLocation] = useState("");
const [warehouseArea, setWarehouseArea] = useState("");
const [error, setError] = useState("");
const [isSubmitting, setIsSubmitting] = useState(false);
@ -91,7 +92,7 @@ function BulkLogModal({ onClose }: { onClose: () => void }) {
};
async function handleLog() {
if (!palletNote || !warehouseLocation) {
if (!palletNote || !warehouseArea) {
setError("All fields are required.");
return;
}
@ -99,10 +100,10 @@ function BulkLogModal({ onClose }: { onClose: () => void }) {
try {
await axios.post("/api/warehouse/log-bulk", {
palletNote,
warehouseLocation,
warehouseArea,
});
alert(`Logged bulk pallet to storage: ${warehouseLocation}`);
alert(`Logged bulk pallet to storage: ${warehouseArea}`);
onClose();
} catch {
setError("Failed to log pallet. Please try again.");
@ -130,11 +131,11 @@ function BulkLogModal({ onClose }: { onClose: () => void }) {
/>
<input
type="text"
placeholder="Storage Location (e.g., B-05)"
value={warehouseLocation}
onChange={(e) => setWarehouseLocation(e.target.value)}
placeholder="Warehouse Area (e.g., B-05)"
value={warehouseArea}
onChange={(e) => setWarehouseArea(e.target.value)}
className="w-full p-2 border border-neutral-300 rounded-md placeholder-neutral-400 focus:ring-2 focus:ring-blue-500"
aria-label="Storage Location"
aria-label="Warehouse Area"
disabled={isSubmitting}
/>
</div>
@ -185,7 +186,7 @@ function LogModal({ onClose }: { onClose: () => void }) {
const [type, setType] = useState("");
const [description, setDescription] = useState("");
const [earthquakeCode, setEarthquakeCode] = useState("");
const [warehouseLocation, setWarehouseLocation] = useState("");
const [warehouseArea, setWarehouseArea] = useState("");
const [isRequired, setIsRequired] = useState(true);
const [error, setError] = useState("");
const [isSubmitting, setIsSubmitting] = useState(false);
@ -213,7 +214,7 @@ function LogModal({ onClose }: { onClose: () => void }) {
};
async function handleLog() {
if (!name || !type || !description || !earthquakeCode || !warehouseLocation) {
if (!name || !type || !description || !earthquakeCode || !warehouseArea) {
setError("All fields are required.");
return;
}
@ -228,7 +229,7 @@ function LogModal({ onClose }: { onClose: () => void }) {
formData.append("type", type);
formData.append("description", description);
formData.append("earthquakeCode", earthquakeCode);
formData.append("warehouseLocation", warehouseLocation);
formData.append("warehouseArea", warehouseArea);
if (image) {
formData.append("image", image);
}
@ -237,7 +238,7 @@ function LogModal({ onClose }: { onClose: () => void }) {
headers: { "Content-Type": "multipart/form-data" },
});
alert(`Logged ${name} to storage: ${warehouseLocation}`);
alert(`Logged ${name} to storage: ${warehouseArea}`);
onClose();
} catch {
setError("Failed to log artefact. Please try again.");
@ -301,11 +302,11 @@ function LogModal({ onClose }: { onClose: () => void }) {
/>
<input
type="text"
placeholder="Warehouse Location (e.g., A-12)"
value={warehouseLocation}
onChange={(e) => setWarehouseLocation(e.target.value)}
placeholder="Warehouse Area (e.g., A-12)"
value={warehouseArea}
onChange={(e) => setWarehouseArea(e.target.value)}
className="w-full p-2 border border-neutral-300 rounded-md placeholder-neutral-400 focus:ring-2 focus:ring-blue-500"
aria-label="Storage Location"
aria-label="Warehouse Area"
disabled={isSubmitting}
/>
<div className="flex items-center gap-2">
@ -362,12 +363,11 @@ function LogModal({ onClose }: { onClose: () => void }) {
);
}
// Modal Component for Editing Artefact
function EditModal({ artefact, onClose }: { artefact: ExtendedArtefact; onClose: () => void }) {
const [name, setName] = useState(artefact.name);
const [type, setType] = useState("");
const [type, setType] = useState(artefact.type);
const [description, setDescription] = useState(artefact.description);
const [warehouseLocation, setWarehouseLocation] = useState("");
const [warehouseArea, setWarehouseArea] = useState(artefact.warehouseArea);
const [earthquakeCode, setEarthquakeCode] = useState(artefact.earthquakeCode);
const [isRequired, setIsRequired] = useState(artefact.isRequired);
const [isSold, setIsSold] = useState(artefact.isSold);
@ -376,9 +376,6 @@ function EditModal({ artefact, onClose }: { artefact: ExtendedArtefact; onClose:
const [error, setError] = useState("");
const [isSubmitting, setIsSubmitting] = useState(false);
// todo add display of image in public dir at /artefact.imageName
// todo add display of artefact.createdAt date
function handleOverlayClick(e: { target: any; currentTarget: any }) {
if (e.target === e.currentTarget) {
onClose();
@ -386,7 +383,7 @@ function EditModal({ artefact, onClose }: { artefact: ExtendedArtefact; onClose:
}
async function handleSave() {
if (!name || !type || !description || !earthquakeCode || !warehouseLocation) {
if (!name || !type || !description || !earthquakeCode || !warehouseArea) {
setError("All fields are required.");
return;
}
@ -396,8 +393,24 @@ function EditModal({ artefact, onClose }: { artefact: ExtendedArtefact; onClose:
}
setIsSubmitting(true);
try {
// todo add api route
await new Promise((resolve) => setTimeout(resolve, 500)); // Simulated API call
const formData = new FormData();
formData.append("id", artefact.id.toString());
formData.append("name", name);
formData.append("type", type);
formData.append("description", description);
formData.append("earthquakeCode", earthquakeCode);
formData.append("warehouseArea", warehouseArea);
formData.append("isRequired", isRequired.toString());
formData.append("isSold", isSold.toString());
formData.append("isCollected", isCollected.toString());
if (image) {
formData.append("image", image);
}
await axios.post("/api/warehouse/edit-artefact", formData, {
headers: { "Content-Type": "multipart/form-data" },
});
alert(`Updated artefact ${name}`);
onClose();
} catch {
@ -431,6 +444,17 @@ function EditModal({ artefact, onClose }: { artefact: ExtendedArtefact; onClose:
<h3 className="text-lg font-semibold mb-4 text-neutral-800">Edit Artefact</h3>
{error && <p className="text-red-600 text-sm mb-2">{error}</p>}
<div className="space-y-2">
{artefact.imageName && (
<div className="mb-2">
<Image
src={`/uploads/${artefact.imageName}`}
alt="Artefact"
width={200}
height={200}
className="object-cover rounded-md"
/>
</div>
)}
<input
type="file"
accept="image/jpeg,image/png"
@ -439,7 +463,7 @@ function EditModal({ artefact, onClose }: { artefact: ExtendedArtefact; onClose:
aria-label="Artefact Image"
disabled={isSubmitting}
/>
<p className="text-sm text-neutral-600">Created At: {new Date(artefact.createdAt).toLocaleDateString("en-GB")}</p>
<input
type="text"
placeholder="Name"
@ -477,14 +501,13 @@ function EditModal({ artefact, onClose }: { artefact: ExtendedArtefact; onClose:
/>
<input
type="text"
placeholder="Warehouse Location (e.g., A-12)"
value={warehouseLocation}
onChange={(e) => setWarehouseLocation(e.target.value)}
placeholder="Warehouse Area (e.g., A-12)"
value={warehouseArea}
onChange={(e) => setWarehouseArea(e.target.value)}
className="w-full p-2 border border-neutral-300 rounded-md placeholder-neutral-400 focus:ring-2 focus:ring-blue-500"
aria-label="Storage Location"
disabled={isSubmitting}
/>
<div className="flex items-center gap-2">
<input
type="checkbox"