1
0
Fork 0
mirror of https://github.com/seanmorley15/AdventureLog.git synced 2025-07-24 15:29:36 +02:00

more localization

This commit is contained in:
Sean Morley 2024-10-28 19:59:44 -04:00
parent 5011829e6e
commit fcd2d27221
12 changed files with 302 additions and 36 deletions

View file

@ -49,8 +49,7 @@
}
});
if (res.ok) {
console.log('Adventure deleted');
addToast('info', 'Adventure deleted successfully!');
addToast('info', $t('adventures.adventure_delete_success'));
dispatch('delete', adventure.id);
} else {
console.log('Error deleting adventure');
@ -107,7 +106,7 @@
{#if isWarningModalOpen}
<DeleteWarning
title="Delete Adventure"
title={$t('adventures.delete_adventure')}
button_text="Delete"
description={$t('adventures.adventure_delete_confirm')}
is_warning={false}
@ -132,8 +131,12 @@
</div>
<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-secondary">{adventure.is_public ? 'Public' : 'Private'}</div>
<div class="badge badge-success">
{isAdventureVisited(adventure) ? $t('adventures.visited') : $t('adventures.planned')}
</div>
<div class="badge badge-secondary">
{adventure.is_public ? $t('adventures.public') : $t('adventures.private')}
</div>
</div>
{#if adventure.location && adventure.location !== ''}
<div class="inline-flex items-center">
@ -147,7 +150,7 @@
<Calendar class="w-5 h-5 mr-1" />
<p class="ml-.5">
{adventure.visits.length}
{adventure.visits.length > 1 ? 'visits' : 'visit'}
{adventure.visits.length > 1 ? $t('adventures.visits') : $t('adventures.visit')}
</p>
</div>
{/if}

View file

@ -5,6 +5,7 @@
import { enhance } from '$app/forms';
import { addToast } from '$lib/toasts';
import { deserialize } from '$app/forms';
import { t } from 'svelte-i18n';
export let longitude: number | null = null;
export let latitude: number | null = null;
@ -111,9 +112,9 @@
images = images.filter((image) => image.id !== id);
adventure.images = images;
console.log(images);
addToast('success', 'Image removed');
addToast('success', $t('adventures.image_removed_success'));
} else {
addToast('error', 'Failed to remove image');
addToast('error', $t('adventures.image_removed_error'));
}
}
@ -139,7 +140,7 @@
let res = await fetch(url);
let data = await res.blob();
if (!data) {
imageError = 'No image found at that URL.';
imageError = $t('adventures.no_image_url');
return;
}
let file = new File([data], 'image.jpg', { type: 'image/jpeg' });
@ -155,9 +156,9 @@
if (data2.type === 'success') {
images = [...images, data2];
adventure.images = images;
addToast('success', 'Image uploaded');
addToast('success', $t('adventures.image_upload_success'));
} else {
addToast('error', 'Failed to upload image');
addToast('error', $t('adventures.image_upload_error'));
}
}
@ -187,10 +188,10 @@
console.log(newImage);
images = [...images, newImage];
adventure.images = images;
addToast('success', 'Image uploaded');
addToast('success', $t('adventures.image_upload_success'));
} else {
addToast('error', 'Failed to upload image');
wikiImageError = 'Failed to upload image';
addToast('error', $t('adventures.image_upload_error'));
wikiImageError = $t('adventures.wiki_image_error');
}
}
}
@ -225,7 +226,7 @@
new_end_date = new_start_date;
}
if (new_start_date > new_end_date) {
addToast('error', 'Start date must be before end date');
addToast('error', $t('adventures.start_before_end_error'));
return;
}
if (new_start_date === '' || new_end_date === '') {

View file

@ -109,12 +109,14 @@
<p>{collection.adventures.length} {$t('navbar.adventures')}</p>
{#if collection.start_date && collection.end_date}
<p>
Dates: {new Date(collection.start_date).toLocaleDateString(undefined, { timeZone: 'UTC' })} -
{$t('adventures.dates')}: {new Date(collection.start_date).toLocaleDateString(undefined, {
timeZone: 'UTC'
})} -
{new Date(collection.end_date).toLocaleDateString(undefined, { timeZone: 'UTC' })}
</p>
<!-- display the duration in days -->
<p>
Duration: {Math.floor(
{$t('adventures.duration')}: {Math.floor(
(new Date(collection.end_date).getTime() - new Date(collection.start_date).getTime()) /
(1000 * 60 * 60 * 24)
) + 1}{' '}

View file

@ -110,6 +110,19 @@
"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",
"delete_collection": "Delete Collection",
"delete_adventure": "Delete Adventure",
"adventure_delete_success": "Adventure deleted successfully!",
"visited": "Visited",
"planned": "Planned",
"duration": "Duration",
"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",
"activities": {
"general": "General 🌍",
"outdoor": "Outdoor 🏞️",
@ -134,5 +147,24 @@
"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"
},
"auth": {
"username": "Username",
"password": "Password",
"forgot_password": "Forgot Password?",
"signup": "Signup",
"login_error": "Unable to login with the provided credentials.",
"login": "Login"
}
}

View file

@ -133,6 +133,38 @@
"edit_collection": "Editar colección",
"share": "Compartir",
"unarchive": "Desarchivar",
"cancel": "Cancelar"
"cancel": "Cancelar",
"adventure_delete_success": "¡Aventura eliminada con éxito!",
"delete_adventure": "Eliminar aventura",
"planned": "Planificado",
"visited": "Visitado",
"dates": "Fechas",
"duration": "Duración",
"image_removed_error": "Error al eliminar la imagen",
"image_removed_success": "¡Imagen eliminada exitosamente!",
"image_upload_error": "Error al subir la imagen",
"image_upload_success": "¡Imagen cargada exitosamente!",
"no_image_url": "No se encontró ninguna imagen en esa URL.",
"start_before_end_error": "La fecha de inicio debe ser anterior a la fecha de finalización.",
"wiki_image_error": "Error al obtener la imagen de Wikipedia"
},
"worldtravel": {
"all": "Todo",
"all_subregions": "Todas las subregiones",
"clear_search": "Borrar búsqueda",
"completely_visited": "Completamente visitado",
"no_countries_found": "No se encontraron países",
"not_visited": "No visitado",
"num_countries": "países encontrados",
"partially_visited": "Parcialmente visitado",
"country_list": "Lista de países"
},
"auth": {
"forgot_password": "¿Has olvidado tu contraseña?",
"login": "Acceso",
"login_error": "No se puede iniciar sesión con las credenciales proporcionadas.",
"password": "Contraseña",
"signup": "Inscribirse",
"username": "Nombre de usuario"
}
}

View file

@ -0,0 +1,154 @@
{
"about": {
"about": "Om",
"close": "Nära",
"license": "Licensierad under GPL-3.0-licensen.",
"message": "Tillverkad med ❤️ i USA.",
"nominatim_1": "Platssökning och geokodning tillhandahålls av",
"nominatim_2": "Deras data är licensierad under ODbL-licensen.",
"oss_attributions": "Tillskrivningar med öppen källkod",
"other_attributions": "Ytterligare attributioner finns i README-filen.",
"source_code": "Källkod"
},
"adventures": {
"activities": {
"activity": "Aktivitet 🏄",
"art_museums": "Konst",
"attraction": "Attraktion 🎢",
"culture": "Kultur 🎭",
"dining": "Mat 🍽️",
"event": "Event 🎉",
"festivals": "Festivaler 🎪",
"fitness": "Fitness 🏋️",
"general": "Allmänt 🌍",
"hiking": "Vandring 🥾",
"historical_sites": "Historiska platser 🏛️",
"lodging": "Logi 🛌",
"music_concerts": "Musik",
"nightlife": "Nattliv 🌃",
"other": "Andra",
"outdoor": "Utomhus 🏞️",
"shopping": "Shopping 🛍️",
"spiritual_journeys": "Andliga resor 🧘‍♀️",
"transportation": "Transport 🚗",
"volunteer_work": "Volontärarbete 🤝",
"water_sports": "Vattensporter 🚤",
"wildlife": "Vilda djur 🦒"
},
"add_to_collection": "Lägg till i samlingen",
"adventure": "Äventyr",
"adventure_delete_confirm": "Är du säker på att du vill ta bort det här äventyret? \nDenna åtgärd kan inte ångras.",
"adventure_delete_success": "Äventyret har raderats!",
"adventure_details": "Äventyrsdetaljer",
"adventure_type": "Äventyrstyp",
"archive": "Arkiv",
"archived": "Arkiverad",
"archived_collection_message": "Samlingen har arkiverats!",
"archived_collections": "Arkiverade samlingar",
"ascending": "Stigande",
"cancel": "Avboka",
"category_filter": "Kategorifilter",
"clear": "Rensa",
"close_filters": "Stäng filter",
"collection": "Samling",
"collection_adventures": "Inkludera samlingsäventyr",
"collection_link_error": "Det gick inte att länka äventyr till samling",
"collection_link_success": "Äventyr kopplat till samling framgångsrikt!",
"collection_remove_error": "Det gick inte att ta bort äventyr från samlingen",
"collection_remove_success": "Äventyret har tagits bort från samlingen!",
"count_txt": "resultat som matchar din sökning",
"create_new": "Skapa nytt...",
"date": "Datum",
"dates": "Datum",
"delete": "Radera",
"delete_adventure": "Ta bort äventyr",
"delete_collection": "Ta bort samling",
"delete_collection_success": "Samlingen har raderats!",
"delete_collection_warning": "Är du säker på att du vill ta bort den här samlingen? \nDetta tar också bort alla länkade äventyr. \nDenna åtgärd kan inte ångras.",
"descending": "Fallande",
"duration": "Varaktighet",
"edit_adventure": "Redigera äventyr",
"edit_collection": "Redigera samling",
"filter": "Filtrera",
"homepage": "Hemsida",
"latitude": "Latitud",
"longitude": "Longitud",
"my_collections": "Mina samlingar",
"name": "Namn",
"no_image_found": "Ingen bild hittades",
"not_found": "Äventyret hittades inte",
"not_found_desc": "Äventyret du letade efter kunde inte hittas. \nProva ett annat äventyr eller kom tillbaka senare.",
"open_details": "Öppna Detaljer",
"open_filters": "Öppna filter",
"order_by": "Beställ efter",
"order_direction": "Beställ riktning",
"planned": "Planerad",
"private": "Privat",
"public": "Offentlig",
"rating": "Gradering",
"remove_from_collection": "Ta bort från samlingen",
"share": "Dela",
"sort": "Sortera",
"sources": "Källor",
"unarchive": "Avarkivera",
"unarchived_collection_message": "Samlingen har tagits bort från arkivet!",
"visit": "Besök",
"visited": "Besökte",
"visits": "Besök"
},
"home": {
"desc_1": "Upptäck, planera och utforska med lätthet",
"desc_2": "AdventureLog är designad för att förenkla din resa och förse dig med verktyg och resurser för att planera, packa och navigera i ditt nästa oförglömliga äventyr.",
"feature_1": "Reselogg",
"feature_1_desc": "Håll koll på dina äventyr med en personlig reselogg och dela dina upplevelser med vänner och familj.",
"feature_2": "Reseplanering",
"feature_2_desc": "Skapa enkelt anpassade resplaner och få en uppdelning av din resa dag för dag.",
"feature_3": "Resekarta",
"feature_3_desc": "Se dina resor över hela världen med en interaktiv karta och utforska nya destinationer.",
"go_to": "Gå till AdventureLog",
"hero_1": "Upptäck världens mest spännande äventyr",
"hero_2": "Upptäck och planera ditt nästa äventyr med AdventureLog. \nUtforska hisnande destinationer, skapa anpassade resplaner och håll kontakten när du är på språng.",
"key_features": "Nyckelfunktioner"
},
"navbar": {
"about": "Om AdventureLog",
"adventures": "Äventyr",
"collections": "Samlingar",
"discord": "Disharmoni",
"documentation": "Dokumentation",
"greeting": "Hej",
"login": "Inloggning",
"logout": "Utloggning",
"map": "Karta",
"my_activities": "Mina aktiviteter",
"my_adventures": "Mina äventyr",
"profile": "Profil",
"search": "Söka",
"settings": "Inställningar",
"shared_with_me": "Delade med mig",
"signup": "Registrera dig",
"theme_selection": "Temaval",
"themes": {
"aestetic-dark": "Estetisk mörk",
"aestetic-light": "Estetiskt ljus",
"aqua": "Aqua",
"dark": "Mörk",
"forest": "Skog",
"light": "Ljus",
"night": "Natt"
},
"users": "Användare",
"worldtravel": "Världsresor"
},
"worldtravel": {
"all": "Alla",
"all_subregions": "Alla underregioner",
"clear_search": "Rensa sökning",
"completely_visited": "Helt besökt",
"country_list": "Lista över länder",
"no_countries_found": "Inga länder hittades",
"not_visited": "Ej besökt",
"num_countries": "hittade länder",
"partially_visited": "Delvis besökt"
}
}

View file

@ -89,7 +89,20 @@
"unarchived_collection_message": "收藏解压成功!",
"updated": "已更新",
"visit": "访问",
"visits": "访问量"
"visits": "访问量",
"adventure_delete_success": "冒险删除成功!",
"dates": "枣子",
"delete_adventure": "删除冒险",
"duration": "期间",
"image_removed_error": "删除图像时出错",
"image_removed_success": "图片删除成功!",
"image_upload_error": "上传图片时出错",
"image_upload_success": "图片上传成功!",
"no_image_url": "在该 URL 中找不到图像。",
"planned": "计划",
"start_before_end_error": "开始日期必须早于结束日期",
"visited": "访问过",
"wiki_image_error": "从维基百科获取图像时出错"
},
"home": {
"desc_1": "轻松发现、规划和探索",
@ -134,5 +147,24 @@
},
"users": "用户",
"worldtravel": "环球旅行"
},
"auth": {
"forgot_password": "忘记密码?",
"login": "登录",
"login_error": "无法使用提供的凭据登录。",
"password": "密码",
"signup": "报名",
"username": "用户名"
},
"worldtravel": {
"all": "全部",
"all_subregions": "所有次区域",
"clear_search": "清除搜索",
"completely_visited": "已完全访问",
"country_list": "国家列表",
"no_countries_found": "没有找到国家",
"not_visited": "未访问过",
"num_countries": "找到的国家",
"partially_visited": "部分访问"
}
}

