UNPKG

phx-react

Version:

PHX REACT

137 lines • 13.1 kB
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