import { useApp } from "../../../hooks"; import clsx from "clsx"; import { ReactNode, useEffect, useState } from "react"; import { MediaDto } from "../../../application/dtos/entities/MediaDto"; import { FileBase64 } from "../../../application/dtos/shared/FileBase64"; import PreviewMediaModal from "../media/PreviewMediaModal"; import HintTooltip from "../tooltips/HintTooltip"; import MediaItem from "../uploaders/MediaItem"; import UploadDocuments from "../uploaders/UploadDocument"; import { updateItemByIdx } from "../../../utils/shared/ObjectUtils"; type RowMedia = any; interface Props { name: string; title?: string; initialMedia?: RowMedia[] | MediaDto[] | undefined; disabled?: boolean; onSelected?: (item: MediaDto[]) => void; className?: string; readOnly?: boolean; required?: boolean; min?: number; max?: number; accept?: string; hint?: ReactNode; help?: string; icon?: string; maxSize?: number; uploadText?: string; autoFocus?: boolean; } export default function InputMedia({ name, title, initialMedia, disabled, onSelected, className, readOnly, required, min, max, accept, hint, help, icon, maxSize, uploadText, autoFocus, }: Props) { const { t } = useApp(); const [error, setError] = useState(undefined); const [items, setItems] = useState(initialMedia ?? []); const [selectedItem, setSelectedItem] = useState(); useEffect(() => { if (onSelected) { onSelected(items); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [items]); function deleteMedia(idx: number) { setItems(items.filter((_f, index) => index !== idx)); } function onDroppedFiles(e: FileBase64[]) { setError(undefined); if (max) { if (e.length + items.length > max) { setError("Maximun number of files exceeded: " + max); return; } } if (maxSize) { const bytesToMegaBytes = (bytes: number) => bytes / (1024 * 1024); const found = e.find((f) => bytesToMegaBytes(f.file.size) > maxSize); if (found) { setError(`Max size is ${maxSize} MB, found ${bytesToMegaBytes(found.file.size).toFixed(2)}`); return; } } if (accept?.includes(".")) { const acceptedFileExtensions = accept.split(","); const invalidFiles = e.map((f) => { let foundExtension = ""; acceptedFileExtensions .filter((f) => f) .forEach((element) => { if (f.file.name.toLowerCase().endsWith(element.toLowerCase())) { foundExtension = element; } }); if (!foundExtension) { return f; } return null; }); if (invalidFiles.find((f) => f !== null)) { setError("Invalid file type: " + accept); return; } } const newAttachments: MediaDto[] = [...items]; e.forEach(({ file, base64 }) => { newAttachments.push({ title: file.name.split(".").slice(0, -1).join("."), file: base64, name: file.name, type: file.type, // _file: file, }); }); setItems(newAttachments); } function preview(item: MediaDto) { setSelectedItem(item); } function download(item: MediaDto) { const downloadLink = document.createElement("a"); downloadLink.href = item.publicUrl ?? item.file; downloadLink.download = item.name; downloadLink.click(); } function isDisabled() { return disabled || readOnly; } return (
{/* */} {!isDisabled() && items.length === 0 && ( )} {isDisabled() && items.length === 0 && (

{t("shared.files.noFilesUploaded")}

)} {items.map((item, idx) => { return ; })} {items.length > 0 ? (
{items.map((item, idx) => { return ( updateItemByIdx(items, setItems, idx, { title, name: title + "." + item.name.split(".").slice(-1)[0], }) } onDelete={() => deleteMedia(idx)} readOnly={isDisabled()} onDownload={() => download(item)} onPreview={item.type.includes("pdf") || item.type.includes("image") ? () => preview(item) : undefined} /> ); })}
) : (
)} {isDisabled() && items.filter((f) => f.type.includes("image")).length > 0 && (
{items .filter((f) => f.type.includes("image")) .map((item) => { return (
{item.title}
); })}
)}
{selectedItem && setSelectedItem(undefined)} onDownload={() => download(selectedItem)} />}
); }