diff --git a/backend/server/.env.example b/backend/server/.env.example index d1af5396..95a489ef 100644 --- a/backend/server/.env.example +++ b/backend/server/.env.example @@ -36,4 +36,8 @@ EMAIL_BACKEND='console' # PGDATABASE='adventurelog' # PGUSER='admin' # PGPASSWORD='admin' + +# For Sean's use: +# re-sync the development branch with main after doing squash merges +# git fetch origin && git checkout development && git reset --hard origin/main && git push origin development --force # ------------------- # \ No newline at end of file diff --git a/backend/server/requirements.txt b/backend/server/requirements.txt index 7eadfd52..662aa226 100644 --- a/backend/server/requirements.txt +++ b/backend/server/requirements.txt @@ -26,4 +26,5 @@ geopy==2.4.1 psutil==6.1.1 geojson==3.2.0 gpxpy==1.6.2 -pymemcache==4.0.0 \ No newline at end of file +pymemcache==4.0.0 +legacy-cgi==2.6.3 \ No newline at end of file diff --git a/frontend/src/lib/components/ChecklistCard.svelte b/frontend/src/lib/components/ChecklistCard.svelte index 9b60029e..adda2f13 100644 --- a/frontend/src/lib/components/ChecklistCard.svelte +++ b/frontend/src/lib/components/ChecklistCard.svelte @@ -9,29 +9,18 @@ import TrashCan from '~icons/mdi/trash-can'; import Calendar from '~icons/mdi/calendar'; import DeleteWarning from './DeleteWarning.svelte'; + import { isEntityOutsideCollectionDateRange } from '$lib/dateUtils'; export let checklist: Checklist; export let user: User | null = null; - export let collection: Collection | null = null; + export let collection: Collection; let isWarningModalOpen: boolean = false; - let unlinked: boolean = false; + let outsideCollectionRange: boolean = false; $: { - if (collection?.start_date && collection.end_date) { - const startOutsideRange = - checklist.date && - collection.start_date < checklist.date && - collection.end_date < checklist.date; - - const endOutsideRange = - checklist.date && - collection.start_date > checklist.date && - collection.end_date > checklist.date; - - unlinked = !!(startOutsideRange || endOutsideRange || !checklist.date); - } + outsideCollectionRange = isEntityOutsideCollectionDateRange(checklist, collection); } function editChecklist() { @@ -71,7 +60,7 @@

{checklist.name}

{$t('adventures.checklist')}
- {#if unlinked} + {#if outsideCollectionRange}
{$t('adventures.out_of_range')}
{/if}
diff --git a/frontend/src/lib/components/ChecklistModal.svelte b/frontend/src/lib/components/ChecklistModal.svelte index 1e16985a..50f17627 100644 --- a/frontend/src/lib/components/ChecklistModal.svelte +++ b/frontend/src/lib/components/ChecklistModal.svelte @@ -14,7 +14,7 @@ let items: ChecklistItem[] = []; - let constrainDates: boolean = false; + let constrainDates: boolean = true; items = checklist?.items || []; diff --git a/frontend/src/lib/components/LocationCard.svelte b/frontend/src/lib/components/LocationCard.svelte index 2549ab97..01249612 100644 --- a/frontend/src/lib/components/LocationCard.svelte +++ b/frontend/src/lib/components/LocationCard.svelte @@ -22,6 +22,7 @@ import StarOutline from '~icons/mdi/star-outline'; import Eye from '~icons/mdi/eye'; import EyeOff from '~icons/mdi/eye-off'; + import { isEntityOutsideCollectionDateRange } from '$lib/dateUtils'; export let type: string | null = null; export let user: User | null; @@ -48,17 +49,13 @@ } } - let unlinked: boolean = false; + let outsideCollectionRange: boolean = false; - // Reactive block to update `unlinked` when dependencies change $: { - if (collection && collection?.start_date && collection.end_date) { - unlinked = adventure.visits.every((visit) => { - if (!visit.start_date || !visit.end_date) return true; - const isBeforeVisit = collection.end_date && collection.end_date < visit.start_date; - const isAfterVisit = collection.start_date && collection.start_date > visit.end_date; - return isBeforeVisit || isAfterVisit; - }); + if (collection) { + outsideCollectionRange = adventure.visits.every((visit) => + isEntityOutsideCollectionDateRange(visit, collection) + ); } } @@ -199,7 +196,7 @@ > {adventure.is_visited ? $t('adventures.visited') : $t('adventures.planned')} - {#if unlinked} + {#if outsideCollectionRange}
{$t('adventures.out_of_range')}
{/if} diff --git a/frontend/src/lib/components/LodgingCard.svelte b/frontend/src/lib/components/LodgingCard.svelte index 1baeb1ea..f9be38af 100644 --- a/frontend/src/lib/components/LodgingCard.svelte +++ b/frontend/src/lib/components/LodgingCard.svelte @@ -7,7 +7,7 @@ import { t } from 'svelte-i18n'; import DeleteWarning from './DeleteWarning.svelte'; import { LODGING_TYPES_ICONS } from '$lib'; - import { formatDateInTimezone } from '$lib/dateUtils'; + import { formatDateInTimezone, isEntityOutsideCollectionDateRange } from '$lib/dateUtils'; import { formatAllDayDate } from '$lib/dateUtils'; import { isAllDay } from '$lib'; import CardCarousel from './CardCarousel.svelte'; @@ -31,38 +31,11 @@ dispatch('edit', lodging); } - let unlinked: boolean = false; + let outsideCollectionRange: boolean = false; $: { - if (collection?.start_date && collection.end_date) { - // Parse transportation dates - let transportationStartDate = lodging.check_in - ? new Date(lodging.check_in.split('T')[0]) // Ensure proper date parsing - : null; - let transportationEndDate = lodging.check_out - ? new Date(lodging.check_out.split('T')[0]) - : null; - - // Parse collection dates - let collectionStartDate = new Date(collection.start_date); - let collectionEndDate = new Date(collection.end_date); - - // Check if the collection range is outside the transportation range - const startOutsideRange = - transportationStartDate && - collectionStartDate < transportationStartDate && - collectionEndDate < transportationStartDate; - - const endOutsideRange = - transportationEndDate && - collectionStartDate > transportationEndDate && - collectionEndDate > transportationEndDate; - - unlinked = !!( - startOutsideRange || - endOutsideRange || - (!transportationStartDate && !transportationEndDate) - ); + if (collection) { + outsideCollectionRange = isEntityOutsideCollectionDateRange(lodging, collection); } } @@ -120,7 +93,7 @@ {$t(`lodging.${lodging.type}`)} {getLodgingIcon(lodging.type)} - {#if unlinked} + {#if outsideCollectionRange}
{$t('adventures.out_of_range')}
{/if} diff --git a/frontend/src/lib/components/Navbar.svelte b/frontend/src/lib/components/Navbar.svelte index 28cf6486..c84afa5e 100644 --- a/frontend/src/lib/components/Navbar.svelte +++ b/frontend/src/lib/components/Navbar.svelte @@ -63,7 +63,8 @@ ru: 'Русский', ja: '日本語', ar: 'العربية', - 'pt-br': 'Português (Brasil)' + 'pt-br': 'Português (Brasil)', + 'sk': 'Slovenský' }; const submitLocaleChange = (event: Event) => { diff --git a/frontend/src/lib/components/NoteCard.svelte b/frontend/src/lib/components/NoteCard.svelte index 0e699a54..6fb6b693 100644 --- a/frontend/src/lib/components/NoteCard.svelte +++ b/frontend/src/lib/components/NoteCard.svelte @@ -15,23 +15,18 @@ import TrashCan from '~icons/mdi/trash-can'; import Calendar from '~icons/mdi/calendar'; import DeleteWarning from './DeleteWarning.svelte'; + import { isEntityOutsideCollectionDateRange } from '$lib/dateUtils'; export let note: Note; export let user: User | null = null; export let collection: Collection | null = null; let isWarningModalOpen: boolean = false; - let unlinked: boolean = false; + let outsideCollectionRange: boolean = false; $: { - if (collection?.start_date && collection.end_date) { - const startOutsideRange = - note.date && collection.start_date < note.date && collection.end_date < note.date; - - const endOutsideRange = - note.date && collection.start_date > note.date && collection.end_date > note.date; - - unlinked = !!(startOutsideRange || endOutsideRange || !note.date); + if (collection) { + outsideCollectionRange = isEntityOutsideCollectionDateRange(note, collection); } } @@ -73,7 +68,7 @@

{note.name}

{$t('adventures.note')}
- {#if unlinked} + {#if outsideCollectionRange}
{$t('adventures.out_of_range')}
{/if}
diff --git a/frontend/src/lib/components/NoteModal.svelte b/frontend/src/lib/components/NoteModal.svelte index 7f66fa47..fce82bd0 100644 --- a/frontend/src/lib/components/NoteModal.svelte +++ b/frontend/src/lib/components/NoteModal.svelte @@ -17,7 +17,7 @@ export let collection: Collection; export let user: User | null = null; - let constrainDates: boolean = false; + let constrainDates: boolean = true; let isReadOnly = !(note && user?.uuid == note?.user) && diff --git a/frontend/src/lib/components/TransportationCard.svelte b/frontend/src/lib/components/TransportationCard.svelte index f5418781..5533c559 100644 --- a/frontend/src/lib/components/TransportationCard.svelte +++ b/frontend/src/lib/components/TransportationCard.svelte @@ -8,7 +8,11 @@ import DeleteWarning from './DeleteWarning.svelte'; // import ArrowDownThick from '~icons/mdi/arrow-down-thick'; import { TRANSPORTATION_TYPES_ICONS } from '$lib'; - import { formatAllDayDate, formatDateInTimezone } from '$lib/dateUtils'; + import { + formatAllDayDate, + formatDateInTimezone, + isEntityOutsideCollectionDateRange + } from '$lib/dateUtils'; import { isAllDay } from '$lib'; import CardCarousel from './CardCarousel.svelte'; @@ -36,52 +40,11 @@ dispatch('edit', transportation); } - let unlinked: boolean = false; + let outsideCollectionRange: boolean = false; $: { - if (collection?.start_date && collection.end_date) { - // Parse transportation dates - let transportationStartDate = transportation.date - ? new Date(transportation.date.split('T')[0]) // Ensure proper date parsing - : null; - let transportationEndDate = transportation.end_date - ? new Date(transportation.end_date.split('T')[0]) - : null; - - // Parse collection dates - let collectionStartDate = new Date(collection.start_date); - let collectionEndDate = new Date(collection.end_date); - - // // Debugging outputs - // console.log( - // 'Transportation Start Date:', - // transportationStartDate, - // 'Transportation End Date:', - // transportationEndDate - // ); - // console.log( - // 'Collection Start Date:', - // collectionStartDate, - // 'Collection End Date:', - // collectionEndDate - // ); - - // Check if the collection range is outside the transportation range - const startOutsideRange = - transportationStartDate && - collectionStartDate < transportationStartDate && - collectionEndDate < transportationStartDate; - - const endOutsideRange = - transportationEndDate && - collectionStartDate > transportationEndDate && - collectionEndDate > transportationEndDate; - - unlinked = !!( - startOutsideRange || - endOutsideRange || - (!transportationStartDate && !transportationEndDate) - ); + if (collection) { + outsideCollectionRange = isEntityOutsideCollectionDateRange(transportation, collection); } } @@ -165,7 +128,7 @@ {#if transportation.type === 'plane' && transportation.flight_number}
{transportation.flight_number}
{/if} - {#if unlinked} + {#if outsideCollectionRange}
{$t('adventures.out_of_range')}
{/if} diff --git a/frontend/src/lib/components/TransportationModal.svelte b/frontend/src/lib/components/TransportationModal.svelte index 6c3ecba1..497a639e 100644 --- a/frontend/src/lib/components/TransportationModal.svelte +++ b/frontend/src/lib/components/TransportationModal.svelte @@ -173,6 +173,10 @@ Math.round(transportation.destination_longitude * 1e6) / 1e6; } + if (transportation.date && !transportation.end_date) { + transportation.end_date = transportation.date; + } + if (!transportation.type) { transportation.type = 'other'; } diff --git a/frontend/src/lib/components/locations/LocationVisits.svelte b/frontend/src/lib/components/locations/LocationVisits.svelte index 7dec8f1d..5248c450 100644 --- a/frontend/src/lib/components/locations/LocationVisits.svelte +++ b/frontend/src/lib/components/locations/LocationVisits.svelte @@ -28,6 +28,7 @@ import ArrowLeftIcon from '~icons/mdi/arrow-left'; import RunFastIcon from '~icons/mdi/run-fast'; import LoadingIcon from '~icons/mdi/loading'; + import InfoIcon from '~icons/mdi/information'; import UploadIcon from '~icons/mdi/upload'; import FileIcon from '~icons/mdi/file'; import CloseIcon from '~icons/mdi/close'; @@ -1535,6 +1536,17 @@ + + {#if localStartDate || localEndDate} +
+ +
+
{$t('adventures.dates_not_saved')}
+
{$t('adventures.dates_not_saved_description')}
+
+
+ {/if} +