Enhance localization support; update error messages and add translations for adventure calendar
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
import TimeGrid from '@event-calendar/time-grid';
|
||||
// @ts-ignore
|
||||
import DayGrid from '@event-calendar/day-grid';
|
||||
import { t } from 'svelte-i18n';
|
||||
|
||||
export let data: PageData;
|
||||
|
||||
@@ -20,6 +21,6 @@
|
||||
};
|
||||
</script>
|
||||
|
||||
<h1 class="text-center text-2xl font-bold">Adventure Calendar</h1>
|
||||
<h1 class="text-center text-2xl font-bold">{$t('adventures.adventure_calendar')}</h1>
|
||||
|
||||
<Calendar {plugins} {options} />
|
||||
|
||||
@@ -1,22 +1,19 @@
|
||||
<script lang="ts">
|
||||
import AdventureCard from '$lib/components/AdventureCard.svelte';
|
||||
import type { PageData } from './$types';
|
||||
import { t } from 'svelte-i18n';
|
||||
|
||||
export let data: PageData;
|
||||
|
||||
const user = data.user;
|
||||
const recentAdventures = data.props.adventures;
|
||||
const stats = data.props.stats;
|
||||
console.log(stats);
|
||||
|
||||
const inspirationQuote = 'The world is a book, and those who do not travel read only one page.';
|
||||
const inspirationImage = 'https://picsum.photos/seed/inspiration/800/400';
|
||||
</script>
|
||||
|
||||
<div class="container mx-auto p-4">
|
||||
<!-- Welcome Message -->
|
||||
<div class="mb-8">
|
||||
<h1 class="text-4xl font-extrabold">Welcome back, {user?.first_name}!</h1>
|
||||
<h1 class="text-4xl font-extrabold">{$t('dashboard.welcome_back')}, {user?.first_name}!</h1>
|
||||
</div>
|
||||
|
||||
<!-- Stats -->
|
||||
@@ -36,7 +33,7 @@
|
||||
></path></svg
|
||||
>
|
||||
</div>
|
||||
<div class="stat-title text-neutral-content">Countries Visited</div>
|
||||
<div class="stat-title text-neutral-content">{$t('dashboard.countries_visited')}</div>
|
||||
<div class="stat-value text-primary">{stats.country_count}</div>
|
||||
</div>
|
||||
<div class="stat">
|
||||
@@ -54,7 +51,7 @@
|
||||
></path></svg
|
||||
>
|
||||
</div>
|
||||
<div class="stat-title text-neutral-content">Total Adventures</div>
|
||||
<div class="stat-title text-neutral-content">{$t('dashboard.total_adventures')}</div>
|
||||
<div class="stat-value text-secondary">{stats.adventure_count}</div>
|
||||
</div>
|
||||
<div class="stat">
|
||||
@@ -72,32 +69,31 @@
|
||||
></path></svg
|
||||
>
|
||||
</div>
|
||||
<div class="stat-title text-neutral-content">Total Visited Regions</div>
|
||||
<div class="stat-title text-neutral-content">{$t('dashboard.total_visited_regions')}</div>
|
||||
<div class="stat-value text-success">{stats.visited_region_count}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Recent Adventures -->
|
||||
<h2 class="text-3xl font-semibold mb-4">Recent Adventures</h2>
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-8">
|
||||
{#each recentAdventures as adventure}
|
||||
<AdventureCard {adventure} user={data.user} readOnly />
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<!-- Inspiration -->
|
||||
<div class="card lg:card-side bg-base-100 shadow-xl mb-8">
|
||||
<figure class="lg:w-1/2">
|
||||
<img src={inspirationImage} alt="Inspiration" class="w-full h-full object-cover" />
|
||||
</figure>
|
||||
<div class="card-body lg:w-1/2">
|
||||
<h2 class="card-title">Get Inspired</h2>
|
||||
<p class="text-lg italic">"{inspirationQuote}"</p>
|
||||
<div class="card-actions justify-end">
|
||||
<button class="btn btn-primary">Plan Your Next Adventure</button>
|
||||
</div>
|
||||
{#if recentAdventures.length > 0}
|
||||
<h2 class="text-3xl font-semibold mb-4">{$t('dashboard.recent_adventures')}</h2>
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-8">
|
||||
{#each recentAdventures as adventure}
|
||||
<AdventureCard {adventure} user={data.user} readOnly />
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Inspiration if there are no recent adventures -->
|
||||
{#if recentAdventures.length === 0}
|
||||
<div class="flex flex-col items-center justify-center bg-neutral shadow p-8 mb-8 rounded-lg">
|
||||
<h2 class="text-3xl font-semibold mb-4">{$t('dashboard.no_recent_adventures')}</h2>
|
||||
<p class="text-lg text-center">
|
||||
{$t('dashboard.add_some')}
|
||||
</p>
|
||||
<a href="/adventures" class="btn btn-primary mt-4">{$t('map.add_adventure')}</a>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<svelte:head>
|
||||
|
||||
@@ -100,7 +100,9 @@
|
||||
emails = [...emails, { email: new_email, verified: false, primary: false }];
|
||||
new_email = '';
|
||||
} else {
|
||||
addToast('error', $t('settings.email_added_error'));
|
||||
let error = await res.json();
|
||||
let error_code = error.errors[0].code;
|
||||
addToast('error', $t(`settings.${error_code}`) || $t('settings.generic_error'));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,11 +41,11 @@ export const actions: Actions = {
|
||||
|
||||
if (!csrfTokenFetch.ok) {
|
||||
event.locals.user = null;
|
||||
return fail(500, { message: 'Failed to fetch CSRF token' });
|
||||
return fail(500, { message: 'settings.csrf_failed' });
|
||||
}
|
||||
|
||||
if (password1 !== password2) {
|
||||
return fail(400, { message: 'Passwords do not match' });
|
||||
return fail(400, { message: 'settings.password_does_not_match' });
|
||||
}
|
||||
|
||||
const tokenPromise = await csrfTokenFetch.json();
|
||||
@@ -69,7 +69,7 @@ export const actions: Actions = {
|
||||
const loginResponse = await loginFetch.json();
|
||||
|
||||
if (!loginFetch.ok) {
|
||||
return fail(loginFetch.status, loginResponse);
|
||||
return fail(loginFetch.status, { message: loginResponse.errors[0].code });
|
||||
} else {
|
||||
const setCookieHeader = loginFetch.headers.get('Set-Cookie');
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
</div>
|
||||
|
||||
{#if $page.form?.message}
|
||||
<div class="text-center text-error mt-4">{$page.form?.message}</div>
|
||||
<div class="text-center text-error mt-4">{$t($page.form?.message)}</div>
|
||||
{/if}
|
||||
{:else}
|
||||
<div class="flex justify-center">
|
||||
|
||||
@@ -21,13 +21,14 @@ export const load = (async (event) => {
|
||||
|
||||
body: JSON.stringify({ key: key })
|
||||
});
|
||||
if (!verifyFetch.ok) {
|
||||
if (verifyFetch.ok || verifyFetch.status == 401) {
|
||||
return {
|
||||
verified: true
|
||||
};
|
||||
} else {
|
||||
let error_message = await verifyFetch.json();
|
||||
console.error(error_message);
|
||||
console.error('Failed to verify email');
|
||||
return { status: 404 };
|
||||
}
|
||||
return {
|
||||
verified: true
|
||||
};
|
||||
}) satisfies PageServerLoad;
|
||||
|
||||
Reference in New Issue
Block a user