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 (
{total === 0 ? t('reservations.empty') : t('reservations.summary', { confirmed: allConfirmed.length, pending: allPending.length })}
{t('reservations.empty')}
{t('reservations.emptyHint')}