101 lines
3.8 KiB
TypeScript
101 lines
3.8 KiB
TypeScript
/**
|
|
* File: AttachmentDisplay.tsx
|
|
* Created by: AI Assistant
|
|
* Date: 2025-11-29
|
|
* Purpose: Component to display file attachments
|
|
* Part of: kreatiVortex - Platform Pembelajaran Tari Online
|
|
*/
|
|
|
|
'use client';
|
|
|
|
import React from 'react';
|
|
|
|
interface Attachment {
|
|
id: string;
|
|
name: string;
|
|
originalName: string;
|
|
mimeType: string;
|
|
size: number;
|
|
url: string;
|
|
}
|
|
|
|
interface AttachmentDisplayProps {
|
|
attachments: Attachment[];
|
|
}
|
|
|
|
export default function AttachmentDisplay({ attachments }: AttachmentDisplayProps) {
|
|
if (!attachments || attachments.length === 0) {
|
|
return null;
|
|
}
|
|
|
|
const getFileIcon = (mimeType: string) => {
|
|
if (mimeType.includes('pdf')) {
|
|
return (
|
|
<svg className="w-4 h-4 text-red-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0015.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" />
|
|
</svg>
|
|
);
|
|
}
|
|
if (mimeType.includes('word') || mimeType.includes('document')) {
|
|
return (
|
|
<svg className="w-4 h-4 text-blue-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
|
|
</svg>
|
|
);
|
|
}
|
|
if (mimeType.includes('image')) {
|
|
return (
|
|
<svg className="w-4 h-4 text-green-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" />
|
|
</svg>
|
|
);
|
|
}
|
|
return (
|
|
<svg className="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
|
|
</svg>
|
|
);
|
|
};
|
|
|
|
const formatFileSize = (bytes: number): string => {
|
|
if (bytes === 0) return '0 Bytes';
|
|
|
|
const k = 1024;
|
|
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
|
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
};
|
|
|
|
return (
|
|
<div className="mt-3 space-y-2">
|
|
<p className="text-sm font-medium text-gray-300 mb-2">Lampiran:</p>
|
|
<div className="space-y-2">
|
|
{attachments.map((attachment) => (
|
|
<a
|
|
key={attachment.id}
|
|
href={attachment.url}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className="flex items-center space-x-3 p-3 bg-white/5 rounded-lg border border-white/10 hover:bg-white/10 transition-colors group"
|
|
>
|
|
<div className="flex-shrink-0">
|
|
{getFileIcon(attachment.mimeType)}
|
|
</div>
|
|
<div className="flex-1 min-w-0">
|
|
<p className="text-sm text-white font-medium truncate group-hover:text-gold-400 transition-colors">
|
|
{attachment.originalName}
|
|
</p>
|
|
<p className="text-xs text-gray-400">{formatFileSize(attachment.size)}</p>
|
|
</div>
|
|
<div className="flex-shrink-0">
|
|
<svg className="w-4 h-4 text-gray-400 group-hover:text-gold-400 transition-colors" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" />
|
|
</svg>
|
|
</div>
|
|
</a>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
} |