import { Trash2, ExternalLink, Download, MapPin, Ticket, StickyNote, Star, RotateCcw, Pencil } from 'lucide-react' import type { TripFile } from '../../types' import type { FileManagerState } from './useFileManager' import { TRANSPORT_TYPES } from './FileManager.constants' import { getFileIcon, isImage, formatSize, formatDateWithLocale, transportIcon, triggerDownload } from './FileManager.helpers' import { AuthedImg } from './FileManagerAuthedImg' import { AvatarChip } from './FileManagerAvatarChip' import { SourceBadge } from './FileManagerSourceBadge' export function FileRow(p: FileManagerState & { file: TripFile; isTrash?: boolean }) { const { file, isTrash = false, places, reservations, t, locale, can, trip, handleStar, handleRestore, handlePermanentDelete, handleDelete, openFile, setAssignFileId, } = p const FileIcon = getFileIcon(file.mime_type) const allLinkedPlaceIds = new Set() if (file.place_id) allLinkedPlaceIds.add(file.place_id) for (const pid of (file.linked_place_ids || [])) allLinkedPlaceIds.add(pid) const linkedPlaces = [...allLinkedPlaceIds].map(pid => places?.find(p => p.id === pid)).filter(Boolean) // All linked reservations (primary + file_links) const allLinkedResIds = new Set() if (file.reservation_id) allLinkedResIds.add(file.reservation_id) for (const rid of (file.linked_reservation_ids || [])) allLinkedResIds.add(rid) const linkedReservations = [...allLinkedResIds].map(rid => reservations?.find(r => r.id === rid)).filter(Boolean) return (
e.currentTarget.style.borderColor = 'var(--text-faint)'} onMouseLeave={e => e.currentTarget.style.borderColor = 'var(--border-primary)'} className="group" > {/* Icon or thumbnail */}
!isTrash && openFile(file)} style={{ flexShrink: 0, width: 36, height: 36, borderRadius: 8, background: 'var(--bg-tertiary)', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: isTrash ? 'default' : 'pointer', overflow: 'hidden', }} > {isImage(file.mime_type) ? : (() => { const ext = (file.original_name || '').split('.').pop()?.toUpperCase() || '?' const isPdf = file.mime_type === 'application/pdf' return (
{ext}
) })() }
{/* Info */}
{file.uploaded_by_name && ( )} {!isTrash && file.starred ? : null} !isTrash && openFile(file)} style={{ fontWeight: 500, fontSize: 13, color: 'var(--text-primary)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', cursor: isTrash ? 'default' : 'pointer' }} > {file.original_name}
{file.description && (

{file.description}

)}
{file.file_size && {formatSize(file.file_size)}} {formatDateWithLocale(file.created_at, locale)} {linkedPlaces.map(p => ( ))} {linkedReservations.map(r => ( TRANSPORT_TYPES.has(r.type) ? : ))} {file.note_id && ( )}
{/* Actions — always visible on mobile, hover on desktop */}
{isTrash ? ( <> {can('file_delete', trip) && } {can('file_delete', trip) && } ) : ( <> {can('file_edit', trip) && } {can('file_delete', trip) && } )}
) }