import { CloudUpload, UploadIcon, X } from "lucide-react"; import { useCallback, useState } from "react"; import toast from "react-hot-toast"; import { Credenza, CredenzaBody, CredenzaContent, CredenzaDescription, CredenzaHeader, CredenzaTitle, CredenzaTrigger, } from "~/components/custom_ui/credenza"; import { FileUpload, FileUploadDropzone, FileUploadItem, FileUploadItemDelete, FileUploadItemMetadata, FileUploadItemPreview, FileUploadItemProgress, FileUploadList, FileUploadTrigger, } from "~/components/custom_ui/fileUpload"; import { Button } from "~/components/ui/button"; import { Upload } from "~/lib/storage_manager"; import { useTranslation } from "~/providers/I18nProvider"; import type { StorageindexId } from "~/schemas/public/Storageindex"; import type { UsersId } from "~/schemas/public/Users"; import { api } from "~/utils/api"; type UploadModalProps = { cb_onUpload?: () => void; isAdmin?: boolean; userId?: UsersId; }; export const UploadModal = ({ cb_onUpload, isAdmin, userId, }: UploadModalProps) => { const { t } = useTranslation(); return ( {t.allegati.carica_nuovi} Allegati modal ); }; type UploadComponentProps = { cb_onUpload?: () => void; isAdmin?: boolean; userId?: UsersId; maxMB?: number; maxFiles?: number; }; export const UploadComponent = ({ cb_onUpload, isAdmin, userId, maxMB = 5, // Default max size is 5MB maxFiles, }: UploadComponentProps) => { const { t } = useTranslation(); const [files, setFiles] = useState([]); const [isUploading, setIsUploading] = useState(false); const { mutateAsync: getToken } = api.storage.getStorageTokenM.useMutation(); const { mutate: setUserStorage } = api.storage.addUserStorage.useMutation({ onMutate: () => { toast(t.allegati.allegato_caricato, { icon: "📤" }); }, onSettled: async () => { await utils.storage.getAll.invalidate(); await utils.storage.getUserStorage.invalidate({ userId, }); }, }); const acceptedMimeTypes = [ "image/jpeg", // jpg, jpeg "image/png", // png "image/webp", // webp "text/plain", // txt "application/pdf", // pdf "application/msword", // doc "application/vnd.openxmlformats-officedocument.wordprocessingml.document", // docx "application/vnd.ms-excel", // xls "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", // xlsx "application/vnd.oasis.opendocument.text", // odt "application/vnd.oasis.opendocument.spreadsheet", // ods ]; const utils = api.useUtils(); const onFileReject = useCallback((file: File, message: string) => { toast( `${message}\n\n"${file.name.length > 15 ? `${file.name.slice(0, 15)}...` : file.name}" ${t.allegati.file_rejected}`, ); }, []); const onFileValidate = useCallback( (file: File): string | null => { if (maxFiles) { // Validate max files if (files.length >= maxFiles) { return `${t.allegati.file_too_many} ${maxFiles}`; } } // Validate file type if (!acceptedMimeTypes.includes(file.type)) { return t.allegati.invalid_file_type; } if (maxMB) { // Validate file size const MAX_SIZE = maxMB * 1024 * 1024; if (file.size > MAX_SIZE) { return `${t.allegati.file_too_large} ${MAX_SIZE / (1024 * 1024)}MB`; } } return null; }, [files], ); const onUpload = useCallback( async ( files: File[], { onProgress, }: { onProgress: (file: File, progress: number) => void; }, ) => { try { setIsUploading(true); const { status, attachments } = await Upload({ files: files, getToken, from_admin: isAdmin ?? true, }); if (userId) { for (const storageId of attachments) { setUserStorage({ userId, fileId: storageId as StorageindexId, }); } } files.forEach((file) => { const randomDelay = Math.random() * 1000 + 500; // Random delay between 500ms and 1500ms let progress = 0; const interval = setInterval(() => { progress += Math.random() * 10; // Increment progress randomly if (progress >= 100) { progress = 100; clearInterval(interval); } onProgress(file, progress); }, randomDelay / 1); // Adjust interval based on random delay }); if (!status) { toast.error(t.allegati.errore_caricamento, { icon: "❌", }); setIsUploading(false); return; } toast.success(t.allegati.success_caricamento, { icon: "✅", }); } catch (error) { setIsUploading(false); toast.error( error instanceof Error ? error.message : t.allegati.errore_sconosciuto, ); } finally { setIsUploading(false); setFiles([]); cb_onUpload?.(); await utils.storage.getAll.invalidate(); } }, [], ); return (

{t.allegati.drag_drop}

{t.allegati.oppure}

{files.map((file, index) => ( ))}
); };