diff --git a/frontend/src/components/FileList.tsx b/frontend/src/components/FileList.tsx index ccb3b20..9df0b70 100644 --- a/frontend/src/components/FileList.tsx +++ b/frontend/src/components/FileList.tsx @@ -1,5 +1,6 @@ -import { useRef } from "react"; +import { useRef, useState } from "react"; import { toast } from "sonner"; +import { Eye, Download, Trash2, X, FileText, Image as ImageIcon, ExternalLink } from "lucide-react"; import type { Attachment } from "../lib/types"; export interface FileListProps { @@ -14,9 +15,18 @@ export interface FileListProps { label?: string; } -// مدیریت چند فاکتور: آپلود مستقیم به سرور (MinIO) + دانلود/حذف فایل‌های ذخیره‌شده +const isImageFile = (name: string = "") => { + return /\.(jpe?g|png|webp|gif|svg|bmp)$/i.test(name.toLowerCase()); +}; + +const isPdfFile = (name: string = "") => { + return /\.pdf$/i.test(name.toLowerCase()); +}; + +// مدیریت چند فاکتور: آپلود مستقیم، پیش‌نمایش آنلاین تصویر/PDF و دانلود export function FileList({ files, onChange, upload, onDelete, urlOf, label = "افزودن فاکتور" }: FileListProps) { const inputRef = useRef(null); + const [previewItem, setPreviewItem] = useState<{ url: string; name: string } | null>(null); const remove = (i: number) => { const removed = files[i]; @@ -39,22 +49,94 @@ export function FileList({ files, onChange, upload, onDelete, urlOf, label = "ا if (added.length) onChange([...files, ...added]); }; + const handleOpenPreview = (inv: Attachment) => { + const url = urlOf?.(inv); + if (!url) { + toast.error("فایل هنوز به طور کامل در سرور ذخیره نشده است"); + return; + } + setPreviewItem({ url, name: inv.name }); + }; + return ( -
- {!files.length &&
هنوز فایلی انتخاب نشده است.
} - {files.map((inv, i) => ( -
- 📎 {inv.name} - {urlOf?.(inv) && ( - - ↓ - - )} - +
+ {!files.length && ( +
+ هنوز فاکتور یا سندی بارگذاری نشده است.
- ))} + )} + + {files.length > 0 && ( +
+ {files.map((inv, i) => { + const url = urlOf?.(inv); + const isImg = isImageFile(inv.name); + const isPdf = isPdfFile(inv.name); + + return ( +
+ {/* نام و آیکون فایل — با قابلیت کلیک برای پیش‌نمایش */} +
url && handleOpenPreview(inv)} + title={url ? "مشاهده پیش‌نمایش" : inv.name} + > + {isImg ? ( + + ) : isPdf ? ( + + ) : ( + + )} + + {inv.name} + +
+ + {/* دکمه‌های عملیات: پیش‌نمایش، دانلود مستقیم، حذف */} +
+ {url && ( + <> + + + + + + + )} + + +
+
+ ); + })} +
+ )} +
-
+ + {/* پنجره مودال پیش‌نمایش (Preview Modal) */} + {previewItem && ( +
setPreviewItem(null)} + > +
e.stopPropagation()} + > + {/* هدر پیش‌نمایش */} +
+
+ {isImageFile(previewItem.name) ? ( + + ) : ( + + )} + + {previewItem.name} + +
+ +
+ + + دانلود فاکتور + + + + + + + +
+
+ + {/* بدنه نمایش فایل */} +
+ {isImageFile(previewItem.name) ? ( + {previewItem.name} + ) : isPdfFile(previewItem.name) ? ( +