phx-react
Version:
PHX REACT
137 lines • 13.1 kB
JavaScript
import Image from 'next/image';
import React, { useEffect, useRef, useState } from 'react';
import { ButtonUpload } from './ButtonUpload';
import { classNames } from '../types';
import { PHXButton } from '../Button';
import { PHXSpinner } from '../Loading';
export function FormUpload({ actionTextDelete, customNextImage, disabled, fileName = '', fileType = 'excel', handleCheckboxChange, handleFileChange, helpText, isHorizontalLayout, isImage, label, length, link = [], oneImg, selectedImages = [], setIsModalOpen, showImage, twoColumn, }) {
const fileInputRef = useRef(null);
const [showLargeImage, setShowLargeImage] = useState(false);
const [largeImageUrl, setLargeImageUrl] = useState('');
const [file, setFile] = useState(fileName);
const [showMoreImage, setShowMoreImage] = useState(false);
const [loading, setLoading] = useState(false);
const showSelectedTitle = (selectedImages === null || selectedImages === void 0 ? void 0 : selectedImages.length) > 0;
const showButtonWithOneImage = (link === null || link === void 0 ? void 0 : link.length) > 0 && isImage && oneImg;
const listImage = !showMoreImage ? link === null || link === void 0 ? void 0 : link.slice(0, 10) : link;
const limitImageShow = 10;
const classCheckColumn = `grid gap-2 ${twoColumn ? 'xl:grid-cols-5 lg:grid-cols-3 grid-cols-6' : 'grid-cols-6'}`;
const handleUploadClick = () => {
if (fileInputRef.current) {
fileInputRef.current.click();
}
};
const handleAwaitUpdate = async (event) => {
try {
setLoading(true);
await handleFileChange(event);
}
catch (e) {
console.log(e);
}
finally {
setLoading(false);
if (showMoreImage) {
setShowMoreImage(false);
}
}
};
useEffect(() => {
const closeImageOnOutsideClick = (event) => {
if (showLargeImage) {
const clickedElement = event.target;
const imageContainer = document.getElementById('large-image-container');
if (!(imageContainer === null || imageContainer === void 0 ? void 0 : imageContainer.contains(clickedElement))) {
setShowLargeImage(false);
}
}
};
document.addEventListener('click', closeImageOnOutsideClick);
return () => {
document.removeEventListener('click', closeImageOnOutsideClick);
};
}, [showLargeImage]);
const handleImageClick = (url) => {
setLargeImageUrl(url);
setShowLargeImage(true);
};
useEffect(() => {
if (fileType === 'image') {
setFile(null);
}
else {
setFile(fileName);
}
}, [link]);
const renderFileInput = (className, id, ref) => (React.createElement("input", { ref: ref, accept: `${(fileType === 'excel' && '.xlsx, .xls') ||
(fileType === 'image' && '.jpg, .jpeg, .png, .gif, .webp') ||
(fileType === 'file' && '.pdf, .png,.jpg, .jpeg') ||
(fileType === 'pdf' && '.pdf')}`, className: className, id: id, name: id, onChange: handleAwaitUpdate, type: 'file' }));
return (React.createElement(React.Fragment, null,
React.createElement("div", { className: classNames('mb-1 flex text-xs font-normal text-gray-700', label ? 'justify-between' : '') }, label && React.createElement("label", null, label)),
showSelectedTitle && (React.createElement("div", { className: 'flex justify-between ' },
React.createElement("div", { className: '-pl-2 mb-4 text-xs leading-5 text-gray-600' },
length,
" \u1EA3nh \u0111\u00E3 \u0111\u01B0\u1EE3c ch\u1ECDn"),
actionTextDelete ? (React.createElement("div", { className: 'cursor-pointer text-xs font-normal text-red-700 hover:underline', onClick: () => setIsModalOpen === null || setIsModalOpen === void 0 ? void 0 : setIsModalOpen(true), onKeyDown: (e) => {
if (e.key === 'Enter' || e.key === ' ') {
setIsModalOpen === null || setIsModalOpen === void 0 ? void 0 : setIsModalOpen(true);
}
}, role: 'button', tabIndex: 0 }, "Xo\u00E1 \u1EA3nh")) : (React.createElement(PHXButton, { deleted: true, onClick: () => setIsModalOpen === null || setIsModalOpen === void 0 ? void 0 : setIsModalOpen(true), size: 'micro' }, "X\u00F3a")))),
React.createElement("div", { className: 'relative' },
isImage && (React.createElement("div", { className: `${oneImg ? 'flex justify-center rounded-lg bg-gray-100' : classCheckColumn}` }, listImage === null || listImage === void 0 ? void 0 :
listImage.map((src, index) => {
const isSelectImage = (selectedImages === null || selectedImages === void 0 ? void 0 : selectedImages.length) > 0;
return (React.createElement("div", { key: index, className: `group relative overflow-hidden ${!oneImg ? 'aspect-square rounded-[10px] border' : ''}` },
customNextImage ? (React.createElement("img", { alt: 'img', className: ` object-contain ${oneImg ? 'max-h-[180px]' : 'h-full w-full object-contain'} ${selectedImages.includes(index) ? 'opacity-60' : ''}`, height: (customNextImage === null || customNextImage === void 0 ? void 0 : customNextImage.height) || 180, src: src, width: (customNextImage === null || customNextImage === void 0 ? void 0 : customNextImage.width) || 400 })) : (React.createElement("img", { alt: 'img', className: ` object-contain ${oneImg ? 'max-h-[180px]' : 'h-full w-full object-contain'} ${selectedImages.includes(index) ? 'opacity-60' : ''}`, src: src })),
React.createElement("button", { className: `absolute inset-0 flex items-center justify-center bg-black text-white opacity-0 transition-opacity duration-300 group-hover:opacity-100 ${!oneImg ? 'bg-opacity-60' : 'bg-opacity-0'}`, onClick: () => {
if (isSelectImage) {
handleCheckboxChange === null || handleCheckboxChange === void 0 ? void 0 : handleCheckboxChange(index);
}
else {
handleImageClick(src);
}
}, type: 'button' }),
!oneImg && (React.createElement("div", { className: `z-8 absolute left-[0.3rem] top-0 opacity-0 ${(selectedImages === null || selectedImages === void 0 ? void 0 : selectedImages.length) > 0 ? 'opacity-100' : 'group-hover:opacity-100'}` },
React.createElement("input", { checked: selectedImages.includes(index), className: 'h-[16px] w-[16px] cursor-pointer rounded-[4px] text-black checked:bg-black checked:ring-0 focus:outline-none focus:ring-0', onChange: () => handleCheckboxChange === null || handleCheckboxChange === void 0 ? void 0 : handleCheckboxChange(index), type: 'checkbox' })))));
}),
!showMoreImage && link.length > limitImageShow && (React.createElement("div", { className: 'group relative aspect-square overflow-hidden rounded-lg border' },
React.createElement("img", { alt: 'img', className: 'mx-auto h-full object-cover', src: link === null || link === void 0 ? void 0 : link[limitImageShow + 1] }),
React.createElement("button", { className: 'absolute inset-0 flex items-center justify-center bg-black bg-opacity-60 text-white backdrop-blur-sm transition-opacity duration-300 ', onClick: () => setShowMoreImage(true), type: 'button' },
React.createElement("p", null,
"+",
((link === null || link === void 0 ? void 0 : link.length) || 0) - limitImageShow)))),
link.length > 0 && !oneImg && (React.createElement("button", { className: ' flex aspect-square items-center justify-center rounded-lg border border-dashed border-gray-300 bg-[#F7F7F7] transition-all hover:bg-[#f1f1f1]', onClick: handleUploadClick, type: 'button' }, loading ? (React.createElement(PHXSpinner, null)) : (React.createElement("svg", { className: 'h-5 w-5', fill: 'none', stroke: 'currentColor', strokeWidth: '1.5', viewBox: '0 0 24 24', xmlns: 'http://www.w3.org/2000/svg' },
React.createElement("path", { d: 'M12 4.5v15m7.5-7.5h-15', strokeLinecap: 'round', strokeLinejoin: 'round' }))))),
showLargeImage && (React.createElement("div", { className: 'fixed left-0 top-0 z-50 flex h-full w-full items-center justify-center bg-black bg-opacity-70', id: 'large-image-container', onClick: () => setShowLargeImage(false), onKeyDown: (e) => {
if (e.key === 'Enter' || e.key === ' ') {
setShowLargeImage(false);
}
}, role: 'button', tabIndex: 0 },
React.createElement(Image, { alt: 'Large Image', className: 'max-h-full max-w-full', onClick: (e) => e.stopPropagation(), src: largeImageUrl }))))),
showButtonWithOneImage && (React.createElement("div", { className: ' mt-3 flex gap-2 ' },
React.createElement(PHXButton, { disabled: disabled, loading: loading, onClick: handleUploadClick, secondary: true, size: 'micro' }, "Thay \u0111\u1ED5i"),
React.createElement(PHXButton, { deleted: true, onClick: () => setIsModalOpen === null || setIsModalOpen === void 0 ? void 0 : setIsModalOpen(true), size: 'micro' }, "Xo\u00E1 \u1EA3nh"))),
((link === null || link === void 0 ? void 0 : link.length) === 0 || isHorizontalLayout) && (React.createElement(React.Fragment, null, !file ? (React.createElement("div", { className: classNames('relative flex flex-col justify-center rounded-lg border border-dashed border-gray-900/25 px-5 pb-8 pt-8 ', disabled ? 'cursor-not-allowed' : 'cursor-pointer hover:bg-[#f7f7f7]') },
renderFileInput('absolute inset-0 z-10 h-full w-full cursor-pointer opacity-0'),
React.createElement("div", { className: 'flex flex-col items-center justify-center' },
React.createElement(ButtonUpload, { disabled: disabled, fileType: fileType, handleUploadClick: () => {
handleUploadClick();
}, helpText: helpText, loading: loading })))) : (React.createElement("div", { className: 'w-full' },
React.createElement("div", { className: 'mx-auto max-w-3xl px-5 pb-3 lg:max-w-full lg:px-0' },
React.createElement("div", { className: 'flex items-center justify-between rounded-lg border border-gray-200 bg-white shadow-[0rem_0.0825rem_0rem_#00000012]' },
React.createElement("div", { className: 'h-full bg-gray-200 p-6' },
React.createElement("svg", { "aria-hidden": 'true', className: 'h-5 w-5', focusable: 'false', viewBox: '0 0 20 20' },
React.createElement("path", { d: 'M6.75 4c-.69 0-1.25.56-1.25 1.25v9.5c0 .69.56 1.25 1.25 1.25h6.5c.69 0 1.25-.56 1.25-1.25v-9a.75.75 0 0 1 1.5 0v9a2.75 2.75 0 0 1-2.75 2.75h-6.5a2.75 2.75 0 0 1-2.75-2.75v-9.5a2.75 2.75 0 0 1 2.75-2.75h3a2.75 2.75 0 0 1 2.75 2.75v6.25a2.5 2.5 0 0 1-5 0v-5.5a.75.75 0 0 1 1.5 0v5.5a1 1 0 1 0 2 0v-6.25c0-.69-.56-1.25-1.25-1.25h-3Z', fillRule: 'evenodd' }))),
React.createElement("p", { className: 'w-[15ch] flex-1 truncate px-2 text-sm text-gray-600 sm:w-full md:w-[20ch]' }, fileName),
React.createElement("div", { className: 'pr-4' },
React.createElement(PHXButton, { disabled: disabled, loading: loading, onClick: handleUploadClick, secondary: true, size: 'micro' }, "Thay \u0111\u1ED5i")))))))),
(link === null || link === void 0 ? void 0 : link.length) > 0 && !isImage && !isHorizontalLayout && (React.createElement("div", { className: classNames('relative flex flex-col justify-center rounded-lg border border-dashed border-gray-900/25 px-5 pb-8 pt-8 ', disabled ? 'cursor-not-allowed' : 'cursor-pointer hover:bg-[#f7f7f7]') },
renderFileInput('absolute inset-0 z-10 h-full w-full cursor-pointer opacity-0'),
React.createElement("div", { className: 'flex flex-col items-center justify-center' }, fileType === 'file' && !showImage ? (React.createElement("div", { className: 'flex h-full items-center justify-center rounded-lg py-6 ' },
React.createElement(PHXSpinner, { className: 'h-5 w-5' }))) : (React.createElement(React.Fragment, null,
React.createElement("p", { className: 'mt-2 text-sm text-gray-600' }, fileName),
React.createElement(ButtonUpload, { disabled: disabled, fileType: fileType, handleUploadClick: handleUploadClick, helpText: helpText, loading: loading }))))))),
renderFileInput('sr-only', 'file-upload', fileInputRef)));
}
//# sourceMappingURL=FormUpload.js.map