mirror of
https://github.com/seanmorley15/AdventureLog.git
synced 2025-07-19 12:59:36 +02:00
localization v2
This commit is contained in:
parent
6cf62cfb82
commit
91c0ec8c07
18 changed files with 432 additions and 101 deletions
28
.vscode/settings.json
vendored
28
.vscode/settings.json
vendored
|
@ -1,3 +1,29 @@
|
||||||
{
|
{
|
||||||
"git.ignoreLimitWarning": true
|
"git.ignoreLimitWarning": true,
|
||||||
|
"i18n-ally.localesPaths": [
|
||||||
|
"frontend/src/locales",
|
||||||
|
"backend/server/backend/lib/python3.12/site-packages/allauth/locale",
|
||||||
|
"backend/server/backend/lib/python3.12/site-packages/dj_rest_auth/locale",
|
||||||
|
"backend/server/backend/lib/python3.12/site-packages/rest_framework/locale",
|
||||||
|
"backend/server/backend/lib/python3.12/site-packages/rest_framework_simplejwt/locale",
|
||||||
|
"backend/server/backend/lib/python3.12/site-packages/django/conf/locale",
|
||||||
|
"backend/server/backend/lib/python3.12/site-packages/django/contrib/messages",
|
||||||
|
"backend/server/backend/lib/python3.12/site-packages/allauth/templates/account/messages",
|
||||||
|
"backend/server/backend/lib/python3.12/site-packages/allauth/templates/mfa/messages",
|
||||||
|
"backend/server/backend/lib/python3.12/site-packages/allauth/templates/socialaccount/messages",
|
||||||
|
"backend/server/backend/lib/python3.12/site-packages/allauth/templates/usersessions/messages",
|
||||||
|
"backend/server/backend/lib/python3.12/site-packages/django/contrib/admindocs/locale",
|
||||||
|
"backend/server/backend/lib/python3.12/site-packages/django/contrib/auth/locale",
|
||||||
|
"backend/server/backend/lib/python3.12/site-packages/django/contrib/admin/locale",
|
||||||
|
"backend/server/backend/lib/python3.12/site-packages/django/contrib/contenttypes/locale",
|
||||||
|
"backend/server/backend/lib/python3.12/site-packages/django/contrib/flatpages/locale",
|
||||||
|
"backend/server/backend/lib/python3.12/site-packages/django/contrib/humanize/locale",
|
||||||
|
"backend/server/backend/lib/python3.12/site-packages/django/contrib/gis/locale",
|
||||||
|
"backend/server/backend/lib/python3.12/site-packages/django/contrib/redirects/locale",
|
||||||
|
"backend/server/backend/lib/python3.12/site-packages/django/contrib/postgres/locale",
|
||||||
|
"backend/server/backend/lib/python3.12/site-packages/django/contrib/sessions/locale",
|
||||||
|
"backend/server/backend/lib/python3.12/site-packages/django/contrib/sites/locale",
|
||||||
|
"backend/server/backend/lib/python3.12/site-packages/rest_framework/templates/rest_framework/docs/langs"
|
||||||
|
],
|
||||||
|
"i18n-ally.keystyle": "nested"
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,17 +109,11 @@ export const themeHook: Handle = async ({ event, resolve }) => {
|
||||||
|
|
||||||
// hook to get the langauge cookie and set the locale
|
// hook to get the langauge cookie and set the locale
|
||||||
export const i18nHook: Handle = async ({ event, resolve }) => {
|
export const i18nHook: Handle = async ({ event, resolve }) => {
|
||||||
let lang = event.cookies.get('lang');
|
let locale = event.cookies.get('locale');
|
||||||
if (!lang) {
|
if (!locale) {
|
||||||
lang = ''; // Set default locale
|
return await resolve(event);
|
||||||
event.cookies.set('lang', lang, {
|
|
||||||
httpOnly: true,
|
|
||||||
sameSite: 'lax',
|
|
||||||
expires: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000), // 1 year
|
|
||||||
path: '/'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
event.locals.locale = lang; // Store the locale in locals
|
event.locals.locale = locale; // Store the locale in locals
|
||||||
return await resolve(event);
|
return await resolve(event);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -11,15 +11,14 @@
|
||||||
import MapMarker from '~icons/mdi/map-marker';
|
import MapMarker from '~icons/mdi/map-marker';
|
||||||
import { addToast } from '$lib/toasts';
|
import { addToast } from '$lib/toasts';
|
||||||
import Link from '~icons/mdi/link-variant';
|
import Link from '~icons/mdi/link-variant';
|
||||||
import CheckBold from '~icons/mdi/check-bold';
|
|
||||||
import FormatListBulletedSquare from '~icons/mdi/format-list-bulleted-square';
|
|
||||||
import LinkVariantRemove from '~icons/mdi/link-variant-remove';
|
import LinkVariantRemove from '~icons/mdi/link-variant-remove';
|
||||||
import Plus from '~icons/mdi/plus';
|
import Plus from '~icons/mdi/plus';
|
||||||
import CollectionLink from './CollectionLink.svelte';
|
import CollectionLink from './CollectionLink.svelte';
|
||||||
import DotsHorizontal from '~icons/mdi/dots-horizontal';
|
import DotsHorizontal from '~icons/mdi/dots-horizontal';
|
||||||
import DeleteWarning from './DeleteWarning.svelte';
|
import DeleteWarning from './DeleteWarning.svelte';
|
||||||
import { isAdventureVisited, typeToString } from '$lib';
|
import { isAdventureVisited } from '$lib';
|
||||||
import CardCarousel from './CardCarousel.svelte';
|
import CardCarousel from './CardCarousel.svelte';
|
||||||
|
import { t } from 'svelte-i18n';
|
||||||
|
|
||||||
export let type: string;
|
export let type: string;
|
||||||
export let user: User | null;
|
export let user: User | null;
|
||||||
|
@ -67,34 +66,13 @@
|
||||||
body: JSON.stringify({ collection: null })
|
body: JSON.stringify({ collection: null })
|
||||||
});
|
});
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
console.log('Adventure removed from collection');
|
addToast('info', `${$t('adventures.collection_remove_success')}`);
|
||||||
addToast('info', 'Adventure removed from collection successfully!');
|
|
||||||
dispatch('delete', adventure.id);
|
dispatch('delete', adventure.id);
|
||||||
} else {
|
} else {
|
||||||
console.log('Error removing adventure from collection');
|
addToast('error', `${$t('adventures.collection_remove_error')}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeType(newType: string) {
|
|
||||||
return async () => {
|
|
||||||
let res = await fetch(`/api/adventures/${adventure.id}/`, {
|
|
||||||
method: 'PATCH',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
body: JSON.stringify({ type: newType })
|
|
||||||
});
|
|
||||||
if (res.ok) {
|
|
||||||
console.log('Adventure type changed');
|
|
||||||
dispatch('typeChange', adventure.id);
|
|
||||||
addToast('info', 'Adventure type changed successfully!');
|
|
||||||
adventure.type = newType;
|
|
||||||
} else {
|
|
||||||
console.log('Error changing adventure type');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
async function linkCollection(event: CustomEvent<number>) {
|
async function linkCollection(event: CustomEvent<number>) {
|
||||||
let collectionId = event.detail;
|
let collectionId = event.detail;
|
||||||
let res = await fetch(`/api/adventures/${adventure.id}`, {
|
let res = await fetch(`/api/adventures/${adventure.id}`, {
|
||||||
|
@ -106,11 +84,11 @@
|
||||||
});
|
});
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
console.log('Adventure linked to collection');
|
console.log('Adventure linked to collection');
|
||||||
addToast('info', 'Adventure linked to collection successfully!');
|
addToast('info', `${$t('adventures.collection_link_success')}`);
|
||||||
isCollectionModalOpen = false;
|
isCollectionModalOpen = false;
|
||||||
dispatch('delete', adventure.id);
|
dispatch('delete', adventure.id);
|
||||||
} else {
|
} else {
|
||||||
console.log('Error linking adventure to collection');
|
addToast('error', `${$t('adventures.collection_link_error')}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,7 +109,7 @@
|
||||||
<DeleteWarning
|
<DeleteWarning
|
||||||
title="Delete Adventure"
|
title="Delete Adventure"
|
||||||
button_text="Delete"
|
button_text="Delete"
|
||||||
description="Are you sure you want to delete this adventure? This action cannot be undone."
|
description={$t('adventures.adventure_delete_confirm')}
|
||||||
is_warning={false}
|
is_warning={false}
|
||||||
on:close={() => (isWarningModalOpen = false)}
|
on:close={() => (isWarningModalOpen = false)}
|
||||||
on:confirm={deleteAdventure}
|
on:confirm={deleteAdventure}
|
||||||
|
@ -153,7 +131,7 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="badge badge-primary">{typeToString(adventure.type)}</div>
|
<div class="badge badge-primary">{$t(`adventures.activities.${adventure.type}`)}</div>
|
||||||
<div class="badge badge-success">{isAdventureVisited(adventure) ? 'Visited' : 'Planned'}</div>
|
<div class="badge badge-success">{isAdventureVisited(adventure) ? 'Visited' : 'Planned'}</div>
|
||||||
<div class="badge badge-secondary">{adventure.is_public ? 'Public' : 'Private'}</div>
|
<div class="badge badge-secondary">{adventure.is_public ? 'Public' : 'Private'}</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -198,30 +176,24 @@
|
||||||
<button
|
<button
|
||||||
class="btn btn-neutral mb-2"
|
class="btn btn-neutral mb-2"
|
||||||
on:click={() => goto(`/adventures/${adventure.id}`)}
|
on:click={() => goto(`/adventures/${adventure.id}`)}
|
||||||
><Launch class="w-6 h-6" />Open Details</button
|
><Launch class="w-6 h-6" />{$t('adventures.open_details')}</button
|
||||||
>
|
>
|
||||||
<button class="btn btn-neutral mb-2" on:click={editAdventure}>
|
<button class="btn btn-neutral mb-2" on:click={editAdventure}>
|
||||||
<FileDocumentEdit class="w-6 h-6" />Edit Adventure
|
<FileDocumentEdit class="w-6 h-6" />
|
||||||
|
{$t('adventures.edit_adventure')}
|
||||||
</button>
|
</button>
|
||||||
{#if adventure.type == 'visited' && user?.pk == adventure.user_id}
|
|
||||||
<button class="btn btn-neutral mb-2" on:click={changeType('planned')}
|
|
||||||
><FormatListBulletedSquare class="w-6 h-6" />Change to Plan</button
|
|
||||||
>
|
|
||||||
{/if}
|
|
||||||
{#if adventure.type == 'planned' && user?.pk == adventure.user_id}
|
|
||||||
<button class="btn btn-neutral mb-2" on:click={changeType('visited')}
|
|
||||||
><CheckBold class="w-6 h-6" />Mark Visited</button
|
|
||||||
>
|
|
||||||
{/if}
|
|
||||||
<!-- remove from collection -->
|
<!-- remove from collection -->
|
||||||
{#if adventure.collection && user?.pk == adventure.user_id}
|
{#if adventure.collection && user?.pk == adventure.user_id}
|
||||||
<button class="btn btn-neutral mb-2" on:click={removeFromCollection}
|
<button class="btn btn-neutral mb-2" on:click={removeFromCollection}
|
||||||
><LinkVariantRemove class="w-6 h-6" />Remove from Collection</button
|
><LinkVariantRemove class="w-6 h-6" />{$t(
|
||||||
|
'adventures.remove_from_collection'
|
||||||
|
)}</button
|
||||||
>
|
>
|
||||||
{/if}
|
{/if}
|
||||||
{#if !adventure.collection}
|
{#if !adventure.collection}
|
||||||
<button class="btn btn-neutral mb-2" on:click={() => (isCollectionModalOpen = true)}
|
<button class="btn btn-neutral mb-2" on:click={() => (isCollectionModalOpen = true)}
|
||||||
><Plus class="w-6 h-6" />Add to Collection</button
|
><Plus class="w-6 h-6" />{$t('adventures.add_to_collection')}</button
|
||||||
>
|
>
|
||||||
{/if}
|
{/if}
|
||||||
<button
|
<button
|
||||||
|
@ -229,7 +201,7 @@
|
||||||
data-umami-event="Delete Adventure"
|
data-umami-event="Delete Adventure"
|
||||||
class="btn btn-warning"
|
class="btn btn-warning"
|
||||||
on:click={() => (isWarningModalOpen = true)}
|
on:click={() => (isWarningModalOpen = true)}
|
||||||
><TrashCan class="w-6 h-6" />Delete</button
|
><TrashCan class="w-6 h-6" />{$t('adventures.delete')}</button
|
||||||
>
|
>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<div class="avatar placeholder">
|
<div class="avatar placeholder">
|
||||||
<div class="bg-neutral rounded-full text-neutral-200 w-10 ml-4">
|
<div class="bg-neutral rounded-full text-neutral-200 w-10 ml-4">
|
||||||
{#if user.profile_pic}
|
{#if user.profile_pic}
|
||||||
<img src={user.profile_pic} alt="User Profile" />
|
<img src={user.profile_pic} alt={$t('navbar.profile')} />
|
||||||
{:else}
|
{:else}
|
||||||
<span class="text-2xl -mt-1">{letter}</span>
|
<span class="text-2xl -mt-1">{letter}</span>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { Adventure } from '$lib/types';
|
import type { Adventure } from '$lib/types';
|
||||||
import ImageDisplayModal from './ImageDisplayModal.svelte';
|
import ImageDisplayModal from './ImageDisplayModal.svelte';
|
||||||
|
import { t } from 'svelte-i18n';
|
||||||
|
|
||||||
export let adventures: Adventure[] = [];
|
export let adventures: Adventure[] = [];
|
||||||
|
|
||||||
|
@ -79,7 +80,7 @@
|
||||||
{:else}
|
{:else}
|
||||||
<!-- svelte-ignore a11y-img-redundant-alt -->
|
<!-- svelte-ignore a11y-img-redundant-alt -->
|
||||||
<img
|
<img
|
||||||
src={'https://placehold.co/300?text=No%20Image%20Found&font=roboto'}
|
src={`https://placehold.co/300?text=${$t('adventures.no_image_found')}&font=roboto`}
|
||||||
alt="No image available"
|
alt="No image available"
|
||||||
class="w-full h-48 object-cover"
|
class="w-full h-48 object-cover"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -8,19 +8,25 @@
|
||||||
import WeatherSunny from '~icons/mdi/weather-sunny';
|
import WeatherSunny from '~icons/mdi/weather-sunny';
|
||||||
import WeatherNight from '~icons/mdi/weather-night';
|
import WeatherNight from '~icons/mdi/weather-night';
|
||||||
import Forest from '~icons/mdi/forest';
|
import Forest from '~icons/mdi/forest';
|
||||||
import Flower from '~icons/mdi/flower';
|
|
||||||
import Water from '~icons/mdi/water';
|
import Water from '~icons/mdi/water';
|
||||||
import AboutModal from './AboutModal.svelte';
|
import AboutModal from './AboutModal.svelte';
|
||||||
import AccountMultiple from '~icons/mdi/account-multiple';
|
import AccountMultiple from '~icons/mdi/account-multiple';
|
||||||
import Avatar from './Avatar.svelte';
|
import Avatar from './Avatar.svelte';
|
||||||
import PaletteOutline from '~icons/mdi/palette-outline';
|
import PaletteOutline from '~icons/mdi/palette-outline';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/stores';
|
||||||
import { t } from 'svelte-i18n';
|
import { t, locale, locales } from 'svelte-i18n';
|
||||||
|
|
||||||
let query: string = '';
|
let query: string = '';
|
||||||
|
|
||||||
let isAboutModalOpen: boolean = false;
|
let isAboutModalOpen: boolean = false;
|
||||||
|
|
||||||
|
const submitLocaleChange = (event: Event) => {
|
||||||
|
const select = event.target as HTMLSelectElement;
|
||||||
|
const newLocale = select.value;
|
||||||
|
document.cookie = `locale=${newLocale}; path=/`;
|
||||||
|
locale.set(newLocale);
|
||||||
|
window.location.reload();
|
||||||
|
};
|
||||||
const submitUpdateTheme: SubmitFunction = ({ action }) => {
|
const submitUpdateTheme: SubmitFunction = ({ action }) => {
|
||||||
const theme = action.searchParams.get('theme');
|
const theme = action.searchParams.get('theme');
|
||||||
console.log('theme', theme);
|
console.log('theme', theme);
|
||||||
|
@ -104,7 +110,7 @@
|
||||||
|
|
||||||
<form class="flex gap-2">
|
<form class="flex gap-2">
|
||||||
<label class="input input-bordered flex items-center gap-2">
|
<label class="input input-bordered flex items-center gap-2">
|
||||||
<input type="text" bind:value={query} class="grow" placeholder="Search" />
|
<input type="text" bind:value={query} class="grow" placeholder={$t('navbar.search')} />
|
||||||
|
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
@ -172,7 +178,7 @@
|
||||||
|
|
||||||
<form class="flex gap-2">
|
<form class="flex gap-2">
|
||||||
<label class="input input-bordered flex items-center gap-2">
|
<label class="input input-bordered flex items-center gap-2">
|
||||||
<input type="text" bind:value={query} class="grow" placeholder="Search" />
|
<input type="text" bind:value={query} class="grow" placeholder={$t('navbar.search')} />
|
||||||
|
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
@ -206,41 +212,55 @@
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
class="dropdown-content bg-neutral text-neutral-content z-[1] menu p-2 shadow rounded-box w-52"
|
class="dropdown-content bg-neutral text-neutral-content z-[1] menu p-2 shadow rounded-box w-52"
|
||||||
>
|
>
|
||||||
<button class="btn" on:click={() => (isAboutModalOpen = true)}>About AdventureLog</button>
|
<button class="btn" on:click={() => (isAboutModalOpen = true)}>{$t('navbar.about')}</button>
|
||||||
<button
|
<button
|
||||||
class="btn btn-sm mt-2"
|
class="btn btn-sm mt-2"
|
||||||
on:click={() => (window.location.href = 'https://docs.adventurelog.app/')}
|
on:click={() => (window.location.href = 'https://docs.adventurelog.app/')}
|
||||||
>Documentation</button
|
>{$t('navbar.documentation')}</button
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
class="btn btn-sm mt-2"
|
class="btn btn-sm mt-2"
|
||||||
on:click={() => (window.location.href = 'https://discord.gg/wRbQ9Egr8C')}>Discord</button
|
on:click={() => (window.location.href = 'https://discord.gg/wRbQ9Egr8C')}
|
||||||
|
>{$t('navbar.discord')}</button
|
||||||
>
|
>
|
||||||
<p class="font-bold m-4 text-lg">Theme Selection</p>
|
<p class="font-bold m-4 text-lg">{$t('navbar.theme_selection')}</p>
|
||||||
<form method="POST" use:enhance={submitUpdateTheme}>
|
<form method="POST" use:enhance={submitUpdateTheme}>
|
||||||
<li>
|
<li>
|
||||||
<button formaction="/?/setTheme&theme=light"
|
<button formaction="/?/setTheme&theme=light"
|
||||||
>Light<WeatherSunny class="w-6 h-6" />
|
>{$t('navbar.themes.light')}<WeatherSunny class="w-6 h-6" />
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<button formaction="/?/setTheme&theme=dark">Dark<WeatherNight class="w-6 h-6" /></button
|
<button formaction="/?/setTheme&theme=dark"
|
||||||
|
>{$t('navbar.themes.dark')}<WeatherNight class="w-6 h-6" /></button
|
||||||
>
|
>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<button formaction="/?/setTheme&theme=night"
|
<button formaction="/?/setTheme&theme=night"
|
||||||
>Night<WeatherNight class="w-6 h-6" /></button
|
>{$t('navbar.themes.night')}<WeatherNight class="w-6 h-6" /></button
|
||||||
>
|
>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<button formaction="/?/setTheme&theme=forest">Forest<Forest class="w-6 h-6" /></button>
|
<button formaction="/?/setTheme&theme=forest"
|
||||||
|
>{$t('navbar.themes.forest')}<Forest class="w-6 h-6" /></button
|
||||||
|
>
|
||||||
<button formaction="/?/setTheme&theme=aestheticLight"
|
<button formaction="/?/setTheme&theme=aestheticLight"
|
||||||
>Aesthetic Light<PaletteOutline class="w-6 h-6" /></button
|
>{$t('navbar.themes.aestetic-light')}<PaletteOutline class="w-6 h-6" /></button
|
||||||
>
|
>
|
||||||
<button formaction="/?/setTheme&theme=aestheticDark"
|
<button formaction="/?/setTheme&theme=aestheticDark"
|
||||||
>Aesthetic Dark<PaletteOutline class="w-6 h-6" /></button
|
>{$t('navbar.themes.aestetic-dark')}<PaletteOutline class="w-6 h-6" /></button
|
||||||
>
|
>
|
||||||
<button formaction="/?/setTheme&theme=aqua">Aqua<Water class="w-6 h-6" /></button>
|
<button formaction="/?/setTheme&theme=aqua"
|
||||||
|
>{$t('navbar.themes.aqua')}<Water class="w-6 h-6" /></button
|
||||||
|
>
|
||||||
|
<form method="POST" use:enhance>
|
||||||
|
<select class="select" on:change={submitLocaleChange} bind:value={$locale}>
|
||||||
|
{#each $locales as loc}
|
||||||
|
<option value={loc}>{loc}</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
<input type="hidden" name="locale" value={$locale} />
|
||||||
|
</form>
|
||||||
</li>
|
</li>
|
||||||
</form>
|
</form>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -253,15 +253,6 @@ export let ADVENTURE_TYPES = [
|
||||||
{ type: 'other', label: 'Other' }
|
{ type: 'other', label: 'Other' }
|
||||||
];
|
];
|
||||||
|
|
||||||
export function typeToString(type: string) {
|
|
||||||
const typeObj = ADVENTURE_TYPES.find((t) => t.type === type);
|
|
||||||
if (typeObj) {
|
|
||||||
return typeObj.label;
|
|
||||||
} else {
|
|
||||||
return 'Unknown';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if an adventure has been visited.
|
* Checks if an adventure has been visited.
|
||||||
*
|
*
|
||||||
|
|
0
frontend/src/lib/localization.ts
Normal file
0
frontend/src/lib/localization.ts
Normal file
93
frontend/src/locales/de.json
Normal file
93
frontend/src/locales/de.json
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
{
|
||||||
|
"about": {
|
||||||
|
"about": "Um",
|
||||||
|
"close": "Schließen",
|
||||||
|
"license": "Lizenziert unter der GPL-3.0-Lizenz.",
|
||||||
|
"message": "Hergestellt mit ❤️ in den Vereinigten Staaten.",
|
||||||
|
"nominatim_1": "Standortsuche und Geokodierung werden bereitgestellt von",
|
||||||
|
"nominatim_2": "Ihre Daten werden unter der ODbL-Lizenz lizenziert.",
|
||||||
|
"oss_attributions": "Open-Source-Zuschreibungen",
|
||||||
|
"other_attributions": "Weitere Hinweise finden Sie in der README-Datei.",
|
||||||
|
"source_code": "Quellcode"
|
||||||
|
},
|
||||||
|
"adventures": {
|
||||||
|
"activities": {
|
||||||
|
"activity": "Aktivität 🏄",
|
||||||
|
"art_museums": "Kunst",
|
||||||
|
"attraction": "Attraktion 🎢",
|
||||||
|
"culture": "Kultur 🎭",
|
||||||
|
"dining": "Essen 🍽️",
|
||||||
|
"event": "Veranstaltung 🎉",
|
||||||
|
"festivals": "Feste 🎪",
|
||||||
|
"fitness": "Fitness 🏋️",
|
||||||
|
"general": "Allgemein 🌍",
|
||||||
|
"hiking": "Wandern 🥾",
|
||||||
|
"historical_sites": "Historische Stätten 🏛️",
|
||||||
|
"lodging": "Unterkunft 🛌",
|
||||||
|
"music_concerts": "Musik",
|
||||||
|
"nightlife": "Nachtleben 🌃",
|
||||||
|
"other": "Andere",
|
||||||
|
"outdoor": "Draußen 🏞️",
|
||||||
|
"shopping": "Einkaufen 🛍️",
|
||||||
|
"spiritual_journeys": "Spirituelle Reisen 🧘♀️",
|
||||||
|
"transportation": "Transport 🚗",
|
||||||
|
"volunteer_work": "Freiwilligenarbeit 🤝",
|
||||||
|
"water_sports": "Wassersport 🚤",
|
||||||
|
"wildlife": "Wildtiere 🦒"
|
||||||
|
},
|
||||||
|
"add_to_collection": "Zur Sammlung hinzufügen",
|
||||||
|
"adventure_delete_confirm": "Sind Sie sicher, dass Sie dieses Abenteuer löschen möchten? \nDiese Aktion kann nicht rückgängig gemacht werden.",
|
||||||
|
"collection_link_error": "Fehler beim Verknüpfen des Abenteuers mit der Sammlung",
|
||||||
|
"collection_link_success": "Abenteuer erfolgreich mit Sammlung verknüpft!",
|
||||||
|
"collection_remove_error": "Beim Entfernen des Abenteuers aus der Sammlung ist ein Fehler aufgetreten",
|
||||||
|
"collection_remove_success": "Abenteuer erfolgreich aus der Sammlung entfernt!",
|
||||||
|
"delete": "Löschen",
|
||||||
|
"edit_adventure": "Abenteuer bearbeiten",
|
||||||
|
"no_image_found": "Kein Bild gefunden",
|
||||||
|
"open_details": "Details öffnen",
|
||||||
|
"remove_from_collection": "Aus der Sammlung entfernen"
|
||||||
|
},
|
||||||
|
"home": {
|
||||||
|
"desc_1": "Entdecken, planen und erkunden Sie mit Leichtigkeit",
|
||||||
|
"desc_2": "AdventureLog wurde entwickelt, um Ihre Reise zu vereinfachen und Ihnen die Tools und Ressourcen zur Verfügung zu stellen, mit denen Sie Ihr nächstes unvergessliches Abenteuer planen, packen und navigieren können.",
|
||||||
|
"feature_1": "Reisetagebuch",
|
||||||
|
"feature_1_desc": "Behalten Sie den Überblick über Ihre Abenteuer mit einem personalisierten Reisetagebuch und teilen Sie Ihre Erlebnisse mit Freunden und Familie.",
|
||||||
|
"feature_2": "Reiseplanung",
|
||||||
|
"feature_3": "Reisekarte",
|
||||||
|
"feature_3_desc": "Sehen Sie sich Ihre Reisen rund um die Welt mit einer interaktiven Karte an und erkunden Sie neue Reiseziele.",
|
||||||
|
"go_to": "Gehen Sie zu AdventureLog",
|
||||||
|
"hero_1": "Entdecken Sie die aufregendsten Abenteuer der Welt",
|
||||||
|
"hero_2": "Entdecken und planen Sie Ihr nächstes Abenteuer mit AdventureLog. \nEntdecken Sie atemberaubende Reiseziele, erstellen Sie individuelle Reiserouten und bleiben Sie unterwegs in Verbindung.",
|
||||||
|
"key_features": "Hauptmerkmale"
|
||||||
|
},
|
||||||
|
"navbar": {
|
||||||
|
"about": "Über AdventureLog",
|
||||||
|
"adventures": "Abenteuer",
|
||||||
|
"collections": "Sammlungen",
|
||||||
|
"discord": "Zwietracht",
|
||||||
|
"documentation": "Dokumentation",
|
||||||
|
"greeting": "Hallo",
|
||||||
|
"login": "Login",
|
||||||
|
"logout": "Abmelden",
|
||||||
|
"map": "Karte",
|
||||||
|
"my_activities": "Meine Aktivitäten",
|
||||||
|
"my_adventures": "Meine Abenteuer",
|
||||||
|
"profile": "Profil",
|
||||||
|
"search": "Suchen",
|
||||||
|
"settings": "Einstellungen",
|
||||||
|
"shared_with_me": "Mit mir geteilt",
|
||||||
|
"signup": "Melden Sie sich an",
|
||||||
|
"theme_selection": "Themenauswahl",
|
||||||
|
"themes": {
|
||||||
|
"aestetic-dark": "Ästhetisches Dunkel",
|
||||||
|
"aestetic-light": "Ästhetisches Licht",
|
||||||
|
"aqua": "Aqua",
|
||||||
|
"dark": "Dunkel",
|
||||||
|
"forest": "Wald",
|
||||||
|
"light": "Licht",
|
||||||
|
"night": "Nacht"
|
||||||
|
},
|
||||||
|
"users": "Benutzer",
|
||||||
|
"worldtravel": "Weltreisen"
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,7 +14,20 @@
|
||||||
"my_activities": "My Activities",
|
"my_activities": "My Activities",
|
||||||
"shared_with_me": "Shared With Me",
|
"shared_with_me": "Shared With Me",
|
||||||
"settings": "Settings",
|
"settings": "Settings",
|
||||||
"logout": "Logout"
|
"logout": "Logout",
|
||||||
|
"about": "About AdventureLog",
|
||||||
|
"documentation": "Documentation",
|
||||||
|
"discord": "Discord",
|
||||||
|
"theme_selection": "Theme Selection",
|
||||||
|
"themes": {
|
||||||
|
"light": "Light",
|
||||||
|
"dark": "Dark",
|
||||||
|
"night": "Night",
|
||||||
|
"forest": "Forest",
|
||||||
|
"aestetic-dark": "Aestetic Dark",
|
||||||
|
"aestetic-light": "Aestetic Light",
|
||||||
|
"aqua": "Aqua"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"about": {
|
"about": {
|
||||||
"about": "About",
|
"about": "About",
|
||||||
|
@ -40,5 +53,42 @@
|
||||||
"feature_2_desc": "Easily create custom itineraries and get a day-by-day breakdown of your trip.",
|
"feature_2_desc": "Easily create custom itineraries and get a day-by-day breakdown of your trip.",
|
||||||
"feature_3": "Travel Map",
|
"feature_3": "Travel Map",
|
||||||
"feature_3_desc": "View your travels throughout the world with an interactive map and explore new destinations."
|
"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.",
|
||||||
|
"open_details": "Open Details",
|
||||||
|
"edit_adventure": "Edit Adventure",
|
||||||
|
"remove_from_collection": "Remove from Collection",
|
||||||
|
"add_to_collection": "Add to Collection",
|
||||||
|
"delete": "Delete",
|
||||||
|
"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"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,32 @@
|
||||||
"navbar": {
|
"navbar": {
|
||||||
"adventures": "Aventuras",
|
"adventures": "Aventuras",
|
||||||
"collections": "Colecciones",
|
"collections": "Colecciones",
|
||||||
"worldtravel": "Viaje Mundial",
|
"worldtravel": "Viajar por el Mundo",
|
||||||
"map": "Mapa",
|
"map": "Mapa",
|
||||||
"users": "Usuarios",
|
"users": "Usuarios",
|
||||||
"login": "Iniciar sesión",
|
"login": "Iniciar Sesión",
|
||||||
"signup": "Registrarse",
|
"signup": "Registrarse",
|
||||||
"search": "Buscar"
|
"search": "Buscar",
|
||||||
|
"profile": "Perfil",
|
||||||
|
"greeting": "Hola",
|
||||||
|
"my_adventures": "Mis Aventuras",
|
||||||
|
"my_activities": "Mis Actividades",
|
||||||
|
"shared_with_me": "Compartido Conmigo",
|
||||||
|
"settings": "Configuraciones",
|
||||||
|
"logout": "Cerrar Sesión",
|
||||||
|
"about": "Acerca de AdventureLog",
|
||||||
|
"documentation": "Documentación",
|
||||||
|
"discord": "Discord",
|
||||||
|
"theme_selection": "Selección de Tema",
|
||||||
|
"themes": {
|
||||||
|
"light": "Claro",
|
||||||
|
"dark": "Oscuro",
|
||||||
|
"night": "Noche",
|
||||||
|
"forest": "Bosque",
|
||||||
|
"aestetic-dark": "Estético Oscuro",
|
||||||
|
"aestetic-light": "Estético Claro",
|
||||||
|
"aqua": "Aqua"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"about": {
|
"about": {
|
||||||
"about": "Acerca de",
|
"about": "Acerca de",
|
||||||
|
@ -15,23 +35,60 @@
|
||||||
"source_code": "Código Fuente",
|
"source_code": "Código Fuente",
|
||||||
"message": "Hecho con ❤️ en los Estados Unidos.",
|
"message": "Hecho con ❤️ en los Estados Unidos.",
|
||||||
"oss_attributions": "Atribuciones de Código Abierto",
|
"oss_attributions": "Atribuciones de Código Abierto",
|
||||||
"nominatim_1": "La búsqueda de ubicación y la geocodificación son proporcionadas por",
|
"nominatim_1": "La búsqueda de ubicaciones y geocodificación es proporcionada por",
|
||||||
"nominatim_2": "Sus datos están licenciados bajo la licencia ODbL.",
|
"nominatim_2": "Sus datos están licenciados bajo la licencia ODbL.",
|
||||||
"other_attributions": "Atribuciones adicionales se pueden encontrar en el archivo README.",
|
"other_attributions": "Atribuciones adicionales se pueden encontrar en el archivo README.",
|
||||||
"close": "Cerrar"
|
"close": "Cerrar"
|
||||||
},
|
},
|
||||||
"home": {
|
"home": {
|
||||||
"hero_1": "Descubre las Aventuras Más Emocionantes del Mundo",
|
"hero_1": "Descubre las Aventuras Más Emocionantes del Mundo",
|
||||||
"hero_2": "Descubre y planifica tu próxima aventura con AdventureLog. Explora destinos impresionantes, crea itinerarios personalizados y mantente conectado sobre la marcha.",
|
"hero_2": "Descubre y planifica tu próxima aventura con AdventureLog. Explora destinos impresionantes, crea itinerarios personalizados y mantente conectado en todo momento.",
|
||||||
"go_to": "Ir a AdventureLog",
|
"go_to": "Ir a AdventureLog",
|
||||||
"key_features": "Características Clave",
|
"key_features": "Características Clave",
|
||||||
"desc_1": "Descubre, Planifica y Explora con Facilidad",
|
"desc_1": "Descubre, Planifica y Explora Fácilmente",
|
||||||
"desc_2": "AdventureLog está diseñado para simplificar tu viaje, proporcionándote las herramientas y recursos para planificar, empacar y navegar tu próxima aventura inolvidable.",
|
"desc_2": "AdventureLog está diseñado para simplificar tu viaje, brindándote las herramientas y recursos para planificar, empacar y navegar tu próxima aventura inolvidable.",
|
||||||
"feature_1": "Diario de Viajes",
|
"feature_1": "Registro de Viajes",
|
||||||
"feature_1_desc": "Lleva un registro de tus aventuras con un diario de viajes personalizado y comparte tus experiencias con amigos y familiares.",
|
"feature_1_desc": "Mantén un registro de tus aventuras con un diario de viaje personalizado y comparte tus experiencias con amigos y familiares.",
|
||||||
"feature_2": "Planificación de Viajes",
|
"feature_2": "Planificación de Viajes",
|
||||||
"feature_2_desc": "Crea fácilmente itinerarios personalizados y obtén un desglose diario de tu viaje.",
|
"feature_2_desc": "Crea fácilmente itinerarios personalizados y obtén un desglose diario de tu viaje.",
|
||||||
"feature_3": "Mapa de Viajes",
|
"feature_3": "Mapa de Viaje",
|
||||||
"feature_3_desc": "Ve tus viajes por todo el mundo con un mapa interactivo y explora nuevos destinos."
|
"feature_3_desc": "Visualiza tus viajes por el mundo con un mapa interactivo y explora nuevos destinos."
|
||||||
|
},
|
||||||
|
"adventures": {
|
||||||
|
"collection_remove_success": "¡Aventura eliminada de la colección con éxito!",
|
||||||
|
"collection_remove_error": "Error al eliminar la aventura de la colección",
|
||||||
|
"collection_link_success": "¡Aventura vinculada a la colección con éxito!",
|
||||||
|
"collection_link_error": "Error al vincular la aventura a la colección",
|
||||||
|
"adventure_delete_confirm": "¿Estás seguro de que quieres eliminar esta aventura? Esta acción no se puede deshacer.",
|
||||||
|
"open_details": "Abrir Detalles",
|
||||||
|
"edit_adventure": "Editar Aventura",
|
||||||
|
"remove_from_collection": "Eliminar de la Colección",
|
||||||
|
"add_to_collection": "Añadir a la Colección",
|
||||||
|
"delete": "Eliminar",
|
||||||
|
"activities": {
|
||||||
|
"activity": "Actividad 🏄",
|
||||||
|
"art_museums": "Arte",
|
||||||
|
"attraction": "Atracción 🎢",
|
||||||
|
"culture": "Cultura 🎭",
|
||||||
|
"dining": "Cenar 🍽️",
|
||||||
|
"event": "Evento 🎉",
|
||||||
|
"festivals": "Festivales 🎪",
|
||||||
|
"fitness": "Fitness 🏋️",
|
||||||
|
"general": "Generales 🌍",
|
||||||
|
"hiking": "Senderismo 🥾",
|
||||||
|
"historical_sites": "Sitios Históricos 🏛️",
|
||||||
|
"lodging": "Alojamiento 🛌",
|
||||||
|
"music_concerts": "Música",
|
||||||
|
"nightlife": "Vida nocturna 🌃",
|
||||||
|
"other": "Otro",
|
||||||
|
"outdoor": "Al aire libre 🏞️",
|
||||||
|
"shopping": "Compras 🛍️",
|
||||||
|
"spiritual_journeys": "Viajes espirituales 🧘♀️",
|
||||||
|
"transportation": "Transporte 🚗",
|
||||||
|
"volunteer_work": "Trabajo voluntario 🤝",
|
||||||
|
"water_sports": "Deportes acuáticos 🚤",
|
||||||
|
"wildlife": "Vida silvestre 🦒"
|
||||||
|
},
|
||||||
|
"no_image_found": "No se encontró ninguna imagen"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
90
frontend/src/locales/fr.json
Normal file
90
frontend/src/locales/fr.json
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
{
|
||||||
|
"about": {
|
||||||
|
"about": "À propos",
|
||||||
|
"close": "Fermer",
|
||||||
|
"license": "Sous licence GPL-3.0.",
|
||||||
|
"message": "Fabriqué avec ❤️ aux États-Unis.",
|
||||||
|
"nominatim_1": "La recherche de localisation et le géocodage sont fournis par",
|
||||||
|
"nominatim_2": "Leurs données sont sous licence ODbL.",
|
||||||
|
"oss_attributions": "Attributions Open Source",
|
||||||
|
"other_attributions": "Des attributions supplémentaires peuvent être trouvées dans le fichier README.",
|
||||||
|
"source_code": "Code source"
|
||||||
|
},
|
||||||
|
"adventures": {
|
||||||
|
"activities": {
|
||||||
|
"activity": "Activité 🏄",
|
||||||
|
"art_museums": "Art",
|
||||||
|
"attraction": "Attraction 🎢",
|
||||||
|
"culture": "Culturel 🎭",
|
||||||
|
"dining": "Restauration 🍽️",
|
||||||
|
"event": "Événement 🎉",
|
||||||
|
"festivals": "Fêtes 🎪",
|
||||||
|
"fitness": "Remise en forme 🏋️",
|
||||||
|
"general": "Général 🌍",
|
||||||
|
"hiking": "Randonnée 🥾",
|
||||||
|
"historical_sites": "Sites historiques 🏛️",
|
||||||
|
"lodging": "Hébergement 🛌",
|
||||||
|
"music_concerts": "Musique",
|
||||||
|
"nightlife": "Vie nocturne 🌃",
|
||||||
|
"other": "Autre",
|
||||||
|
"outdoor": "En plein air 🏞️",
|
||||||
|
"shopping": "Shopping 🛍️",
|
||||||
|
"spiritual_journeys": "Voyages spirituels 🧘♀️",
|
||||||
|
"transportation": "Transport 🚗",
|
||||||
|
"volunteer_work": "Travail bénévole 🤝",
|
||||||
|
"water_sports": "Sports nautiques 🚤",
|
||||||
|
"wildlife": "Faune 🦒"
|
||||||
|
},
|
||||||
|
"add_to_collection": "Ajouter à la collection",
|
||||||
|
"adventure_delete_confirm": "Êtes-vous sûr de vouloir supprimer cette aventure ? \nCette action ne peut pas être annulée.",
|
||||||
|
"collection_link_error": "Erreur lors de la liaison de l'aventure à la collection",
|
||||||
|
"collection_link_success": "Aventure liée à la collection avec succès !",
|
||||||
|
"collection_remove_error": "Erreur lors de la suppression de l'aventure de la collection",
|
||||||
|
"collection_remove_success": "Aventure supprimée de la collection avec succès !",
|
||||||
|
"delete": "Supprimer",
|
||||||
|
"edit_adventure": "Modifier l'aventure",
|
||||||
|
"no_image_found": "Aucune image trouvée",
|
||||||
|
"open_details": "Ouvrir les détails",
|
||||||
|
"remove_from_collection": "Supprimer de la collection"
|
||||||
|
},
|
||||||
|
"home": {
|
||||||
|
"desc_1": "Découvrez, planifiez et explorez en toute simplicité",
|
||||||
|
"desc_2": "AdventureLog est conçu pour simplifier votre voyage, en vous fournissant les outils et les ressources nécessaires pour planifier, préparer et naviguer dans votre prochaine aventure inoubliable.",
|
||||||
|
"feature_1": "Carnet de voyage",
|
||||||
|
"feature_1_desc": "Gardez une trace de vos aventures avec un carnet de voyage personnalisé et partagez vos expériences avec vos amis et votre famille.",
|
||||||
|
"feature_2": "Planification du voyage",
|
||||||
|
"feature_2_desc": "Créez facilement des itinéraires personnalisés et obtenez un aperçu quotidien de votre voyage.",
|
||||||
|
"feature_3": "Carte de voyage",
|
||||||
|
"feature_3_desc": "Visualisez vos voyages à travers le monde avec une carte interactive et explorez de nouvelles destinations.",
|
||||||
|
"go_to": "Aller au journal d'aventure",
|
||||||
|
"hero_1": "Découvrez les aventures les plus palpitantes du monde",
|
||||||
|
"hero_2": "Découvrez et planifiez votre prochaine aventure avec AdventureLog. \nExplorez des destinations à couper le souffle, créez des itinéraires personnalisés et restez connecté lors de vos déplacements.",
|
||||||
|
"key_features": "Principales fonctionnalités"
|
||||||
|
},
|
||||||
|
"navbar": {
|
||||||
|
"about": "À propos de AdventureLog",
|
||||||
|
"adventures": "Aventures",
|
||||||
|
"collections": "Collections",
|
||||||
|
"discord": "Discorde",
|
||||||
|
"documentation": "Documentation",
|
||||||
|
"greeting": "Salut",
|
||||||
|
"login": "Se connecter",
|
||||||
|
"logout": "Déconnexion",
|
||||||
|
"map": "Carte",
|
||||||
|
"my_activities": "Mes activités",
|
||||||
|
"my_adventures": "Mes aventures",
|
||||||
|
"profile": "Profil",
|
||||||
|
"search": "Recherche",
|
||||||
|
"settings": "Paramètres",
|
||||||
|
"shared_with_me": "Partagé avec moi",
|
||||||
|
"signup": "S'inscrire",
|
||||||
|
"theme_selection": "Sélection de thèmes",
|
||||||
|
"themes": {
|
||||||
|
"forest": "Forêt",
|
||||||
|
"light": "Lumière",
|
||||||
|
"night": "Nuit"
|
||||||
|
},
|
||||||
|
"users": "Utilisateurs",
|
||||||
|
"worldtravel": "Voyage dans le monde"
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,8 @@
|
||||||
// Register your translations for each locale
|
// Register your translations for each locale
|
||||||
register('en', () => import('../locales/en.json'));
|
register('en', () => import('../locales/en.json'));
|
||||||
register('es', () => import('../locales/es.json'));
|
register('es', () => import('../locales/es.json'));
|
||||||
|
register('fr', () => import('../locales/fr.json'));
|
||||||
|
register('de', () => import('../locales/de.json'));
|
||||||
|
|
||||||
if (browser) {
|
if (browser) {
|
||||||
init({
|
init({
|
||||||
|
@ -37,3 +39,11 @@
|
||||||
<Toast />
|
<Toast />
|
||||||
<slot />
|
<slot />
|
||||||
{/await}
|
{/await}
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<title>AdventureLog</title>
|
||||||
|
<meta
|
||||||
|
name="description"
|
||||||
|
content="Embark, explore, remember with AdventureLog. AdventureLog is the ultimate travel companion."
|
||||||
|
/>
|
||||||
|
</svelte:head>
|
||||||
|
|
|
@ -49,5 +49,15 @@ export const actions: Actions = {
|
||||||
} else {
|
} else {
|
||||||
return redirect(302, '/');
|
return redirect(302, '/');
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
setLocale: async ({ url, cookies }) => {
|
||||||
|
const locale = url.searchParams.get('locale');
|
||||||
|
// change the theme only if it is one of the allowed themes
|
||||||
|
if (locale && ['en', 'es'].includes(locale)) {
|
||||||
|
cookies.set('locale', locale, {
|
||||||
|
path: '/',
|
||||||
|
maxAge: 60 * 60 * 24 * 365
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,6 +26,13 @@
|
||||||
let resultsPerPage: number = 25;
|
let resultsPerPage: number = 25;
|
||||||
|
|
||||||
let count = data.props.count || 0;
|
let count = data.props.count || 0;
|
||||||
|
|
||||||
|
$: {
|
||||||
|
if (count != adventures.length) {
|
||||||
|
count = adventures.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let totalPages = Math.ceil(count / resultsPerPage);
|
let totalPages = Math.ceil(count / resultsPerPage);
|
||||||
let currentPage: number = 1;
|
let currentPage: number = 1;
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import Lost from '$lib/assets/undraw_lost.svg';
|
import Lost from '$lib/assets/undraw_lost.svg';
|
||||||
import { DefaultMarker, MapLibre, Popup } from 'svelte-maplibre';
|
import { DefaultMarker, MapLibre, Popup } from 'svelte-maplibre';
|
||||||
|
import { t } from 'svelte-i18n';
|
||||||
|
|
||||||
export let data: PageData;
|
export let data: PageData;
|
||||||
console.log(data);
|
console.log(data);
|
||||||
|
@ -22,10 +23,8 @@
|
||||||
let image_url: string | null = null;
|
let image_url: string | null = null;
|
||||||
|
|
||||||
import ClipboardList from '~icons/mdi/clipboard-list';
|
import ClipboardList from '~icons/mdi/clipboard-list';
|
||||||
import EditAdventure from '$lib/components/AdventureModal.svelte';
|
|
||||||
import AdventureModal from '$lib/components/AdventureModal.svelte';
|
import AdventureModal from '$lib/components/AdventureModal.svelte';
|
||||||
import ImageDisplayModal from '$lib/components/ImageDisplayModal.svelte';
|
import ImageDisplayModal from '$lib/components/ImageDisplayModal.svelte';
|
||||||
import { typeToString } from '$lib';
|
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
if (data.props.adventure) {
|
if (data.props.adventure) {
|
||||||
|
@ -265,7 +264,7 @@
|
||||||
<div>
|
<div>
|
||||||
<p class="text-sm text-muted-foreground">Adventure Type</p>
|
<p class="text-sm text-muted-foreground">Adventure Type</p>
|
||||||
<p class="text-base font-medium">
|
<p class="text-base font-medium">
|
||||||
{typeToString(adventure.type)}
|
{$t(`adventures.activities.${adventure.type}`)}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{#if data.props.collection}
|
{#if data.props.collection}
|
||||||
|
|
|
@ -27,6 +27,12 @@
|
||||||
let totalPages = Math.ceil(count / resultsPerPage);
|
let totalPages = Math.ceil(count / resultsPerPage);
|
||||||
let currentPage: number = 1;
|
let currentPage: number = 1;
|
||||||
|
|
||||||
|
$: {
|
||||||
|
if (count != collections.length) {
|
||||||
|
count = collections.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function handleChangePage() {
|
function handleChangePage() {
|
||||||
return async ({ result }: any) => {
|
return async ({ result }: any) => {
|
||||||
if (result.type === 'success') {
|
if (result.type === 'success') {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
|
|
||||||
import { isAdventureVisited, typeToString } from '$lib';
|
import { isAdventureVisited } from '$lib';
|
||||||
import AdventureModal from '$lib/components/AdventureModal.svelte';
|
import AdventureModal from '$lib/components/AdventureModal.svelte';
|
||||||
import {
|
import {
|
||||||
DefaultMarker,
|
DefaultMarker,
|
||||||
|
@ -14,6 +14,7 @@
|
||||||
FillLayer,
|
FillLayer,
|
||||||
SymbolLayer
|
SymbolLayer
|
||||||
} from 'svelte-maplibre';
|
} from 'svelte-maplibre';
|
||||||
|
import { t } from 'svelte-i18n';
|
||||||
export let data;
|
export let data;
|
||||||
|
|
||||||
let clickedName = '';
|
let clickedName = '';
|
||||||
|
@ -162,7 +163,9 @@
|
||||||
<Popup openOn="click" offset={[0, -10]}>
|
<Popup openOn="click" offset={[0, -10]}>
|
||||||
<div class="text-lg text-black font-bold">{marker.name}</div>
|
<div class="text-lg text-black font-bold">{marker.name}</div>
|
||||||
<p class="font-semibold text-black text-md">Visited</p>
|
<p class="font-semibold text-black text-md">Visited</p>
|
||||||
<p class="font-semibold text-black text-md">{typeToString(marker.type)}</p>
|
<p class="font-semibold text-black text-md">
|
||||||
|
{$t(`adventures.activities.${marker.type}`)}
|
||||||
|
</p>
|
||||||
{#if marker.visits && marker.visits.length > 0}
|
{#if marker.visits && marker.visits.length > 0}
|
||||||
<p class="text-black text-sm">
|
<p class="text-black text-sm">
|
||||||
{#each marker.visits as visit}
|
{#each marker.visits as visit}
|
||||||
|
@ -201,7 +204,9 @@
|
||||||
<Popup openOn="click" offset={[0, -10]}>
|
<Popup openOn="click" offset={[0, -10]}>
|
||||||
<div class="text-lg text-black font-bold">{marker.name}</div>
|
<div class="text-lg text-black font-bold">{marker.name}</div>
|
||||||
<p class="font-semibold text-black text-md">Planned</p>
|
<p class="font-semibold text-black text-md">Planned</p>
|
||||||
<p class="font-semibold text-black text-md">{typeToString(marker.type)}</p>
|
<p class="font-semibold text-black text-md">
|
||||||
|
{$t(`adventures.activities.${marker.type}`)}}
|
||||||
|
</p>
|
||||||
{#if marker.visits && marker.visits.length > 0}
|
{#if marker.visits && marker.visits.length > 0}
|
||||||
<p class="text-black text-sm">
|
<p class="text-black text-sm">
|
||||||
{#each marker.visits as visit}
|
{#each marker.visits as visit}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue