feat(i18n): integrate internationalization for game pages
- Added translation support for various game-related texts in the home, daily, infinite, login, and profile pages. - Replaced hardcoded French strings with translation keys using the `$t` function. - Updated titles, descriptions, and button texts to enhance localization.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import ProfileButton from '$lib/components/ProfileButton.svelte';
|
||||
import LanguageSwitcher from '$lib/components/LanguageSwitcher.svelte';
|
||||
import { resolve } from '$app/paths';
|
||||
|
||||
let { children, data } = $props();
|
||||
@@ -11,7 +12,10 @@
|
||||
<a href={resolve("/")} class="text-lg font-black uppercase tracking-[0.15em] text-amber-50 transition hover:text-amber-100">
|
||||
OnePieceDle
|
||||
</a>
|
||||
<ProfileButton user={data.user} />
|
||||
<div class="flex items-center gap-3">
|
||||
<LanguageSwitcher />
|
||||
<ProfileButton user={data.user} />
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<main class="pt-20">
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
export let data;
|
||||
|
||||
import { resolve } from '$app/paths';
|
||||
import { t } from '$lib/i18n';
|
||||
|
||||
$: yesterdayCharacter = data.yesterdayCharacter;
|
||||
</script>
|
||||
@@ -23,30 +24,30 @@
|
||||
OnePieceDle
|
||||
</h1>
|
||||
<p class="mt-4 max-w-2xl text-base text-slate-200 sm:text-lg">
|
||||
Devine le personnage de l'equipage, des marines ou du vaste monde. Chaque indice te rapproche du tresor.
|
||||
{$t.game.home.heroDescription}
|
||||
</p>
|
||||
</div>
|
||||
<div class="grid w-full gap-4 sm:grid-cols-2">
|
||||
<div class="rounded-2xl border border-white/10 bg-white/5 p-6 shadow-[0_24px_60px_rgba(0,0,0,0.45)] backdrop-blur">
|
||||
<h2 class="text-sm font-semibold uppercase tracking-[0.2em] text-amber-100">Personnage du jour</h2>
|
||||
<p class="mt-3 text-lg font-semibold text-white">Nouveau mystere toutes les 24 heures</p>
|
||||
<p class="mt-2 text-sm text-slate-200">Compare tes essais, debloque des indices et garde ta serie.</p>
|
||||
<h2 class="text-sm font-semibold uppercase tracking-[0.2em] text-amber-100">{$t.game.home.dailyTitle}</h2>
|
||||
<p class="mt-3 text-lg font-semibold text-white">{$t.game.home.dailySubtitle}</p>
|
||||
<p class="mt-2 text-sm text-slate-200">{$t.game.home.dailyDescription}</p>
|
||||
<a
|
||||
href={resolve("/daily")}
|
||||
class="mt-5 inline-flex w-full items-center justify-center rounded-full bg-amber-300 px-5 py-3 text-sm font-semibold text-slate-900 transition hover:bg-amber-200"
|
||||
>
|
||||
Commencer
|
||||
{$t.game.home.dailyCta}
|
||||
</a>
|
||||
</div>
|
||||
<div class="rounded-2xl border border-white/10 bg-white/5 p-6 shadow-[0_24px_60px_rgba(0,0,0,0.45)] backdrop-blur">
|
||||
<h2 class="text-sm font-semibold uppercase tracking-[0.2em] text-amber-100">Mode Infini</h2>
|
||||
<p class="mt-3 text-lg font-semibold text-white">Des defis sans fin</p>
|
||||
<p class="mt-2 text-sm text-slate-200">Enchaine les personnages et croise ton score. Pas de limite, que du plaisir.</p>
|
||||
<h2 class="text-sm font-semibold uppercase tracking-[0.2em] text-amber-100">{$t.game.home.infiniteTitle}</h2>
|
||||
<p class="mt-3 text-lg font-semibold text-white">{$t.game.home.infiniteSubtitle}</p>
|
||||
<p class="mt-2 text-sm text-slate-200">{$t.game.home.infiniteDescription}</p>
|
||||
<a
|
||||
href={resolve("/infinite")}
|
||||
class="mt-5 inline-flex w-full items-center justify-center rounded-full border border-amber-200/40 bg-transparent px-5 py-3 text-sm font-semibold text-amber-100 transition hover:border-amber-200 hover:text-amber-50"
|
||||
>
|
||||
Jouer
|
||||
{$t.game.home.infiniteCta}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -61,11 +62,11 @@
|
||||
/>
|
||||
{:else}
|
||||
<div class="flex h-20 w-20 items-center justify-center rounded-full border border-amber-200/40 bg-slate-900/70 text-xs uppercase tracking-[0.25em] text-amber-100">
|
||||
Photo
|
||||
{$t.game.home.photoFallback}
|
||||
</div>
|
||||
{/if}
|
||||
<div class="flex-1">
|
||||
<p class="text-xs font-semibold uppercase tracking-[0.28em] text-amber-100">Personnage d'hier</p>
|
||||
<p class="text-xs font-semibold uppercase tracking-[0.28em] text-amber-100">{$t.game.home.yesterdayCharacter}</p>
|
||||
<p class="mt-2 text-lg font-semibold text-white">{yesterdayCharacter.name}</p>
|
||||
{#if yesterdayCharacter.epithets}
|
||||
<p class="mt-1 text-sm text-slate-400">
|
||||
@@ -81,18 +82,18 @@
|
||||
rel="noopener noreferrer"
|
||||
class="w-full rounded-full border border-amber-200/40 bg-transparent px-5 py-3 text-sm font-semibold text-amber-100 transition hover:border-amber-200 hover:text-amber-50 sm:w-auto"
|
||||
>
|
||||
Voir la page
|
||||
{$t.game.home.openPage}
|
||||
</a>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="flex flex-col items-center gap-5 text-center sm:flex-row sm:text-left">
|
||||
<div class="flex h-20 w-20 items-center justify-center rounded-full border border-amber-200/40 bg-slate-900/70 text-xs uppercase tracking-[0.25em] text-amber-100">
|
||||
Photo
|
||||
{$t.game.home.photoFallback}
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<p class="text-xs font-semibold uppercase tracking-[0.28em] text-amber-100">Personnage d'hier</p>
|
||||
<p class="mt-2 text-lg font-semibold text-white">Aucun personnage</p>
|
||||
<p class="mt-1 text-sm text-slate-200">Aucun personnage d'hier disponible</p>
|
||||
<p class="text-xs font-semibold uppercase tracking-[0.28em] text-amber-100">{$t.game.home.yesterdayCharacter}</p>
|
||||
<p class="mt-2 text-lg font-semibold text-white">{$t.game.home.noCharacter}</p>
|
||||
<p class="mt-1 text-sm text-slate-200">{$t.game.home.noYesterdayCharacter}</p>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
import GuessHistoryTable from '$lib/components/GuessHistoryTable.svelte';
|
||||
import WinPanel from '$lib/components/WinPanel.svelte';
|
||||
import type { CharacterWithRelations } from '$lib/server/daily-character.js';
|
||||
import { t } from '$lib/i18n';
|
||||
|
||||
export let data;
|
||||
|
||||
@@ -186,7 +187,7 @@
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>OnePieceDle - Mode du jour</title>
|
||||
<title>{$t.game.daily.metaTitle}</title>
|
||||
<style>
|
||||
@keyframes shadow-pulse {
|
||||
0% {
|
||||
@@ -264,10 +265,10 @@
|
||||
<div class="flex w-full items-center justify-between gap-4">
|
||||
<div>
|
||||
<h1 class="text-3xl font-black uppercase tracking-[0.25em] text-amber-50 sm:text-5xl">
|
||||
Personnage du jour
|
||||
{$t.game.daily.title}
|
||||
</h1>
|
||||
<p class="mt-2 text-sm text-amber-300">
|
||||
{data.winCount} {data.winCount > 1 ? 'personnes' : 'personne'} {data.winCount > 1 ? 'ont' : 'a'} trouvé aujourd'hui 🎉
|
||||
{data.winCount} {data.winCount > 1 ? $t.game.daily.winsPeoplePlural : $t.game.daily.winsPeopleSingular} {data.winCount > 1 ? $t.game.daily.winsVerbPlural : $t.game.daily.winsVerbSingular} {$t.game.daily.winsSuffix}
|
||||
</p>
|
||||
</div>
|
||||
{#if hasWon}
|
||||
@@ -275,12 +276,12 @@
|
||||
class="rounded-full border border-amber-200/40 bg-transparent px-5 py-3 text-sm font-semibold text-amber-100 transition hover:border-amber-200 hover:text-amber-50"
|
||||
onclick={resetHistory}
|
||||
>
|
||||
Recommencer
|
||||
{$t.game.daily.reset}
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
<p class="max-w-2xl text-base text-slate-200 sm:text-lg">
|
||||
Devine le personnage. Chaque indice se débloque après un certain nombre de tentatives. Bonne chance !
|
||||
{$t.game.daily.description}
|
||||
</p>
|
||||
</header>
|
||||
|
||||
@@ -313,7 +314,7 @@
|
||||
|
||||
{#if hasWon && data.friendsTodayResults && data.friendsTodayResults.length > 0}
|
||||
<section class="mt-6 rounded-3xl border border-white/10 bg-white/5 p-6 shadow-[0_24px_60px_rgba(0,0,0,0.45)] backdrop-blur">
|
||||
<p class="text-xs font-semibold uppercase tracking-[0.28em] text-amber-100 text-center">Tes amis aujourd'hui</p>
|
||||
<p class="text-xs font-semibold uppercase tracking-[0.28em] text-amber-100 text-center">{$t.game.daily.friendsToday}</p>
|
||||
<div class="mt-4 space-y-2">
|
||||
{#each data.friendsTodayResults as friendResult (friendResult.userId)}
|
||||
<div class="flex items-center justify-between rounded-lg border border-white/10 bg-slate-950/50 px-4 py-2">
|
||||
@@ -332,7 +333,7 @@
|
||||
<p class="text-sm font-semibold text-slate-100">{friendResult.name}</p>
|
||||
</div>
|
||||
<p class="text-sm text-amber-300">
|
||||
{friendResult.tryCount} {friendResult.tryCount > 1 ? 'coups' : 'coup'}
|
||||
{friendResult.tryCount} {friendResult.tryCount > 1 ? $t.game.daily.friendTryPlural : $t.game.daily.friendTrySingular}
|
||||
</p>
|
||||
</div>
|
||||
{/each}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
import WinPanel from '$lib/components/WinPanel.svelte';
|
||||
import HintsPanel from '$lib/components/HintsPanel.svelte';
|
||||
import type { CharacterWithRelations } from '$lib/server/daily-character.js';
|
||||
import { t } from '$lib/i18n';
|
||||
|
||||
export let data;
|
||||
|
||||
@@ -18,17 +19,7 @@
|
||||
let availableArcs: ArcFilterOption[] = [];
|
||||
let hasWon = false;
|
||||
let columnVisibility: Record<string, boolean> = {};
|
||||
const columnDisplayNames: Record<string, string> = {
|
||||
status: 'Statut',
|
||||
gender: 'Genre',
|
||||
affiliations: 'Affiliations',
|
||||
devilFruitType: 'Fruit',
|
||||
haki: 'Haki',
|
||||
bounty: 'Prime',
|
||||
height: 'Taille',
|
||||
origin: 'Origine',
|
||||
arc: 'Arc'
|
||||
};
|
||||
let columnDisplayNames: Record<string, string> = {};
|
||||
|
||||
// Character filters
|
||||
let characterFilters = {
|
||||
@@ -291,6 +282,17 @@
|
||||
} else if (!hasWon) {
|
||||
isGeckoMoriaWin = false;
|
||||
}
|
||||
$: columnDisplayNames = {
|
||||
status: $t.game.components.guessHistory.status,
|
||||
gender: $t.game.components.guessHistory.gender,
|
||||
affiliations: $t.game.components.guessHistory.affiliations,
|
||||
devilFruitType: $t.game.components.guessHistory.fruit,
|
||||
haki: $t.game.components.guessHistory.haki,
|
||||
bounty: $t.game.components.guessHistory.bounty,
|
||||
height: $t.game.components.guessHistory.height,
|
||||
origin: $t.game.components.guessHistory.origin,
|
||||
arc: $t.game.components.guessHistory.arc
|
||||
};
|
||||
|
||||
function generateNewCharacter() {
|
||||
if (characters.length === 0) return;
|
||||
@@ -473,7 +475,7 @@
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>OnePieceDle - Mode Infini</title>
|
||||
<title>{$t.game.infinite.metaTitle}</title>
|
||||
<style>
|
||||
@keyframes shadow-pulse {
|
||||
0% {
|
||||
@@ -564,22 +566,21 @@
|
||||
<div class="flex w-full items-center justify-between gap-4">
|
||||
<div>
|
||||
<h1 class="text-3xl font-black tracking-[0.25em] text-amber-50 uppercase sm:text-5xl">
|
||||
Mode Infini
|
||||
{$t.game.infinite.title}
|
||||
</h1>
|
||||
<p class="mt-2 text-2xl font-bold text-amber-300">Score: {score}</p>
|
||||
<p class="mt-2 text-2xl font-bold text-amber-300">{$t.game.infinite.score}: {score}</p>
|
||||
</div>
|
||||
{#if score > 0}
|
||||
<button
|
||||
class="rounded-full border border-amber-200/40 bg-transparent px-5 py-3 text-sm font-semibold text-amber-100 transition hover:border-amber-200 hover:text-amber-50"
|
||||
onclick={resetScore}
|
||||
>
|
||||
Réinitialiser
|
||||
{$t.game.infinite.resetScore}
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
<p class="max-w-2xl text-base text-slate-200 sm:text-lg">
|
||||
Devine des personnages à l'infini ! Chaque indice se débloque après un certain nombre de
|
||||
tentatives. Bonne chance !
|
||||
{$t.game.infinite.description}
|
||||
</p>
|
||||
</header>
|
||||
|
||||
@@ -593,7 +594,7 @@
|
||||
onclick={nextCharacter}
|
||||
class="mt-4 w-full rounded-full bg-emerald-500 px-6 py-2 text-sm font-semibold text-white transition hover:bg-emerald-600"
|
||||
>
|
||||
Recommencer
|
||||
{$t.game.infinite.nextCharacter}
|
||||
</button>
|
||||
</div>
|
||||
{:else}
|
||||
@@ -611,7 +612,7 @@
|
||||
onclick={revealAnswer}
|
||||
class="rounded-lg border border-red-600/40 bg-red-900/20 px-4 py-2 text-sm text-red-300 transition hover:border-red-500 hover:bg-red-900/40 hover:text-red-200"
|
||||
>
|
||||
Révéler la réponse
|
||||
{$t.game.infinite.revealAnswer}
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
@@ -625,7 +626,7 @@
|
||||
<div
|
||||
class="rounded-3xl border border-white/10 bg-white/5 p-6 shadow-[0_24px_60px_rgba(0,0,0,0.45)] backdrop-blur"
|
||||
>
|
||||
<p class="text-center text-slate-300">Chargement du personnage...</p>
|
||||
<p class="text-center text-slate-300">{$t.game.infinite.loadingCharacter}</p>
|
||||
</div>
|
||||
{/if}
|
||||
</section>
|
||||
@@ -642,7 +643,7 @@
|
||||
<div class="rounded-2xl border border-white/10 bg-white/5 p-3 backdrop-blur sm:p-4">
|
||||
<div class="mb-3 flex items-center justify-between gap-3">
|
||||
<h3 class="text-xs font-semibold tracking-[0.2em] text-amber-200 uppercase">
|
||||
Filtres de personnages
|
||||
{$t.game.infinite.filtersTitle}
|
||||
</h3>
|
||||
{#if characterFilters.gender.length > 0 || characterFilters.hasHaki || characterFilters.hasDevilFruit !== null || characterFilters.status.length > 0 || characterFilters.hasHeight || characterFilters.hasOrigin || characterFilters.arcs.length > 0}
|
||||
<button
|
||||
@@ -650,7 +651,7 @@
|
||||
onclick={clearAllFilters}
|
||||
class="text-xs text-red-300 transition hover:text-red-200"
|
||||
>
|
||||
Réinitialiser
|
||||
{$t.game.infinite.clearFilters}
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
@@ -658,7 +659,7 @@
|
||||
<div class="space-y-3">
|
||||
<!-- Gender Filter -->
|
||||
<div>
|
||||
<p class="mb-2 text-xs text-slate-400">Genre</p>
|
||||
<p class="mb-2 text-xs text-slate-400">{$t.game.infinite.filterGender}</p>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
{#each ['Male', 'Female'] as gender (gender)}
|
||||
<button
|
||||
@@ -670,7 +671,7 @@
|
||||
? 'border-amber-300/50 bg-amber-300/10 text-amber-100 hover:bg-amber-300/20'
|
||||
: 'border-white/20 bg-slate-900/40 text-slate-400 hover:bg-slate-900/60'}"
|
||||
>
|
||||
{gender === 'Male' ? 'Homme' : 'Femme'}
|
||||
{gender === 'Male' ? $t.game.infinite.male : $t.game.infinite.female}
|
||||
</button>
|
||||
{/each}
|
||||
</div>
|
||||
@@ -678,7 +679,7 @@
|
||||
|
||||
<!-- Status Filter -->
|
||||
<div>
|
||||
<p class="mb-2 text-xs text-slate-400">Statut</p>
|
||||
<p class="mb-2 text-xs text-slate-400">{$t.game.infinite.filterStatus}</p>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
{#each ['Alive', 'Dead', 'Unknown'] as status (status)}
|
||||
<button
|
||||
@@ -690,7 +691,7 @@
|
||||
? 'border-amber-300/50 bg-amber-300/10 text-amber-100 hover:bg-amber-300/20'
|
||||
: 'border-white/20 bg-slate-900/40 text-slate-400 hover:bg-slate-900/60'}"
|
||||
>
|
||||
{status === 'Alive' ? 'Vivant' : status === 'Dead' ? 'Mort' : 'Inconnu'}
|
||||
{status === 'Alive' ? $t.game.infinite.alive : status === 'Dead' ? $t.game.infinite.dead : $t.game.infinite.unknown}
|
||||
</button>
|
||||
{/each}
|
||||
</div>
|
||||
@@ -698,7 +699,7 @@
|
||||
|
||||
<!-- Haki Filter -->
|
||||
<div>
|
||||
<p class="mb-2 text-xs text-slate-400">Capacités</p>
|
||||
<p class="mb-2 text-xs text-slate-400">{$t.game.infinite.filterAbilities}</p>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<button
|
||||
type="button"
|
||||
@@ -707,7 +708,7 @@
|
||||
? 'border-amber-300/50 bg-amber-300/10 text-amber-100 hover:bg-amber-300/20'
|
||||
: 'border-white/20 bg-slate-900/40 text-slate-400 hover:bg-slate-900/60'}"
|
||||
>
|
||||
A du Haki
|
||||
{$t.game.infinite.hasHaki}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
@@ -720,17 +721,17 @@
|
||||
: 'border-white/20 bg-slate-900/40 text-slate-400 hover:bg-slate-900/60'}"
|
||||
>
|
||||
{characterFilters.hasDevilFruit === null
|
||||
? 'Fruit (Tous)'
|
||||
? $t.game.infinite.fruitAll
|
||||
: characterFilters.hasDevilFruit
|
||||
? 'Avec Fruit'
|
||||
: 'Sans Fruit'}
|
||||
? $t.game.infinite.withFruit
|
||||
: $t.game.infinite.withoutFruit}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Informations Filter -->
|
||||
<div>
|
||||
<p class="mb-2 text-xs text-slate-400">Informations</p>
|
||||
<p class="mb-2 text-xs text-slate-400">{$t.game.infinite.filterInformation}</p>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<button
|
||||
type="button"
|
||||
@@ -739,7 +740,7 @@
|
||||
? 'border-amber-300/50 bg-amber-300/10 text-amber-100 hover:bg-amber-300/20'
|
||||
: 'border-white/20 bg-slate-900/40 text-slate-400 hover:bg-slate-900/60'}"
|
||||
>
|
||||
Taille définie
|
||||
{$t.game.infinite.heightDefined}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
@@ -748,14 +749,14 @@
|
||||
? 'border-amber-300/50 bg-amber-300/10 text-amber-100 hover:bg-amber-300/20'
|
||||
: 'border-white/20 bg-slate-900/40 text-slate-400 hover:bg-slate-900/60'}"
|
||||
>
|
||||
Origine définie
|
||||
{$t.game.infinite.originDefined}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Arc Filter -->
|
||||
<div>
|
||||
<p class="mb-2 text-xs text-slate-400">Arcs</p>
|
||||
<p class="mb-2 text-xs text-slate-400">{$t.game.infinite.filterArcs}</p>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
{#each availableArcs as arc (arc.id)}
|
||||
<button
|
||||
@@ -774,10 +775,7 @@
|
||||
</div>
|
||||
|
||||
<p class="mt-2 text-xs text-slate-500">
|
||||
{characters.length} personnage{characters.length > 1 ? 's' : ''} disponible{characters.length >
|
||||
1
|
||||
? 's'
|
||||
: ''}
|
||||
{characters.length} {characters.length > 1 ? $t.game.infinite.availableCharactersPlural : $t.game.infinite.availableCharactersSingular}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -788,7 +786,7 @@
|
||||
<div class="rounded-2xl border border-white/10 bg-white/5 p-3 backdrop-blur sm:p-4">
|
||||
<div class="mb-3 flex items-center justify-between gap-3">
|
||||
<h3 class="text-xs font-semibold tracking-[0.2em] text-amber-200 uppercase">
|
||||
Colonnes
|
||||
{$t.game.infinite.columnsTitle}
|
||||
</h3>
|
||||
<p class="text-xs text-slate-400">
|
||||
{Object.values(columnVisibility).filter(Boolean).length}/{Object.keys(
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { enhance } from '$app/forms';
|
||||
import { resolve } from '$app/paths';
|
||||
import { t } from '$lib/i18n';
|
||||
import type { ActionData } from './$types';
|
||||
|
||||
export let form: ActionData;
|
||||
@@ -25,7 +26,7 @@
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>OnePieceDle - {isSignUp ? 'Inscription' : 'Connexion'}</title>
|
||||
<title>OnePieceDle - {isSignUp ? $t.game.login.titleSignUp : $t.game.login.titleSignIn}</title>
|
||||
</svelte:head>
|
||||
|
||||
<main class="relative min-h-[calc(100vh-5rem)] bg-slate-950 text-slate-100">
|
||||
@@ -42,7 +43,7 @@
|
||||
OnePieceDle
|
||||
</h1>
|
||||
<p class="mt-4 text-slate-300">
|
||||
{isSignUp ? 'Créer votre compte' : 'Bienvenue, pirate'}
|
||||
{isSignUp ? $t.game.login.headerSignUp : $t.game.login.headerSignIn}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -64,7 +65,7 @@
|
||||
{#if isSignUp}
|
||||
<div>
|
||||
<label for="name" class="block text-sm font-semibold uppercase tracking-[0.2em] text-amber-100">
|
||||
Nom
|
||||
{$t.game.login.nameLabel}
|
||||
</label>
|
||||
<input
|
||||
id="name"
|
||||
@@ -72,7 +73,7 @@
|
||||
name="name"
|
||||
bind:value={name}
|
||||
required
|
||||
placeholder="Votre nom"
|
||||
placeholder={$t.game.login.namePlaceholder}
|
||||
class="mt-3 w-full rounded-lg border border-white/10 bg-white/5 px-4 py-3 text-white placeholder-slate-500 transition focus:border-amber-300 focus:outline-none focus:ring-2 focus:ring-amber-300/30"
|
||||
/>
|
||||
</div>
|
||||
@@ -82,7 +83,7 @@
|
||||
{#if isSignUp}
|
||||
<div>
|
||||
<label for="username" class="block text-sm font-semibold uppercase tracking-[0.2em] text-amber-100">
|
||||
Nom d'utilisateur
|
||||
{$t.game.login.usernameLabel}
|
||||
</label>
|
||||
<input
|
||||
id="username"
|
||||
@@ -90,7 +91,7 @@
|
||||
name="username"
|
||||
bind:value={username}
|
||||
required
|
||||
placeholder="ex: luffy_gear5"
|
||||
placeholder={$t.game.login.usernamePlaceholder}
|
||||
class="mt-3 w-full rounded-lg border border-white/10 bg-white/5 px-4 py-3 text-white placeholder-slate-500 transition focus:border-amber-300 focus:outline-none focus:ring-2 focus:ring-amber-300/30"
|
||||
/>
|
||||
</div>
|
||||
@@ -99,7 +100,7 @@
|
||||
<!-- Email / Username Field -->
|
||||
<div>
|
||||
<label for="identifier" class="block text-sm font-semibold uppercase tracking-[0.2em] text-amber-100">
|
||||
{isSignUp ? 'E-mail' : 'E-mail ou nom d\'utilisateur'}
|
||||
{isSignUp ? $t.game.login.identifierLabelSignUp : $t.game.login.identifierLabelSignIn}
|
||||
</label>
|
||||
<input
|
||||
id="identifier"
|
||||
@@ -107,7 +108,7 @@
|
||||
name={isSignUp ? 'email' : 'identifier'}
|
||||
bind:value={email}
|
||||
required
|
||||
placeholder={isSignUp ? 'votremail@email.com' : 'votremail@email.com ou luffy_gear5'}
|
||||
placeholder={isSignUp ? $t.game.login.identifierPlaceholderSignUp : $t.game.login.identifierPlaceholderSignIn}
|
||||
class="mt-3 w-full rounded-lg border border-white/10 bg-white/5 px-4 py-3 text-white placeholder-slate-500 transition focus:border-amber-300 focus:outline-none focus:ring-2 focus:ring-amber-300/30"
|
||||
/>
|
||||
</div>
|
||||
@@ -115,7 +116,7 @@
|
||||
<!-- Password Field -->
|
||||
<div>
|
||||
<label for="password" class="block text-sm font-semibold uppercase tracking-[0.2em] text-amber-100">
|
||||
Mot de passe
|
||||
{$t.game.login.passwordLabel}
|
||||
</label>
|
||||
<input
|
||||
id="password"
|
||||
@@ -135,7 +136,7 @@
|
||||
for="confirmPassword"
|
||||
class="block text-sm font-semibold uppercase tracking-[0.2em] text-amber-100"
|
||||
>
|
||||
Confirmer le mot de passe
|
||||
{$t.game.login.confirmPasswordLabel}
|
||||
</label>
|
||||
<input
|
||||
id="confirmPassword"
|
||||
@@ -162,20 +163,20 @@
|
||||
disabled={isLoading}
|
||||
class="w-full rounded-full bg-amber-300 px-6 py-3 text-sm font-semibold text-slate-900 transition disabled:opacity-50 hover:bg-amber-200"
|
||||
>
|
||||
{isLoading ? 'Chargement...' : isSignUp ? 'Créer un compte' : 'Se connecter'}
|
||||
{isLoading ? $t.game.login.loading : isSignUp ? $t.game.login.submitSignUp : $t.game.login.submitSignIn}
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<!-- Toggle Sign Up / Login -->
|
||||
<div class="mt-6 border-t border-white/10 pt-6">
|
||||
<p class="text-center text-sm text-slate-400">
|
||||
{isSignUp ? 'Vous avez déjà un compte ?' : "Vous n'avez pas de compte ?"}
|
||||
{isSignUp ? $t.game.login.togglePromptSignUp : $t.game.login.togglePromptSignIn}
|
||||
<button
|
||||
type="button"
|
||||
on:click={handleToggle}
|
||||
class="text-amber-300 transition hover:text-amber-200"
|
||||
>
|
||||
{isSignUp ? 'Se connecter' : "S'inscrire"}
|
||||
{isSignUp ? $t.game.login.toggleActionSignUp : $t.game.login.toggleActionSignIn}
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
@@ -184,7 +185,7 @@
|
||||
<!-- Back to Home -->
|
||||
<div class="text-center">
|
||||
<a href={resolve("/")} class="text-sm text-slate-400 transition hover:text-slate-300">
|
||||
← Retour à l'accueil
|
||||
← {$t.game.login.backHome}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import { enhance } from '$app/forms';
|
||||
import type { PageData } from './$types';
|
||||
import { resolve } from '$app/paths';
|
||||
import { t, language } from '$lib/i18n';
|
||||
|
||||
interface Props {
|
||||
data: PageData;
|
||||
@@ -56,7 +57,7 @@
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Mon Profil - OnePieceDle</title>
|
||||
<title>{$t.game.profile.pageTitle} - OnePieceDle</title>
|
||||
</svelte:head>
|
||||
|
||||
<main class="relative min-h-[calc(100vh-5rem)] bg-slate-950 text-slate-100">
|
||||
@@ -68,10 +69,10 @@
|
||||
<!-- Header -->
|
||||
<div class="text-center">
|
||||
<h1 class="text-3xl font-black uppercase tracking-[0.3em] text-amber-50 sm:text-4xl">
|
||||
Mon Profil
|
||||
{$t.game.profile.headerTitle}
|
||||
</h1>
|
||||
<p class="mt-2 text-sm text-slate-300">
|
||||
Modifie les informations de ton profil
|
||||
{$t.game.profile.headerSubtitle}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -83,7 +84,7 @@
|
||||
? 'border-b-2 border-amber-300 text-amber-100'
|
||||
: 'text-slate-400 hover:text-slate-100'}"
|
||||
>
|
||||
Profil
|
||||
{$t.game.profile.tabProfile}
|
||||
</button>
|
||||
<button
|
||||
onclick={() => handleTabChange('password')}
|
||||
@@ -91,7 +92,7 @@
|
||||
? 'border-b-2 border-amber-300 text-amber-100'
|
||||
: 'text-slate-400 hover:text-slate-100'}"
|
||||
>
|
||||
Mot de passe
|
||||
{$t.game.profile.tabPassword}
|
||||
</button>
|
||||
<button
|
||||
onclick={() => handleTabChange('daily')}
|
||||
@@ -99,7 +100,7 @@
|
||||
? 'border-b-2 border-amber-300 text-amber-100'
|
||||
: 'text-slate-400 hover:text-slate-100'}"
|
||||
>
|
||||
Historique Daily
|
||||
{$t.game.profile.tabDaily}
|
||||
</button>
|
||||
<button
|
||||
onclick={() => handleTabChange('sessions')}
|
||||
@@ -107,7 +108,7 @@
|
||||
? 'border-b-2 border-amber-300 text-amber-100'
|
||||
: 'text-slate-400 hover:text-slate-100'}"
|
||||
>
|
||||
Sessions
|
||||
{$t.game.profile.tabSessions}
|
||||
</button>
|
||||
<button
|
||||
onclick={() => handleTabChange('friends')}
|
||||
@@ -115,7 +116,7 @@
|
||||
? 'border-b-2 border-amber-300 text-amber-100'
|
||||
: 'text-slate-400 hover:text-slate-100'}"
|
||||
>
|
||||
Amis
|
||||
{$t.game.profile.tabFriends}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -127,7 +128,7 @@
|
||||
{#if data.user.image}
|
||||
<img
|
||||
src={data.user.image}
|
||||
alt={data.user.name || 'Profil'}
|
||||
alt={data.user.name || $t.game.profile.avatarFallbackAlt}
|
||||
class="h-24 w-24 rounded-full border-2 border-amber-300 object-cover"
|
||||
/>
|
||||
{:else}
|
||||
@@ -136,7 +137,7 @@
|
||||
</div>
|
||||
{/if}
|
||||
<div class="text-center">
|
||||
<p class="text-sm text-slate-400">Email</p>
|
||||
<p class="text-sm text-slate-400">{$t.game.profile.email}</p>
|
||||
<p class="font-semibold text-white">{data.user.email}</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -158,7 +159,7 @@
|
||||
<!-- Name Field -->
|
||||
<div>
|
||||
<label for="name" class="block text-sm font-semibold uppercase tracking-[0.2em] text-amber-100">
|
||||
Nom d'affichage
|
||||
{$t.game.profile.displayName}
|
||||
</label>
|
||||
<input
|
||||
id="name"
|
||||
@@ -166,7 +167,7 @@
|
||||
name="name"
|
||||
bind:value={name}
|
||||
required
|
||||
placeholder="Ton nom"
|
||||
placeholder={$t.game.profile.displayNamePlaceholder}
|
||||
class="mt-3 w-full rounded-lg border border-white/10 bg-white/5 px-4 py-3 text-white placeholder-slate-500 transition focus:border-amber-300 focus:outline-none focus:ring-2 focus:ring-amber-300/30"
|
||||
/>
|
||||
</div>
|
||||
@@ -181,7 +182,7 @@
|
||||
<!-- Success Message -->
|
||||
{#if showSuccess}
|
||||
<div class="rounded-lg border border-green-500/30 bg-green-900/20 px-4 py-3 text-sm text-green-200">
|
||||
Profil mis à jour avec succès !
|
||||
{$t.game.profile.profileUpdateSuccess}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -191,7 +192,7 @@
|
||||
disabled={isLoading}
|
||||
class="w-full rounded-full bg-amber-300 px-6 py-3 text-sm font-semibold text-slate-900 transition disabled:opacity-50 hover:bg-amber-200"
|
||||
>
|
||||
{isLoading ? 'Mise à jour...' : 'Enregistrer les modifications'}
|
||||
{isLoading ? $t.game.profile.updating : $t.game.profile.saveChanges}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
@@ -201,7 +202,7 @@
|
||||
{#if activeTab === 'friends'}
|
||||
<div class="rounded-3xl border border-white/10 bg-white/5 p-6 shadow-[0_24px_60px_rgba(0,0,0,0.45)] backdrop-blur sm:p-8">
|
||||
<h2 class="mb-6 text-2xl font-bold uppercase tracking-[0.2em] text-amber-50">
|
||||
Système d'amis
|
||||
{$t.game.profile.friendsTitle}
|
||||
</h2>
|
||||
|
||||
<form
|
||||
@@ -218,7 +219,7 @@
|
||||
class="mb-8 space-y-3"
|
||||
>
|
||||
<label for="friendUsername" class="block text-sm font-semibold uppercase tracking-[0.2em] text-amber-100">
|
||||
Ajouter un ami par nom d'utilisateur
|
||||
{$t.game.profile.addFriendByUsername}
|
||||
</label>
|
||||
<div class="flex gap-2">
|
||||
<input
|
||||
@@ -227,7 +228,7 @@
|
||||
name="friendUsername"
|
||||
required
|
||||
bind:value={friendUsername}
|
||||
placeholder="ex: luffy_gear5"
|
||||
placeholder={$t.game.profile.friendUsernamePlaceholder}
|
||||
class="w-full rounded-lg border border-white/10 bg-white/5 px-4 py-3 text-white placeholder-slate-500 transition focus:border-amber-300 focus:outline-none focus:ring-2 focus:ring-amber-300/30"
|
||||
/>
|
||||
<button
|
||||
@@ -235,7 +236,7 @@
|
||||
disabled={isLoading}
|
||||
class="rounded-full bg-amber-300 px-4 py-2 text-sm font-semibold text-slate-900 transition disabled:opacity-50 hover:bg-amber-200"
|
||||
>
|
||||
{isLoading ? 'Envoi...' : 'Envoyer'}
|
||||
{isLoading ? $t.game.profile.sending : $t.game.profile.send}
|
||||
</button>
|
||||
</div>
|
||||
{#if form?.message}
|
||||
@@ -245,9 +246,9 @@
|
||||
|
||||
<div class="space-y-8">
|
||||
<div>
|
||||
<h3 class="mb-3 text-sm font-semibold uppercase tracking-[0.15em] text-amber-100">Demandes reçues</h3>
|
||||
<h3 class="mb-3 text-sm font-semibold uppercase tracking-[0.15em] text-amber-100">{$t.game.profile.incomingRequests}</h3>
|
||||
{#if incomingRequests.length === 0}
|
||||
<p class="text-sm text-slate-400">Aucune demande reçue.</p>
|
||||
<p class="text-sm text-slate-400">{$t.game.profile.noIncomingRequests}</p>
|
||||
{:else}
|
||||
<div class="space-y-3">
|
||||
{#each incomingRequests as req (req.id)}
|
||||
@@ -259,11 +260,11 @@
|
||||
<div class="flex gap-2">
|
||||
<form method="POST" action="?/acceptFriendRequest" use:enhance>
|
||||
<input type="hidden" name="friendshipId" value={req.id} />
|
||||
<button type="submit" class="rounded-lg border border-emerald-400/50 bg-emerald-900/20 px-3 py-1.5 text-xs font-semibold text-emerald-300 transition hover:bg-emerald-900/40">Accepter</button>
|
||||
<button type="submit" class="rounded-lg border border-emerald-400/50 bg-emerald-900/20 px-3 py-1.5 text-xs font-semibold text-emerald-300 transition hover:bg-emerald-900/40">{$t.game.profile.accept}</button>
|
||||
</form>
|
||||
<form method="POST" action="?/declineFriendRequest" use:enhance>
|
||||
<input type="hidden" name="friendshipId" value={req.id} />
|
||||
<button type="submit" class="rounded-lg border border-red-500/50 bg-red-900/20 px-3 py-1.5 text-xs font-semibold text-red-300 transition hover:bg-red-900/40">Refuser</button>
|
||||
<button type="submit" class="rounded-lg border border-red-500/50 bg-red-900/20 px-3 py-1.5 text-xs font-semibold text-red-300 transition hover:bg-red-900/40">{$t.game.profile.decline}</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@@ -273,9 +274,9 @@
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 class="mb-3 text-sm font-semibold uppercase tracking-[0.15em] text-amber-100">Demandes envoyées</h3>
|
||||
<h3 class="mb-3 text-sm font-semibold uppercase tracking-[0.15em] text-amber-100">{$t.game.profile.outgoingRequests}</h3>
|
||||
{#if outgoingRequests.length === 0}
|
||||
<p class="text-sm text-slate-400">Aucune demande envoyée.</p>
|
||||
<p class="text-sm text-slate-400">{$t.game.profile.noOutgoingRequests}</p>
|
||||
{:else}
|
||||
<div class="space-y-3">
|
||||
{#each outgoingRequests as req (req.id)}
|
||||
@@ -286,7 +287,7 @@
|
||||
</div>
|
||||
<form method="POST" action="?/cancelFriendRequest" use:enhance>
|
||||
<input type="hidden" name="friendshipId" value={req.id} />
|
||||
<button type="submit" class="rounded-lg border border-red-500/50 bg-red-900/20 px-3 py-1.5 text-xs font-semibold text-red-300 transition hover:bg-red-900/40">Annuler</button>
|
||||
<button type="submit" class="rounded-lg border border-red-500/50 bg-red-900/20 px-3 py-1.5 text-xs font-semibold text-red-300 transition hover:bg-red-900/40">{$t.game.profile.cancel}</button>
|
||||
</form>
|
||||
</div>
|
||||
{/each}
|
||||
@@ -295,9 +296,9 @@
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 class="mb-3 text-sm font-semibold uppercase tracking-[0.15em] text-amber-100">Mes amis</h3>
|
||||
<h3 class="mb-3 text-sm font-semibold uppercase tracking-[0.15em] text-amber-100">{$t.game.profile.myFriends}</h3>
|
||||
{#if friends.length === 0}
|
||||
<p class="text-sm text-slate-400">Tu n'as pas encore d'amis.</p>
|
||||
<p class="text-sm text-slate-400">{$t.game.profile.noFriends}</p>
|
||||
{:else}
|
||||
<div class="space-y-3">
|
||||
{#each friends as friend (friend.id)}
|
||||
@@ -308,7 +309,7 @@
|
||||
</div>
|
||||
<form method="POST" action="?/removeFriend" use:enhance>
|
||||
<input type="hidden" name="friendshipId" value={friend.id} />
|
||||
<button type="submit" class="rounded-lg border border-red-500/50 bg-red-900/20 px-3 py-1.5 text-xs font-semibold text-red-300 transition hover:bg-red-900/40">Supprimer</button>
|
||||
<button type="submit" class="rounded-lg border border-red-500/50 bg-red-900/20 px-3 py-1.5 text-xs font-semibold text-red-300 transition hover:bg-red-900/40">{$t.game.profile.remove}</button>
|
||||
</form>
|
||||
</div>
|
||||
{/each}
|
||||
@@ -323,7 +324,7 @@
|
||||
{#if activeTab === 'password'}
|
||||
<div class="rounded-3xl border border-white/10 bg-white/5 p-6 shadow-[0_24px_60px_rgba(0,0,0,0.45)] backdrop-blur sm:p-8">
|
||||
<h2 class="mb-6 text-2xl font-bold uppercase tracking-[0.2em] text-amber-50">
|
||||
Changer le mot de passe
|
||||
{$t.game.profile.changePasswordTitle}
|
||||
</h2>
|
||||
|
||||
<!-- Form -->
|
||||
@@ -345,7 +346,7 @@
|
||||
<!-- Old Password Field -->
|
||||
<div>
|
||||
<label for="oldPassword" class="block text-sm font-semibold uppercase tracking-[0.2em] text-amber-100">
|
||||
Mot de passe actuel
|
||||
{$t.game.profile.currentPassword}
|
||||
</label>
|
||||
<input
|
||||
id="oldPassword"
|
||||
@@ -361,7 +362,7 @@
|
||||
<!-- New Password Field -->
|
||||
<div>
|
||||
<label for="newPassword" class="block text-sm font-semibold uppercase tracking-[0.2em] text-amber-100">
|
||||
Nouveau mot de passe
|
||||
{$t.game.profile.newPassword}
|
||||
</label>
|
||||
<input
|
||||
id="newPassword"
|
||||
@@ -377,7 +378,7 @@
|
||||
<!-- Confirm Password Field -->
|
||||
<div>
|
||||
<label for="confirmPassword" class="block text-sm font-semibold uppercase tracking-[0.2em] text-amber-100">
|
||||
Confirmer le mot de passe
|
||||
{$t.game.profile.confirmPassword}
|
||||
</label>
|
||||
<input
|
||||
id="confirmPassword"
|
||||
@@ -400,7 +401,7 @@
|
||||
<!-- Success Message -->
|
||||
{#if showSuccess}
|
||||
<div class="rounded-lg border border-green-500/30 bg-green-900/20 px-4 py-3 text-sm text-green-200">
|
||||
Mot de passe changé avec succès !
|
||||
{$t.game.profile.passwordChangeSuccess}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -410,7 +411,7 @@
|
||||
disabled={isLoading}
|
||||
class="w-full rounded-full bg-amber-300 px-6 py-3 text-sm font-semibold text-slate-900 transition disabled:opacity-50 hover:bg-amber-200"
|
||||
>
|
||||
{isLoading ? 'Changement en cours...' : 'Changer le mot de passe'}
|
||||
{isLoading ? $t.game.profile.changing : $t.game.profile.changePassword}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
@@ -420,11 +421,11 @@
|
||||
{#if activeTab === 'daily'}
|
||||
<div class="rounded-3xl border border-white/10 bg-white/5 p-6 shadow-[0_24px_60px_rgba(0,0,0,0.45)] backdrop-blur sm:p-8">
|
||||
<h2 class="mb-6 text-2xl font-bold uppercase tracking-[0.2em] text-amber-50">
|
||||
Historique des Daily
|
||||
{$t.game.profile.dailyHistoryTitle}
|
||||
</h2>
|
||||
|
||||
{#if dailyHistory.length === 0}
|
||||
<p class="text-center text-slate-400">Aucun historique disponible</p>
|
||||
<p class="text-center text-slate-400">{$t.game.profile.noDailyHistory}</p>
|
||||
{:else}
|
||||
<div class="space-y-4">
|
||||
{#each dailyHistory as day (day.id)}
|
||||
@@ -439,7 +440,7 @@
|
||||
/>
|
||||
{:else}
|
||||
<div class="flex h-16 w-16 items-center justify-center rounded-lg border border-white/20 bg-slate-700">
|
||||
<span class="text-xs text-slate-400">N/A</span>
|
||||
<span class="text-xs text-slate-400">{$t.game.profile.noImage}</span>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
@@ -448,7 +449,7 @@
|
||||
<div class="flex-1">
|
||||
<p class="font-semibold text-white">{day.characterName}</p>
|
||||
<p class="text-xs text-slate-400">
|
||||
{new Date(day.date).toLocaleDateString('fr-FR', {
|
||||
{new Date(day.date).toLocaleDateString($language === 'fr' ? 'fr-FR' : 'en-US', {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric'
|
||||
@@ -459,7 +460,7 @@
|
||||
<!-- Tries -->
|
||||
<div class="flex flex-col items-end">
|
||||
<p class="text-xs text-slate-400">
|
||||
{day.tryCount} {day.tryCount === 1 ? 'tentative' : 'tentatives'}
|
||||
{day.tryCount} {day.tryCount === 1 ? $t.game.profile.trySingular : $t.game.profile.tryPlural}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -473,24 +474,24 @@
|
||||
{#if activeTab === 'sessions'}
|
||||
<div class="rounded-3xl border border-white/10 bg-white/5 p-6 shadow-[0_24px_60px_rgba(0,0,0,0.45)] backdrop-blur sm:p-8">
|
||||
<h2 class="mb-6 text-2xl font-bold uppercase tracking-[0.2em] text-amber-50">
|
||||
Sessions actives
|
||||
{$t.game.profile.activeSessionsTitle}
|
||||
</h2>
|
||||
|
||||
{#if sessions.length === 0}
|
||||
<p class="text-center text-slate-400">Aucune session active</p>
|
||||
<p class="text-center text-slate-400">{$t.game.profile.noActiveSessions}</p>
|
||||
{:else}
|
||||
<div class="space-y-4">
|
||||
{#each sessions as sess (sess.id)}
|
||||
<div class="flex items-center justify-between rounded-lg border border-white/10 bg-white/5 px-4 py-4">
|
||||
<div class="flex-1">
|
||||
<p class="font-semibold text-white">
|
||||
{sess.userAgent || 'Appareil inconnu'}
|
||||
{sess.userAgent || $t.game.profile.unknownDevice}
|
||||
</p>
|
||||
<p class="text-xs text-slate-400">
|
||||
IP: {sess.ipAddress || 'Inconnue'}
|
||||
{$t.game.profile.ip}: {sess.ipAddress || $t.game.profile.unknown}
|
||||
</p>
|
||||
<p class="mt-1 text-xs text-slate-500">
|
||||
Créée: {new Date(sess.createdAt).toLocaleDateString('fr-FR', {
|
||||
{$t.game.profile.created}: {new Date(sess.createdAt).toLocaleDateString($language === 'fr' ? 'fr-FR' : 'en-US', {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
@@ -514,7 +515,7 @@
|
||||
type="submit"
|
||||
class="rounded-lg border border-red-500/50 bg-red-900/20 px-4 py-2 text-xs font-semibold text-red-300 transition hover:border-red-500 hover:bg-red-900/40"
|
||||
>
|
||||
Terminer
|
||||
{$t.game.profile.terminate}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
@@ -527,7 +528,7 @@
|
||||
<!-- Back to Home -->
|
||||
<div class="text-center">
|
||||
<a href={resolve("/")} class="text-sm text-slate-400 transition hover:text-slate-300">
|
||||
← Retour à l'accueil
|
||||
← {$t.game.profile.backHome}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user