105 lines
3.1 KiB
TypeScript
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>
|
|
);
|
|
}
|