feat(lodging): improve lodging date handling with all-day event support and timezone adjustments

This commit is contained in:
Sean Morley
2025-06-18 21:10:10 -04:00
parent 63e8e96d52
commit df24316837
5 changed files with 170 additions and 78 deletions

View File

@@ -120,23 +120,39 @@
</div>
{/if}
{#if lodging.check_in && lodging.check_out}
<div class="flex items-center gap-2">
<span class="text-sm font-medium">{$t('adventures.dates')}:</span>
<p class="text-sm">
{#if isAllDay(lodging.check_in)}
{formatAllDayDate(lodging.check_in)}
{formatAllDayDate(lodging.check_out)}
{:else}
{formatDateInTimezone(lodging.check_in, lodging.timezone)}
{formatDateInTimezone(lodging.check_out, lodging.timezone)}
{#if lodging.timezone}
<span class="ml-1 text-xs opacity-60">({lodging.timezone})</span>
<div class="space-y-3">
{#if lodging.check_in}
<div class="flex gap-2 text-sm">
<span class="font-medium whitespace-nowrap">{$t('adventures.check_in')}:</span>
<span>
{#if isAllDay(lodging.check_in)}
{formatAllDayDate(lodging.check_in)}
{:else}
{formatDateInTimezone(lodging.check_in, lodging.timezone)}
{#if lodging.timezone}
<span class="ml-1 text-xs opacity-60">({lodging.timezone})</span>
{/if}
{/if}
{/if}
</p>
</div>
{/if}
</span>
</div>
{/if}
{#if lodging.check_out}
<div class="flex gap-2 text-sm">
<span class="font-medium whitespace-nowrap">{$t('adventures.check_out')}:</span>
<span>
{#if isAllDay(lodging.check_out)}
{formatAllDayDate(lodging.check_out)}
{:else}
{formatDateInTimezone(lodging.check_out, lodging.timezone)}
{#if lodging.timezone}
<span class="ml-1 text-xs opacity-60">({lodging.timezone})</span>
{/if}
{/if}
</span>
</div>
{/if}
</div>
</div>
<!-- Reservation Info -->

View File

@@ -6,6 +6,7 @@
import type { Collection, Lodging } from '$lib/types';
import LocationDropdown from './LocationDropdown.svelte';
import DateRangeCollapse from './DateRangeCollapse.svelte';
import { isAllDay } from '$lib';
const dispatch = createEventDispatcher();
@@ -82,6 +83,24 @@
async function handleSubmit(event: Event) {
event.preventDefault();
lodging.timezone = lodgingTimezone || null;
// Auto-set end date if missing but start date exists
if (lodging.check_in && !lodging.check_out) {
const startDate = new Date(lodging.check_in);
const nextDay = new Date(startDate);
nextDay.setDate(nextDay.getDate() + 1);
if (isAllDay(lodging.check_in)) {
// For all-day, set to next day at 00:00:00
lodging.check_out = nextDay.toISOString().split('T')[0] + 'T00:00:00';
} else {
// For timed events, set to next day at 9:00 AM
nextDay.setHours(9, 0, 0, 0);
lodging.check_out = nextDay.toISOString();
}
}
// Create or update lodging...
const url = lodging.id === '' ? '/api/lodging' : `/api/lodging/${lodging.id}`;
const method = lodging.id === '' ? 'POST' : 'PATCH';

View File

@@ -8,7 +8,8 @@
import DeleteWarning from './DeleteWarning.svelte';
// import ArrowDownThick from '~icons/mdi/arrow-down-thick';
import { TRANSPORTATION_TYPES_ICONS } from '$lib';
import { formatDateInTimezone } from '$lib/dateUtils';
import { formatAllDayDate, formatDateInTimezone } from '$lib/dateUtils';
import { isAllDay } from '$lib';
function getTransportationIcon(type: string) {
if (type in TRANSPORTATION_TYPES_ICONS) {
@@ -161,9 +162,13 @@
<div class="flex gap-2 text-sm">
<span class="font-medium whitespace-nowrap">{$t('adventures.start')}:</span>
<span>
{formatDateInTimezone(transportation.date, transportation.start_timezone)}
{#if transportation.start_timezone}
<span class="ml-1 text-xs opacity-60">({transportation.start_timezone})</span>
{#if isAllDay(transportation.date) && (!transportation.end_date || isAllDay(transportation.end_date))}
{formatAllDayDate(transportation.date)}
{:else}
{formatDateInTimezone(transportation.date, transportation.start_timezone)}
{#if transportation.start_timezone}
<span class="ml-1 text-xs opacity-60">({transportation.start_timezone})</span>
{/if}
{/if}
</span>
</div>
@@ -173,9 +178,13 @@
<div class="flex gap-2 text-sm">
<span class="font-medium whitespace-nowrap">{$t('adventures.end')}:</span>
<span>
{formatDateInTimezone(transportation.end_date, transportation.end_timezone)}
{#if transportation.end_timezone}
<span class="ml-1 text-xs opacity-60">({transportation.end_timezone})</span>
{#if isAllDay(transportation.end_date) && (!transportation.date || isAllDay(transportation.date))}
{formatAllDayDate(transportation.end_date)}
{:else}
{formatDateInTimezone(transportation.end_date, transportation.end_timezone)}
{#if transportation.end_timezone}
<span class="ml-1 text-xs opacity-60">({transportation.end_timezone})</span>
{/if}
{/if}
</span>
</div>