diff --git a/client/src/components/PDF/TripPDF.tsx b/client/src/components/PDF/TripPDF.tsx index 2ef5fdc7..1491a4cf 100644 --- a/client/src/components/PDF/TripPDF.tsx +++ b/client/src/components/PDF/TripPDF.tsx @@ -1,7 +1,7 @@ // Trip PDF via browser print window import { createElement } from 'react' import { getCategoryIcon } from '../shared/categoryIcons' -import { FileText, Info, Clock, MapPin, Navigation, Train, Plane, Bus, Car, Ship, Coffee, Ticket, Star, Heart, Camera, Flag, Lightbulb, AlertTriangle, ShoppingBag, Bookmark, Hotel, LogIn, LogOut, KeyRound, BedDouble, LucideIcon } from 'lucide-react' +import { FileText, Info, Clock, MapPin, Navigation, Train, Plane, Bus, Car, Ship, Coffee, Ticket, Star, Heart, Camera, Flag, Lightbulb, AlertTriangle, ShoppingBag, Bookmark, Hotel, LogIn, LogOut, KeyRound, BedDouble, Utensils, Users, LucideIcon } from 'lucide-react' import { accommodationsApi, mapsApi } from '../../api/client' import type { Trip, Day, Place, Category, AssignmentsMap, DayNotesMap } from '../../types' @@ -18,10 +18,12 @@ function noteIconSvg(iconId) { return renderLucideIcon(Icon, { size: 14, strokeWidth: 1.8, color: '#94a3b8' }) } -const TRANSPORT_ICON_MAP = { flight: Plane, train: Train, bus: Bus, car: Car, cruise: Ship } -function transportIconSvg(type) { - const Icon = TRANSPORT_ICON_MAP[type] || Ticket - return renderLucideIcon(Icon, { size: 14, strokeWidth: 1.8, color: '#3b82f6' }) +const RESERVATION_ICON_MAP = { flight: Plane, train: Train, bus: Bus, car: Car, cruise: Ship, restaurant: Utensils, event: Ticket, tour: Users, other: FileText } +const RESERVATION_COLOR_MAP = { flight: '#3b82f6', train: '#06b6d4', bus: '#6b7280', car: '#6b7280', cruise: '#0ea5e9', restaurant: '#ef4444', event: '#f59e0b', tour: '#10b981', other: '#6b7280' } +function reservationIconSvg(type) { + const Icon = RESERVATION_ICON_MAP[type] || Ticket + const color = RESERVATION_COLOR_MAP[type] || '#3b82f6' + return renderLucideIcon(Icon, { size: 14, strokeWidth: 1.8, color }) } const ACCOMMODATION_ICON_MAP = { accommodation: Hotel, checkin: LogIn, checkout: LogOut, location: MapPin, note: FileText, confirmation: KeyRound } @@ -144,19 +146,18 @@ export async function downloadTripPDF({ trip, days, places, assignments, categor const notes = (dayNotes || []).filter(n => n.day_id === day.id) const cost = dayCost(assignments, day.id, loc) - // Transport bookings for this day - const TRANSPORT_TYPES = new Set(['flight', 'train', 'bus', 'car', 'cruise']) - const dayTransport = (reservations || []).filter(r => { - if (!r.reservation_time || !TRANSPORT_TYPES.has(r.type)) return false + // Reservations for this day (hotel rendered via accommodations block) + const dayReservations = (reservations || []).filter(r => { + if (!r.reservation_time || r.type === 'hotel') return false return day.date && r.reservation_time.split('T')[0] === day.date }) const merged = [] assigned.forEach(a => merged.push({ type: 'place', k: a.order_index ?? a.sort_order ?? 0, data: a })) notes.forEach(n => merged.push({ type: 'note', k: n.sort_order ?? 0, data: n })) - dayTransport.forEach(r => { + dayReservations.forEach(r => { const pos = r.day_plan_position ?? (merged.length > 0 ? Math.max(...merged.map(m => m.k)) + 0.5 : 0.5) - merged.push({ type: 'transport', k: pos, data: r }) + merged.push({ type: 'reservation', k: pos, data: r }) }) merged.sort((a, b) => a.k - b.k) @@ -164,21 +165,27 @@ export async function downloadTripPDF({ trip, days, places, assignments, categor const itemsHtml = merged.length === 0 ? `