diff --git a/backend/server/adventures/serializers.py b/backend/server/adventures/serializers.py index 5a67aae9..5cd95ba1 100644 --- a/backend/server/adventures/serializers.py +++ b/backend/server/adventures/serializers.py @@ -716,11 +716,13 @@ class UltraSlimCollectionSerializer(serializers.ModelSerializer): location__collections=obj ).select_related('user').prefetch_related('location') - return ContentImageSerializer( + serializer = ContentImageSerializer( images, many=True, context={'request': self.context.get('request')} - ).data + ) + # Filter out None values from the serialized data + return [image for image in serializer.data if image is not None] def get_location_count(self, obj): """Get count of locations in this collection""" diff --git a/frontend/src/lib/components/ImmichSelect.svelte b/frontend/src/lib/components/ImmichSelect.svelte index 3ff2a86c..050e1815 100644 --- a/frontend/src/lib/components/ImmichSelect.svelte +++ b/frontend/src/lib/components/ImmichSelect.svelte @@ -306,7 +306,7 @@
Image from Immich diff --git a/frontend/src/lib/components/collections/CollectionItineraryPlanner.svelte b/frontend/src/lib/components/collections/CollectionItineraryPlanner.svelte index f5bd62e9..b84c10da 100644 --- a/frontend/src/lib/components/collections/CollectionItineraryPlanner.svelte +++ b/frontend/src/lib/components/collections/CollectionItineraryPlanner.svelte @@ -593,6 +593,7 @@ // If we updated the item's date, update local state directly if (updateItemDate) { const isoDate = `${dateISO}T00:00:00`; + const nextDayISO = DateTime.fromISO(dateISO).plus({ days: 1 }).toISODate(); if (objectType === 'location') { // For locations, create a new visit locally @@ -620,15 +621,59 @@ } } else if (objectType === 'transportation') { if (collection.transportations) { - collection.transportations = collection.transportations.map((t) => - t.id === objectId ? { ...t, date: isoDate } : t - ); + collection.transportations = collection.transportations.map((t) => { + if (t.id === objectId) { + // If end_date exists and is before the new start date, set it to next day + let newEndDate = t.end_date; + if (newEndDate) { + const endDate = DateTime.fromISO(newEndDate); + const startDate = DateTime.fromISO(isoDate); + if (endDate < startDate) { + // Check if original end_date has a time component (not all-day) + const hasTime = !newEndDate.includes('T00:00:00'); + if (hasTime && t.end_timezone) { + // Set to 9am in the end timezone + newEndDate = DateTime.fromISO(nextDayISO, { zone: t.end_timezone }) + .set({ hour: 9, minute: 0, second: 0 }) + .toISO(); + } else { + // All-day event, keep at UTC 0 + newEndDate = `${nextDayISO}T00:00:00`; + } + } + } + return { ...t, date: isoDate, end_date: newEndDate }; + } + return t; + }); } } else if (objectType === 'lodging') { if (collection.lodging) { - collection.lodging = collection.lodging.map((l) => - l.id === objectId ? { ...l, check_in: isoDate } : l - ); + collection.lodging = collection.lodging.map((l) => { + if (l.id === objectId) { + // If check_out exists and is before the new check_in, set it to next day + let newCheckOut = l.check_out; + if (newCheckOut) { + const checkOut = DateTime.fromISO(newCheckOut); + const checkIn = DateTime.fromISO(isoDate); + if (checkOut < checkIn) { + // Check if original check_out has a time component (not all-day) + const hasTime = !newCheckOut.includes('T00:00:00'); + if (hasTime && l.timezone) { + // Set to 9am in the lodging timezone + newCheckOut = DateTime.fromISO(nextDayISO, { zone: l.timezone }) + .set({ hour: 9, minute: 0, second: 0 }) + .toISO(); + } else { + // All-day event, keep at UTC 0 + newCheckOut = `${nextDayISO}T00:00:00`; + } + } + } + return { ...l, check_in: isoDate, check_out: newCheckOut }; + } + return l; + }); } } else if (objectType === 'note') { if (collection.notes) { diff --git a/frontend/src/lib/components/lodging/LodgingDetails.svelte b/frontend/src/lib/components/lodging/LodgingDetails.svelte index e456ef9e..4519d2fb 100644 --- a/frontend/src/lib/components/lodging/LodgingDetails.svelte +++ b/frontend/src/lib/components/lodging/LodgingDetails.svelte @@ -745,10 +745,6 @@
-
diff --git a/frontend/src/lib/components/lodging/LodgingModal.svelte b/frontend/src/lib/components/lodging/LodgingModal.svelte index 8b43dc45..4c4e4c00 100644 --- a/frontend/src/lib/components/lodging/LodgingModal.svelte +++ b/frontend/src/lib/components/lodging/LodgingModal.svelte @@ -258,14 +258,12 @@ bind:images={lodging.images} bind:attachments={lodging.attachments} itemName={lodging.name} - {user} on:back={() => { steps[1].selected = false; steps[0].selected = true; }} on:close={() => close()} itemId={lodging.id} - measurementSystem={user?.measurement_system || 'metric'} /> {/if} diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index d6aafaa0..e4a49a65 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -963,6 +963,8 @@ "load_more": "Load More", "immich_error": "Error updating Immich integration", "immich_disabled": "Immich integration disabled successfully!", + "immich_updated": "Immich integration updated successfully!", + "immich_enabled": "Immich integration enabled successfully!", "disable": "Disable", "server_url": "Immich Server URL", "api_note": "Note: this must be the URL to the Immich API server so it likely ends with /api unless you have a custom config.",