diff --git a/client/src/components/Planner/DayDetailPanel.tsx b/client/src/components/Planner/DayDetailPanel.tsx
index 49cd6ff8..e841abde 100644
--- a/client/src/components/Planner/DayDetailPanel.tsx
+++ b/client/src/components/Planner/DayDetailPanel.tsx
@@ -1,6 +1,6 @@
import React, { useState, useEffect } from 'react'
import ReactDOM from 'react-dom'
-import { X, Sun, Cloud, CloudRain, CloudSnow, CloudDrizzle, CloudLightning, Wind, Droplets, Sunrise, Sunset, Hotel, Calendar, MapPin, LogIn, LogOut, Hash, Pencil, Plane, Utensils, Train, Car, Ship, Ticket, FileText, Users } from 'lucide-react'
+import { X, Sun, Cloud, CloudRain, CloudSnow, CloudDrizzle, CloudLightning, Wind, Droplets, Sunrise, Sunset, Hotel, Calendar, MapPin, LogIn, LogOut, Hash, Pencil, Plane, Utensils, Train, Car, Ship, Ticket, FileText, Users, ChevronsDown, ChevronsUp } from 'lucide-react'
const RES_TYPE_ICONS = { flight: Plane, hotel: Hotel, restaurant: Utensils, train: Train, car: Car, cruise: Ship, event: Ticket, tour: Users, other: FileText }
const RES_TYPE_COLORS = { flight: '#3b82f6', hotel: '#8b5cf6', restaurant: '#ef4444', train: '#06b6d4', car: '#6b7280', cruise: '#0ea5e9', event: '#f59e0b', tour: '#10b981', other: '#6b7280' }
@@ -54,9 +54,11 @@ interface DayDetailPanelProps {
onAccommodationChange: () => void
leftWidth?: number
rightWidth?: number
+ collapsed?: boolean
+ onToggleCollapse?: () => void
}
-export default function DayDetailPanel({ day, days, places, categories = [], tripId, assignments, reservations = [], lat, lng, onClose, onAccommodationChange, leftWidth = 0, rightWidth = 0 }: DayDetailPanelProps) {
+export default function DayDetailPanel({ day, days, places, categories = [], tripId, assignments, reservations = [], lat, lng, onClose, onAccommodationChange, leftWidth = 0, rightWidth = 0, collapsed: collapsedProp = false, onToggleCollapse }: DayDetailPanelProps) {
const { t, language, locale } = useTranslation()
const can = useCanDo()
const tripObj = useTripStore((s) => s.trip)
@@ -66,6 +68,8 @@ export default function DayDetailPanel({ day, days, places, categories = [], tri
const blurCodes = useSettingsStore(s => s.settings.blur_booking_codes)
const fmtTime = (v) => formatTime12(v, is12h)
const unit = isFahrenheit ? '°F' : '°C'
+ const collapsed = collapsedProp
+ const toggleCollapse = () => onToggleCollapse?.()
const [weather, setWeather] = useState(null)
const [loading, setLoading] = useState(false)
const [accommodation, setAccommodation] = useState(null)
@@ -170,26 +174,36 @@ export default function DayDetailPanel({ day, days, places, categories = [], tri
WebkitBackdropFilter: 'blur(40px) saturate(180%)',
borderRadius: 20,
boxShadow: '0 8px 40px rgba(0,0,0,0.14), 0 0 0 1px rgba(0,0,0,0.06)',
- overflow: 'hidden', maxHeight: '60vh', display: 'flex', flexDirection: 'column',
+ overflow: 'hidden', maxHeight: collapsed ? 'none' : '60vh', display: 'flex', flexDirection: 'column',
}}>
{/* Header */}
-
-
-
+
toggleCollapse()}>
+
+
-
+
{day.title || t('planner.dayN', { n: (days.indexOf(day) + 1) || '?' })}
+ {collapsed && formattedDate && {formattedDate}}
- {formattedDate &&
{formattedDate}
}
+ {!collapsed && formattedDate &&
{formattedDate}
}
-
{/* Scrollable content */}
-
+
{/* ── Weather ── */}
{day.date && lat && lng && (
diff --git a/client/src/pages/TripPlannerPage.tsx b/client/src/pages/TripPlannerPage.tsx
index 365131ee..139c05cb 100644
--- a/client/src/pages/TripPlannerPage.tsx
+++ b/client/src/pages/TripPlannerPage.tsx
@@ -154,6 +154,7 @@ export default function TripPlannerPage(): React.ReactElement | null {
const { leftWidth, rightWidth, leftCollapsed, rightCollapsed, setLeftCollapsed, setRightCollapsed, startResizeLeft, startResizeRight } = useResizablePanels()
const { selectedPlaceId, selectedAssignmentId, setSelectedPlaceId, selectAssignment } = usePlaceSelection()
const [showDayDetail, setShowDayDetail] = useState
(null)
+ const [dayDetailCollapsed, setDayDetailCollapsed] = useState(false)
const [showPlaceForm, setShowPlaceForm] = useState(false)
const [editingPlace, setEditingPlace] = useState(null)
const [prefillCoords, setPrefillCoords] = useState<{ lat: number; lng: number; name?: string; address?: string } | null>(null)
@@ -766,6 +767,8 @@ export default function TripPlannerPage(): React.ReactElement | null {
onAccommodationChange={loadAccommodations}
leftWidth={isMobile ? 0 : (leftCollapsed ? 0 : leftWidth)}
rightWidth={isMobile ? 0 : (rightCollapsed ? 0 : rightWidth)}
+ collapsed={dayDetailCollapsed}
+ onToggleCollapse={() => setDayDetailCollapsed(c => !c)}
/>
)
})()}
diff --git a/server/src/services/budgetService.ts b/server/src/services/budgetService.ts
index 36927c2e..8fc82240 100644
--- a/server/src/services/budgetService.ts
+++ b/server/src/services/budgetService.ts
@@ -14,12 +14,13 @@ export function verifyTripAccess(tripId: string | number, userId: number) {
}
function loadItemMembers(itemId: number | string) {
- return db.prepare(`
+ const rows = db.prepare(`
SELECT bm.user_id, bm.paid, u.username, u.avatar
FROM budget_item_members bm
JOIN users u ON bm.user_id = u.id
WHERE bm.budget_item_id = ?
`).all(itemId) as BudgetItemMember[];
+ return rows.map(m => ({ ...m, avatar_url: avatarUrl(m) }));
}
// ---------------------------------------------------------------------------