import React, { useState, useMemo } from 'react' import { useTripStore } from '../../store/tripStore' import { useSettingsStore } from '../../store/settingsStore' import { useToast } from '../shared/Toast' import { useTranslation } from '../../i18n' import { Plane, Hotel, Utensils, Train, Car, Ship, Ticket, FileText, MapPin, Calendar, Hash, CheckCircle2, Circle, Pencil, Trash2, Plus, ChevronDown, ChevronRight, Users, ExternalLink, BookMarked, Lightbulb, Link2, Clock, } from 'lucide-react' const TYPE_OPTIONS = [ { value: 'flight', labelKey: 'reservations.type.flight', Icon: Plane, color: '#3b82f6' }, { value: 'hotel', labelKey: 'reservations.type.hotel', Icon: Hotel, color: '#8b5cf6' }, { value: 'restaurant', labelKey: 'reservations.type.restaurant', Icon: Utensils, color: '#ef4444' }, { value: 'train', labelKey: 'reservations.type.train', Icon: Train, color: '#06b6d4' }, { value: 'car', labelKey: 'reservations.type.car', Icon: Car, color: '#6b7280' }, { value: 'cruise', labelKey: 'reservations.type.cruise', Icon: Ship, color: '#0ea5e9' }, { value: 'event', labelKey: 'reservations.type.event', Icon: Ticket, color: '#f59e0b' }, { value: 'tour', labelKey: 'reservations.type.tour', Icon: Users, color: '#10b981' }, { value: 'other', labelKey: 'reservations.type.other', Icon: FileText, color: '#6b7280' }, ] function getType(type) { return TYPE_OPTIONS.find(t => t.value === type) || TYPE_OPTIONS[TYPE_OPTIONS.length - 1] } function buildAssignmentLookup(days, assignments) { const map = {} for (const day of (days || [])) { const da = (assignments?.[String(day.id)] || []).slice().sort((a, b) => a.order_index - b.order_index) for (const a of da) { if (!a.place) continue map[a.id] = { dayNumber: day.day_number, dayTitle: day.title, dayDate: day.date, placeName: a.place.name, startTime: a.place.place_time, endTime: a.place.end_time } } } return map } function ReservationCard({ r, tripId, onEdit, onDelete, files = [], onNavigateToFiles, assignmentLookup }) { const { toggleReservationStatus } = useTripStore() const toast = useToast() const { t, locale } = useTranslation() const timeFormat = useSettingsStore(s => s.settings.time_format) || '24h' const typeInfo = getType(r.type) const TypeIcon = typeInfo.Icon const confirmed = r.status === 'confirmed' const attachedFiles = files.filter(f => f.reservation_id === r.id) const linked = r.assignment_id ? assignmentLookup[r.assignment_id] : null const handleToggle = async () => { try { await toggleReservationStatus(tripId, r.id) } catch { toast.error(t('reservations.toast.updateError')) } } const handleDelete = async () => { if (!confirm(t('reservations.confirm.delete', { name: r.title }))) return try { await onDelete(r.id) } catch { toast.error(t('reservations.toast.deleteError')) } } const fmtDate = (str) => { const d = new Date(str) return d.toLocaleDateString(locale, { weekday: 'short', day: 'numeric', month: 'short' }) } const fmtTime = (str) => { const d = new Date(str) return d.toLocaleTimeString(locale, { hour: '2-digit', minute: '2-digit', hour12: timeFormat === '12h' }) } return (
{/* Header bar */}
{t(typeInfo.labelKey)} {r.title}
{/* Details */} {(r.reservation_time || r.confirmation_number || r.location || linked) && (
{/* Row 1: Date, Time, Code */} {(r.reservation_time || r.confirmation_number) && (
{r.reservation_time && (
{t('reservations.date')}
{fmtDate(r.reservation_time)}
)} {r.reservation_time && (
{t('reservations.time')}
{fmtTime(r.reservation_time)}
)} {r.confirmation_number && (
{t('reservations.confirmationCode')}
{r.confirmation_number}
)}
)} {/* Row 2: Location + Assignment */} {(r.location || linked) && (
{r.location && (
{t('reservations.locationAddress')}
{r.location}
)} {linked && (
{t('reservations.linkAssignment')}
{linked.dayTitle || t('dayplan.dayN', { n: linked.dayNumber })} — {linked.placeName} {linked.startTime ? ` · ${linked.startTime}${linked.endTime ? ' – ' + linked.endTime : ''}` : ''}
)}
)}
)} {/* Notes */} {r.notes && (
{t('reservations.notes')}
{r.notes}
)} {/* Files */} {attachedFiles.length > 0 && (
{t('files.title')}
{attachedFiles.map(f => ( {f.original_name} ))}
)}
) } function Section({ title, count, children, defaultOpen = true, accent }) { const [open, setOpen] = useState(defaultOpen) return (
{open &&
{children}
}
) } export default function ReservationsPanel({ tripId, reservations, days, assignments, files = [], onAdd, onEdit, onDelete, onNavigateToFiles }) { const { t, locale } = useTranslation() const [showHint, setShowHint] = useState(() => !localStorage.getItem('hideReservationHint')) const assignmentLookup = useMemo(() => buildAssignmentLookup(days, assignments), [days, assignments]) const allPending = reservations.filter(r => r.status !== 'confirmed') const allConfirmed = reservations.filter(r => r.status === 'confirmed') const total = reservations.length return (
{/* Header */}

{t('reservations.title')}

{total === 0 ? t('reservations.empty') : t('reservations.summary', { confirmed: allConfirmed.length, pending: allPending.length })}

{/* Content */}
{total === 0 ? (

{t('reservations.empty')}

{t('reservations.emptyHint')}

) : ( <> {allPending.length > 0 && (
{allPending.map(r => )}
)} {allConfirmed.length > 0 && (
{allConfirmed.map(r => )}
)} )}
) }