View file

@ -12,6 +12,7 @@
register('it', () => import('../locales/it.json'));
register('zh', () => import('../locales/zh.json'));
register('nl', () => import('../locales/nl.json'));
register('sv', () => import('../locales/sv.json'));
if (browser) {
init({

View file

@ -1,5 +1,7 @@
const PUBLIC_SERVER_URL = process.env['PUBLIC_SERVER_URL'];
import { redirect, type Actions } from '@sveltejs/kit';
import type { PageServerLoad } from './$types';
import { getRandomBackground } from '$lib';
const serverEndpoint = PUBLIC_SERVER_URL || 'http://localhost:8000';

View file

@ -3,6 +3,7 @@
export let data;
console.log(data);
import { t } from 'svelte-i18n';
import FileImageBox from '~icons/mdi/file-image-box';
@ -32,36 +33,38 @@
<div class="flex-1">
<h3 class="text-center">AdventureLog</h3>
<article class="text-center text-4xl mb-4 font-extrabold">
<h1>Login</h1>
<h1>{$t('auth.login')}</h1>
</article>
<div class="flex justify-center">
<form method="post" use:enhance class="w-full max-w-xs">
<label for="username">Username</label>
<label for="username">{$t('auth.username')}</label>
<input
name="username"
id="username"
class="block input input-bordered w-full max-w-xs"
/><br />
<label for="password">Password</label>
<label for="password">{$t('auth.password')}</label>
<input
type="password"
name="password"
id="password"
class="block input input-bordered w-full max-w-xs"
/><br />
<button class="py-2 px-4 btn btn-primary mr-2">Login</button>
<button class="py-2 px-4 btn btn-primary mr-2">{$t('auth.login')}</button>
<div class="flex justify-between mt-4">
<p><a href="/signup" class="underline">Signup</a></p>
<p><a href="/settings/forgot-password" class="underline">Forgot Password</a></p>
<p><a href="/signup" class="underline">{$t('auth.signup')}</a></p>
<p>
<a href="/settings/forgot-password" class="underline">{$t('auth.forgot_password')}</a>
</p>
</div>
</form>
</div>
{#if ($page.form?.message && $page.form?.message.length > 1) || $page.form?.type === 'error'}
<div class="text-center text-error mt-4">
{$page.form.message || 'Unable to login with the provided credentials.'}
{$page.form.message || $t('auth.login_error')}
</div>
{/if}
</div>

View file

@ -2,6 +2,7 @@
import CountryCard from '$lib/components/CountryCard.svelte';
import type { Country } from '$lib/types';
import type { PageData } from './$types';
import { t } from 'svelte-i18n';
export let data: PageData;
console.log(data);
@ -51,10 +52,11 @@
}
</script>
<h1 class="text-center font-bold text-4xl">Country List</h1>
<h1 class="text-center font-bold text-4xl">{$t('worldtravel.country_list')}</h1>
<!-- result count -->
<p class="text-center mb-4">
{filteredCountries.length} countries found
{filteredCountries.length}
{$t('worldtravel.num_countries')}
</p>
<div class="flex items-center justify-center mb-4">
<div class="join">
@ -62,7 +64,7 @@
class="join-item btn"
type="radio"
name="filter"
aria-label="All"
aria-label={$t('worldtravel.all')}
checked
on:click={() => (filterOption = 'all')}
/>
@ -70,26 +72,26 @@
class="join-item btn"
type="radio"
name="filter"
aria-label="Partially Visited"
aria-label={$t('worldtravel.partially_visited')}
on:click={() => (filterOption = 'partial')}
/>
<input
class="join-item btn"
type="radio"
name="filter"
aria-label="Completely Visited"
aria-label={$t('worldtravel.completely_visited')}
on:click={() => (filterOption = 'complete')}
/>
<input
class="join-item btn"
type="radio"
name="filter"
aria-label="Not Visited"
aria-label={$t('worldtravel.not_visited')}
on:click={() => (filterOption = 'not')}
/>
</div>
<select class="select select-bordered w-full max-w-xs ml-4" bind:value={subRegionOption}>
<option value="">All Subregions</option>
<option value="">{$t('worldtravel.all_subregions')}</option>
{#each worldSubregions as subregion}
<option value={subregion}>{subregion}</option>
{/each}
@ -99,14 +101,16 @@
<div class="flex items-center justify-center mb-4">
<input
type="text"
placeholder="Search"
placeholder={$t('navbar.search')}
class="input input-bordered w-full max-w-xs"
bind:value={searchQuery}
/>
{#if searchQuery.length > 0}
<!-- clear button -->
<div class="flex items-center justify-center ml-4">
<button class="btn btn-neutral" on:click={() => (searchQuery = '')}> Clear Search </button>
<button class="btn btn-neutral" on:click={() => (searchQuery = '')}>
{$t('worldtravel.clear_search')}
</button>
</div>
{/if}
</div>
@ -119,7 +123,7 @@
</div>
{#if filteredCountries.length === 0}
<p class="text-center font-bold text-2xl mt-12">No countries found</p>
<p class="text-center font-bold text-2xl mt-12">{$t('worldtravel.no_countries_found')}</p>
{/if}
<svelte:head>