diff --git a/backend/server/adventures/views/reverse_geocode_view.py b/backend/server/adventures/views/reverse_geocode_view.py
index dbbd026..4dc1d6b 100644
--- a/backend/server/adventures/views/reverse_geocode_view.py
+++ b/backend/server/adventures/views/reverse_geocode_view.py
@@ -21,10 +21,14 @@ class ReverseGeocodeViewSet(viewsets.ViewSet):
country_code = None
city = None
visited_city = None
+ location_name = None
# town = None
# city = None
# county = None
+
+ if 'name' in data.keys():
+ location_name = data['name']
if 'address' in data.keys():
keys = data['address'].keys()
@@ -58,7 +62,7 @@ class ReverseGeocodeViewSet(viewsets.ViewSet):
if visited_city:
city_visited = True
if region:
- return {"region_id": iso_code, "region": region.name, "country": region.country.name, "region_visited": region_visited, "display_name": display_name, "city": city.name if city else None, "city_id": city.id if city else None, "city_visited": city_visited}
+ return {"region_id": iso_code, "region": region.name, "country": region.country.name, "region_visited": region_visited, "display_name": display_name, "city": city.name if city else None, "city_id": city.id if city else None, "city_visited": city_visited, 'location_name': location_name}
return {"error": "No region found"}
@action(detail=False, methods=['get'])
diff --git a/backend/server/adventures/views/stats_view.py b/backend/server/adventures/views/stats_view.py
index 37d9f07..da2146a 100644
--- a/backend/server/adventures/views/stats_view.py
+++ b/backend/server/adventures/views/stats_view.py
@@ -48,4 +48,11 @@ class StatsViewSet(viewsets.ViewSet):
'total_regions': total_regions,
'visited_country_count': visited_country_count,
'total_countries': total_countries
- })
\ No newline at end of file
+ })
+
+ # locations - returns a list of all of the latitude, longitude locations of all public adventrues on the server
+ @action(detail=False, methods=['get'], url_path='locations')
+ def locations(self, request):
+ adventures = Adventure.objects.filter(
+ is_public=True).values('latitude', 'longitude', 'id', 'name')
+ return Response(adventures)
\ No newline at end of file
diff --git a/backend/server/main/settings.py b/backend/server/main/settings.py
index 1c894c5..cf3d3ba 100644
--- a/backend/server/main/settings.py
+++ b/backend/server/main/settings.py
@@ -61,7 +61,7 @@ INSTALLED_APPS = (
'users',
'integrations',
'django.contrib.gis',
- 'achievements',
+ # 'achievements', # Not done yet, will be added later in a future update
# 'widget_tweaks',
# 'slippers',
@@ -303,4 +303,7 @@ LOGGING = {
},
}
-ADVENTURELOG_CDN_URL = getenv('ADVENTURELOG_CDN_URL', 'https://cdn.adventurelog.app')
\ No newline at end of file
+# ADVENTURELOG_CDN_URL = getenv('ADVENTURELOG_CDN_URL', 'https://cdn.adventurelog.app')
+
+# https://github.com/dr5hn/countries-states-cities-database/tags
+COUNTRY_REGION_JSON_VERSION = 'v2.5'
\ No newline at end of file
diff --git a/backend/server/users/views.py b/backend/server/users/views.py
index 0d0fca1..428c5b8 100644
--- a/backend/server/users/views.py
+++ b/backend/server/users/views.py
@@ -68,6 +68,9 @@ class PublicUserListView(APIView):
for user in users:
user.email = None
serializer = PublicUserSerializer(users, many=True)
+ # for every user, remove the field has_password
+ for user in serializer.data:
+ user.pop('has_password', None)
return Response(serializer.data, status=status.HTTP_200_OK)
class PublicUserDetailView(APIView):
@@ -87,6 +90,8 @@ class PublicUserDetailView(APIView):
else:
user = get_object_or_404(User, username=username, public_profile=True)
serializer = PublicUserSerializer(user)
+ # for every user, remove the field has_password
+ serializer.data.pop('has_password', None)
# remove the email address from the response
user.email = None
diff --git a/backend/server/worldtravel/management/commands/download-countries.py b/backend/server/worldtravel/management/commands/download-countries.py
index 9930b8e..f5c5702 100644
--- a/backend/server/worldtravel/management/commands/download-countries.py
+++ b/backend/server/worldtravel/management/commands/download-countries.py
@@ -8,7 +8,7 @@ import ijson
from django.conf import settings
-ADVENTURELOG_CDN_URL = settings.ADVENTURELOG_CDN_URL
+COUNTRY_REGION_JSON_VERSION = settings.COUNTRY_REGION_JSON_VERSION
media_root = settings.MEDIA_ROOT
@@ -27,7 +27,7 @@ def saveCountryFlag(country_code):
print(f'Flag for {country_code} already exists')
return
- res = requests.get(f'{ADVENTURELOG_CDN_URL}/data/flags/{country_code}.png'.lower())
+ res = requests.get(f'https://flagcdn.com/h240/{country_code}.png'.lower())
if res.status_code == 200:
with open(flag_path, 'wb') as f:
f.write(res.content)
@@ -39,56 +39,30 @@ class Command(BaseCommand):
help = 'Imports the world travel data'
def add_arguments(self, parser):
- parser.add_argument('--force', action='store_true', help='Force re-download of AdventureLog setup content from the CDN')
+ parser.add_argument('--force', action='store_true', help='Force download the countries+regions+states.json file')
def handle(self, **options):
force = options['force']
batch_size = 100
- current_version_json = os.path.join(settings.MEDIA_ROOT, 'data_version.json')
- try:
- cdn_version_json = requests.get(f'{ADVENTURELOG_CDN_URL}/data/version.json')
- cdn_version_json.raise_for_status()
- cdn_version = cdn_version_json.json().get('version')
- if os.path.exists(current_version_json):
- with open(current_version_json, 'r') as f:
- local_version = f.read().strip()
- self.stdout.write(self.style.SUCCESS(f'Local version: {local_version}'))
+ countries_json_path = os.path.join(settings.MEDIA_ROOT, f'countries+regions+states-{COUNTRY_REGION_JSON_VERSION}.json')
+ if not os.path.exists(countries_json_path) or force:
+ res = requests.get(f'https://raw.githubusercontent.com/dr5hn/countries-states-cities-database/{COUNTRY_REGION_JSON_VERSION}/json/countries%2Bstates%2Bcities.json')
+ if res.status_code == 200:
+ with open(countries_json_path, 'w') as f:
+ f.write(res.text)
+ self.stdout.write(self.style.SUCCESS('countries+regions+states.json downloaded successfully'))
else:
- local_version = None
-
- if force or local_version != cdn_version:
- with open(current_version_json, 'w') as f:
- f.write(cdn_version)
- self.stdout.write(self.style.SUCCESS('Version updated successfully to ' + cdn_version))
- else:
- self.stdout.write(self.style.SUCCESS('Data is already up-to-date. Run with --force to re-download'))
+ self.stdout.write(self.style.ERROR('Error downloading countries+regions+states.json'))
return
- except requests.RequestException as e:
- self.stdout.write(self.style.ERROR(f'Error fetching version from the CDN: {e}, skipping data import. Try restarting the container once CDN connection has been restored.'))
+ elif not os.path.isfile(countries_json_path):
+ self.stdout.write(self.style.ERROR('countries+regions+states.json is not a file'))
return
-
- self.stdout.write(self.style.SUCCESS('Fetching latest data from the AdventureLog CDN located at: ' + ADVENTURELOG_CDN_URL))
-
- # Delete the existing flags
- flags_dir = os.path.join(media_root, 'flags')
- if os.path.exists(flags_dir):
- for file in os.listdir(flags_dir):
- os.remove(os.path.join(flags_dir, file))
-
- # Delete the existing countries, regions, and cities json files
- countries_json_path = os.path.join(media_root, 'countries_states_cities.json')
- if os.path.exists(countries_json_path):
- os.remove(countries_json_path)
- self.stdout.write(self.style.SUCCESS('countries_states_cities.json deleted successfully'))
-
- # Download the latest countries, regions, and cities json file
- res = requests.get(f'{ADVENTURELOG_CDN_URL}/data/countries_states_cities.json')
- if res.status_code == 200:
- with open(countries_json_path, 'w') as f:
- f.write(res.text)
- self.stdout.write(self.style.SUCCESS('countries_states_cities.json downloaded successfully'))
+ elif os.path.getsize(countries_json_path) == 0:
+ self.stdout.write(self.style.ERROR('countries+regions+states.json is empty'))
+ elif Country.objects.count() == 0 or Region.objects.count() == 0 or City.objects.count() == 0:
+ self.stdout.write(self.style.WARNING('Some region data is missing. Re-importing all data.'))
else:
- self.stdout.write(self.style.ERROR('Error downloading countries_states_cities.json'))
+ self.stdout.write(self.style.SUCCESS('Latest country, region, and state data already downloaded.'))
return
with open(countries_json_path, 'r') as f:
diff --git a/frontend/src/lib/components/ActivityComplete.svelte b/frontend/src/lib/components/ActivityComplete.svelte
index ef39c52..099898c 100644
--- a/frontend/src/lib/components/ActivityComplete.svelte
+++ b/frontend/src/lib/components/ActivityComplete.svelte
@@ -18,9 +18,7 @@
'Content-Type': 'application/json'
}
});
- console.log(res);
let data = await res.json();
- console.log('ACTIVITIES' + data.activities);
if (data && data.activities) {
allActivities = data.activities;
}
diff --git a/frontend/src/lib/components/AdventureModal.svelte b/frontend/src/lib/components/AdventureModal.svelte
index 3a5afc9..84c41a9 100644
--- a/frontend/src/lib/components/AdventureModal.svelte
+++ b/frontend/src/lib/components/AdventureModal.svelte
@@ -14,6 +14,8 @@
let categories: Category[] = [];
+ export let initialLatLng: { lat: number; lng: number } | null = null; // Used to pass the location from the map selection to the modal
+
let fileInput: HTMLInputElement;
let immichIntegration: boolean = false;
@@ -87,7 +89,6 @@
onMount(async () => {
modal = document.getElementById('my_modal_1') as HTMLDialogElement;
modal.showModal();
- console.log('open');
});
let url: string = '';
@@ -142,14 +143,11 @@
const input = event.target as HTMLInputElement;
if (input.files && input.files.length) {
selectedFile = input.files[0];
- console.log('Selected file:', selectedFile);
}
}
async function uploadAttachment(event: Event) {
event.preventDefault();
- console.log('UPLOAD');
- console.log(selectedFile);
if (!selectedFile) {
console.error('No files selected');
@@ -157,23 +155,18 @@
}
const file = selectedFile;
- console.log(file);
const formData = new FormData();
formData.append('file', file);
formData.append('adventure', adventure.id);
formData.append('name', attachmentName);
- console.log(formData);
-
try {
const res = await fetch('/adventures?/attachment', {
method: 'POST',
body: formData
});
- console.log(res);
-
if (res.ok) {
const newData = deserialize(await res.text()) as { data: Attachment };
adventure.attachments = [...adventure.attachments, newData.data];
@@ -202,7 +195,6 @@
if (res.status === 204) {
images = images.filter((image) => image.id !== id);
adventure.images = images;
- console.log(images);
addToast('success', $t('adventures.image_removed_success'));
} else {
addToast('error', $t('adventures.image_removed_error'));
@@ -255,9 +247,7 @@
});
if (res.ok) {
let newData = deserialize(await res.text()) as { data: { id: string; image: string } };
- console.log(newData);
let newImage = { id: newData.data.id, image: newData.data.image, is_primary: false };
- console.log(newImage);
images = [...images, newImage];
adventure.images = images;
addToast('success', $t('adventures.image_upload_success'));
@@ -308,9 +298,7 @@
});
if (res2.ok) {
let newData = deserialize(await res2.text()) as { data: { id: string; image: string } };
- console.log(newData);
let newImage = { id: newData.data.id, image: newData.data.image, is_primary: false };
- console.log(newImage);
images = [...images, newImage];
adventure.images = images;
addToast('success', $t('adventures.image_upload_success'));
@@ -371,30 +359,11 @@
}
}
- function imageSubmit() {
- return async ({ result }: any) => {
- if (result.type === 'success') {
- if (result.data.id && result.data.image) {
- adventure.images = [...adventure.images, result.data];
- images = [...images, result.data];
- addToast('success', $t('adventures.image_upload_success'));
-
- fileInput.value = '';
- console.log(adventure);
- } else {
- addToast('error', result.data.error || $t('adventures.image_upload_error'));
- }
- }
- };
- }
-
async function handleSubmit(event: Event) {
event.preventDefault();
triggerMarkVisted = true;
- console.log(adventure);
if (adventure.id === '') {
- console.log(categories);
if (adventure.category?.display_name == '') {
if (categories.some((category) => category.name === 'general')) {
adventure.category = categories.find(
@@ -597,7 +566,7 @@
-
+
@@ -958,7 +927,7 @@
{/if}
{#if adventure.is_public && adventure.id}
-
+
{$t('adventures.share_adventure')}
diff --git a/frontend/src/lib/components/Avatar.svelte b/frontend/src/lib/components/Avatar.svelte
index 4bae036..2220e0f 100644
--- a/frontend/src/lib/components/Avatar.svelte
+++ b/frontend/src/lib/components/Avatar.svelte
@@ -40,6 +40,9 @@
+ {#if user.is_staff}
+
+ {/if}
diff --git a/frontend/src/lib/components/LocationDropdown.svelte b/frontend/src/lib/components/LocationDropdown.svelte
index 83a2837..65efc4e 100644
--- a/frontend/src/lib/components/LocationDropdown.svelte
+++ b/frontend/src/lib/components/LocationDropdown.svelte
@@ -2,12 +2,15 @@
import { appVersion } from '$lib/config';
import { addToast } from '$lib/toasts';
import type { Adventure, Lodging, OpenStreetMapPlace, Point, ReverseGeocode } from '$lib/types';
+ import { onMount } from 'svelte';
import { t } from 'svelte-i18n';
import { DefaultMarker, MapEvents, MapLibre } from 'svelte-maplibre';
export let item: Adventure | Lodging;
export let triggerMarkVisted: boolean = false;
+ export let initialLatLng: { lat: number; lng: number } | null = null; // Used to pass the location from the map selection to the modal
+
let reverseGeocodePlace: ReverseGeocode | null = null;
let markers: Point[] = [];
@@ -19,6 +22,22 @@
let places: OpenStreetMapPlace[] = [];
let noPlaces: boolean = false;
+ onMount(() => {
+ if (initialLatLng) {
+ markers = [
+ {
+ lngLat: { lng: initialLatLng.lng, lat: initialLatLng.lat },
+ name: '',
+ location: '',
+ activity_type: ''
+ }
+ ];
+ item.latitude = initialLatLng.lat;
+ item.longitude = initialLatLng.lng;
+ reverseGeocode();
+ }
+ });
+
$: if (markers.length > 0) {
const newLat = Math.round(markers[0].lngLat.lat * 1e6) / 1e6;
const newLng = Math.round(markers[0].lngLat.lng * 1e6) / 1e6;
@@ -35,10 +54,6 @@
}
}
- $: {
- console.log(triggerMarkVisted);
- }
-
$: if (triggerMarkVisted && willBeMarkedVisited) {
markVisited();
triggerMarkVisted = false;
@@ -84,8 +99,6 @@
break; // Exit the loop since we've determined the result
}
}
-
- console.log('WMBV:', willBeMarkedVisited);
}
}
@@ -180,6 +193,9 @@
) {
old_display_name = reverseGeocodePlace.display_name;
item.location = reverseGeocodePlace.display_name;
+ if (reverseGeocodePlace.location_name) {
+ item.name = reverseGeocodePlace.location_name;
+ }
}
console.log(data);
}
@@ -187,6 +203,8 @@
function clearMap() {
console.log('CLEAR');
markers = [];
+ item.latitude = null;
+ item.longitude = null;
}
@@ -268,6 +286,8 @@
style="https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json"
class="relative aspect-[9/16] max-h-[70vh] w-full sm:aspect-video sm:max-h-full rounded-lg"
standardControls
+ zoom={item.latitude && item.longitude ? 12 : 1}
+ center={{ lng: item.longitude || 0, lat: item.latitude || 0 }}
>
+
{#if lodging.location}
-
{$t('adventures.from')}:
-
{lodging.location}
+
{$t('adventures.location')}:
+
{lodging.location}
{/if}
+
{#if lodging.check_in && lodging.check_out}
-
{$t('adventures.start')}:
-
{new Date(lodging.check_in).toLocaleDateString(undefined, { timeZone: 'UTC' })}
-
- {/if}
-
-
-
-
- {#if lodging.location}
-
-
-
{$t('adventures.to')}:
-
-
{lodging.location}
-
- {/if}
- {#if lodging.check_out}
-
-
{$t('adventures.end')}:
-
{new Date(lodging.check_out).toLocaleDateString(undefined, { timeZone: 'UTC' })}
+
{$t('adventures.dates')}:
+
+ {new Date(lodging.check_in).toLocaleString('en-US', {
+ month: 'short',
+ day: 'numeric',
+ year: 'numeric',
+ hour: 'numeric',
+ minute: 'numeric'
+ })}
+ -
+ {new Date(lodging.check_out).toLocaleString('en-US', {
+ month: 'short',
+ day: 'numeric',
+ year: 'numeric',
+ hour: 'numeric',
+ minute: 'numeric'
+ })}
+
{/if}
diff --git a/frontend/src/lib/components/LodgingModal.svelte b/frontend/src/lib/components/LodgingModal.svelte
index f4a5c66..b7b9815 100644
--- a/frontend/src/lib/components/LodgingModal.svelte
+++ b/frontend/src/lib/components/LodgingModal.svelte
@@ -53,8 +53,8 @@
description: hotelToEdit?.description || '',
rating: hotelToEdit?.rating || NaN,
link: hotelToEdit?.link || '',
- check_in: hotelToEdit?.check_in || null,
- check_out: hotelToEdit?.check_out || null,
+ check_in: hotelToEdit?.check_in ? toLocalDatetime(hotelToEdit.check_in) : null,
+ check_out: hotelToEdit?.check_out ? toLocalDatetime(hotelToEdit.check_out) : null,
reservation_number: hotelToEdit?.reservation_number || '',
price: hotelToEdit?.price || null,
latitude: hotelToEdit?.latitude || null,
@@ -166,6 +166,32 @@
required
/>
+
+
+
+
+
+
@@ -250,13 +276,53 @@
+
+
+
+
+ {$t('adventures.lodging_information')}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{$t('adventures.date_information')}
-
+
+
+
+
+
+
-
-
-
-
-
diff --git a/frontend/src/lib/index.ts b/frontend/src/lib/index.ts
index e5d96e3..df3e9e3 100644
--- a/frontend/src/lib/index.ts
+++ b/frontend/src/lib/index.ts
@@ -5,6 +5,7 @@ import type {
Background,
Checklist,
Collection,
+ Lodging,
Note,
Transportation,
User
@@ -149,6 +150,50 @@ export function groupTransportationsByDate(
return groupedTransportations;
}
+export function groupLodgingByDate(
+ transportations: Lodging[],
+ startDate: Date,
+ numberOfDays: number
+): Record
{
+ const groupedTransportations: Record = {};
+
+ // Initialize all days in the range
+ for (let i = 0; i < numberOfDays; i++) {
+ const currentDate = new Date(startDate);
+ currentDate.setUTCDate(startDate.getUTCDate() + i);
+ const dateString = currentDate.toISOString().split('T')[0];
+ groupedTransportations[dateString] = [];
+ }
+
+ transportations.forEach((transportation) => {
+ if (transportation.check_in) {
+ const transportationDate = new Date(transportation.check_in).toISOString().split('T')[0];
+ if (transportation.check_out) {
+ const endDate = new Date(transportation.check_out).toISOString().split('T')[0];
+
+ // Loop through all days and include transportation if it falls within the range
+ for (let i = 0; i < numberOfDays; i++) {
+ const currentDate = new Date(startDate);
+ currentDate.setUTCDate(startDate.getUTCDate() + i);
+ const dateString = currentDate.toISOString().split('T')[0];
+
+ // Include the current day if it falls within the transportation date range
+ if (dateString >= transportationDate && dateString <= endDate) {
+ if (groupedTransportations[dateString]) {
+ groupedTransportations[dateString].push(transportation);
+ }
+ }
+ }
+ } else if (groupedTransportations[transportationDate]) {
+ // If there's no end date, add transportation to the start date only
+ groupedTransportations[transportationDate].push(transportation);
+ }
+ }
+ });
+
+ return groupedTransportations;
+}
+
export function groupNotesByDate(
notes: Note[],
startDate: Date,
@@ -473,4 +518,4 @@ export function debounce(func: Function, timeout: number) {
func(...args);
}, timeout);
};
-}
\ No newline at end of file
+}
diff --git a/frontend/src/lib/types.ts b/frontend/src/lib/types.ts
index b86b670..15ada33 100644
--- a/frontend/src/lib/types.ts
+++ b/frontend/src/lib/types.ts
@@ -210,6 +210,7 @@ export type ReverseGeocode = {
display_name: string;
city: string;
city_id: string;
+ location_name: string;
};
export type Category = {
diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json
index df04d4c..579a179 100644
--- a/frontend/src/locales/en.json
+++ b/frontend/src/locales/en.json
@@ -1,605 +1,616 @@
{
- "navbar": {
- "adventures": "Adventures",
- "collections": "Collections",
- "worldtravel": "World Travel",
- "map": "Map",
- "users": "Users",
- "search": "Search",
- "profile": "Profile",
- "greeting": "Hi",
- "my_adventures": "My Adventures",
- "my_tags": "My Tags",
- "tag": "Tag",
- "shared_with_me": "Shared With Me",
- "settings": "Settings",
- "logout": "Logout",
- "about": "About AdventureLog",
- "documentation": "Documentation",
- "discord": "Discord",
- "language_selection": "Language",
- "support": "Support",
- "calendar": "Calendar",
- "theme_selection": "Theme Selection",
- "themes": {
- "light": "Light",
- "dark": "Dark",
- "night": "Night",
- "forest": "Forest",
- "aestheticLight": "Aesthetic Light",
- "aestheticDark": "Aesthetic Dark",
- "aqua": "Aqua",
- "northernLights": "Northern Lights"
- }
- },
- "about": {
- "about": "About",
- "license": "Licensed under the GPL-3.0 License.",
- "source_code": "Source Code",
- "message": "Made with ❤️ in the United States.",
- "oss_attributions": "Open Source Attributions",
- "nominatim_1": "Location Search and Geocoding is provided by",
- "nominatim_2": "Their data is liscensed under the ODbL license.",
- "other_attributions": "Additional attributions can be found in the README file.",
- "close": "Close"
- },
- "home": {
- "hero_1": "Discover the World's Most Thrilling Adventures",
- "hero_2": "Discover and plan your next adventure with AdventureLog. Explore breathtaking destinations, create custom itineraries, and stay connected on the go.",
- "go_to": "Go To AdventureLog",
- "key_features": "Key Features",
- "desc_1": "Discover, Plan, and Explore with Ease",
- "desc_2": "AdventureLog is designed to simplify your journey, providing you with the tools and resources to plan, pack, and navigate your next unforgettable adventure.",
- "feature_1": "Travel Log",
- "feature_1_desc": "Keep track of your adventures with a personalized travel log and share your experiences with friends and family.",
- "feature_2": "Trip Planning",
- "feature_2_desc": "Easily create custom itineraries and get a day-by-day breakdown of your trip.",
- "feature_3": "Travel Map",
- "feature_3_desc": "View your travels throughout the world with an interactive map and explore new destinations."
- },
- "adventures": {
- "collection_remove_success": "Adventure removed from collection successfully!",
- "collection_remove_error": "Error removing adventure from collection",
- "collection_link_success": "Adventure linked to collection successfully!",
- "no_image_found": "No image found",
- "collection_link_error": "Error linking adventure to collection",
- "adventure_delete_confirm": "Are you sure you want to delete this adventure? This action cannot be undone.",
- "checklist_delete_confirm": "Are you sure you want to delete this checklist? This action cannot be undone.",
- "note_delete_confirm": "Are you sure you want to delete this note? This action cannot be undone.",
- "transportation_delete_confirm": "Are you sure you want to delete this transportation? This action cannot be undone.",
- "delete_checklist": "Delete Checklist",
- "delete_note": "Delete Note",
- "delete_transportation": "Delete Transportation",
- "open_details": "Open Details",
- "edit_adventure": "Edit Adventure",
- "remove_from_collection": "Remove from Collection",
- "add_to_collection": "Add to Collection",
- "delete": "Delete",
- "not_found": "Adventure not found",
- "not_found_desc": "The adventure you were looking for could not be found. Please try a different adventure or check back later.",
- "homepage": "Homepage",
- "adventure_details": "Adventure Details",
- "collection": "Collection",
- "adventure_type": "Adventure Type",
- "longitude": "Longitude",
- "latitude": "Latitude",
- "visit": "Visit",
- "visits": "Visits",
- "create_new": "Create New...",
- "adventure": "Adventure",
- "count_txt": "results matching your search",
- "sort": "Sort",
- "order_by": "Order By",
- "order_direction": "Order Direction",
- "ascending": "Ascending",
- "descending": "Descending",
- "updated": "Updated",
- "name": "Name",
- "date": "Date",
- "activity_types": "Activity Types",
- "tags": "Tags",
- "add_a_tag": "Add a tag",
- "date_constrain": "Constrain to collection dates",
- "rating": "Rating",
- "my_images": "My Images",
- "add_an_activity": "Add an activity",
- "show_region_labels": "Show Region Labels",
- "no_images": "No Images",
- "upload_images_here": "Upload images here",
- "share_adventure": "Share this Adventure!",
- "copy_link": "Copy Link",
- "image": "Image",
- "upload_image": "Upload Image",
- "url": "URL",
- "fetch_image": "Fetch Image",
- "wikipedia": "Wikipedia",
- "add_notes": "Add notes",
- "warning": "Warning",
- "my_adventures": "My Adventures",
- "no_linkable_adventures": "No adventures found that can be linked to this collection.",
- "add": "Add",
- "save_next": "Save & Next",
- "end_date": "End Date",
- "my_visits": "My Visits",
- "start_date": "Start Date",
- "remove": "Remove",
- "location": "Location",
- "search_for_location": "Search for a location",
- "clear_map": "Clear map",
- "search_results": "Searh results",
- "no_results": "No results found",
- "wiki_desc": "Pulls excerpt from Wikipedia article matching the name of the adventure.",
- "attachments": "Attachments",
- "attachment": "Attachment",
- "images": "Images",
- "primary": "Primary",
- "view_attachment": "View Attachment",
- "generate_desc": "Generate Description",
- "public_adventure": "Public Adventure",
- "location_information": "Location Information",
- "link": "Link",
- "links": "Links",
- "description": "Description",
- "sources": "Sources",
- "collection_adventures": "Include Collection Adventures",
- "filter": "Filter",
- "category_filter": "Category Filter",
- "category": "Category",
- "select_adventure_category": "Select Adventure Category",
- "clear": "Clear",
- "my_collections": "My Collections",
- "open_filters": "Open Filters",
- "close_filters": "Close Filters",
- "archived_collections": "Archived Collections",
- "share": "Share",
- "private": "Private",
- "public": "Public",
- "archived": "Archived",
- "edit_collection": "Edit Collection",
- "unarchive": "Unarchive",
- "archive": "Archive",
- "no_collections_found": "No collections found to add this adventure to.",
- "not_visited": "Not Visited",
- "archived_collection_message": "Collection archived successfully!",
- "unarchived_collection_message": "Collection unarchived successfully!",
- "delete_collection_success": "Collection deleted successfully!",
- "delete_collection_warning": "Are you sure you want to delete this collection? This will also delete all of the linked adventures. This action cannot be undone.",
- "cancel": "Cancel",
- "of": "of",
- "delete_collection": "Delete Collection",
- "delete_adventure": "Delete Adventure",
- "adventure_delete_success": "Adventure deleted successfully!",
- "visited": "Visited",
- "planned": "Planned",
- "duration": "Duration",
- "all": "All",
- "image_removed_success": "Image removed successfully!",
- "image_removed_error": "Error removing image",
- "no_image_url": "No image found at that URL.",
- "image_upload_success": "Image uploaded successfully!",
- "image_upload_error": "Error uploading image",
- "dates": "Dates",
- "wiki_image_error": "Error fetching image from Wikipedia",
- "start_before_end_error": "Start date must be before end date",
- "activity": "Activity",
- "actions": "Actions",
- "no_end_date": "Please enter an end date",
- "see_adventures": "See Adventures",
- "image_fetch_failed": "Failed to fetch image",
- "no_location": "Please enter a location",
- "no_start_date": "Please enter a start date",
- "no_description_found": "No description found",
- "adventure_created": "Adventure created",
- "adventure_create_error": "Failed to create adventure",
- "lodging": "Lodging",
- "create_adventure": "Create Adventure",
- "adventure_updated": "Adventure updated",
- "adventure_update_error": "Failed to update adventure",
- "set_to_pin": "Set to Pin",
- "category_fetch_error": "Error fetching categories",
- "new_adventure": "New Adventure",
- "basic_information": "Basic Information",
- "no_adventures_to_recommendations": "No adventures found. Add at leat one adventure to get recommendations.",
- "display_name": "Display Name",
- "adventure_not_found": "There are no adventures to display. Add some using the plus button at the bottom right or try changing filters!",
- "no_adventures_found": "No adventures found",
- "mark_region_as_visited": "Mark region {region}, {country} as visited?",
- "mark_visited": "Mark Visited",
- "error_updating_regions": "Error updating regions",
- "regions_updated": "regions updated",
- "cities_updated": "cities updated",
- "visited_region_check": "Visited Region Check",
- "visited_region_check_desc": "By selecting this, the server will check all of your visited adventures and mark the regions they are located in as visited in world travel.",
- "update_visited_regions": "Update Visited Regions",
- "update_visited_regions_disclaimer": "This may take a while depending on the number of adventures you have visited.",
- "link_new": "Link New...",
- "add_new": "Add New...",
- "transportation": "Transportation",
- "note": "Note",
- "checklist": "Checklist",
- "collection_archived": "This collection has been archived.",
- "visit_link": "Visit Link",
- "collection_completed": "You've completed this collection!",
- "collection_stats": "Collection Stats",
- "keep_exploring": "Keep Exploring!",
- "linked_adventures": "Linked Adventures",
- "notes": "Notes",
- "checklists": "Checklists",
- "transportations": "Transportations",
- "adventure_calendar": "Adventure Calendar",
- "day": "Day",
- "itineary_by_date": "Itinerary by Date",
- "nothing_planned": "Nothing planned for this day. Enjoy the journey!",
- "copied_to_clipboard": "Copied to clipboard!",
- "copy_failed": "Copy failed",
- "show": "Show",
- "hide": "Hide",
- "clear_location": "Clear Location",
- "starting_airport": "Starting Airport",
- "ending_airport": "Ending Airport",
- "no_location_found": "No location found",
- "from": "From",
- "to": "To",
- "will_be_marked": "will be marked as visited once the adventure is saved.",
- "start": "Start",
- "end": "End",
- "show_map": "Show Map",
- "emoji_picker": "Emoji Picker",
- "download_calendar": "Download Calendar",
- "date_information": "Date Information",
- "flight_information": "Flight Information",
- "out_of_range": "Not in itinerary date range",
- "preview": "Preview",
- "finding_recommendations": "Discovering hidden gems for your next adventure",
- "location_details": "Location Details",
- "city": "City",
- "region": "Region",
- "md_instructions": "Write your markdown here...",
- "days": "days",
- "attachment_upload_success": "Attachment uploaded successfully!",
- "attachment_upload_error": "Error uploading attachment",
- "upload": "Upload",
- "attachment_delete_success": "Attachment deleted successfully!",
- "attachment_update_success": "Attachment updated successfully!",
- "attachment_name": "Attachment Name",
- "gpx_tip": "Upload GPX files to attachments to view them on the map!",
- "attachment_update_error": "Error updating attachment",
- "activities": {
- "general": "General 🌍",
- "outdoor": "Outdoor 🏞️",
- "lodging": "Lodging 🛌",
- "dining": "Dining 🍽️",
- "activity": "Activity 🏄",
- "attraction": "Attraction 🎢",
- "shopping": "Shopping 🛍️",
- "nightlife": "Nightlife 🌃",
- "event": "Event 🎉",
- "transportation": "Transportation 🚗",
- "culture": "Culture 🎭",
- "water_sports": "Water Sports 🚤",
- "hiking": "Hiking 🥾",
- "wildlife": "Wildlife 🦒",
- "historical_sites": "Historical Sites 🏛️",
- "music_concerts": "Music & Concerts 🎶",
- "fitness": "Fitness 🏋️",
- "art_museums": "Art & Museums 🎨",
- "festivals": "Festivals 🎪",
- "spiritual_journeys": "Spiritual Journeys 🧘♀️",
- "volunteer_work": "Volunteer Work 🤝",
- "other": "Other"
- }
- },
- "worldtravel": {
- "country_list": "Country List",
- "num_countries": "countries found",
- "all": "All",
- "partially_visited": "Partially Visited",
- "not_visited": "Not Visited",
- "completely_visited": "Completely Visited",
- "all_subregions": "All Subregions",
- "clear_search": "Clear Search",
- "no_countries_found": "No countries found",
- "view_cities": "View Cities",
- "no_cities_found": "No cities found",
- "visit_to": "Visit to",
- "region_failed_visited": "Failed to mark region as visited",
- "failed_to_mark_visit": "Failed to mark visit to",
- "visit_remove_failed": "Failed to remove visit",
- "removed": "removed",
- "failed_to_remove_visit": "Failed to remove visit to",
- "marked_visited": "marked as visited",
- "regions_in": "Regions in",
- "region_stats": "Region Stats",
- "all_visited": "You've visited all regions in",
- "cities": "cities"
- },
- "auth": {
- "username": "Username",
- "password": "Password",
- "forgot_password": "Forgot Password?",
- "signup": "Signup",
- "login_error": "Unable to login with the provided credentials.",
- "login": "Login",
- "email": "Email",
- "first_name": "First Name",
- "last_name": "Last Name",
- "confirm_password": "Confirm Password",
- "registration_disabled": "Registration is currently disabled.",
- "profile_picture": "Profile Picture",
- "public_profile": "Public Profile",
- "public_tooltip": "With a public profile, users can share collections with you and view your profile on the users page.",
- "email_required": "Email is required",
- "new_password": "New Password (6+ characters)",
- "both_passwords_required": "Both passwords are required",
- "reset_failed": "Failed to reset password",
- "or_3rd_party": "Or login with a third-party service",
- "no_public_adventures": "No public adventures found",
- "no_public_collections": "No public collections found",
- "user_adventures": "User Adventures",
- "user_collections": "User Collections"
- },
- "users": {
- "no_users_found": "No users found with public profiles."
- },
- "settings": {
- "update_error": "Error updating settings",
- "update_success": "Settings updated successfully!",
- "settings_page": "Settings Page",
- "account_settings": "User Account Settings",
- "update": "Update",
- "no_verified_email_warning": "You must have a verified email address to enable two-factor authentication.",
- "password_change": "Change Password",
- "new_password": "New Password",
- "confirm_new_password": "Confirm New Password",
- "email_change": "Change Email",
- "current_email": "Current Email",
- "no_email_set": "No email set",
- "new_email": "New Email",
- "change_password": "Change Password",
- "login_redir": "You will then be redirected to the login page.",
- "token_required": "Token and UID are required for password reset.",
- "reset_password": "Reset Password",
- "possible_reset": "If the email address you provided is associated with an account, you will receive an email with instructions to reset your password!",
- "missing_email": "Please enter an email address",
- "submit": "Submit",
- "password_does_not_match": "Passwords do not match",
- "password_is_required": "Password is required",
- "invalid_token": "Token is invalid or has expired",
- "about_this_background": "About this background",
- "photo_by": "Photo by",
- "join_discord": "Join the Discord",
- "join_discord_desc": "to share your own photos. Post them in the #travel-share channel.",
- "current_password": "Current Password",
- "change_password_error": "Unable to change password. Invalid current password or invalid new password.",
- "password_change_lopout_warning": "You will be logged out after changing your password.",
- "generic_error": "An error occurred while processing your request.",
- "email_removed": "Email removed successfully!",
- "email_removed_error": "Error removing email",
- "verify_email_success": "Email verification sent successfully!",
- "verify_email_error": "Error verifying email. Try again in a few minutes.",
- "email_added": "Email added successfully!",
- "email_added_error": "Error adding email",
- "email_set_primary": "Email set as primary successfully!",
- "email_set_primary_error": "Error setting email as primary",
- "verified": "Verified",
- "primary": "Primary",
- "not_verified": "Not Verified",
- "make_primary": "Make Primary",
- "verify": "Verify",
- "no_emai_set": "No email set",
- "error_change_password": "Error changing password. Please check your current password and try again.",
- "mfa_disabled": "Multi-factor authentication disabled successfully!",
- "mfa_page_title": "Multi-factor Authentication",
- "enable_mfa": "Enable MFA",
- "disable_mfa": "Disable MFA",
- "mfa_not_enabled": "MFA is not enabled",
- "mfa_enabled": "Multi-factor authentication enabled successfully!",
- "copy": "Copy",
- "recovery_codes": "Recovery Codes",
- "recovery_codes_desc": "These are your recovery codes. Keep them safe. You will not be able to see them again.",
- "reset_session_error": "Please logout and back in to refresh your session and try again.",
- "authenticator_code": "Authenticator Code",
- "email_verified": "Email verified successfully!",
- "email_verified_success": "Your email has been verified. You can now log in.",
- "email_verified_error": "Error verifying email",
- "email_verified_erorr_desc": "Your email could not be verified. Please try again.",
- "invalid_code": "Invalid MFA code",
- "invalid_credentials": "Invalid username or password",
- "mfa_required": "Multi-factor authentication is required",
- "required": "This field is required",
- "add_email_blocked": "You cannot add an email address to an account protected by two-factor authentication.",
- "duplicate_email": "This email address is already in use.",
- "csrf_failed": "Failed to fetch CSRF token",
- "email_taken": "This email address is already in use.",
- "username_taken": "This username is already in use.",
- "administration_settings": "Administration Settings",
- "launch_administration_panel": "Launch Administration Panel",
- "social_oidc_auth": "Social and OIDC Authentication",
- "social_auth_desc": "Enable or disable social and OIDC authentication providers for your account. These connections allow you to sign in with self hosted authentication identity providers like Authentik or 3rd party providers like GitHub.",
- "social_auth_desc_2": "These settings are managed in the AdventureLog server and must be manually enabled by the administrator.",
- "documentation_link": "Documentation Link",
- "launch_account_connections": "Launch Account Connections",
- "password_too_short": "Password must be at least 6 characters",
- "add_email": "Add Email"
- },
- "collection": {
- "collection_created": "Collection created successfully!",
- "error_creating_collection": "Error creating collection",
- "new_collection": "New Collection",
- "create": "Create",
- "collection_edit_success": "Collection edited successfully!",
- "error_editing_collection": "Error editing collection",
- "edit_collection": "Edit Collection",
- "public_collection": "Public Collection"
- },
- "notes": {
- "note_deleted": "Note deleted successfully!",
- "note_delete_error": "Error deleting note",
- "open": "Open",
- "failed_to_save": "Failed to save note",
- "note_editor": "Note Editor",
- "note_viewer": "Note Viewer",
- "editing_note": "Editing note",
- "content": "Content",
- "save": "Save",
- "note_public": "This note is public because it is in a public collection.",
- "add_a_link": "Add a link",
- "invalid_url": "Invalid URL"
- },
- "checklist": {
- "checklist_deleted": "Checklist deleted successfully!",
- "checklist_delete_error": "Error deleting checklist",
- "failed_to_save": "Failed to save checklist",
- "checklist_editor": "Checklist Editor",
- "checklist_viewer": "Checklist Viewer",
- "editing_checklist": "Editing checklist",
- "new_checklist": "New Checklist",
- "item": "Item",
- "items": "Items",
- "add_item": "Add Item",
- "new_item": "New Item",
- "save": "Save",
- "checklist_public": "This checklist is public because it is in a public collection.",
- "item_cannot_be_empty": "Item cannot be empty",
- "item_already_exists": "Item already exists"
- },
- "transportation": {
- "transportation_deleted": "Transportation deleted successfully!",
- "transportation_delete_error": "Error deleting transportation",
- "provide_start_date": "Please provide a start date",
- "transport_type": "Transport Type",
- "type": "Type",
- "transportation_added": "Transportation added successfully!",
- "error_editing_transportation": "Error editing transportation",
- "new_transportation": "New Transportation",
- "date_time": "Start Date & Time",
- "end_date_time": "End Date & Time",
- "flight_number": "Flight Number",
- "from_location": "From Location",
- "to_location": "To Location",
- "edit": "Edit",
- "modes": {
- "car": "Car",
- "plane": "Plane",
- "train": "Train",
- "bus": "Bus",
- "boat": "Boat",
- "bike": "Bike",
- "walking": "Walking",
- "other": "Other"
- },
- "transportation_edit_success": "Transportation edited successfully!",
- "edit_transportation": "Edit Transportation",
- "start": "Start",
- "date_and_time": "Date & Time"
- },
- "lodging": {
- "lodging_deleted": "Lodging deleted successfully!",
- "lodging_delete_error": "Error deleting lodging",
- "provide_start_date": "Please provide a start date",
- "lodging_type": "Lodging Type",
- "type": "Type",
- "lodging_added": "Lodging added successfully!",
- "error_editing_lodging": "Error editing lodging",
- "new_lodging": "New Lodging",
- "check_in": "Check In",
- "check_out": "Check Out",
- "edit": "Edit",
- "modes": {
- "hotel": "Hotel",
- "hostel": "Hostel",
- "airbnb": "Airbnb",
- "camping": "Camping",
- "other": "Other"
- },
- "lodging_edit_success": "Lodging edited successfully!",
- "edit_lodging": "Edit Lodging",
- "start": "Start",
- "date_and_time": "Date & Time"
- },
- "search": {
- "adventurelog_results": "AdventureLog Results",
- "public_adventures": "Public Adventures",
- "online_results": "Online Results"
- },
- "map": {
- "view_details": "View Details",
- "adventure_map": "Adventure Map",
- "map_options": "Map Options",
- "show_visited_regions": "Show Visited Regions",
- "add_adventure_at_marker": "Add New Adventure at Marker",
- "clear_marker": "Clear Marker",
- "add_adventure": "Add New Adventure"
- },
- "share": {
- "shared": "Shared",
- "with": "with",
- "unshared": "Unshared",
- "share_desc": "Share this collection with other users.",
- "shared_with": "Shared With",
- "no_users_shared": "No users shared with",
- "not_shared_with": "Not Shared With",
- "no_shared_found": "No collections found that are shared with you.",
- "set_public": "In order to allow users to share with you, you need your profile set to public.",
- "go_to_settings": "Go to settings"
- },
- "languages": {},
- "profile": {
- "member_since": "Member since",
- "user_stats": "User Stats",
- "visited_countries": "Visited Countries",
- "visited_regions": "Visited Regions",
- "visited_cities": "Visited Cities"
- },
- "categories": {
- "manage_categories": "Manage Categories",
- "no_categories_found": "No categories found.",
- "edit_category": "Edit Category",
- "icon": "Icon",
- "update_after_refresh": "The adventure cards will be updated once you refresh the page.",
- "select_category": "Select Category",
- "category_name": "Category Name"
- },
- "dashboard": {
- "welcome_back": "Welcome back",
- "countries_visited": "Countries Visited",
- "total_adventures": "Total Adventures",
- "total_visited_regions": "Total Visited Regions",
- "total_visited_cities": "Total Visited Cities",
- "recent_adventures": "Recent Adventures",
- "no_recent_adventures": "No recent adventures?",
- "add_some": "Why not start planning your next adventure? You can add a new adventure by clicking the button below."
- },
- "immich": {
- "immich": "Immich",
- "integration_fetch_error": "Error fetching data from the Immich integration",
- "integration_missing": "The Immich integration is missing from the backend",
- "query_required": "Query is required",
- "server_down": "The Immich server is currently down or unreachable",
- "no_items_found": "No items found",
- "imageid_required": "Image ID is required",
- "load_more": "Load More",
- "immich_updated": "Immich settings updated successfully!",
- "immich_enabled": "Immich integration enabled successfully!",
- "immich_error": "Error updating Immich integration",
- "immich_disabled": "Immich integration disabled successfully!",
- "immich_desc": "Integrate your Immich account with AdventureLog to allow you to search your photos library and import photos for your adventures.",
- "integration_enabled": "Integration Enabled",
- "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.",
- "api_key": "Immich API Key",
- "enable_immich": "Enable Immich",
- "update_integration": "Update Integration",
- "immich_integration": "Immich Integration",
- "localhost_note": "Note: localhost will most likely not work unless you have setup docker networks accordingly. It is recommended to use the IP address of the server or the domain name.",
- "documentation": "Immich Integration Documentation"
- },
- "recomendations": {
- "address": "Address",
- "phone": "Phone",
- "contact": "Contact",
- "website": "Website",
- "recommendation": "Recommendation"
- }
+ "navbar": {
+ "adventures": "Adventures",
+ "collections": "Collections",
+ "worldtravel": "World Travel",
+ "map": "Map",
+ "users": "Users",
+ "search": "Search",
+ "profile": "Profile",
+ "greeting": "Hi",
+ "my_adventures": "My Adventures",
+ "my_tags": "My Tags",
+ "tag": "Tag",
+ "shared_with_me": "Shared With Me",
+ "settings": "Settings",
+ "logout": "Logout",
+ "about": "About AdventureLog",
+ "documentation": "Documentation",
+ "discord": "Discord",
+ "language_selection": "Language",
+ "support": "Support",
+ "calendar": "Calendar",
+ "theme_selection": "Theme Selection",
+ "admin_panel": "Admin Panel",
+ "themes": {
+ "light": "Light",
+ "dark": "Dark",
+ "night": "Night",
+ "forest": "Forest",
+ "aestheticLight": "Aesthetic Light",
+ "aestheticDark": "Aesthetic Dark",
+ "aqua": "Aqua",
+ "northernLights": "Northern Lights"
+ }
+ },
+ "about": {
+ "about": "About",
+ "license": "Licensed under the GPL-3.0 License.",
+ "source_code": "Source Code",
+ "message": "Made with ❤️ in the United States.",
+ "oss_attributions": "Open Source Attributions",
+ "nominatim_1": "Location Search and Geocoding is provided by",
+ "nominatim_2": "Their data is liscensed under the ODbL license.",
+ "other_attributions": "Additional attributions can be found in the README file.",
+ "close": "Close"
+ },
+ "home": {
+ "hero_1": "Discover the World's Most Thrilling Adventures",
+ "hero_2": "Discover and plan your next adventure with AdventureLog. Explore breathtaking destinations, create custom itineraries, and stay connected on the go.",
+ "go_to": "Go To AdventureLog",
+ "key_features": "Key Features",
+ "desc_1": "Discover, Plan, and Explore with Ease",
+ "desc_2": "AdventureLog is designed to simplify your journey, providing you with the tools and resources to plan, pack, and navigate your next unforgettable adventure.",
+ "feature_1": "Travel Log",
+ "feature_1_desc": "Keep track of your adventures with a personalized travel log and share your experiences with friends and family.",
+ "feature_2": "Trip Planning",
+ "feature_2_desc": "Easily create custom itineraries and get a day-by-day breakdown of your trip.",
+ "feature_3": "Travel Map",
+ "feature_3_desc": "View your travels throughout the world with an interactive map and explore new destinations."
+ },
+ "adventures": {
+ "collection_remove_success": "Adventure removed from collection successfully!",
+ "collection_remove_error": "Error removing adventure from collection",
+ "collection_link_success": "Adventure linked to collection successfully!",
+ "no_image_found": "No image found",
+ "collection_link_error": "Error linking adventure to collection",
+ "adventure_delete_confirm": "Are you sure you want to delete this adventure? This action cannot be undone.",
+ "checklist_delete_confirm": "Are you sure you want to delete this checklist? This action cannot be undone.",
+ "note_delete_confirm": "Are you sure you want to delete this note? This action cannot be undone.",
+ "transportation_delete_confirm": "Are you sure you want to delete this transportation? This action cannot be undone.",
+ "lodging_delete_confirm": "Are you sure you want to delete this lodging location? This action cannot be undone.",
+ "delete_checklist": "Delete Checklist",
+ "delete_note": "Delete Note",
+ "delete_transportation": "Delete Transportation",
+ "delete_lodging": "Delete Lodging",
+ "open_details": "Open Details",
+ "edit_adventure": "Edit Adventure",
+ "remove_from_collection": "Remove from Collection",
+ "add_to_collection": "Add to Collection",
+ "delete": "Delete",
+ "not_found": "Adventure not found",
+ "not_found_desc": "The adventure you were looking for could not be found. Please try a different adventure or check back later.",
+ "homepage": "Homepage",
+ "adventure_details": "Adventure Details",
+ "collection": "Collection",
+ "adventure_type": "Adventure Type",
+ "longitude": "Longitude",
+ "latitude": "Latitude",
+ "visit": "Visit",
+ "visits": "Visits",
+ "create_new": "Create New...",
+ "adventure": "Adventure",
+ "count_txt": "results matching your search",
+ "sort": "Sort",
+ "order_by": "Order By",
+ "order_direction": "Order Direction",
+ "ascending": "Ascending",
+ "descending": "Descending",
+ "updated": "Updated",
+ "name": "Name",
+ "date": "Date",
+ "activity_types": "Activity Types",
+ "tags": "Tags",
+ "add_a_tag": "Add a tag",
+ "date_constrain": "Constrain to collection dates",
+ "rating": "Rating",
+ "my_images": "My Images",
+ "add_an_activity": "Add an activity",
+ "show_region_labels": "Show Region Labels",
+ "no_images": "No Images",
+ "upload_images_here": "Upload images here",
+ "share_adventure": "Share this Adventure!",
+ "copy_link": "Copy Link",
+ "image": "Image",
+ "upload_image": "Upload Image",
+ "url": "URL",
+ "fetch_image": "Fetch Image",
+ "wikipedia": "Wikipedia",
+ "add_notes": "Add notes",
+ "warning": "Warning",
+ "my_adventures": "My Adventures",
+ "no_linkable_adventures": "No adventures found that can be linked to this collection.",
+ "add": "Add",
+ "save_next": "Save & Next",
+ "end_date": "End Date",
+ "my_visits": "My Visits",
+ "start_date": "Start Date",
+ "remove": "Remove",
+ "location": "Location",
+ "search_for_location": "Search for a location",
+ "clear_map": "Clear map",
+ "search_results": "Searh results",
+ "no_results": "No results found",
+ "wiki_desc": "Pulls excerpt from Wikipedia article matching the name of the adventure.",
+ "attachments": "Attachments",
+ "attachment": "Attachment",
+ "images": "Images",
+ "primary": "Primary",
+ "view_attachment": "View Attachment",
+ "generate_desc": "Generate Description",
+ "public_adventure": "Public Adventure",
+ "location_information": "Location Information",
+ "link": "Link",
+ "links": "Links",
+ "description": "Description",
+ "sources": "Sources",
+ "collection_adventures": "Include Collection Adventures",
+ "filter": "Filter",
+ "category_filter": "Category Filter",
+ "category": "Category",
+ "select_adventure_category": "Select Adventure Category",
+ "clear": "Clear",
+ "my_collections": "My Collections",
+ "open_filters": "Open Filters",
+ "close_filters": "Close Filters",
+ "archived_collections": "Archived Collections",
+ "share": "Share",
+ "private": "Private",
+ "public": "Public",
+ "archived": "Archived",
+ "edit_collection": "Edit Collection",
+ "unarchive": "Unarchive",
+ "archive": "Archive",
+ "no_collections_found": "No collections found to add this adventure to.",
+ "not_visited": "Not Visited",
+ "archived_collection_message": "Collection archived successfully!",
+ "unarchived_collection_message": "Collection unarchived successfully!",
+ "delete_collection_success": "Collection deleted successfully!",
+ "delete_collection_warning": "Are you sure you want to delete this collection? This will also delete all of the linked adventures. This action cannot be undone.",
+ "cancel": "Cancel",
+ "of": "of",
+ "delete_collection": "Delete Collection",
+ "delete_adventure": "Delete Adventure",
+ "adventure_delete_success": "Adventure deleted successfully!",
+ "visited": "Visited",
+ "planned": "Planned",
+ "duration": "Duration",
+ "all": "All",
+ "image_removed_success": "Image removed successfully!",
+ "image_removed_error": "Error removing image",
+ "no_image_url": "No image found at that URL.",
+ "image_upload_success": "Image uploaded successfully!",
+ "image_upload_error": "Error uploading image",
+ "dates": "Dates",
+ "wiki_image_error": "Error fetching image from Wikipedia",
+ "start_before_end_error": "Start date must be before end date",
+ "activity": "Activity",
+ "actions": "Actions",
+ "no_end_date": "Please enter an end date",
+ "see_adventures": "See Adventures",
+ "image_fetch_failed": "Failed to fetch image",
+ "no_location": "Please enter a location",
+ "no_start_date": "Please enter a start date",
+ "no_description_found": "No description found",
+ "adventure_created": "Adventure created",
+ "adventure_create_error": "Failed to create adventure",
+ "lodging": "Lodging",
+ "create_adventure": "Create Adventure",
+ "adventure_updated": "Adventure updated",
+ "adventure_update_error": "Failed to update adventure",
+ "set_to_pin": "Set to Pin",
+ "category_fetch_error": "Error fetching categories",
+ "new_adventure": "New Adventure",
+ "basic_information": "Basic Information",
+ "no_adventures_to_recommendations": "No adventures found. Add at leat one adventure to get recommendations.",
+ "display_name": "Display Name",
+ "adventure_not_found": "There are no adventures to display. Add some using the plus button at the bottom right or try changing filters!",
+ "no_adventures_found": "No adventures found",
+ "mark_region_as_visited": "Mark region {region}, {country} as visited?",
+ "mark_visited": "Mark Visited",
+ "error_updating_regions": "Error updating regions",
+ "regions_updated": "regions updated",
+ "cities_updated": "cities updated",
+ "visited_region_check": "Visited Region Check",
+ "visited_region_check_desc": "By selecting this, the server will check all of your visited adventures and mark the regions they are located in as visited in world travel.",
+ "update_visited_regions": "Update Visited Regions",
+ "update_visited_regions_disclaimer": "This may take a while depending on the number of adventures you have visited.",
+ "link_new": "Link New...",
+ "add_new": "Add New...",
+ "transportation": "Transportation",
+ "note": "Note",
+ "checklist": "Checklist",
+ "collection_archived": "This collection has been archived.",
+ "visit_link": "Visit Link",
+ "collection_completed": "You've completed this collection!",
+ "collection_stats": "Collection Stats",
+ "keep_exploring": "Keep Exploring!",
+ "linked_adventures": "Linked Adventures",
+ "notes": "Notes",
+ "checklists": "Checklists",
+ "transportations": "Transportations",
+ "adventure_calendar": "Adventure Calendar",
+ "day": "Day",
+ "itineary_by_date": "Itinerary by Date",
+ "nothing_planned": "Nothing planned for this day. Enjoy the journey!",
+ "copied_to_clipboard": "Copied to clipboard!",
+ "copy_failed": "Copy failed",
+ "show": "Show",
+ "hide": "Hide",
+ "clear_location": "Clear Location",
+ "starting_airport": "Starting Airport",
+ "ending_airport": "Ending Airport",
+ "no_location_found": "No location found",
+ "from": "From",
+ "to": "To",
+ "will_be_marked": "will be marked as visited once the adventure is saved.",
+ "start": "Start",
+ "end": "End",
+ "show_map": "Show Map",
+ "emoji_picker": "Emoji Picker",
+ "download_calendar": "Download Calendar",
+ "date_information": "Date Information",
+ "flight_information": "Flight Information",
+ "out_of_range": "Not in itinerary date range",
+ "preview": "Preview",
+ "finding_recommendations": "Discovering hidden gems for your next adventure",
+ "location_details": "Location Details",
+ "city": "City",
+ "region": "Region",
+ "md_instructions": "Write your markdown here...",
+ "days": "days",
+ "attachment_upload_success": "Attachment uploaded successfully!",
+ "attachment_upload_error": "Error uploading attachment",
+ "upload": "Upload",
+ "attachment_delete_success": "Attachment deleted successfully!",
+ "attachment_update_success": "Attachment updated successfully!",
+ "attachment_name": "Attachment Name",
+ "gpx_tip": "Upload GPX files to attachments to view them on the map!",
+ "welcome_map_info": "Public adventures on this server",
+ "attachment_update_error": "Error updating attachment",
+ "activities": {
+ "general": "General 🌍",
+ "outdoor": "Outdoor 🏞️",
+ "lodging": "Lodging 🛌",
+ "dining": "Dining 🍽️",
+ "activity": "Activity 🏄",
+ "attraction": "Attraction 🎢",
+ "shopping": "Shopping 🛍️",
+ "nightlife": "Nightlife 🌃",
+ "event": "Event 🎉",
+ "transportation": "Transportation 🚗",
+ "culture": "Culture 🎭",
+ "water_sports": "Water Sports 🚤",
+ "hiking": "Hiking 🥾",
+ "wildlife": "Wildlife 🦒",
+ "historical_sites": "Historical Sites 🏛️",
+ "music_concerts": "Music & Concerts 🎶",
+ "fitness": "Fitness 🏋️",
+ "art_museums": "Art & Museums 🎨",
+ "festivals": "Festivals 🎪",
+ "spiritual_journeys": "Spiritual Journeys 🧘♀️",
+ "volunteer_work": "Volunteer Work 🤝",
+ "other": "Other"
+ },
+ "lodging_information": "Lodging Information",
+ "price": "Price"
+ },
+ "worldtravel": {
+ "country_list": "Country List",
+ "num_countries": "countries found",
+ "all": "All",
+ "partially_visited": "Partially Visited",
+ "not_visited": "Not Visited",
+ "completely_visited": "Completely Visited",
+ "all_subregions": "All Subregions",
+ "clear_search": "Clear Search",
+ "no_countries_found": "No countries found",
+ "view_cities": "View Cities",
+ "no_cities_found": "No cities found",
+ "visit_to": "Visit to",
+ "region_failed_visited": "Failed to mark region as visited",
+ "failed_to_mark_visit": "Failed to mark visit to",
+ "visit_remove_failed": "Failed to remove visit",
+ "removed": "removed",
+ "failed_to_remove_visit": "Failed to remove visit to",
+ "marked_visited": "marked as visited",
+ "regions_in": "Regions in",
+ "region_stats": "Region Stats",
+ "all_visited": "You've visited all regions in",
+ "cities": "cities"
+ },
+ "auth": {
+ "username": "Username",
+ "password": "Password",
+ "forgot_password": "Forgot Password?",
+ "signup": "Signup",
+ "login_error": "Unable to login with the provided credentials.",
+ "login": "Login",
+ "email": "Email",
+ "first_name": "First Name",
+ "last_name": "Last Name",
+ "confirm_password": "Confirm Password",
+ "registration_disabled": "Registration is currently disabled.",
+ "profile_picture": "Profile Picture",
+ "public_profile": "Public Profile",
+ "public_tooltip": "With a public profile, users can share collections with you and view your profile on the users page.",
+ "email_required": "Email is required",
+ "new_password": "New Password (6+ characters)",
+ "both_passwords_required": "Both passwords are required",
+ "reset_failed": "Failed to reset password",
+ "or_3rd_party": "Or login with a third-party service",
+ "no_public_adventures": "No public adventures found",
+ "no_public_collections": "No public collections found",
+ "user_adventures": "User Adventures",
+ "user_collections": "User Collections"
+ },
+ "users": {
+ "no_users_found": "No users found with public profiles."
+ },
+ "settings": {
+ "update_error": "Error updating settings",
+ "update_success": "Settings updated successfully!",
+ "settings_page": "Settings Page",
+ "account_settings": "User Account Settings",
+ "update": "Update",
+ "no_verified_email_warning": "You must have a verified email address to enable two-factor authentication.",
+ "password_change": "Change Password",
+ "new_password": "New Password",
+ "confirm_new_password": "Confirm New Password",
+ "email_change": "Change Email",
+ "current_email": "Current Email",
+ "no_email_set": "No email set",
+ "new_email": "New Email",
+ "change_password": "Change Password",
+ "login_redir": "You will then be redirected to the login page.",
+ "token_required": "Token and UID are required for password reset.",
+ "reset_password": "Reset Password",
+ "possible_reset": "If the email address you provided is associated with an account, you will receive an email with instructions to reset your password!",
+ "missing_email": "Please enter an email address",
+ "submit": "Submit",
+ "password_does_not_match": "Passwords do not match",
+ "password_is_required": "Password is required",
+ "invalid_token": "Token is invalid or has expired",
+ "about_this_background": "About this background",
+ "photo_by": "Photo by",
+ "join_discord": "Join the Discord",
+ "join_discord_desc": "to share your own photos. Post them in the #travel-share channel.",
+ "current_password": "Current Password",
+ "change_password_error": "Unable to change password. Invalid current password or invalid new password.",
+ "password_change_lopout_warning": "You will be logged out after changing your password.",
+ "generic_error": "An error occurred while processing your request.",
+ "email_removed": "Email removed successfully!",
+ "email_removed_error": "Error removing email",
+ "verify_email_success": "Email verification sent successfully!",
+ "verify_email_error": "Error verifying email. Try again in a few minutes.",
+ "email_added": "Email added successfully!",
+ "email_added_error": "Error adding email",
+ "email_set_primary": "Email set as primary successfully!",
+ "email_set_primary_error": "Error setting email as primary",
+ "verified": "Verified",
+ "primary": "Primary",
+ "not_verified": "Not Verified",
+ "make_primary": "Make Primary",
+ "verify": "Verify",
+ "no_emai_set": "No email set",
+ "error_change_password": "Error changing password. Please check your current password and try again.",
+ "mfa_disabled": "Multi-factor authentication disabled successfully!",
+ "mfa_page_title": "Multi-factor Authentication",
+ "enable_mfa": "Enable MFA",
+ "disable_mfa": "Disable MFA",
+ "mfa_not_enabled": "MFA is not enabled",
+ "mfa_enabled": "Multi-factor authentication enabled successfully!",
+ "copy": "Copy",
+ "recovery_codes": "Recovery Codes",
+ "recovery_codes_desc": "These are your recovery codes. Keep them safe. You will not be able to see them again.",
+ "reset_session_error": "Please logout and back in to refresh your session and try again.",
+ "authenticator_code": "Authenticator Code",
+ "email_verified": "Email verified successfully!",
+ "email_verified_success": "Your email has been verified. You can now log in.",
+ "email_verified_error": "Error verifying email",
+ "email_verified_erorr_desc": "Your email could not be verified. Please try again.",
+ "invalid_code": "Invalid MFA code",
+ "invalid_credentials": "Invalid username or password",
+ "mfa_required": "Multi-factor authentication is required",
+ "required": "This field is required",
+ "add_email_blocked": "You cannot add an email address to an account protected by two-factor authentication.",
+ "duplicate_email": "This email address is already in use.",
+ "csrf_failed": "Failed to fetch CSRF token",
+ "email_taken": "This email address is already in use.",
+ "username_taken": "This username is already in use.",
+ "administration_settings": "Administration Settings",
+ "launch_administration_panel": "Launch Administration Panel",
+ "social_oidc_auth": "Social and OIDC Authentication",
+ "social_auth_desc": "Enable or disable social and OIDC authentication providers for your account. These connections allow you to sign in with self hosted authentication identity providers like Authentik or 3rd party providers like GitHub.",
+ "social_auth_desc_2": "These settings are managed in the AdventureLog server and must be manually enabled by the administrator.",
+ "documentation_link": "Documentation Link",
+ "launch_account_connections": "Launch Account Connections",
+ "password_too_short": "Password must be at least 6 characters",
+ "add_email": "Add Email"
+ },
+ "collection": {
+ "collection_created": "Collection created successfully!",
+ "error_creating_collection": "Error creating collection",
+ "new_collection": "New Collection",
+ "create": "Create",
+ "collection_edit_success": "Collection edited successfully!",
+ "error_editing_collection": "Error editing collection",
+ "edit_collection": "Edit Collection",
+ "public_collection": "Public Collection"
+ },
+ "notes": {
+ "note_deleted": "Note deleted successfully!",
+ "note_delete_error": "Error deleting note",
+ "open": "Open",
+ "failed_to_save": "Failed to save note",
+ "note_editor": "Note Editor",
+ "note_viewer": "Note Viewer",
+ "editing_note": "Editing note",
+ "content": "Content",
+ "save": "Save",
+ "note_public": "This note is public because it is in a public collection.",
+ "add_a_link": "Add a link",
+ "invalid_url": "Invalid URL"
+ },
+ "checklist": {
+ "checklist_deleted": "Checklist deleted successfully!",
+ "checklist_delete_error": "Error deleting checklist",
+ "failed_to_save": "Failed to save checklist",
+ "checklist_editor": "Checklist Editor",
+ "checklist_viewer": "Checklist Viewer",
+ "editing_checklist": "Editing checklist",
+ "new_checklist": "New Checklist",
+ "item": "Item",
+ "items": "Items",
+ "add_item": "Add Item",
+ "new_item": "New Item",
+ "save": "Save",
+ "checklist_public": "This checklist is public because it is in a public collection.",
+ "item_cannot_be_empty": "Item cannot be empty",
+ "item_already_exists": "Item already exists"
+ },
+ "transportation": {
+ "transportation_deleted": "Transportation deleted successfully!",
+ "transportation_delete_error": "Error deleting transportation",
+ "provide_start_date": "Please provide a start date",
+ "transport_type": "Transport Type",
+ "type": "Type",
+ "transportation_added": "Transportation added successfully!",
+ "error_editing_transportation": "Error editing transportation",
+ "new_transportation": "New Transportation",
+ "date_time": "Start Date & Time",
+ "end_date_time": "End Date & Time",
+ "flight_number": "Flight Number",
+ "from_location": "From Location",
+ "to_location": "To Location",
+ "edit": "Edit",
+ "modes": {
+ "car": "Car",
+ "plane": "Plane",
+ "train": "Train",
+ "bus": "Bus",
+ "boat": "Boat",
+ "bike": "Bike",
+ "walking": "Walking",
+ "other": "Other"
+ },
+ "transportation_edit_success": "Transportation edited successfully!",
+ "edit_transportation": "Edit Transportation",
+ "start": "Start",
+ "date_and_time": "Date & Time"
+ },
+ "lodging": {
+ "lodging_deleted": "Lodging deleted successfully!",
+ "lodging_delete_error": "Error deleting lodging",
+ "provide_start_date": "Please provide a start date",
+ "lodging_type": "Lodging Type",
+ "type": "Type",
+ "lodging_added": "Lodging added successfully!",
+ "error_editing_lodging": "Error editing lodging",
+ "new_lodging": "New Lodging",
+ "check_in": "Check In",
+ "check_out": "Check Out",
+ "edit": "Edit",
+ "lodging_edit_success": "Lodging edited successfully!",
+ "edit_lodging": "Edit Lodging",
+ "start": "Start",
+ "date_and_time": "Date & Time",
+ "hotel": "Hotel",
+ "hostel": "Hostel",
+ "resort": "Resort",
+ "bnb": "Bed and Breakfast",
+ "campground": "Campground",
+ "cabin": "Cabin",
+ "apartment": "Apartment",
+ "house": "House",
+ "villa": "Villa",
+ "motel": "Motel",
+ "other": "Other",
+ "reservation_number": "Reservation Number"
+ },
+ "search": {
+ "adventurelog_results": "AdventureLog Results",
+ "public_adventures": "Public Adventures",
+ "online_results": "Online Results"
+ },
+ "map": {
+ "view_details": "View Details",
+ "adventure_map": "Adventure Map",
+ "map_options": "Map Options",
+ "show_visited_regions": "Show Visited Regions",
+ "add_adventure_at_marker": "Add New Adventure at Marker",
+ "clear_marker": "Clear Marker",
+ "add_adventure": "Add New Adventure"
+ },
+ "share": {
+ "shared": "Shared",
+ "with": "with",
+ "unshared": "Unshared",
+ "share_desc": "Share this collection with other users.",
+ "shared_with": "Shared With",
+ "no_users_shared": "No users shared with",
+ "not_shared_with": "Not Shared With",
+ "no_shared_found": "No collections found that are shared with you.",
+ "set_public": "In order to allow users to share with you, you need your profile set to public.",
+ "go_to_settings": "Go to settings"
+ },
+ "languages": {},
+ "profile": {
+ "member_since": "Member since",
+ "user_stats": "User Stats",
+ "visited_countries": "Visited Countries",
+ "visited_regions": "Visited Regions",
+ "visited_cities": "Visited Cities"
+ },
+ "categories": {
+ "manage_categories": "Manage Categories",
+ "no_categories_found": "No categories found.",
+ "edit_category": "Edit Category",
+ "icon": "Icon",
+ "update_after_refresh": "The adventure cards will be updated once you refresh the page.",
+ "select_category": "Select Category",
+ "category_name": "Category Name"
+ },
+ "dashboard": {
+ "welcome_back": "Welcome back",
+ "countries_visited": "Countries Visited",
+ "total_adventures": "Total Adventures",
+ "total_visited_regions": "Total Visited Regions",
+ "total_visited_cities": "Total Visited Cities",
+ "recent_adventures": "Recent Adventures",
+ "no_recent_adventures": "No recent adventures?",
+ "add_some": "Why not start planning your next adventure? You can add a new adventure by clicking the button below."
+ },
+ "immich": {
+ "immich": "Immich",
+ "integration_fetch_error": "Error fetching data from the Immich integration",
+ "integration_missing": "The Immich integration is missing from the backend",
+ "query_required": "Query is required",
+ "server_down": "The Immich server is currently down or unreachable",
+ "no_items_found": "No items found",
+ "imageid_required": "Image ID is required",
+ "load_more": "Load More",
+ "immich_updated": "Immich settings updated successfully!",
+ "immich_enabled": "Immich integration enabled successfully!",
+ "immich_error": "Error updating Immich integration",
+ "immich_disabled": "Immich integration disabled successfully!",
+ "immich_desc": "Integrate your Immich account with AdventureLog to allow you to search your photos library and import photos for your adventures.",
+ "integration_enabled": "Integration Enabled",
+ "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.",
+ "api_key": "Immich API Key",
+ "enable_immich": "Enable Immich",
+ "update_integration": "Update Integration",
+ "immich_integration": "Immich Integration",
+ "localhost_note": "Note: localhost will most likely not work unless you have setup docker networks accordingly. It is recommended to use the IP address of the server or the domain name.",
+ "documentation": "Immich Integration Documentation"
+ },
+ "recomendations": {
+ "address": "Address",
+ "phone": "Phone",
+ "contact": "Contact",
+ "website": "Website",
+ "recommendation": "Recommendation"
+ }
}
diff --git a/frontend/src/routes/+page.server.ts b/frontend/src/routes/+page.server.ts
index b8c71b5..221b103 100644
--- a/frontend/src/routes/+page.server.ts
+++ b/frontend/src/routes/+page.server.ts
@@ -11,6 +11,19 @@ const serverEndpoint = PUBLIC_SERVER_URL || 'http://localhost:8000';
export const load = (async (event) => {
if (event.locals.user) {
return redirect(302, '/dashboard');
+ } else {
+ let res = await fetch(`${serverEndpoint}/api/stats/locations/`, {
+ method: 'GET',
+ headers: {
+ 'Content-Type': 'application/json'
+ }
+ });
+ let data = await res.json();
+ return {
+ props: {
+ locations: data
+ }
+ };
}
}) satisfies PageServerLoad;
diff --git a/frontend/src/routes/+page.svelte b/frontend/src/routes/+page.svelte
index 9fadd74..1b3cd2e 100644
--- a/frontend/src/routes/+page.svelte
+++ b/frontend/src/routes/+page.svelte
@@ -1,126 +1,141 @@
-
-
-
-
-
- {#if data.user}
- {#if data.user.first_name && data.user.first_name !== null}
-
- {data.user.first_name.charAt(0).toUpperCase() + data.user.first_name.slice(1)},
- {$t('home.hero_1')}
-
- {:else}
-
- {$t('home.hero_1')}
-
- {/if}
- {:else}
-
- {$t('home.hero_1')}
-
- {/if}
-
- {$t('home.hero_2')}
-
-
-
- {#if data.user}
-
- {:else}
-
-
- {/if}
-
+
+
+
+
+
+ {#if data.user}
+ {#if data.user.first_name && data.user.first_name !== null}
+
+ {:else}
+
+ {/if}
+ {:else}
+
+ {/if}
+
+ {$t('home.hero_2')}
+
+
+ {#if data.user}
+
+ {:else}
+
+
+ {/if}
-

+
+
+
+
+
+ {$t('adventures.welcome_map_info')}
+
+
+ {#each data.props.locations as location}
+ {#if location.latitude && location.longitude}
+ goto(`/locations/${location.id}`)}
+ >
+ {location.name}
+
+ {location.name}
+
+
+
+ {/if}
+ {/each}
+
-
-
-
-
-
- {$t('home.key_features')}
-
-
- {$t('home.desc_1')}
-
-
- {$t('home.desc_2')}
-
+
+
+
+
+
+
+ {$t('home.key_features')}
+
+ {$t('home.desc_1')}
+
+
+ {$t('home.desc_2')}
+
-
-
-

-
-
- -
-
-
{$t('home.feature_1')}
-
- {$t('home.feature_1_desc')}
-
-
+
+
+
+

+
+
+
+
+ -
+
{$t('home.feature_1')}
+
+ {$t('home.feature_1_desc')}
+
- -
-
-
{$t('home.feature_2')}
-
- {$t('home.feature_2_desc')}
-
-
+ -
+
{$t('home.feature_2')}
+
+ {$t('home.feature_2_desc')}
+
- -
-
-
{$t('home.feature_3')}
-
- {$t('home.feature_3_desc')}
-
-
+ -
+
{$t('home.feature_3')}
+
+ {$t('home.feature_3_desc')}
+
diff --git a/frontend/src/routes/adventures/[id]/+page.svelte b/frontend/src/routes/adventures/[id]/+page.svelte
index 64a59d6..d282083 100644
--- a/frontend/src/routes/adventures/[id]/+page.svelte
+++ b/frontend/src/routes/adventures/[id]/+page.svelte
@@ -12,7 +12,6 @@
import toGeoJSON from '@mapbox/togeojson';
import LightbulbOn from '~icons/mdi/lightbulb-on';
- import Account from '~icons/mdi/account';
let geojson: any;
@@ -186,7 +185,10 @@
alt={adventure.name}
/>
-
+
+
{#each adventure.images as _, i}
{/if}
+
-
- {#if adventure.user.profile_pic}
-
-
-

+ {#if adventure.user}
+
+ {#if adventure.user.profile_pic}
+
+
+

+
-
- {:else}
-
-
- {adventure.user.first_name
- ? adventure.user.first_name.charAt(0)
- : adventure.user.username.charAt(0)}{adventure.user.last_name
- ? adventure.user.last_name.charAt(0)
- : ''}
-
-
- {/if}
-
-
+ {/if}
{/each}
{/if}
+ {#if dayLodging.length > 0}
+ {#each dayLodging as hotel}
+
{
+ lodging = lodging.filter((t) => t.id != event.detail);
+ }}
+ on:edit={editLodging}
+ />
+ {/each}
+ {/if}
{#if dayChecklists.length > 0}
{#each dayChecklists as checklist}
- {#if dayAdventures.length == 0 && dayTransportations.length == 0 && dayNotes.length == 0 && dayChecklists.length == 0}
+ {#if dayAdventures.length == 0 && dayTransportations.length == 0 && dayNotes.length == 0 && dayChecklists.length == 0 && dayLodging.length == 0}
{$t('adventures.nothing_planned')}
{/if}
@@ -1068,7 +1085,7 @@
{/if}
- {#if currentView == 'recommendations'}
+ {#if currentView == 'recommendations' && data.user}
Adventure Recommendations
diff --git a/frontend/src/routes/map/+page.svelte b/frontend/src/routes/map/+page.svelte
index f550760..fb10e6c 100644
--- a/frontend/src/routes/map/+page.svelte
+++ b/frontend/src/routes/map/+page.svelte
@@ -10,6 +10,8 @@
let createModalOpen: boolean = false;
let showGeo: boolean = false;
+ export let initialLatLng: { lat: number; lng: number } | null = null;
+
let visitedRegions: VisitedRegion[] = data.props.visitedRegions;
let adventures: Adventure[] = data.props.adventures;
@@ -49,6 +51,11 @@
newLatitude = e.detail.lngLat.lat;
}
+ function newAdventure() {
+ initialLatLng = { lat: newLatitude, lng: newLongitude } as { lat: number; lng: number };
+ createModalOpen = true;
+ }
+
function createNewAdventure(event: CustomEvent) {
adventures = [...adventures, event.detail];
newMarker = null;
@@ -86,7 +93,7 @@
/>
{#if newMarker}
-