import { format } from "date-fns"; import { Download, File, FileArchive, FileAudio, FileCode, FileSpreadsheet, FileText, FileVideo, ImageIcon, MoreVertical, Pencil, Trash2, TriangleAlert, } from "lucide-react"; import Link from "next/link"; import { type FormEvent, useState } from "react"; import toast from "react-hot-toast"; import Input from "~/components/custom_ui/input"; import { LoadingPage } from "~/components/loading"; import { Status500 } from "~/components/status-page"; import { Button } from "~/components/ui/button"; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, } from "~/components/ui/dialog"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "~/components/ui/dropdown-menu"; import { Separator } from "~/components/ui/separator"; import { UploadModal } from "~/components/upload_modal"; import { cn } from "~/lib/utils"; import { useTranslation } from "~/providers/I18nProvider"; import type { UsersId } from "~/schemas/public/Users"; import type { FileMetadata } from "~/server/services/storage.service"; import { api } from "~/utils/api"; export const AllegatiComp = ({ userId, isAdmin, }: { userId: UsersId; isAdmin: boolean; }) => { const { t } = useTranslation(); const { data: allegati, isLoading: isLoadingAllegati } = api.storage.retrieveUserFileData.useQuery({ userId }); const { mutate: deleteFile } = api.storage.deleteUserStorageEntry.useMutation( { onMutate: () => { const toastId = toast.loading(t.caricamento, { icon: "🪛", }); return { toastId }; }, onSuccess: async (_error, _variables, context) => { await utils.storage.retrieveUserFileData.invalidate({ userId: userId, }); toast.success(t.allegati.allegato_rimosso, { icon: "🗑️", id: context?.toastId, }); }, }, ); const { mutate: renameFile } = api.storage.renameFile.useMutation({ onMutate: () => { setEditOpen(false); const toastId = toast.loading(t.caricamento, { icon: "🪛", }); return { toastId }; }, onSuccess: async (_error, _variables, context) => { await utils.storage.retrieveUserFileData.invalidate({ userId: userId, }); toast.success(t.successo, { icon: "👍", id: context?.toastId, }); }, }); const [editData, setEditData] = useState<{ id: string; filename: string; } | null>(null); const [editOpen, setEditOpen] = useState(false); const handleEditSubmit = (e: FormEvent) => { e.preventDefault(); const form = e.currentTarget; const formData = new FormData(form); if (!formData.get("id") || !formData.get("filename")) { return; } renameFile({ fileId: formData.get("id") as string, name: formData.get("filename") as string, }); }; const utils = api.useUtils(); if (isLoadingAllegati) return ; if (!allegati) return ; const from_admin = allegati.filter((a) => a.from_admin); const not_from_admin = allegati.filter((a) => !a.from_admin); return (

{t.allegati.title}

{t.allegati.da_info}

{from_admin && ( deleteFile({ storageId: id, userId })} files={from_admin} isAdmin={isAdmin} selectHandler={(id, filename) => { setEditData({ filename, id }); setEditOpen(true); }} /> )}
{" "} Max 5 MB per file
{t.importante}:
{t.allegati.disclamer}
{not_from_admin && ( deleteFile({ storageId: id, userId })} files={not_from_admin} isAdmin={isAdmin} selectHandler={(id, filename) => { setEditData({ filename, id }); setEditOpen(true); }} /> )}
); }; export const ExtIcon = ({ mimeType, className, }: { mimeType: string; className?: string; }) => { const lower = mimeType?.toLowerCase() || ""; if (!lower) return ; // PDF if (lower.includes("pdf")) { return ; } // Images if ( lower.startsWith("image/") || /\b(jpg|jpeg|png|gif|svg|webp)\b/.test(lower) ) { return ; } // Code files if (/\b(html|css|js|jsx|ts|tsx|json|xml)\b/.test(lower)) { return ; } // Spreadsheets if (/\b(xls|xlsx|csv)\b/.test(lower)) { return ( ); } // Archives if (/\b(zip|rar|7z|tar|gz)\b/.test(lower)) { return ; } // Audio if (/\b(mp3|wav|ogg|flac)\b/.test(lower)) { return ; } // Video if (/\b(mp4|avi|mov|wmv|webm)\b/.test(lower)) { return ; } return ; }; const EditFileDialog = ({ open, onOpenChange, data, handleEditSubmit, }: { open: boolean; onOpenChange: (status: boolean) => void; data: { id: string; filename: string; } | null; handleEditSubmit: (e: FormEvent) => void; }) => { const { t } = useTranslation(); return ( {t.modifica} Edit {data && (
)}
); }; interface FileListProps { files: FileMetadata[]; delete_onClick: (id: string) => void; isAdmin: boolean; selectHandler: (id: string, filename: string) => void; } function FileList({ files, delete_onClick, isAdmin, selectHandler, }: FileListProps) { return (
File
Data
Azioni
{files.map((file) => (
{file.originalName}
{format(new Date(file.uploadedAt), "d MMM yyyy")}
{isAdmin && ( selectHandler(file.id, file.originalName || "") } > Rinomina delete_onClick(file.id)} > Elimina )}
))}
); }