Compare commits

..

2 Commits

Author SHA1 Message Date
a0f5a2f1de Added warehouse EditModal image edit overlay 2025-06-06 20:24:30 +01:00
5c17c8df0f Improved EditModal styling 2025-06-06 19:59:39 +01:00

View File

@ -1,5 +1,6 @@
"use client"; "use client";
import Image from "next/image"; import Image from "next/image";
import { useRef } from "react";
import axios from "axios"; import axios from "axios";
import useSWR from "swr"; import useSWR from "swr";
import { Dispatch, SetStateAction, useMemo, useState } from "react"; import { Dispatch, SetStateAction, useMemo, useState } from "react";
@ -373,8 +374,10 @@ function EditModal({ artefact, onClose }: { artefact: ExtendedArtefact; onClose:
const [isSold, setIsSold] = useState(artefact.isSold); const [isSold, setIsSold] = useState(artefact.isSold);
const [isCollected, setIsCollected] = useState(artefact.isCollected); const [isCollected, setIsCollected] = useState(artefact.isCollected);
const [image, setImage] = useState<File | null>(null); const [image, setImage] = useState<File | null>(null);
const [previewImage, setPreviewImage] = useState<string | null>(null);
const [error, setError] = useState(""); const [error, setError] = useState("");
const [isSubmitting, setIsSubmitting] = useState(false); const [isSubmitting, setIsSubmitting] = useState(false);
const fileInputRef = useRef<HTMLInputElement>(null);
function handleOverlayClick(e: { target: any; currentTarget: any }) { function handleOverlayClick(e: { target: any; currentTarget: any }) {
if (e.target === e.currentTarget) { if (e.target === e.currentTarget) {
@ -432,82 +435,126 @@ function EditModal({ artefact, onClose }: { artefact: ExtendedArtefact; onClose:
return; return;
} }
setImage(file); setImage(file);
setPreviewImage(URL.createObjectURL(file));
} }
} }
function handleRemoveImage() {
setImage(null);
setPreviewImage(null);
if (fileInputRef.current) {
fileInputRef.current.value = "";
}
}
function handleEditClick() {
fileInputRef.current?.click();
}
return ( return (
<div <div
className="fixed inset-0 bg-neutral-900 bg-opacity-50 flex justify-center items-center z-50" className="fixed inset-0 bg-neutral-900 bg-opacity-50 flex justify-center items-center z-50"
onClick={handleOverlayClick} onClick={handleOverlayClick}
> >
<div className="bg-white rounded-lg shadow-xl max-w-md w-full p-6 border border-neutral-300"> <div className="bg-white rounded-lg shadow-xl max-w-lg w-full p-6 border border-neutral-300">
<h3 className="text-lg font-semibold mb-4 text-neutral-800">Edit Artefact</h3> <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>} {error && <p className="text-red-600 text-sm mb-2">{error}</p>}
<div className="space-y-2"> <div className="space-y-2">
{artefact.imageName && ( {(artefact.imageName || previewImage) && (
<div className="mb-2"> <div className="mb-2 flex justify-center">
<Image <div className="relative group">
src={`/artefactImages/${artefact.imageName || "NoImageFound.PNG"}`} <Image
alt="Artefact" src={previewImage || `/artefactImages/${artefact.imageName || "NoImageFound.PNG"}`}
width={200} alt="Artefact"
height={200} width={200}
className="object-cover mx-auto rounded-md" height={200}
/> className="object-contain rounded-md"
/>
<div className="absolute inset-0 bg-black bg-opacity-50 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center rounded-md">
{previewImage ? (
<button onClick={handleRemoveImage} className="text-white text-2xl" aria-label="Remove Image">
</button>
) : (
<button onClick={handleEditClick} className="text-white text-2xl" aria-label="Edit Image">
</button>
)}
</div>
</div>
</div> </div>
)} )}
<input <div>
type="file" <input
accept="image/jpeg,image/png" type="file"
onChange={handleImageChange} accept="image/jpeg,image/png"
className="w-full p-2 border border-neutral-300 rounded-md placeholder-neutral-400 focus:ring-2 focus:ring-blue-500" onChange={handleImageChange}
aria-label="Artefact Image" className="hidden"
disabled={isSubmitting} aria-label="Artefact Image"
/> disabled={isSubmitting}
ref={fileInputRef}
/>
</div>
<p className="text-sm text-neutral-600">Created At: {new Date(artefact.createdAt).toLocaleDateString("en-GB")}</p> <p className="text-sm text-neutral-600">Created At: {new Date(artefact.createdAt).toLocaleDateString("en-GB")}</p>
<input <div>
type="text" <label className="text-sm font-medium text-neutral-600">Name</label>
placeholder="Name" <input
value={name} type="text"
onChange={(e) => setName(e.target.value)} placeholder="Name"
className="w-full p-2 border border-neutral-300 rounded-md placeholder-neutral-400 focus:ring-2 focus:ring-blue-500" value={name}
aria-label="Artefact Name" onChange={(e) => setName(e.target.value)}
disabled={isSubmitting} className="w-full p-2 border border-neutral-300 rounded-md placeholder-neutral-400 focus:ring-2 focus:ring-blue-500"
/> aria-label="Artefact Name"
<input disabled={isSubmitting}
type="text" />
placeholder="Type (e.g., Lava, Tephra, Ash)" </div>
value={type} <div>
onChange={(e) => setType(e.target.value)} <label className="text-sm font-medium text-neutral-600">Type</label>
className="w-full p-2 border border-neutral-300 rounded-md placeholder-neutral-400 focus:ring-2 focus:ring-blue-500" <input
aria-label="Artefact Type" type="text"
disabled={isSubmitting} placeholder="Type (e.g., Lava, Tephra, Ash)"
/> value={type}
<textarea onChange={(e) => setType(e.target.value)}
placeholder="Description" className="w-full p-2 border border-neutral-300 rounded-md placeholder-neutral-400 focus:ring-2 focus:ring-blue-500"
value={description} aria-label="Artefact Type"
onChange={(e) => setDescription(e.target.value)} disabled={isSubmitting}
className="w-full p-2 border border-neutral-300 rounded-md placeholder-neutral-400 focus:ring-2 focus:ring-blue-500 h-16" />
aria-label="Artefact Description" </div>
disabled={isSubmitting} <div>
/> <label className="text-sm font-medium text-neutral-600">Description</label>
<input <textarea
type="text" placeholder="Description"
placeholder="Earthquake Code (e.g., EC-3.9-Belgium-05467)" value={description}
value={earthquakeCode} onChange={(e) => setDescription(e.target.value)}
onChange={(e) => setEarthquakeCode(e.target.value)} className="w-full p-2 border border-neutral-300 rounded-md placeholder-neutral-400 focus:ring-2 focus:ring-blue-500 h-16"
className="w-full p-2 border border-neutral-300 rounded-md placeholder-neutral-400 focus:ring-2 focus:ring-blue-500" aria-label="Artefact Description"
aria-label="Earthquake ID" disabled={isSubmitting}
disabled={isSubmitting} />
/> </div>
<input <div>
type="text" <label className="text-sm font-medium text-neutral-600">Earthquake Code</label>
placeholder="Warehouse Area (e.g., A-12)" <input
value={warehouseArea} type="text"
onChange={(e) => setWarehouseArea(e.target.value)} placeholder="Earthquake Code (e.g., EC-3.9-Belgium-05467)"
className="w-full p-2 border border-neutral-300 rounded-md placeholder-neutral-400 focus:ring-2 focus:ring-blue-500" value={earthquakeCode}
aria-label="Storage Location" onChange={(e) => setEarthquakeCode(e.target.value)}
disabled={isSubmitting} className="w-full p-2 border border-neutral-300 rounded-md placeholder-neutral-400 focus:ring-2 focus:ring-blue-500"
/> aria-label="Earthquake ID"
disabled={isSubmitting}
/>
</div>
<div>
<label className="text-sm font-medium text-neutral-600">Warehouse Area</label>
<input
type="text"
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>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<input <input
type="checkbox" type="checkbox"