import React, { useEffect, useMemo, useRef } from 'react' import { Check, MapPin } from 'lucide-react' import type { CollectionPlace, CollectionStatus, CollectionLabel } from '@trek/shared' import type { TranslationFn } from '../../types' import PlaceAvatar from '../shared/PlaceAvatar' import { getCategoryIcon } from '../shared/categoryIcons' import StatusBadge from './StatusBadge' interface CollectionListProps { places: CollectionPlace[] labels: CollectionLabel[] selectedPlaceId: number | null selectMode: boolean selectedIds: number[] onOpenPlace: (id: number) => void onStatusChange?: (placeId: number, status: CollectionStatus) => void onToggleSelect: (id: number) => void t: TranslationFn } /** * List view — one glass row per saved place with a photo avatar, name + * category/address, and a one-tap status cycle on the badge. Click the row to * open the place (or toggle it in select mode). */ export default function CollectionList({ places, labels, selectedPlaceId, selectMode, selectedIds, onOpenPlace, onStatusChange, onToggleSelect, t, }: CollectionListProps): React.ReactElement { const labelsById = useMemo(() => new Map(labels.map(l => [l.id, l])), [labels]) // Bring the selected row into view — e.g. when it was picked from the map. const selectedRef = useRef(null) useEffect(() => { selectedRef.current?.scrollIntoView({ behavior: 'smooth', block: 'nearest' }) }, [selectedPlaceId]) return (
{places.map(place => { const selected = selectedIds.includes(place.id) const active = selectedPlaceId === place.id const placeLabels = (place.label_ids ?? []).map(id => labelsById.get(id)).filter(Boolean) as CollectionLabel[] return (
(selectMode ? onToggleSelect(place.id) : onOpenPlace(place.id))} onKeyDown={e => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); if (selectMode) onToggleSelect(place.id); else onOpenPlace(place.id) } }} className={`col-lrow${active || selected ? ' sel' : ''}`} > {selectMode ? ( {selected && } ) : ( )}
{place.name}
{place.address && (
{place.address}
)}
{placeLabels.slice(0, 2).map(l => ( {l.name} ))} {placeLabels.length > 2 && l.name).join(', ')}>+{placeLabels.length - 2}} {place.category?.name && (() => { const CatIcon = getCategoryIcon(place.category.icon ?? undefined) return ( <> {place.category.name} ) })()} onStatusChange(place.id, next)} t={t} />
) })}
) }