mirror of
https://github.com/seanmorley15/AdventureLog.git
synced 2025-07-19 12:59:36 +02:00
feat(lodging): add check-in and check-out labels and enhance date handling for lodging events
This commit is contained in:
parent
df24316837
commit
9964398e25
15 changed files with 93 additions and 68 deletions
|
@ -263,7 +263,9 @@
|
||||||
<label for="date" class="text-sm font-medium">
|
<label for="date" class="text-sm font-medium">
|
||||||
{type === 'transportation'
|
{type === 'transportation'
|
||||||
? $t('adventures.departure_date')
|
? $t('adventures.departure_date')
|
||||||
: $t('adventures.start_date')}
|
: type === 'lodging'
|
||||||
|
? $t('adventures.check_in')
|
||||||
|
: $t('adventures.start_date')}
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
{#if allDay}
|
{#if allDay}
|
||||||
|
@ -295,7 +297,11 @@
|
||||||
{#if localStartDate}
|
{#if localStartDate}
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
<label for="end_date" class="text-sm font-medium">
|
<label for="end_date" class="text-sm font-medium">
|
||||||
{type === 'transportation' ? $t('adventures.arrival_date') : $t('adventures.end_date')}
|
{type === 'transportation'
|
||||||
|
? $t('adventures.arrival_date')
|
||||||
|
: type === 'lodging'
|
||||||
|
? $t('adventures.check_out')
|
||||||
|
: $t('adventures.end_date')}
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
{#if allDay}
|
{#if allDay}
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
import LocationDropdown from './LocationDropdown.svelte';
|
import LocationDropdown from './LocationDropdown.svelte';
|
||||||
import DateRangeCollapse from './DateRangeCollapse.svelte';
|
import DateRangeCollapse from './DateRangeCollapse.svelte';
|
||||||
import { isAllDay } from '$lib';
|
import { isAllDay } from '$lib';
|
||||||
|
// @ts-ignore
|
||||||
|
import { DateTime } from 'luxon';
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
|
@ -85,19 +87,21 @@
|
||||||
|
|
||||||
lodging.timezone = lodgingTimezone || null;
|
lodging.timezone = lodgingTimezone || null;
|
||||||
|
|
||||||
|
console.log(lodgingTimezone);
|
||||||
|
|
||||||
// Auto-set end date if missing but start date exists
|
// Auto-set end date if missing but start date exists
|
||||||
if (lodging.check_in && !lodging.check_out) {
|
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)) {
|
if (isAllDay(lodging.check_in)) {
|
||||||
// For all-day, set to next day at 00:00:00
|
// For all-day, just add one day and keep at UTC 00:00:00
|
||||||
lodging.check_out = nextDay.toISOString().split('T')[0] + 'T00:00:00';
|
const start = DateTime.fromISO(lodging.check_in, { zone: 'utc' });
|
||||||
|
const nextDay = start.plus({ days: 1 });
|
||||||
|
lodging.check_out = nextDay.toISO();
|
||||||
} else {
|
} else {
|
||||||
// For timed events, set to next day at 9:00 AM
|
// For timed events, set to next day at 9:00 AM in lodging's timezone, then convert to UTC
|
||||||
nextDay.setHours(9, 0, 0, 0);
|
const start = DateTime.fromISO(lodging.check_in, { zone: lodging.timezone || 'utc' });
|
||||||
lodging.check_out = nextDay.toISOString();
|
const nextDay = start.plus({ days: 1 });
|
||||||
|
const end = nextDay.set({ hour: 9, minute: 0, second: 0, millisecond: 0 });
|
||||||
|
lodging.check_out = end.toUTC().toISO();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,66 +70,57 @@ export function groupAdventuresByDate(
|
||||||
): Record<string, Adventure[]> {
|
): Record<string, Adventure[]> {
|
||||||
const groupedAdventures: Record<string, Adventure[]> = {};
|
const groupedAdventures: Record<string, Adventure[]> = {};
|
||||||
|
|
||||||
// Initialize all days in the range
|
// Initialize all days in the range using DateTime
|
||||||
for (let i = 0; i < numberOfDays; i++) {
|
for (let i = 0; i < numberOfDays; i++) {
|
||||||
const currentDate = new Date(startDate);
|
const currentDate = DateTime.fromJSDate(startDate).plus({ days: i });
|
||||||
currentDate.setDate(startDate.getDate() + i);
|
const dateString = currentDate.toISODate(); // 'YYYY-MM-DD'
|
||||||
const dateString = getLocalDateString(currentDate);
|
|
||||||
groupedAdventures[dateString] = [];
|
groupedAdventures[dateString] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
adventures.forEach((adventure) => {
|
adventures.forEach((adventure) => {
|
||||||
adventure.visits.forEach((visit) => {
|
adventure.visits.forEach((visit) => {
|
||||||
if (visit.start_date) {
|
if (visit.start_date) {
|
||||||
// Check if this is an all-day event (both start and end at midnight)
|
// Check if it's all-day: start has 00:00:00 AND (no end OR end also has 00:00:00)
|
||||||
const isAllDayEvent =
|
const startHasZeros = visit.start_date.includes('T00:00:00');
|
||||||
isAllDay(visit.start_date) && (visit.end_date ? isAllDay(visit.end_date) : false);
|
const endHasZeros = visit.end_date ? visit.end_date.includes('T00:00:00') : true;
|
||||||
|
const isAllDayEvent = startHasZeros && endHasZeros;
|
||||||
|
|
||||||
// For all-day events, we need to handle dates differently
|
let startDT: DateTime;
|
||||||
if (isAllDayEvent && visit.end_date) {
|
let endDT: DateTime;
|
||||||
// Extract just the date parts without time
|
|
||||||
const startDateStr = visit.start_date.split('T')[0];
|
|
||||||
const endDateStr = visit.end_date.split('T')[0];
|
|
||||||
|
|
||||||
// Loop through all days in the range
|
if (isAllDayEvent) {
|
||||||
for (let i = 0; i < numberOfDays; i++) {
|
// For all-day events, extract just the date part and ignore timezone
|
||||||
const currentDate = new Date(startDate);
|
const dateOnly = visit.start_date.split('T')[0]; // Get 'YYYY-MM-DD'
|
||||||
currentDate.setDate(startDate.getDate() + i);
|
startDT = DateTime.fromISO(dateOnly); // This creates a date without time/timezone
|
||||||
const currentDateStr = getLocalDateString(currentDate);
|
|
||||||
|
|
||||||
// Include the current day if it falls within the adventure date range
|
endDT = visit.end_date
|
||||||
if (currentDateStr >= startDateStr && currentDateStr <= endDateStr) {
|
? DateTime.fromISO(visit.end_date.split('T')[0])
|
||||||
if (groupedAdventures[currentDateStr]) {
|
: startDT;
|
||||||
groupedAdventures[currentDateStr].push(adventure);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Handle regular events with time components
|
// For timed events, use timezone conversion
|
||||||
const adventureStartDate = new Date(visit.start_date);
|
startDT = DateTime.fromISO(visit.start_date, {
|
||||||
const adventureDateStr = getLocalDateString(adventureStartDate);
|
zone: visit.timezone ?? 'UTC'
|
||||||
|
});
|
||||||
|
|
||||||
if (visit.end_date) {
|
endDT = visit.end_date
|
||||||
const adventureEndDate = new Date(visit.end_date);
|
? DateTime.fromISO(visit.end_date, {
|
||||||
const endDateStr = getLocalDateString(adventureEndDate);
|
zone: visit.timezone ?? 'UTC'
|
||||||
|
})
|
||||||
|
: startDT;
|
||||||
|
}
|
||||||
|
|
||||||
// Loop through all days and include adventure if it falls within the range
|
const startDateStr = startDT.toISODate();
|
||||||
for (let i = 0; i < numberOfDays; i++) {
|
const endDateStr = endDT.toISODate();
|
||||||
const currentDate = new Date(startDate);
|
|
||||||
currentDate.setDate(startDate.getDate() + i);
|
|
||||||
const dateString = getLocalDateString(currentDate);
|
|
||||||
|
|
||||||
// Include the current day if it falls within the adventure date range
|
// Loop through all days in range
|
||||||
if (dateString >= adventureDateStr && dateString <= endDateStr) {
|
for (let i = 0; i < numberOfDays; i++) {
|
||||||
if (groupedAdventures[dateString]) {
|
const currentDate = DateTime.fromJSDate(startDate).plus({ days: i });
|
||||||
groupedAdventures[dateString].push(adventure);
|
const currentDateStr = currentDate.toISODate();
|
||||||
}
|
|
||||||
}
|
// Include the current day if it falls within the adventure date range
|
||||||
}
|
if (currentDateStr >= startDateStr && currentDateStr <= endDateStr) {
|
||||||
} else {
|
if (groupedAdventures[currentDateStr]) {
|
||||||
// If there's no end date, add adventure to the start date only
|
groupedAdventures[currentDateStr].push(adventure);
|
||||||
if (groupedAdventures[adventureDateStr]) {
|
|
||||||
groupedAdventures[adventureDateStr].push(adventure);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -244,7 +244,9 @@
|
||||||
"done": "Erledigt",
|
"done": "Erledigt",
|
||||||
"loading_adventures": "Ladeabenteuer ...",
|
"loading_adventures": "Ladeabenteuer ...",
|
||||||
"name_location": "Name, Ort",
|
"name_location": "Name, Ort",
|
||||||
"collection_contents": "Sammelinhalt"
|
"collection_contents": "Sammelinhalt",
|
||||||
|
"check_in": "Einchecken",
|
||||||
|
"check_out": "Kasse"
|
||||||
},
|
},
|
||||||
"home": {
|
"home": {
|
||||||
"desc_1": "Entdecken, planen und erkunden Sie mühelos",
|
"desc_1": "Entdecken, planen und erkunden Sie mühelos",
|
||||||
|
|
|
@ -98,6 +98,8 @@
|
||||||
"latitude": "Latitude",
|
"latitude": "Latitude",
|
||||||
"visit": "Visit",
|
"visit": "Visit",
|
||||||
"timed": "Timed",
|
"timed": "Timed",
|
||||||
|
"check_in": "Check In",
|
||||||
|
"check_out": "Check Out",
|
||||||
"coordinates": "Coordinates",
|
"coordinates": "Coordinates",
|
||||||
"copy_coordinates": "Copy Coordinates",
|
"copy_coordinates": "Copy Coordinates",
|
||||||
"visits": "Visits",
|
"visits": "Visits",
|
||||||
|
|
|
@ -296,7 +296,9 @@
|
||||||
"done": "Hecho",
|
"done": "Hecho",
|
||||||
"loading_adventures": "Cargando aventuras ...",
|
"loading_adventures": "Cargando aventuras ...",
|
||||||
"name_location": "Nombre, ubicación",
|
"name_location": "Nombre, ubicación",
|
||||||
"collection_contents": "Contenido de la colección"
|
"collection_contents": "Contenido de la colección",
|
||||||
|
"check_in": "Registrarse",
|
||||||
|
"check_out": "Verificar"
|
||||||
},
|
},
|
||||||
"worldtravel": {
|
"worldtravel": {
|
||||||
"all": "Todo",
|
"all": "Todo",
|
||||||
|
|
|
@ -244,7 +244,9 @@
|
||||||
"done": "Fait",
|
"done": "Fait",
|
||||||
"loading_adventures": "Chargement des aventures ...",
|
"loading_adventures": "Chargement des aventures ...",
|
||||||
"name_location": "nom, emplacement",
|
"name_location": "nom, emplacement",
|
||||||
"collection_contents": "Contenu de la collection"
|
"collection_contents": "Contenu de la collection",
|
||||||
|
"check_in": "Enregistrement",
|
||||||
|
"check_out": "Vérifier"
|
||||||
},
|
},
|
||||||
"home": {
|
"home": {
|
||||||
"desc_1": "Découvrez, planifiez et explorez en toute simplicité",
|
"desc_1": "Découvrez, planifiez et explorez en toute simplicité",
|
||||||
|
|
|
@ -244,7 +244,9 @@
|
||||||
"done": "Fatto",
|
"done": "Fatto",
|
||||||
"loading_adventures": "Caricamento di avventure ...",
|
"loading_adventures": "Caricamento di avventure ...",
|
||||||
"name_location": "Nome, posizione",
|
"name_location": "Nome, posizione",
|
||||||
"collection_contents": "Contenuto di raccolta"
|
"collection_contents": "Contenuto di raccolta",
|
||||||
|
"check_in": "Check -in",
|
||||||
|
"check_out": "Guardare"
|
||||||
},
|
},
|
||||||
"home": {
|
"home": {
|
||||||
"desc_1": "Scopri, pianifica ed esplora con facilità",
|
"desc_1": "Scopri, pianifica ed esplora con facilità",
|
||||||
|
|
|
@ -244,7 +244,9 @@
|
||||||
"done": "완료",
|
"done": "완료",
|
||||||
"loading_adventures": "적재 모험 ...",
|
"loading_adventures": "적재 모험 ...",
|
||||||
"name_location": "이름, 위치",
|
"name_location": "이름, 위치",
|
||||||
"collection_contents": "수집 내용"
|
"collection_contents": "수집 내용",
|
||||||
|
"check_in": "체크인",
|
||||||
|
"check_out": "체크 아웃"
|
||||||
},
|
},
|
||||||
"auth": {
|
"auth": {
|
||||||
"confirm_password": "비밀번호 확인",
|
"confirm_password": "비밀번호 확인",
|
||||||
|
|
|
@ -244,7 +244,9 @@
|
||||||
"done": "Klaar",
|
"done": "Klaar",
|
||||||
"loading_adventures": "Adventuren laden ...",
|
"loading_adventures": "Adventuren laden ...",
|
||||||
"name_location": "naam, locatie",
|
"name_location": "naam, locatie",
|
||||||
"collection_contents": "Verzamelingsinhoud"
|
"collection_contents": "Verzamelingsinhoud",
|
||||||
|
"check_in": "Inchecken",
|
||||||
|
"check_out": "Uitchecken"
|
||||||
},
|
},
|
||||||
"home": {
|
"home": {
|
||||||
"desc_1": "Ontdek, plan en verken met gemak",
|
"desc_1": "Ontdek, plan en verken met gemak",
|
||||||
|
|
|
@ -296,7 +296,9 @@
|
||||||
"done": "Ferdig",
|
"done": "Ferdig",
|
||||||
"loading_adventures": "Laster opp eventyr ...",
|
"loading_adventures": "Laster opp eventyr ...",
|
||||||
"name_location": "Navn, plassering",
|
"name_location": "Navn, plassering",
|
||||||
"collection_contents": "Samlingsinnhold"
|
"collection_contents": "Samlingsinnhold",
|
||||||
|
"check_in": "Sjekk inn",
|
||||||
|
"check_out": "Sjekk ut"
|
||||||
},
|
},
|
||||||
"worldtravel": {
|
"worldtravel": {
|
||||||
"country_list": "Liste over land",
|
"country_list": "Liste over land",
|
||||||
|
|
|
@ -296,7 +296,9 @@
|
||||||
"loading_adventures": "Ładowanie przygód ...",
|
"loading_adventures": "Ładowanie przygód ...",
|
||||||
"name_location": "Nazwa, lokalizacja",
|
"name_location": "Nazwa, lokalizacja",
|
||||||
"delete_collection_warning": "Czy na pewno chcesz usunąć tę kolekcję? \nTego działania nie można cofnąć.",
|
"delete_collection_warning": "Czy na pewno chcesz usunąć tę kolekcję? \nTego działania nie można cofnąć.",
|
||||||
"collection_contents": "Zawartość kolekcji"
|
"collection_contents": "Zawartość kolekcji",
|
||||||
|
"check_in": "Zameldować się",
|
||||||
|
"check_out": "Wymeldować się"
|
||||||
},
|
},
|
||||||
"worldtravel": {
|
"worldtravel": {
|
||||||
"country_list": "Lista krajów",
|
"country_list": "Lista krajów",
|
||||||
|
|
|
@ -296,7 +296,9 @@
|
||||||
"done": "Сделанный",
|
"done": "Сделанный",
|
||||||
"loading_adventures": "Загрузка приключений ...",
|
"loading_adventures": "Загрузка приключений ...",
|
||||||
"name_location": "имя, местоположение",
|
"name_location": "имя, местоположение",
|
||||||
"collection_contents": "Содержание коллекции"
|
"collection_contents": "Содержание коллекции",
|
||||||
|
"check_in": "Регистрироваться",
|
||||||
|
"check_out": "Проверить"
|
||||||
},
|
},
|
||||||
"worldtravel": {
|
"worldtravel": {
|
||||||
"country_list": "Список стран",
|
"country_list": "Список стран",
|
||||||
|
|
|
@ -244,7 +244,9 @@
|
||||||
"done": "Gjort",
|
"done": "Gjort",
|
||||||
"loading_adventures": "Laddar äventyr ...",
|
"loading_adventures": "Laddar äventyr ...",
|
||||||
"name_location": "namn, plats",
|
"name_location": "namn, plats",
|
||||||
"collection_contents": "Insamlingsinnehåll"
|
"collection_contents": "Insamlingsinnehåll",
|
||||||
|
"check_in": "Checka in",
|
||||||
|
"check_out": "Checka ut"
|
||||||
},
|
},
|
||||||
"home": {
|
"home": {
|
||||||
"desc_1": "Upptäck, planera och utforska med lätthet",
|
"desc_1": "Upptäck, planera och utforska med lätthet",
|
||||||
|
|
|
@ -296,7 +296,9 @@
|
||||||
"done": "完毕",
|
"done": "完毕",
|
||||||
"loading_adventures": "加载冒险...",
|
"loading_adventures": "加载冒险...",
|
||||||
"name_location": "名称,位置",
|
"name_location": "名称,位置",
|
||||||
"collection_contents": "收集内容"
|
"collection_contents": "收集内容",
|
||||||
|
"check_in": "报到",
|
||||||
|
"check_out": "查看"
|
||||||
},
|
},
|
||||||
"auth": {
|
"auth": {
|
||||||
"forgot_password": "忘记密码?",
|
"forgot_password": "忘记密码?",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue