Spaces:
Running
Running
File size: 4,292 Bytes
4bae792 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | import { FiFile, FiDownload, FiImage } from "react-icons/fi";
/**
* FileAttachment component - displays file attachments in messages
* Supports PDF, images, and other file types
*/
function FileAttachment({ attachment, isDark, onDownload }) {
const { name, type, url } = attachment;
// Handle click to download/view
const handleClick = () => {
if (onDownload) {
onDownload(attachment);
} else if (url) {
window.open(url, "_blank");
}
};
// Render image attachment
if (type === "image") {
return (
<div
className="mt-2 rounded-lg overflow-hidden border cursor-pointer max-w-md"
style={{
background: "var(--card-bg)",
borderColor: "var(--border-primary)",
}}
onClick={handleClick}
>
<div className="relative">
<img
src={url}
alt={name}
className="w-full h-auto object-cover max-h-80"
onError={(e) => {
e.target.style.display = "none";
const parent = e.target.parentElement;
if (parent) {
const errorDiv = document.createElement("div");
errorDiv.className =
"w-full h-40 flex items-center justify-center";
errorDiv.style.background = "var(--bg-surface-tertiary)";
errorDiv.innerHTML =
'<span style="color: var(--text-secondary); font-size: 0.875rem;">Không thể tải ảnh</span>';
parent.appendChild(errorDiv);
}
}}
/>
</div>
</div>
);
}
// Render PDF attachment
if (type === "pdf") {
return (
<div
className=" flex items-center gap-3 mt-2 px-3 py-3 border rounded-lg cursor-pointer max-w-md transition-colors"
style={{
background: isDark ? "var(--bg-surface-tertiary)" : "#fef2f2",
borderColor: "var(--border-primary)",
}}
onClick={handleClick}
>
<div
className="flex items-center justify-center w-10 h-10 rounded-lg shrink-0"
style={{
background: "#ef4444",
color: "#fff",
}}
>
<FiFile size={18} />
</div>
<div className="flex-1 min-w-0">
<div
className="text-sm font-medium truncate"
style={{ color: "var(--text-primary)" }}
>
{name}
</div>
<div
className="text-xs mt-0.5"
style={{ color: "var(--text-secondary)" }}
>
PDF Document
</div>
</div>
<FiDownload
size={16}
style={{ color: "var(--text-secondary)", flexShrink: 0 }}
/>
</div>
);
}
// Render other file types
return (
<div
className="flex items-center gap-3 mt-2 px-3 py-3 border rounded-lg cursor-pointer max-w-md transition-colors"
style={{
background: "var(--card-bg)",
borderColor: "var(--border-primary)",
}}
onClick={handleClick}
onMouseEnter={(e) => {
e.currentTarget.style.borderColor = "var(--primary)";
}}
onMouseLeave={(e) => {
e.currentTarget.style.borderColor = "var(--border-primary)";
}}
>
<div
className="flex items-center justify-center w-10 h-10 rounded-lg shrink-0"
style={{
background: isDark ? "var(--bg-surface-secondary)" : "#e5e7eb",
color: "var(--text-secondary)",
}}
>
<FiFile size={18} />
</div>
<div className="flex-1 min-w-0">
<div
className="text-sm font-medium truncate"
style={{ color: "var(--text-primary)" }}
>
{name}
</div>
<div
className="text-xs mt-0.5"
style={{ color: "var(--text-secondary)" }}
>
{getFileExtension(name)}
</div>
</div>
<FiDownload
size={16}
style={{ color: "var(--text-secondary)", flexShrink: 0 }}
/>
</div>
);
}
/**
* Get file extension from filename
*/
function getFileExtension(filename) {
const ext = filename.split(".").pop().toUpperCase();
return `${ext} File`;
}
export default FileAttachment;
|