All files / src/components AttachmentList.tsx

100% Statements 6/6
100% Branches 14/14
100% Functions 3/3
100% Lines 5/5

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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              10x 1x       10x   6x               8x                                
import type { Attachment } from "../api";
import { api } from "../api";
import { formatFileSize } from "../email-sanitizer";
import { useAsync } from "../hooks";
import { PaperclipIcon } from "./Icons";
 
export function AttachmentList({ messageId }: { messageId: number }) {
	const { data: attachments, loading } = useAsync(
		() => api.messages.attachments(messageId),
		[messageId],
	);
 
	if (loading || !attachments || attachments.length === 0) return null;
 
	return (
		<div className="mt-3 pt-3 border-t border-gray-100 dark:border-gray-800">
			<p className="text-xs font-medium text-gray-500 dark:text-gray-400 mb-2 flex items-center gap-1.5">
				<PaperclipIcon className="w-3.5 h-3.5" />
				{attachments.length} attachment{attachments.length !== 1 ? "s" : ""}
			</p>
			<div className="flex flex-wrap gap-2">
				{attachments.map((att: Attachment) => (
					<a
						key={att.id}
						href={`/api/attachments/${att.id}`}
						download={att.filename ?? "attachment"}
						className="flex items-center gap-2 px-3 py-1.5 text-xs bg-gray-50 dark:bg-gray-800 hover:bg-gray-100 dark:hover:bg-gray-700 border border-gray-200 dark:border-gray-700 rounded-md transition-colors"
					>
						<span className="truncate max-w-[200px]">{att.filename ?? "attachment"}</span>
						{att.size != null && att.size > 0 && (
							<span className="text-gray-400 flex-shrink-0">{formatFileSize(att.size)}</span>
						)}
					</a>
				))}
			</div>
		</div>
	);
}