Added uploading of image with warehouse artefact logging
This commit is contained in:
parent
5ae30b4178
commit
74aea1a86a
@ -1,14 +1,22 @@
|
|||||||
import { NextRequest, NextResponse } from "next/server";
|
import { NextRequest, NextResponse } from "next/server";
|
||||||
import { apiAuthMiddleware } from "@utils/apiAuthMiddleware";
|
import { apiAuthMiddleware } from "@utils/apiAuthMiddleware";
|
||||||
import { prisma } from "@utils/prisma";
|
import { prisma } from "@utils/prisma";
|
||||||
|
import { writeFile } from "fs/promises";
|
||||||
|
import { join } from "path";
|
||||||
|
|
||||||
export async function POST(request: NextRequest) {
|
export async function POST(request: NextRequest) {
|
||||||
try {
|
try {
|
||||||
const body = await request.json();
|
const formData = await request.formData();
|
||||||
const { name, type, description, location, earthquakeCode, warehouseLocation } = body;
|
const name = formData.get("name") as string;
|
||||||
|
const type = formData.get("type") as string;
|
||||||
|
const description = formData.get("description") as string;
|
||||||
|
const location = formData.get("location") as string;
|
||||||
|
const earthquakeCode = formData.get("earthquakeCode") as string;
|
||||||
|
const warehouseLocation = formData.get("warehouseLocation") as string;
|
||||||
|
const image = formData.get("image") as File | null;
|
||||||
|
|
||||||
const authResult = await apiAuthMiddleware();
|
const authResult = await apiAuthMiddleware();
|
||||||
if ("user" in authResult === false) return authResult; // Handle error response
|
if ("user" in authResult === false) return authResult;
|
||||||
|
|
||||||
const { user } = authResult;
|
const { user } = authResult;
|
||||||
|
|
||||||
@ -22,6 +30,15 @@ export async function POST(request: NextRequest) {
|
|||||||
return NextResponse.json({ error: "Earthquake code not found" }, { status: 400 });
|
return NextResponse.json({ error: "Earthquake code not found" }, { status: 400 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let imageName = "NoImageFound.PNG";
|
||||||
|
if (image) {
|
||||||
|
const buffer = Buffer.from(await image.arrayBuffer());
|
||||||
|
const extension = image.type === "image/jpeg" ? "jpg" : "png";
|
||||||
|
imageName = `${name}-${new Date().toLocaleDateString("en-GB")}.${extension}`;
|
||||||
|
const imagePath = join(process.cwd(), "public", "uploads", imageName);
|
||||||
|
await writeFile(imagePath, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
await prisma.artefact.create({
|
await prisma.artefact.create({
|
||||||
data: {
|
data: {
|
||||||
name,
|
name,
|
||||||
@ -29,7 +46,7 @@ export async function POST(request: NextRequest) {
|
|||||||
description,
|
description,
|
||||||
earthquakeId: linkedEarthquake.id,
|
earthquakeId: linkedEarthquake.id,
|
||||||
warehouseArea: warehouseLocation,
|
warehouseArea: warehouseLocation,
|
||||||
imageName: "NoImageFound.PNG",
|
imageName,
|
||||||
creatorId: user.id,
|
creatorId: user.id,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@ -77,7 +77,6 @@ function FilterInput({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Modal Component for Logging Artefact
|
|
||||||
function LogModal({ onClose }: { onClose: () => void }) {
|
function LogModal({ onClose }: { onClose: () => void }) {
|
||||||
const [name, setName] = useState("");
|
const [name, setName] = useState("");
|
||||||
const [type, setType] = useState("");
|
const [type, setType] = useState("");
|
||||||
@ -88,6 +87,7 @@ function LogModal({ onClose }: { onClose: () => void }) {
|
|||||||
const [isRequired, setIsRequired] = useState(true);
|
const [isRequired, setIsRequired] = useState(true);
|
||||||
const [error, setError] = useState("");
|
const [error, setError] = useState("");
|
||||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||||
|
const [image, setImage] = useState<File | null>(null);
|
||||||
|
|
||||||
const handleOverlayClick = (e: { target: any; currentTarget: any }) => {
|
const handleOverlayClick = (e: { target: any; currentTarget: any }) => {
|
||||||
if (e.target === e.currentTarget) {
|
if (e.target === e.currentTarget) {
|
||||||
@ -95,7 +95,21 @@ function LogModal({ onClose }: { onClose: () => void }) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// todo add uploading image
|
const handleImageChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
if (e.target.files && e.target.files[0]) {
|
||||||
|
const file = e.target.files[0];
|
||||||
|
if (file.size > 5 * 1024 * 1024) {
|
||||||
|
setError("Image size must be less than 5MB");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!["image/jpeg", "image/png"].includes(file.type)) {
|
||||||
|
setError("Only JPEG or PNG images are allowed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setImage(file);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
async function handleLog() {
|
async function handleLog() {
|
||||||
if (!name || !type || !description || !location || !earthquakeCode || !warehouseLocation) {
|
if (!name || !type || !description || !location || !earthquakeCode || !warehouseLocation) {
|
||||||
setError("All fields are required.");
|
setError("All fields are required.");
|
||||||
@ -107,13 +121,19 @@ function LogModal({ onClose }: { onClose: () => void }) {
|
|||||||
}
|
}
|
||||||
setIsSubmitting(true);
|
setIsSubmitting(true);
|
||||||
try {
|
try {
|
||||||
await axios.post("/api/warehouse/log", {
|
const formData = new FormData();
|
||||||
name,
|
formData.append("name", name);
|
||||||
type,
|
formData.append("type", type);
|
||||||
description,
|
formData.append("description", description);
|
||||||
location,
|
formData.append("location", location);
|
||||||
earthquakeCode,
|
formData.append("earthquakeCode", earthquakeCode);
|
||||||
warehouseLocation,
|
formData.append("warehouseLocation", warehouseLocation);
|
||||||
|
if (image) {
|
||||||
|
formData.append("image", image);
|
||||||
|
}
|
||||||
|
|
||||||
|
await axios.post("/api/warehouse/log", formData, {
|
||||||
|
headers: { "Content-Type": "multipart/form-data" },
|
||||||
});
|
});
|
||||||
|
|
||||||
alert(`Logged ${name} to storage: ${warehouseLocation}`);
|
alert(`Logged ${name} to storage: ${warehouseLocation}`);
|
||||||
@ -187,6 +207,14 @@ function LogModal({ onClose }: { onClose: () => void }) {
|
|||||||
aria-label="Storage Location"
|
aria-label="Storage Location"
|
||||||
disabled={isSubmitting}
|
disabled={isSubmitting}
|
||||||
/>
|
/>
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
accept="image/jpeg,image/png"
|
||||||
|
onChange={handleImageChange}
|
||||||
|
className="w-full p-2 border border-neutral-300 rounded-md placeholder-neutral-400 focus:ring-2 focus:ring-blue-500"
|
||||||
|
aria-label="Artefact Image"
|
||||||
|
disabled={isSubmitting}
|
||||||
|
/>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
@ -357,6 +385,8 @@ function EditModal({ artefact, onClose }: { artefact: ExtendedArtefact; onClose:
|
|||||||
const [error, setError] = useState("");
|
const [error, setError] = useState("");
|
||||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||||
|
|
||||||
|
// todo add display of image
|
||||||
|
|
||||||
const handleOverlayClick = (e: { target: any; currentTarget: any }) => {
|
const handleOverlayClick = (e: { target: any; currentTarget: any }) => {
|
||||||
if (e.target === e.currentTarget) {
|
if (e.target === e.currentTarget) {
|
||||||
onClose();
|
onClose();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user