diff --git a/frontend/src/lib/components/DateRangeCollapse.svelte b/frontend/src/lib/components/DateRangeCollapse.svelte
index 7ff595f..eeec650 100644
--- a/frontend/src/lib/components/DateRangeCollapse.svelte
+++ b/frontend/src/lib/components/DateRangeCollapse.svelte
@@ -263,7 +263,9 @@
{#if allDay}
@@ -295,7 +297,11 @@
{#if localStartDate}
{#if allDay}
diff --git a/frontend/src/lib/components/LodgingModal.svelte b/frontend/src/lib/components/LodgingModal.svelte
index 5db3818..6eb97a2 100644
--- a/frontend/src/lib/components/LodgingModal.svelte
+++ b/frontend/src/lib/components/LodgingModal.svelte
@@ -7,6 +7,8 @@
import LocationDropdown from './LocationDropdown.svelte';
import DateRangeCollapse from './DateRangeCollapse.svelte';
import { isAllDay } from '$lib';
+ // @ts-ignore
+ import { DateTime } from 'luxon';
const dispatch = createEventDispatcher();
@@ -85,19 +87,21 @@
lodging.timezone = lodgingTimezone || null;
+ console.log(lodgingTimezone);
+
// 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';
+ // For all-day, just add one day and keep at UTC 00:00:00
+ const start = DateTime.fromISO(lodging.check_in, { zone: 'utc' });
+ const nextDay = start.plus({ days: 1 });
+ lodging.check_out = nextDay.toISO();
} else {
- // For timed events, set to next day at 9:00 AM
- nextDay.setHours(9, 0, 0, 0);
- lodging.check_out = nextDay.toISOString();
+ // For timed events, set to next day at 9:00 AM in lodging's timezone, then convert to UTC
+ const start = DateTime.fromISO(lodging.check_in, { zone: lodging.timezone || 'utc' });
+ const nextDay = start.plus({ days: 1 });
+ const end = nextDay.set({ hour: 9, minute: 0, second: 0, millisecond: 0 });
+ lodging.check_out = end.toUTC().toISO();
}
}
diff --git a/frontend/src/lib/index.ts b/frontend/src/lib/index.ts
index 4f890e8..21bee80 100644
--- a/frontend/src/lib/index.ts
+++ b/frontend/src/lib/index.ts
@@ -70,66 +70,57 @@ export function groupAdventuresByDate(
): Record {
const groupedAdventures: Record = {};
- // Initialize all days in the range
+ // Initialize all days in the range using DateTime
for (let i = 0; i < numberOfDays; i++) {
- const currentDate = new Date(startDate);
- currentDate.setDate(startDate.getDate() + i);
- const dateString = getLocalDateString(currentDate);
+ const currentDate = DateTime.fromJSDate(startDate).plus({ days: i });
+ const dateString = currentDate.toISODate(); // 'YYYY-MM-DD'
groupedAdventures[dateString] = [];
}
adventures.forEach((adventure) => {
adventure.visits.forEach((visit) => {
if (visit.start_date) {
- // Check if this is an all-day event (both start and end at midnight)
- const isAllDayEvent =
- isAllDay(visit.start_date) && (visit.end_date ? isAllDay(visit.end_date) : false);
+ // Check if it's all-day: start has 00:00:00 AND (no end OR end also has 00:00:00)
+ const startHasZeros = visit.start_date.includes('T00:00:00');
+ 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
- if (isAllDayEvent && visit.end_date) {
- // Extract just the date parts without time
- const startDateStr = visit.start_date.split('T')[0];
- const endDateStr = visit.end_date.split('T')[0];
+ let startDT: DateTime;
+ let endDT: DateTime;
- // Loop through all days in the range
- for (let i = 0; i < numberOfDays; i++) {
- const currentDate = new Date(startDate);
- currentDate.setDate(startDate.getDate() + i);
- const currentDateStr = getLocalDateString(currentDate);
+ if (isAllDayEvent) {
+ // For all-day events, extract just the date part and ignore timezone
+ const dateOnly = visit.start_date.split('T')[0]; // Get 'YYYY-MM-DD'
+ startDT = DateTime.fromISO(dateOnly); // This creates a date without time/timezone
- // Include the current day if it falls within the adventure date range
- if (currentDateStr >= startDateStr && currentDateStr <= endDateStr) {
- if (groupedAdventures[currentDateStr]) {
- groupedAdventures[currentDateStr].push(adventure);
- }
- }
- }
+ endDT = visit.end_date
+ ? DateTime.fromISO(visit.end_date.split('T')[0])
+ : startDT;
} else {
- // Handle regular events with time components
- const adventureStartDate = new Date(visit.start_date);
- const adventureDateStr = getLocalDateString(adventureStartDate);
+ // For timed events, use timezone conversion
+ startDT = DateTime.fromISO(visit.start_date, {
+ zone: visit.timezone ?? 'UTC'
+ });
- if (visit.end_date) {
- const adventureEndDate = new Date(visit.end_date);
- const endDateStr = getLocalDateString(adventureEndDate);
+ endDT = visit.end_date
+ ? DateTime.fromISO(visit.end_date, {
+ zone: visit.timezone ?? 'UTC'
+ })
+ : startDT;
+ }
- // Loop through all days and include adventure if it falls within the range
- for (let i = 0; i < numberOfDays; i++) {
- const currentDate = new Date(startDate);
- currentDate.setDate(startDate.getDate() + i);
- const dateString = getLocalDateString(currentDate);
+ const startDateStr = startDT.toISODate();
+ const endDateStr = endDT.toISODate();
- // Include the current day if it falls within the adventure date range
- if (dateString >= adventureDateStr && dateString <= endDateStr) {
- if (groupedAdventures[dateString]) {
- groupedAdventures[dateString].push(adventure);
- }
- }
- }
- } else {
- // If there's no end date, add adventure to the start date only
- if (groupedAdventures[adventureDateStr]) {
- groupedAdventures[adventureDateStr].push(adventure);
+ // Loop through all days in range
+ for (let i = 0; i < numberOfDays; i++) {
+ const currentDate = DateTime.fromJSDate(startDate).plus({ days: i });
+ const currentDateStr = currentDate.toISODate();
+
+ // Include the current day if it falls within the adventure date range
+ if (currentDateStr >= startDateStr && currentDateStr <= endDateStr) {
+ if (groupedAdventures[currentDateStr]) {
+ groupedAdventures[currentDateStr].push(adventure);
}
}
}
diff --git a/frontend/src/locales/de.json b/frontend/src/locales/de.json
index 33308ba..c007da1 100644
--- a/frontend/src/locales/de.json
+++ b/frontend/src/locales/de.json
@@ -244,7 +244,9 @@
"done": "Erledigt",
"loading_adventures": "Ladeabenteuer ...",
"name_location": "Name, Ort",
- "collection_contents": "Sammelinhalt"
+ "collection_contents": "Sammelinhalt",
+ "check_in": "Einchecken",
+ "check_out": "Kasse"
},
"home": {
"desc_1": "Entdecken, planen und erkunden Sie mühelos",
diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json
index 82e2fa4..31c0614 100644
--- a/frontend/src/locales/en.json
+++ b/frontend/src/locales/en.json
@@ -98,6 +98,8 @@
"latitude": "Latitude",
"visit": "Visit",
"timed": "Timed",
+ "check_in": "Check In",
+ "check_out": "Check Out",
"coordinates": "Coordinates",
"copy_coordinates": "Copy Coordinates",
"visits": "Visits",
diff --git a/frontend/src/locales/es.json b/frontend/src/locales/es.json
index 61f54e7..fcf8502 100644
--- a/frontend/src/locales/es.json
+++ b/frontend/src/locales/es.json
@@ -296,7 +296,9 @@
"done": "Hecho",
"loading_adventures": "Cargando aventuras ...",
"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": {
"all": "Todo",
diff --git a/frontend/src/locales/fr.json b/frontend/src/locales/fr.json
index c8412ce..9e61eb8 100644
--- a/frontend/src/locales/fr.json
+++ b/frontend/src/locales/fr.json
@@ -244,7 +244,9 @@
"done": "Fait",
"loading_adventures": "Chargement des aventures ...",
"name_location": "nom, emplacement",
- "collection_contents": "Contenu de la collection"
+ "collection_contents": "Contenu de la collection",
+ "check_in": "Enregistrement",
+ "check_out": "Vérifier"
},
"home": {
"desc_1": "Découvrez, planifiez et explorez en toute simplicité",
diff --git a/frontend/src/locales/it.json b/frontend/src/locales/it.json
index 9a1060b..ce522e0 100644
--- a/frontend/src/locales/it.json
+++ b/frontend/src/locales/it.json
@@ -244,7 +244,9 @@
"done": "Fatto",
"loading_adventures": "Caricamento di avventure ...",
"name_location": "Nome, posizione",
- "collection_contents": "Contenuto di raccolta"
+ "collection_contents": "Contenuto di raccolta",
+ "check_in": "Check -in",
+ "check_out": "Guardare"
},
"home": {
"desc_1": "Scopri, pianifica ed esplora con facilità",
diff --git a/frontend/src/locales/ko.json b/frontend/src/locales/ko.json
index 3b2cd2d..f23fc7b 100644
--- a/frontend/src/locales/ko.json
+++ b/frontend/src/locales/ko.json
@@ -244,7 +244,9 @@
"done": "완료",
"loading_adventures": "적재 모험 ...",
"name_location": "이름, 위치",
- "collection_contents": "수집 내용"
+ "collection_contents": "수집 내용",
+ "check_in": "체크인",
+ "check_out": "체크 아웃"
},
"auth": {
"confirm_password": "비밀번호 확인",
diff --git a/frontend/src/locales/nl.json b/frontend/src/locales/nl.json
index e060694..ec06221 100644
--- a/frontend/src/locales/nl.json
+++ b/frontend/src/locales/nl.json
@@ -244,7 +244,9 @@
"done": "Klaar",
"loading_adventures": "Adventuren laden ...",
"name_location": "naam, locatie",
- "collection_contents": "Verzamelingsinhoud"
+ "collection_contents": "Verzamelingsinhoud",
+ "check_in": "Inchecken",
+ "check_out": "Uitchecken"
},
"home": {
"desc_1": "Ontdek, plan en verken met gemak",
diff --git a/frontend/src/locales/no.json b/frontend/src/locales/no.json
index b703275..b3b3539 100644
--- a/frontend/src/locales/no.json
+++ b/frontend/src/locales/no.json
@@ -296,7 +296,9 @@
"done": "Ferdig",
"loading_adventures": "Laster opp eventyr ...",
"name_location": "Navn, plassering",
- "collection_contents": "Samlingsinnhold"
+ "collection_contents": "Samlingsinnhold",
+ "check_in": "Sjekk inn",
+ "check_out": "Sjekk ut"
},
"worldtravel": {
"country_list": "Liste over land",
diff --git a/frontend/src/locales/pl.json b/frontend/src/locales/pl.json
index 51c0324..af72437 100644
--- a/frontend/src/locales/pl.json
+++ b/frontend/src/locales/pl.json
@@ -296,7 +296,9 @@
"loading_adventures": "Ładowanie przygód ...",
"name_location": "Nazwa, lokalizacja",
"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": {
"country_list": "Lista krajów",
diff --git a/frontend/src/locales/ru.json b/frontend/src/locales/ru.json
index 149d2f1..7d063fe 100644
--- a/frontend/src/locales/ru.json
+++ b/frontend/src/locales/ru.json
@@ -296,7 +296,9 @@
"done": "Сделанный",
"loading_adventures": "Загрузка приключений ...",
"name_location": "имя, местоположение",
- "collection_contents": "Содержание коллекции"
+ "collection_contents": "Содержание коллекции",
+ "check_in": "Регистрироваться",
+ "check_out": "Проверить"
},
"worldtravel": {
"country_list": "Список стран",
diff --git a/frontend/src/locales/sv.json b/frontend/src/locales/sv.json
index 309b984..87d747c 100644
--- a/frontend/src/locales/sv.json
+++ b/frontend/src/locales/sv.json
@@ -244,7 +244,9 @@
"done": "Gjort",
"loading_adventures": "Laddar äventyr ...",
"name_location": "namn, plats",
- "collection_contents": "Insamlingsinnehåll"
+ "collection_contents": "Insamlingsinnehåll",
+ "check_in": "Checka in",
+ "check_out": "Checka ut"
},
"home": {
"desc_1": "Upptäck, planera och utforska med lätthet",
diff --git a/frontend/src/locales/zh.json b/frontend/src/locales/zh.json
index f111b07..55a98ce 100644
--- a/frontend/src/locales/zh.json
+++ b/frontend/src/locales/zh.json
@@ -296,7 +296,9 @@
"done": "完毕",
"loading_adventures": "加载冒险...",
"name_location": "名称,位置",
- "collection_contents": "收集内容"
+ "collection_contents": "收集内容",
+ "check_in": "报到",
+ "check_out": "查看"
},
"auth": {
"forgot_password": "忘记密码?",