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 { Tooltip } from '../shared/Tooltip' 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 (
{/* Icon or thumbnail */} {/* Info */}
{file.uploaded_by_name && ( )} {!isTrash && file.starred ? : null}
{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) && handleRestore(file.id)}>} {can('file_delete', trip) && handlePermanentDelete(file.id)}>} ) : ( <> handleStar(file.id)}> {can('file_edit', trip) && setAssignFileId(file.id)}>} openFile(file)}> triggerDownload(file.url, file.original_name)}> {can('file_delete', trip) && handleDelete(file.id)}>} )}
) } const STAR_ON = 'text-[#facc15]' // theme-lint-disable: the star keeps its gold const TONE_HOVER = { plain: 'hover:text-content', success: 'hover:text-success', danger: 'hover:text-danger', star: 'hover:text-[#facc15]' } as const // theme-lint-disable: the star keeps its gold /** A small action at the end of a file row, named by its tooltip. */ function RowAction({ label, onClick, tone = 'plain', active = false, children }: { label: string; onClick: () => void; tone?: keyof typeof TONE_HOVER; active?: boolean; children: React.ReactNode }) { return ( ) }