diff --git a/client/src/components/Planner/DayDetailPanel.test.tsx b/client/src/components/Planner/DayDetailPanel.test.tsx
index ef5aa39ec..eb0b47936 100644
--- a/client/src/components/Planner/DayDetailPanel.test.tsx
+++ b/client/src/components/Planner/DayDetailPanel.test.tsx
@@ -564,6 +564,30 @@ describe('DayDetailPanel', () => {
});
});
+ it('FE-PLANNER-DAYDETAIL-067: hotel picker defaults check-out to the day AFTER check-in', async () => {
+ const day2 = buildDay({ id: 2, trip_id: 1, date: '2025-06-16', title: 'Day 2' });
+ const day3 = buildDay({ id: 3, trip_id: 1, date: '2025-06-17', title: 'Day 3' });
+ render();
+ await userEvent.click(await screen.findByText(/Add accommodation/i));
+ await waitFor(() => {
+ const portal = document.body.querySelector('[style*="z-index: 99999"]');
+ // Closed selects render only their chosen label: check-in on the opened
+ // day, check-out on the following one — nobody stays a few hours.
+ expect(portal?.textContent).toContain('Day in Paris');
+ expect(portal?.textContent).toContain('Day 2');
+ expect(portal?.textContent).not.toContain('Day 3');
+ });
+ });
+
+ it('FE-PLANNER-DAYDETAIL-068: hotel picker falls back to a same-day range on the last trip day', async () => {
+ render();
+ await userEvent.click(await screen.findByText(/Add accommodation/i));
+ await waitFor(() => {
+ const portal = document.body.querySelector('[style*="z-index: 99999"]');
+ expect(portal?.textContent?.match(/Day in Paris/g)).toHaveLength(2);
+ });
+ });
+
it('FE-PLANNER-DAYDETAIL-034: accommodation with all fields shows full details grid', async () => {
server.use(
http.get('/api/trips/1/accommodations', () =>
diff --git a/client/src/components/Planner/useDayDetail.ts b/client/src/components/Planner/useDayDetail.ts
index e86c00ffa..b4e5ad94a 100644
--- a/client/src/components/Planner/useDayDetail.ts
+++ b/client/src/components/Planner/useDayDetail.ts
@@ -11,7 +11,13 @@ export function useDayDetail(day: any, days: any, tripId: any, lat: any, lng: an
const [dayAccommodations, setDayAccommodations] = useState([])
const [accommodations, setAccommodations] = useState([])
const [showHotelPicker, setShowHotelPicker] = useState(false)
- const [hotelDayRange, setHotelDayRange] = useState({ start: day?.id, end: day?.id })
+ // A stay virtually never checks out the day it checks in — default the range
+ // to check-out on the next day, unless the trip ends here.
+ const defaultHotelDayRange = (d: any) => {
+ const idx = (days || []).findIndex((x: any) => x.id === d?.id)
+ return { start: d?.id, end: (idx >= 0 && days[idx + 1]?.id) || d?.id }
+ }
+ const [hotelDayRange, setHotelDayRange] = useState(() => defaultHotelDayRange(day))
const [hotelCategoryFilter, setHotelCategoryFilter] = useState('')
const [hotelForm, setHotelForm] = useState({ check_in: '', check_in_end: '', check_out: '', confirmation: '', place_id: null })
@@ -38,7 +44,7 @@ export function useDayDetail(day: any, days: any, tripId: any, lat: any, lng: an
.catch(() => {})
}, [tripId, day?.id])
- useEffect(() => { if (day) setHotelDayRange({ start: day.id, end: day.id }) }, [day?.id])
+ useEffect(() => { if (day) setHotelDayRange(defaultHotelDayRange(day)) }, [day?.id])
const handleSelectPlace = (placeId) => {
setHotelForm(f => ({ ...f, place_id: placeId }))