import { useState, useEffect } from 'react' import { attachmentService, Attachment } from '../services/attachments' interface AttachmentListProps { taskId: string onRefresh?: () => void } export function AttachmentList({ taskId, onRefresh }: AttachmentListProps) { const [attachments, setAttachments] = useState([]) const [loading, setLoading] = useState(true) const [deleting, setDeleting] = useState(null) useEffect(() => { loadAttachments() }, [taskId]) const loadAttachments = async () => { setLoading(true) try { const response = await attachmentService.listAttachments(taskId) setAttachments(response.attachments) } catch (error) { console.error('Failed to load attachments:', error) } finally { setLoading(false) } } const handleDownload = async (attachment: Attachment) => { try { await attachmentService.downloadAttachment(attachment.id) } catch (error) { console.error('Failed to download attachment:', error) alert('Failed to download file') } } const handleDelete = async (attachment: Attachment) => { if (!confirm(`Are you sure you want to delete "${attachment.filename}"?`)) { return } setDeleting(attachment.id) try { await attachmentService.deleteAttachment(attachment.id) setAttachments(prev => prev.filter(a => a.id !== attachment.id)) onRefresh?.() } catch (error) { console.error('Failed to delete attachment:', error) alert('Failed to delete file') } finally { setDeleting(null) } } if (loading) { return
Loading attachments...
} if (attachments.length === 0) { return
No attachments
} return (
{attachments.map((attachment) => (
{attachmentService.getFileIcon(attachment.mime_type)}
{attachment.filename}
{attachmentService.formatFileSize(attachment.file_size)} {attachment.current_version > 1 && ( v{attachment.current_version} )} by {attachment.uploader_name || 'Unknown'}
))}
) } const styles: Record = { container: { display: 'flex', flexDirection: 'column', gap: '8px', }, item: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '12px', backgroundColor: '#f8f9fa', borderRadius: '8px', border: '1px solid #e9ecef', }, itemInfo: { display: 'flex', alignItems: 'center', gap: '12px', flex: 1, minWidth: 0, }, icon: { fontSize: '24px', }, details: { flex: 1, minWidth: 0, }, filename: { fontWeight: 500, fontSize: '14px', color: '#212529', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', }, meta: { fontSize: '12px', color: '#6c757d', display: 'flex', gap: '8px', marginTop: '2px', }, version: { backgroundColor: '#e9ecef', padding: '1px 6px', borderRadius: '4px', fontSize: '11px', }, uploader: { fontStyle: 'italic', }, actions: { display: 'flex', gap: '8px', }, downloadBtn: { padding: '6px 12px', backgroundColor: '#007bff', color: 'white', border: 'none', borderRadius: '4px', fontSize: '12px', cursor: 'pointer', }, deleteBtn: { padding: '6px 12px', backgroundColor: '#dc3545', color: 'white', border: 'none', borderRadius: '4px', fontSize: '12px', cursor: 'pointer', }, loading: { padding: '16px', textAlign: 'center', color: '#6c757d', }, empty: { padding: '16px', textAlign: 'center', color: '#6c757d', fontSize: '14px', }, } export default AttachmentList