metms_fe/src/components/utils/UploadMultipleFile/UploadMultipleFile.tsx
2026-05-24 23:33:43 +07:00

105 lines
3.1 KiB
TypeScript

"use client";
import React from "react";
import Image from "next/image";
import { X, CirclePlus } from "lucide-react";
import clsx from "clsx";
import { PropsUploadMultipleFile } from "./interface";
export default function UploadMultipleFile({
images = [],
setImages,
isDisableDelete = false,
}: PropsUploadMultipleFile) {
// 👉 upload files
const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const files = event.target.files;
if (!files) return;
const newImages = Array.from(files).map((file) => ({
url: URL.createObjectURL(file),
file,
}));
setImages((prev: any) => [...prev, ...newImages]);
};
// 👉 delete file
const handleDelete = (index: number) => {
setImages((prev: any) => {
const target = prev[index];
if (target?.url) URL.revokeObjectURL(target.url);
return prev.filter((_: any, i: number) => i !== index);
});
};
return (
<div className="flex items-center flex-wrap gap-2">
{/* LIST IMAGE */}
{images?.length > 0 && (
<div className="flex items-center flex-wrap gap-2">
{images.map((image, index) => (
<div
key={index}
className="relative w-[72px] h-[72px] rounded-md border border-[#99a2b34d] overflow-hidden select-none"
>
<Image
src={
image?.url ||
`${process.env.NEXT_PUBLIC_IMAGE}/${image?.path}`
}
alt="image"
fill
className="object-cover"
/>
{/* DELETE BUTTON */}
{isDisableDelete && !image?.file && image?.img ? null : (
<div
onClick={() => handleDelete(index)}
className="absolute top-[2px] right-[2px] w-[18px] h-[18px] bg-white rounded-sm flex items-center justify-center cursor-pointer transition active:scale-90"
>
<X size={14} color="#8496AC" />
</div>
)}
</div>
))}
</div>
)}
{/* UPLOAD BUTTON */}
<div className="flex items-center gap-2">
<label
className={clsx(
"flex items-center justify-center",
"w-[72px] h-[72px] rounded-md border cursor-pointer bg-white",
"border-[#99a2b34d] hover:border-gray-400 transition",
)}
>
<CirclePlus color="rgba(198, 201, 206, 1)" />
<input
hidden
type="file"
multiple
accept="image/png, image/jpeg, image/gif"
onClick={(e) => {
(e.target as HTMLInputElement).value = "";
}}
onChange={handleFileChange}
/>
</label>
{/* NOTE */}
<div className="flex flex-col">
<p className="text-[14px] font-medium text-[#2f3643]">Upload file</p>
<p className="text-[12px] font-medium text-[#99a2b3]">
File không vượt quá 50MB
</p>
</div>
</div>
</div>
);
}