mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 23:21:08 +02:00
feat(i18n): add language picker and 5-language support to all auth screens
- Add svelte-i18n and @manacore/shared-i18n to Chat, Presi, Zitare - Create LanguageSelector component for each app - Add locale files for DE, EN, IT, FR, ES in all apps - Update auth pages (login, register, forgot-password) to use shared translations - Add headerControls snippet to RegisterPage and ForgotPasswordPage - Export ZitareLogo and NutriPhiLogo from shared-branding 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
e85ef8babe
commit
eab69c512c
41 changed files with 626 additions and 142 deletions
|
|
@ -42,6 +42,7 @@
|
|||
"@manacore/shared-profile-ui": "workspace:*",
|
||||
"@manacore/shared-ui": "workspace:*",
|
||||
"@manacore/shared-utils": "workspace:*",
|
||||
"marked": "^17.0.0"
|
||||
"marked": "^17.0.0",
|
||||
"svelte-i18n": "^4.0.1"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
<script lang="ts">
|
||||
import { locale } from 'svelte-i18n';
|
||||
import { LanguageSelector } from '@manacore/shared-i18n';
|
||||
import { setLocale, supportedLocales } from '$lib/i18n';
|
||||
import { theme } from '$lib/stores/theme';
|
||||
|
||||
let currentLocale = $derived($locale || 'de');
|
||||
|
||||
function handleLocaleChange(newLocale: string) {
|
||||
setLocale(newLocale as any);
|
||||
}
|
||||
</script>
|
||||
|
||||
<LanguageSelector
|
||||
{currentLocale}
|
||||
{supportedLocales}
|
||||
onLocaleChange={handleLocaleChange}
|
||||
isDark={theme.isDark}
|
||||
primaryColor="#0ea5e9"
|
||||
/>
|
||||
52
apps/chat/apps/web/src/lib/i18n/index.ts
Normal file
52
apps/chat/apps/web/src/lib/i18n/index.ts
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
import { browser } from '$app/environment';
|
||||
import { init, register, locale, waitLocale } from 'svelte-i18n';
|
||||
|
||||
// List of supported locales
|
||||
export const supportedLocales = ['de', 'en', 'it', 'fr', 'es'] as const;
|
||||
export type SupportedLocale = (typeof supportedLocales)[number];
|
||||
|
||||
// Default locale
|
||||
const defaultLocale = 'de';
|
||||
|
||||
// Register all available locales
|
||||
register('de', () => import('./locales/de.json'));
|
||||
register('en', () => import('./locales/en.json'));
|
||||
register('it', () => import('./locales/it.json'));
|
||||
register('fr', () => import('./locales/fr.json'));
|
||||
register('es', () => import('./locales/es.json'));
|
||||
|
||||
// Get initial locale from browser or localStorage
|
||||
function getInitialLocale(): SupportedLocale {
|
||||
if (browser) {
|
||||
// Check localStorage first
|
||||
const stored = localStorage.getItem('chat_locale');
|
||||
if (stored && supportedLocales.includes(stored as SupportedLocale)) {
|
||||
return stored as SupportedLocale;
|
||||
}
|
||||
|
||||
// Fall back to browser language
|
||||
const browserLang = navigator.language.split('-')[0];
|
||||
if (supportedLocales.includes(browserLang as SupportedLocale)) {
|
||||
return browserLang as SupportedLocale;
|
||||
}
|
||||
}
|
||||
|
||||
return defaultLocale;
|
||||
}
|
||||
|
||||
// Initialize i18n at module scope (required for SSR)
|
||||
init({
|
||||
fallbackLocale: defaultLocale,
|
||||
initialLocale: getInitialLocale(),
|
||||
});
|
||||
|
||||
// Set locale and persist to localStorage
|
||||
export function setLocale(newLocale: SupportedLocale) {
|
||||
locale.set(newLocale);
|
||||
if (browser) {
|
||||
localStorage.setItem('chat_locale', newLocale);
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for locale to be loaded (useful for SSR)
|
||||
export { waitLocale };
|
||||
13
apps/chat/apps/web/src/lib/i18n/locales/de.json
Normal file
13
apps/chat/apps/web/src/lib/i18n/locales/de.json
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"app_slider": {
|
||||
"title": "Weitere Manacore Apps",
|
||||
"memoro_desc": "KI-gestützte Sprachmemos",
|
||||
"maerchenzauber_desc": "Magische Gute-Nacht-Geschichten",
|
||||
"manadeck_desc": "KI Lernkarten",
|
||||
"picture_desc": "KI Bildgenerierung",
|
||||
"moodlit_desc": "Dein Stimmungsbegleiter",
|
||||
"manacore_desc": "KI-Produktivitätssuite",
|
||||
"coming_soon": "Demnächst",
|
||||
"download": "Download"
|
||||
}
|
||||
}
|
||||
13
apps/chat/apps/web/src/lib/i18n/locales/en.json
Normal file
13
apps/chat/apps/web/src/lib/i18n/locales/en.json
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"app_slider": {
|
||||
"title": "More Manacore Apps",
|
||||
"memoro_desc": "AI-powered voice memos",
|
||||
"maerchenzauber_desc": "Magical bedtime stories",
|
||||
"manadeck_desc": "AI flashcards",
|
||||
"picture_desc": "AI image generation",
|
||||
"moodlit_desc": "Your mood companion",
|
||||
"manacore_desc": "AI productivity suite",
|
||||
"coming_soon": "Coming soon",
|
||||
"download": "Download"
|
||||
}
|
||||
}
|
||||
13
apps/chat/apps/web/src/lib/i18n/locales/es.json
Normal file
13
apps/chat/apps/web/src/lib/i18n/locales/es.json
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"app_slider": {
|
||||
"title": "Más Apps de Manacore",
|
||||
"memoro_desc": "Notas de voz con IA",
|
||||
"maerchenzauber_desc": "Cuentos mágicos para dormir",
|
||||
"manadeck_desc": "Flashcards con IA",
|
||||
"picture_desc": "Generación de imágenes con IA",
|
||||
"moodlit_desc": "Tu compañero de ánimo",
|
||||
"manacore_desc": "Suite de productividad IA",
|
||||
"coming_soon": "Próximamente",
|
||||
"download": "Descargar"
|
||||
}
|
||||
}
|
||||
13
apps/chat/apps/web/src/lib/i18n/locales/fr.json
Normal file
13
apps/chat/apps/web/src/lib/i18n/locales/fr.json
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"app_slider": {
|
||||
"title": "Autres Apps Manacore",
|
||||
"memoro_desc": "Mémos vocaux avec IA",
|
||||
"maerchenzauber_desc": "Histoires magiques du soir",
|
||||
"manadeck_desc": "Flashcards avec IA",
|
||||
"picture_desc": "Génération d'images avec IA",
|
||||
"moodlit_desc": "Ton compagnon d'humeur",
|
||||
"manacore_desc": "Suite de productivité IA",
|
||||
"coming_soon": "Bientôt disponible",
|
||||
"download": "Télécharger"
|
||||
}
|
||||
}
|
||||
13
apps/chat/apps/web/src/lib/i18n/locales/it.json
Normal file
13
apps/chat/apps/web/src/lib/i18n/locales/it.json
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"app_slider": {
|
||||
"title": "Altre App Manacore",
|
||||
"memoro_desc": "Memo vocali con IA",
|
||||
"maerchenzauber_desc": "Storie magiche della buonanotte",
|
||||
"manadeck_desc": "Flashcard con IA",
|
||||
"picture_desc": "Generazione immagini con IA",
|
||||
"moodlit_desc": "Il tuo compagno d'umore",
|
||||
"manacore_desc": "Suite di produttività IA",
|
||||
"coming_soon": "Prossimamente",
|
||||
"download": "Scarica"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,26 +1,16 @@
|
|||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { locale } from 'svelte-i18n';
|
||||
import { ForgotPasswordPage } from '@manacore/shared-auth-ui';
|
||||
import { getForgotPasswordTranslations } from '@manacore/shared-i18n';
|
||||
import { ChatLogo } from '@manacore/shared-branding';
|
||||
import { authStore } from '$lib/stores/auth.svelte';
|
||||
import AppSlider from '$lib/components/AppSlider.svelte';
|
||||
import LanguageSelector from '$lib/components/LanguageSelector.svelte';
|
||||
import '$lib/i18n';
|
||||
|
||||
// German translations
|
||||
const translations = {
|
||||
titleForm: 'Passwort zurücksetzen',
|
||||
titleSuccess: 'E-Mail gesendet',
|
||||
description:
|
||||
'Gib deine E-Mail-Adresse ein und wir senden dir einen Link zum Zurücksetzen deines Passworts.',
|
||||
emailPlaceholder: 'E-Mail',
|
||||
sendResetLinkButton: 'Link senden',
|
||||
sending: 'Wird gesendet...',
|
||||
backToLogin: 'Zurück zur Anmeldung',
|
||||
resendEmail: 'E-Mail erneut senden',
|
||||
successMessage:
|
||||
'Wir haben einen Link zum Zurücksetzen deines Passworts an {email} gesendet. Bitte überprüfe deinen Posteingang.',
|
||||
emailRequired: 'E-Mail ist erforderlich',
|
||||
sendFailed: 'Fehler beim Senden der E-Mail',
|
||||
};
|
||||
// Get translations based on current locale
|
||||
const translations = $derived(getForgotPasswordTranslations($locale || 'de'));
|
||||
|
||||
async function handleForgotPassword(email: string) {
|
||||
return authStore.resetPassword(email);
|
||||
|
|
@ -28,7 +18,7 @@
|
|||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Passwort zurücksetzen | ManaChat</title>
|
||||
<title>{translations.titleForm} | ManaChat</title>
|
||||
</svelte:head>
|
||||
|
||||
<ForgotPasswordPage
|
||||
|
|
@ -42,6 +32,9 @@
|
|||
darkBackground="#0c1929"
|
||||
{translations}
|
||||
>
|
||||
{#snippet headerControls()}
|
||||
<LanguageSelector />
|
||||
{/snippet}
|
||||
{#snippet appSlider()}
|
||||
<AppSlider />
|
||||
{/snippet}
|
||||
|
|
|
|||
|
|
@ -1,39 +1,20 @@
|
|||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { page } from '$app/stores';
|
||||
import { locale } from 'svelte-i18n';
|
||||
import { LoginPage } from '@manacore/shared-auth-ui';
|
||||
import { getLoginTranslations } from '@manacore/shared-i18n';
|
||||
import { ChatLogo } from '@manacore/shared-branding';
|
||||
import { authStore } from '$lib/stores/auth.svelte';
|
||||
import AppSlider from '$lib/components/AppSlider.svelte';
|
||||
import LanguageSelector from '$lib/components/LanguageSelector.svelte';
|
||||
import '$lib/i18n';
|
||||
|
||||
// Get redirect URL from query params
|
||||
const redirectTo = $derived($page.url.searchParams.get('redirectTo') || '/chat');
|
||||
|
||||
// German translations
|
||||
const translations = {
|
||||
title: 'Anmelden',
|
||||
subtitle: 'Melde dich mit deinem Konto an',
|
||||
emailPlaceholder: 'E-Mail',
|
||||
passwordPlaceholder: 'Passwort',
|
||||
rememberMe: 'Angemeldet bleiben',
|
||||
forgotPassword: 'Passwort vergessen?',
|
||||
signInButton: 'Anmelden',
|
||||
signingIn: 'Wird angemeldet...',
|
||||
success: 'Erfolgreich!',
|
||||
orDivider: 'oder',
|
||||
noAccount: 'Noch kein Konto?',
|
||||
createAccount: 'Jetzt registrieren',
|
||||
skipToForm: 'Zum Login-Formular springen',
|
||||
showPassword: 'Passwort anzeigen',
|
||||
hidePassword: 'Passwort verbergen',
|
||||
emailRequired: 'E-Mail ist erforderlich',
|
||||
emailInvalid: 'Bitte gib eine gültige E-Mail-Adresse ein',
|
||||
passwordRequired: 'Passwort ist erforderlich',
|
||||
signInFailed: 'Anmeldung fehlgeschlagen',
|
||||
googleSignInFailed: 'Google-Anmeldung fehlgeschlagen',
|
||||
signInSuccess: 'Erfolgreich angemeldet. Weiterleitung...',
|
||||
googleSignInSuccess: 'Erfolgreich mit Google angemeldet. Weiterleitung...',
|
||||
};
|
||||
// Get translations based on current locale
|
||||
const translations = $derived(getLoginTranslations($locale || 'de'));
|
||||
|
||||
async function handleSignIn(email: string, password: string) {
|
||||
return authStore.signIn(email, password);
|
||||
|
|
@ -41,7 +22,7 @@
|
|||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Anmelden | ManaChat</title>
|
||||
<title>{translations.title} | ManaChat</title>
|
||||
</svelte:head>
|
||||
|
||||
<LoginPage
|
||||
|
|
@ -59,6 +40,9 @@
|
|||
darkBackground="#0c1929"
|
||||
{translations}
|
||||
>
|
||||
{#snippet headerControls()}
|
||||
<LanguageSelector />
|
||||
{/snippet}
|
||||
{#snippet appSlider()}
|
||||
<AppSlider />
|
||||
{/snippet}
|
||||
|
|
|
|||
|
|
@ -1,33 +1,16 @@
|
|||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { locale } from 'svelte-i18n';
|
||||
import { RegisterPage } from '@manacore/shared-auth-ui';
|
||||
import { getRegisterTranslations } from '@manacore/shared-i18n';
|
||||
import { ChatLogo } from '@manacore/shared-branding';
|
||||
import { authStore } from '$lib/stores/auth.svelte';
|
||||
import AppSlider from '$lib/components/AppSlider.svelte';
|
||||
import LanguageSelector from '$lib/components/LanguageSelector.svelte';
|
||||
import '$lib/i18n';
|
||||
|
||||
// German translations
|
||||
const translations = {
|
||||
title: 'Konto erstellen',
|
||||
emailPlaceholder: 'E-Mail',
|
||||
passwordPlaceholder: 'Passwort',
|
||||
confirmPasswordPlaceholder: 'Passwort bestätigen',
|
||||
passwordRequirements:
|
||||
'Passwort muss mindestens 8 Zeichen mit Kleinbuchstaben, Großbuchstaben, Zahl und Sonderzeichen enthalten.',
|
||||
createAccountButton: 'Konto erstellen',
|
||||
creatingAccount: 'Wird erstellt...',
|
||||
backToLogin: 'Zurück zur Anmeldung',
|
||||
showPassword: 'Passwort anzeigen',
|
||||
hidePassword: 'Passwort verbergen',
|
||||
emailRequired: 'E-Mail ist erforderlich',
|
||||
passwordRequired: 'Passwort ist erforderlich',
|
||||
confirmPasswordRequired: 'Bitte bestätige dein Passwort',
|
||||
passwordsDoNotMatch: 'Passwörter stimmen nicht überein',
|
||||
passwordTooShort: 'Passwort muss mindestens 8 Zeichen lang sein',
|
||||
passwordStrengthError:
|
||||
'Passwort muss Kleinbuchstaben, Großbuchstaben, Zahl und Sonderzeichen enthalten',
|
||||
registrationFailed: 'Registrierung fehlgeschlagen',
|
||||
accountCreated: 'Konto erstellt! Bitte überprüfe deine E-Mails zur Bestätigung.',
|
||||
};
|
||||
// Get translations based on current locale
|
||||
const translations = $derived(getRegisterTranslations($locale || 'de'));
|
||||
|
||||
async function handleSignUp(email: string, password: string) {
|
||||
return authStore.signUp(email, password);
|
||||
|
|
@ -35,7 +18,7 @@
|
|||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Registrieren | ManaChat</title>
|
||||
<title>{translations.title} | ManaChat</title>
|
||||
</svelte:head>
|
||||
|
||||
<RegisterPage
|
||||
|
|
@ -50,6 +33,9 @@
|
|||
darkBackground="#0c1929"
|
||||
{translations}
|
||||
>
|
||||
{#snippet headerControls()}
|
||||
<LanguageSelector />
|
||||
{/snippet}
|
||||
{#snippet appSlider()}
|
||||
<AppSlider />
|
||||
{/snippet}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { browser } from '$app/environment';
|
|||
import { init, register, locale, waitLocale } from 'svelte-i18n';
|
||||
|
||||
// List of supported locales
|
||||
export const supportedLocales = ['de', 'en'] as const;
|
||||
export const supportedLocales = ['de', 'en', 'it', 'fr', 'es'] as const;
|
||||
export type SupportedLocale = (typeof supportedLocales)[number];
|
||||
|
||||
// Default locale
|
||||
|
|
@ -11,6 +11,9 @@ const defaultLocale = 'de';
|
|||
// Register all available locales
|
||||
register('de', () => import('./locales/de.json'));
|
||||
register('en', () => import('./locales/en.json'));
|
||||
register('it', () => import('./locales/it.json'));
|
||||
register('fr', () => import('./locales/fr.json'));
|
||||
register('es', () => import('./locales/es.json'));
|
||||
|
||||
// Get initial locale from browser or localStorage
|
||||
function getInitialLocale(): SupportedLocale {
|
||||
|
|
|
|||
23
apps/picture/apps/web/src/lib/i18n/locales/es.json
Normal file
23
apps/picture/apps/web/src/lib/i18n/locales/es.json
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"app_slider": {
|
||||
"title": "Más Apps de Manacore",
|
||||
"memoro_desc": "Notas de voz con IA",
|
||||
"memoro_long_desc": "Transforma tu voz en notas organizadas y accionables con transcripción y análisis impulsados por IA. Perfecto para capturar ideas en movimiento.",
|
||||
"maerchenzauber_desc": "Cuentos mágicos para dormir",
|
||||
"maerchenzauber_long_desc": "Crea cuentos personalizados para dormir para tus hijos con IA. Enciende la imaginación y haz cada noche mágica con narrativas únicas.",
|
||||
"manadeck_desc": "Flashcards con IA",
|
||||
"manadeck_long_desc": "Crea y estudia con flashcards inteligentes y repetición espaciada impulsada por IA.",
|
||||
"picture_desc": "Generación de imágenes con IA",
|
||||
"picture_long_desc": "Crea imágenes impresionantes con IA. Transforma tus ideas en obras de arte visuales en segundos.",
|
||||
"moodlit_desc": "Tu compañero de ánimo",
|
||||
"moodlit_long_desc": "Rastrea y comprende tus emociones con análisis impulsados por IA. Desarrolla conciencia emocional y mejora tu bienestar mental.",
|
||||
"manacore_desc": "Suite de productividad IA",
|
||||
"manacore_long_desc": "El centro para todas las apps de Manacore. Gestiona tus suscripciones, sincroniza datos y accede a potentes herramientas de IA desde un solo lugar.",
|
||||
"coming_soon": "Próximamente",
|
||||
"download": "Descargar",
|
||||
"status_published": "Publicado",
|
||||
"status_beta": "Beta",
|
||||
"status_development": "En desarrollo",
|
||||
"status_planning": "Planificado"
|
||||
}
|
||||
}
|
||||
23
apps/picture/apps/web/src/lib/i18n/locales/fr.json
Normal file
23
apps/picture/apps/web/src/lib/i18n/locales/fr.json
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"app_slider": {
|
||||
"title": "Autres Apps Manacore",
|
||||
"memoro_desc": "Mémos vocaux avec IA",
|
||||
"memoro_long_desc": "Transformez votre voix en notes organisées et exploitables grâce à la transcription et l'analyse alimentées par l'IA. Parfait pour capturer des idées en déplacement.",
|
||||
"maerchenzauber_desc": "Histoires magiques du soir",
|
||||
"maerchenzauber_long_desc": "Créez des histoires du soir personnalisées pour vos enfants avec l'IA. Éveillez l'imagination et rendez chaque nuit magique avec des récits uniques.",
|
||||
"manadeck_desc": "Flashcards avec IA",
|
||||
"manadeck_long_desc": "Créez et apprenez avec des flashcards intelligentes et une répétition espacée alimentée par l'IA.",
|
||||
"picture_desc": "Génération d'images avec IA",
|
||||
"picture_long_desc": "Créez des images époustouflantes avec l'IA. Transformez vos idées en œuvres d'art visuelles en quelques secondes.",
|
||||
"moodlit_desc": "Ton compagnon d'humeur",
|
||||
"moodlit_long_desc": "Suivez et comprenez vos émotions grâce aux analyses alimentées par l'IA. Développez votre conscience émotionnelle et améliorez votre bien-être mental.",
|
||||
"manacore_desc": "Suite de productivité IA",
|
||||
"manacore_long_desc": "Le hub central pour toutes les apps Manacore. Gérez vos abonnements, synchronisez vos données et accédez à de puissants outils IA depuis un seul endroit.",
|
||||
"coming_soon": "Bientôt disponible",
|
||||
"download": "Télécharger",
|
||||
"status_published": "Publié",
|
||||
"status_beta": "Bêta",
|
||||
"status_development": "En développement",
|
||||
"status_planning": "Planifié"
|
||||
}
|
||||
}
|
||||
23
apps/picture/apps/web/src/lib/i18n/locales/it.json
Normal file
23
apps/picture/apps/web/src/lib/i18n/locales/it.json
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"app_slider": {
|
||||
"title": "Altre App Manacore",
|
||||
"memoro_desc": "Memo vocali con IA",
|
||||
"memoro_long_desc": "Trasforma la tua voce in appunti organizzati e azionabili con trascrizione e analisi basate su IA. Perfetto per catturare idee in movimento.",
|
||||
"maerchenzauber_desc": "Storie magiche della buonanotte",
|
||||
"maerchenzauber_long_desc": "Crea storie della buonanotte personalizzate per i tuoi bambini con l'IA. Accendi l'immaginazione e rendi ogni notte magica con racconti unici.",
|
||||
"manadeck_desc": "Flashcard con IA",
|
||||
"manadeck_long_desc": "Crea e studia con flashcard intelligenti e ripetizione spaziata basata su IA.",
|
||||
"picture_desc": "Generazione immagini con IA",
|
||||
"picture_long_desc": "Crea immagini straordinarie con l'IA. Trasforma le tue idee in opere d'arte visive in pochi secondi.",
|
||||
"moodlit_desc": "Il tuo compagno d'umore",
|
||||
"moodlit_long_desc": "Monitora e comprendi le tue emozioni con approfondimenti basati su IA. Sviluppa la consapevolezza emotiva e migliora il tuo benessere mentale.",
|
||||
"manacore_desc": "Suite di produttività IA",
|
||||
"manacore_long_desc": "L'hub centrale per tutte le app Manacore. Gestisci i tuoi abbonamenti, sincronizza i dati e accedi a potenti strumenti IA da un unico posto.",
|
||||
"coming_soon": "Prossimamente",
|
||||
"download": "Scarica",
|
||||
"status_published": "Pubblicato",
|
||||
"status_beta": "Beta",
|
||||
"status_development": "In sviluppo",
|
||||
"status_planning": "Pianificato"
|
||||
}
|
||||
}
|
||||
|
|
@ -35,6 +35,7 @@
|
|||
"@manacore/shared-branding": "workspace:*",
|
||||
"@manacore/shared-feedback-service": "workspace:*",
|
||||
"@manacore/shared-feedback-ui": "workspace:*",
|
||||
"@manacore/shared-i18n": "workspace:*",
|
||||
"@manacore/shared-icons": "workspace:*",
|
||||
"@manacore/shared-profile-ui": "workspace:*",
|
||||
"@manacore/shared-subscription-ui": "workspace:*",
|
||||
|
|
@ -42,7 +43,8 @@
|
|||
"@manacore/shared-theme": "workspace:*",
|
||||
"@manacore/shared-theme-ui": "workspace:*",
|
||||
"@manacore/shared-ui": "workspace:*",
|
||||
"lucide-svelte": "^0.460.0"
|
||||
"lucide-svelte": "^0.460.0",
|
||||
"svelte-i18n": "^4.0.1"
|
||||
},
|
||||
"type": "module"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
<script lang="ts">
|
||||
import { locale } from 'svelte-i18n';
|
||||
import { LanguageSelector } from '@manacore/shared-i18n';
|
||||
import { setLocale, supportedLocales } from '$lib/i18n';
|
||||
import { theme } from '$lib/stores/theme';
|
||||
|
||||
let currentLocale = $derived($locale || 'de');
|
||||
|
||||
function handleLocaleChange(newLocale: string) {
|
||||
setLocale(newLocale as any);
|
||||
}
|
||||
</script>
|
||||
|
||||
<LanguageSelector
|
||||
{currentLocale}
|
||||
{supportedLocales}
|
||||
onLocaleChange={handleLocaleChange}
|
||||
isDark={theme.isDark}
|
||||
primaryColor="#f97316"
|
||||
/>
|
||||
52
apps/presi/apps/web/src/lib/i18n/index.ts
Normal file
52
apps/presi/apps/web/src/lib/i18n/index.ts
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
import { browser } from '$app/environment';
|
||||
import { init, register, locale, waitLocale } from 'svelte-i18n';
|
||||
|
||||
// List of supported locales
|
||||
export const supportedLocales = ['de', 'en', 'it', 'fr', 'es'] as const;
|
||||
export type SupportedLocale = (typeof supportedLocales)[number];
|
||||
|
||||
// Default locale
|
||||
const defaultLocale = 'de';
|
||||
|
||||
// Register all available locales
|
||||
register('de', () => import('./locales/de.json'));
|
||||
register('en', () => import('./locales/en.json'));
|
||||
register('it', () => import('./locales/it.json'));
|
||||
register('fr', () => import('./locales/fr.json'));
|
||||
register('es', () => import('./locales/es.json'));
|
||||
|
||||
// Get initial locale from browser or localStorage
|
||||
function getInitialLocale(): SupportedLocale {
|
||||
if (browser) {
|
||||
// Check localStorage first
|
||||
const stored = localStorage.getItem('presi_locale');
|
||||
if (stored && supportedLocales.includes(stored as SupportedLocale)) {
|
||||
return stored as SupportedLocale;
|
||||
}
|
||||
|
||||
// Fall back to browser language
|
||||
const browserLang = navigator.language.split('-')[0];
|
||||
if (supportedLocales.includes(browserLang as SupportedLocale)) {
|
||||
return browserLang as SupportedLocale;
|
||||
}
|
||||
}
|
||||
|
||||
return defaultLocale;
|
||||
}
|
||||
|
||||
// Initialize i18n at module scope (required for SSR)
|
||||
init({
|
||||
fallbackLocale: defaultLocale,
|
||||
initialLocale: getInitialLocale(),
|
||||
});
|
||||
|
||||
// Set locale and persist to localStorage
|
||||
export function setLocale(newLocale: SupportedLocale) {
|
||||
locale.set(newLocale);
|
||||
if (browser) {
|
||||
localStorage.setItem('presi_locale', newLocale);
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for locale to be loaded (useful for SSR)
|
||||
export { waitLocale };
|
||||
13
apps/presi/apps/web/src/lib/i18n/locales/de.json
Normal file
13
apps/presi/apps/web/src/lib/i18n/locales/de.json
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"app_slider": {
|
||||
"title": "Weitere Manacore Apps",
|
||||
"memoro_desc": "KI-gestützte Sprachmemos",
|
||||
"maerchenzauber_desc": "Magische Gute-Nacht-Geschichten",
|
||||
"manadeck_desc": "KI Lernkarten",
|
||||
"picture_desc": "KI Bildgenerierung",
|
||||
"moodlit_desc": "Dein Stimmungsbegleiter",
|
||||
"manacore_desc": "KI-Produktivitätssuite",
|
||||
"coming_soon": "Demnächst",
|
||||
"download": "Download"
|
||||
}
|
||||
}
|
||||
13
apps/presi/apps/web/src/lib/i18n/locales/en.json
Normal file
13
apps/presi/apps/web/src/lib/i18n/locales/en.json
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"app_slider": {
|
||||
"title": "More Manacore Apps",
|
||||
"memoro_desc": "AI-powered voice memos",
|
||||
"maerchenzauber_desc": "Magical bedtime stories",
|
||||
"manadeck_desc": "AI flashcards",
|
||||
"picture_desc": "AI image generation",
|
||||
"moodlit_desc": "Your mood companion",
|
||||
"manacore_desc": "AI productivity suite",
|
||||
"coming_soon": "Coming soon",
|
||||
"download": "Download"
|
||||
}
|
||||
}
|
||||
13
apps/presi/apps/web/src/lib/i18n/locales/es.json
Normal file
13
apps/presi/apps/web/src/lib/i18n/locales/es.json
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"app_slider": {
|
||||
"title": "Más Apps de Manacore",
|
||||
"memoro_desc": "Notas de voz con IA",
|
||||
"maerchenzauber_desc": "Cuentos mágicos para dormir",
|
||||
"manadeck_desc": "Flashcards con IA",
|
||||
"picture_desc": "Generación de imágenes con IA",
|
||||
"moodlit_desc": "Tu compañero de ánimo",
|
||||
"manacore_desc": "Suite de productividad IA",
|
||||
"coming_soon": "Próximamente",
|
||||
"download": "Descargar"
|
||||
}
|
||||
}
|
||||
13
apps/presi/apps/web/src/lib/i18n/locales/fr.json
Normal file
13
apps/presi/apps/web/src/lib/i18n/locales/fr.json
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"app_slider": {
|
||||
"title": "Autres Apps Manacore",
|
||||
"memoro_desc": "Mémos vocaux avec IA",
|
||||
"maerchenzauber_desc": "Histoires magiques du soir",
|
||||
"manadeck_desc": "Flashcards avec IA",
|
||||
"picture_desc": "Génération d'images avec IA",
|
||||
"moodlit_desc": "Ton compagnon d'humeur",
|
||||
"manacore_desc": "Suite de productivité IA",
|
||||
"coming_soon": "Bientôt disponible",
|
||||
"download": "Télécharger"
|
||||
}
|
||||
}
|
||||
13
apps/presi/apps/web/src/lib/i18n/locales/it.json
Normal file
13
apps/presi/apps/web/src/lib/i18n/locales/it.json
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"app_slider": {
|
||||
"title": "Altre App Manacore",
|
||||
"memoro_desc": "Memo vocali con IA",
|
||||
"maerchenzauber_desc": "Storie magiche della buonanotte",
|
||||
"manadeck_desc": "Flashcard con IA",
|
||||
"picture_desc": "Generazione immagini con IA",
|
||||
"moodlit_desc": "Il tuo compagno d'umore",
|
||||
"manacore_desc": "Suite di produttività IA",
|
||||
"coming_soon": "Prossimamente",
|
||||
"download": "Scarica"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,24 +1,16 @@
|
|||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { locale } from 'svelte-i18n';
|
||||
import { ForgotPasswordPage } from '@manacore/shared-auth-ui';
|
||||
import { getForgotPasswordTranslations } from '@manacore/shared-i18n';
|
||||
import { PresiLogo } from '@manacore/shared-branding';
|
||||
import { auth } from '$lib/stores/auth.svelte';
|
||||
import AppSlider from '$lib/components/AppSlider.svelte';
|
||||
import LanguageSelector from '$lib/components/LanguageSelector.svelte';
|
||||
import '$lib/i18n';
|
||||
|
||||
// English translations
|
||||
const translations = {
|
||||
titleForm: 'Reset Password',
|
||||
titleSuccess: 'Email Sent',
|
||||
description: "Enter your email address and we'll send you a link to reset your password.",
|
||||
emailPlaceholder: 'Email',
|
||||
sendResetLinkButton: 'Send Reset Link',
|
||||
sending: 'Sending...',
|
||||
backToLogin: 'Back to Login',
|
||||
resendEmail: 'Resend Email',
|
||||
successMessage: "We've sent a password reset link to {email}. Please check your inbox.",
|
||||
emailRequired: 'Email is required',
|
||||
sendFailed: 'Failed to send reset email',
|
||||
};
|
||||
// Get translations based on current locale
|
||||
const translations = $derived(getForgotPasswordTranslations($locale || 'de'));
|
||||
|
||||
async function handleForgotPassword(email: string) {
|
||||
return auth.forgotPassword(email);
|
||||
|
|
@ -26,7 +18,7 @@
|
|||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Forgot Password | Presi</title>
|
||||
<title>{translations.titleForm} | Presi</title>
|
||||
</svelte:head>
|
||||
|
||||
<ForgotPasswordPage
|
||||
|
|
@ -40,6 +32,9 @@
|
|||
darkBackground="#1c1210"
|
||||
{translations}
|
||||
>
|
||||
{#snippet headerControls()}
|
||||
<LanguageSelector />
|
||||
{/snippet}
|
||||
{#snippet appSlider()}
|
||||
<AppSlider />
|
||||
{/snippet}
|
||||
|
|
|
|||
|
|
@ -1,39 +1,20 @@
|
|||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { page } from '$app/stores';
|
||||
import { locale } from 'svelte-i18n';
|
||||
import { LoginPage } from '@manacore/shared-auth-ui';
|
||||
import { getLoginTranslations } from '@manacore/shared-i18n';
|
||||
import { PresiLogo } from '@manacore/shared-branding';
|
||||
import { auth } from '$lib/stores/auth.svelte';
|
||||
import AppSlider from '$lib/components/AppSlider.svelte';
|
||||
import LanguageSelector from '$lib/components/LanguageSelector.svelte';
|
||||
import '$lib/i18n';
|
||||
|
||||
// Get redirect URL from query params
|
||||
const redirectTo = $derived($page.url.searchParams.get('redirectTo') || '/');
|
||||
|
||||
// English translations
|
||||
const translations = {
|
||||
title: 'Sign In',
|
||||
subtitle: 'Sign in with your account',
|
||||
emailPlaceholder: 'Email',
|
||||
passwordPlaceholder: 'Password',
|
||||
rememberMe: 'Remember me',
|
||||
forgotPassword: 'Forgot password?',
|
||||
signInButton: 'Sign In',
|
||||
signingIn: 'Signing in...',
|
||||
success: 'Success!',
|
||||
orDivider: 'or',
|
||||
noAccount: "Don't have an account?",
|
||||
createAccount: 'Create one',
|
||||
skipToForm: 'Skip to login form',
|
||||
showPassword: 'Show password',
|
||||
hidePassword: 'Hide password',
|
||||
emailRequired: 'Email is required',
|
||||
emailInvalid: 'Please enter a valid email address',
|
||||
passwordRequired: 'Password is required',
|
||||
signInFailed: 'Sign in failed',
|
||||
googleSignInFailed: 'Google sign in failed',
|
||||
signInSuccess: 'Successfully signed in. Redirecting...',
|
||||
googleSignInSuccess: 'Successfully signed in with Google. Redirecting...',
|
||||
};
|
||||
// Get translations based on current locale
|
||||
const translations = $derived(getLoginTranslations($locale || 'de'));
|
||||
|
||||
async function handleSignIn(email: string, password: string) {
|
||||
return auth.login(email, password);
|
||||
|
|
@ -41,7 +22,7 @@
|
|||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Login | Presi</title>
|
||||
<title>{translations.title} | Presi</title>
|
||||
</svelte:head>
|
||||
|
||||
<LoginPage
|
||||
|
|
@ -59,6 +40,9 @@
|
|||
darkBackground="#1c1210"
|
||||
{translations}
|
||||
>
|
||||
{#snippet headerControls()}
|
||||
<LanguageSelector />
|
||||
{/snippet}
|
||||
{#snippet appSlider()}
|
||||
<AppSlider />
|
||||
{/snippet}
|
||||
|
|
|
|||
|
|
@ -1,33 +1,16 @@
|
|||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { locale } from 'svelte-i18n';
|
||||
import { RegisterPage } from '@manacore/shared-auth-ui';
|
||||
import { getRegisterTranslations } from '@manacore/shared-i18n';
|
||||
import { PresiLogo } from '@manacore/shared-branding';
|
||||
import { auth } from '$lib/stores/auth.svelte';
|
||||
import AppSlider from '$lib/components/AppSlider.svelte';
|
||||
import LanguageSelector from '$lib/components/LanguageSelector.svelte';
|
||||
import '$lib/i18n';
|
||||
|
||||
// English translations
|
||||
const translations = {
|
||||
title: 'Create Account',
|
||||
emailPlaceholder: 'Email',
|
||||
passwordPlaceholder: 'Password',
|
||||
confirmPasswordPlaceholder: 'Confirm Password',
|
||||
passwordRequirements:
|
||||
'Password must be at least 8 characters with lowercase, uppercase, number, and special character.',
|
||||
createAccountButton: 'Create Account',
|
||||
creatingAccount: 'Creating Account...',
|
||||
backToLogin: 'Back to Login',
|
||||
showPassword: 'Show password',
|
||||
hidePassword: 'Hide password',
|
||||
emailRequired: 'Email is required',
|
||||
passwordRequired: 'Password is required',
|
||||
confirmPasswordRequired: 'Please confirm your password',
|
||||
passwordsDoNotMatch: 'Passwords do not match',
|
||||
passwordTooShort: 'Password must be at least 8 characters',
|
||||
passwordStrengthError:
|
||||
'Password must include lowercase, uppercase, number, and special character',
|
||||
registrationFailed: 'Registration failed',
|
||||
accountCreated: 'Account created! Please check your email to verify your account.',
|
||||
};
|
||||
// Get translations based on current locale
|
||||
const translations = $derived(getRegisterTranslations($locale || 'de'));
|
||||
|
||||
async function handleSignUp(email: string, password: string) {
|
||||
return auth.register(email, password);
|
||||
|
|
@ -35,7 +18,7 @@
|
|||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Register | Presi</title>
|
||||
<title>{translations.title} | Presi</title>
|
||||
</svelte:head>
|
||||
|
||||
<RegisterPage
|
||||
|
|
@ -50,6 +33,9 @@
|
|||
darkBackground="#1c1210"
|
||||
{translations}
|
||||
>
|
||||
{#snippet headerControls()}
|
||||
<LanguageSelector />
|
||||
{/snippet}
|
||||
{#snippet appSlider()}
|
||||
<AppSlider />
|
||||
{/snippet}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
"@manacore/shared-branding": "workspace:*",
|
||||
"@manacore/shared-feedback-service": "workspace:*",
|
||||
"@manacore/shared-feedback-ui": "workspace:*",
|
||||
"@manacore/shared-i18n": "workspace:*",
|
||||
"@manacore/shared-icons": "workspace:*",
|
||||
"@manacore/shared-profile-ui": "workspace:*",
|
||||
"@manacore/shared-subscription-ui": "workspace:*",
|
||||
|
|
@ -40,7 +41,8 @@
|
|||
"@manacore/shared-theme-ui": "workspace:*",
|
||||
"@manacore/shared-ui": "workspace:*",
|
||||
"@zitare/shared": "workspace:*",
|
||||
"@zitare/web-ui": "workspace:*"
|
||||
"@zitare/web-ui": "workspace:*",
|
||||
"svelte-i18n": "^4.0.1"
|
||||
},
|
||||
"type": "module"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
<script lang="ts">
|
||||
import { locale } from 'svelte-i18n';
|
||||
import { LanguageSelector } from '@manacore/shared-i18n';
|
||||
import { setLocale, supportedLocales } from '$lib/i18n';
|
||||
import { theme } from '$lib/stores/theme';
|
||||
|
||||
let currentLocale = $derived($locale || 'de');
|
||||
|
||||
function handleLocaleChange(newLocale: string) {
|
||||
setLocale(newLocale as any);
|
||||
}
|
||||
</script>
|
||||
|
||||
<LanguageSelector
|
||||
{currentLocale}
|
||||
{supportedLocales}
|
||||
onLocaleChange={handleLocaleChange}
|
||||
isDark={theme.isDark}
|
||||
primaryColor="#f59e0b"
|
||||
/>
|
||||
52
apps/zitare/apps/web/src/lib/i18n/index.ts
Normal file
52
apps/zitare/apps/web/src/lib/i18n/index.ts
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
import { browser } from '$app/environment';
|
||||
import { init, register, locale, waitLocale } from 'svelte-i18n';
|
||||
|
||||
// List of supported locales
|
||||
export const supportedLocales = ['de', 'en', 'it', 'fr', 'es'] as const;
|
||||
export type SupportedLocale = (typeof supportedLocales)[number];
|
||||
|
||||
// Default locale
|
||||
const defaultLocale = 'de';
|
||||
|
||||
// Register all available locales
|
||||
register('de', () => import('./locales/de.json'));
|
||||
register('en', () => import('./locales/en.json'));
|
||||
register('it', () => import('./locales/it.json'));
|
||||
register('fr', () => import('./locales/fr.json'));
|
||||
register('es', () => import('./locales/es.json'));
|
||||
|
||||
// Get initial locale from browser or localStorage
|
||||
function getInitialLocale(): SupportedLocale {
|
||||
if (browser) {
|
||||
// Check localStorage first
|
||||
const stored = localStorage.getItem('zitare_locale');
|
||||
if (stored && supportedLocales.includes(stored as SupportedLocale)) {
|
||||
return stored as SupportedLocale;
|
||||
}
|
||||
|
||||
// Fall back to browser language
|
||||
const browserLang = navigator.language.split('-')[0];
|
||||
if (supportedLocales.includes(browserLang as SupportedLocale)) {
|
||||
return browserLang as SupportedLocale;
|
||||
}
|
||||
}
|
||||
|
||||
return defaultLocale;
|
||||
}
|
||||
|
||||
// Initialize i18n at module scope (required for SSR)
|
||||
init({
|
||||
fallbackLocale: defaultLocale,
|
||||
initialLocale: getInitialLocale(),
|
||||
});
|
||||
|
||||
// Set locale and persist to localStorage
|
||||
export function setLocale(newLocale: SupportedLocale) {
|
||||
locale.set(newLocale);
|
||||
if (browser) {
|
||||
localStorage.setItem('zitare_locale', newLocale);
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for locale to be loaded (useful for SSR)
|
||||
export { waitLocale };
|
||||
13
apps/zitare/apps/web/src/lib/i18n/locales/de.json
Normal file
13
apps/zitare/apps/web/src/lib/i18n/locales/de.json
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"app_slider": {
|
||||
"title": "Weitere Manacore Apps",
|
||||
"memoro_desc": "KI-gestützte Sprachmemos",
|
||||
"maerchenzauber_desc": "Magische Gute-Nacht-Geschichten",
|
||||
"manadeck_desc": "KI Lernkarten",
|
||||
"picture_desc": "KI Bildgenerierung",
|
||||
"moodlit_desc": "Dein Stimmungsbegleiter",
|
||||
"manacore_desc": "KI-Produktivitätssuite",
|
||||
"coming_soon": "Demnächst",
|
||||
"download": "Download"
|
||||
}
|
||||
}
|
||||
13
apps/zitare/apps/web/src/lib/i18n/locales/en.json
Normal file
13
apps/zitare/apps/web/src/lib/i18n/locales/en.json
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"app_slider": {
|
||||
"title": "More Manacore Apps",
|
||||
"memoro_desc": "AI-powered voice memos",
|
||||
"maerchenzauber_desc": "Magical bedtime stories",
|
||||
"manadeck_desc": "AI flashcards",
|
||||
"picture_desc": "AI image generation",
|
||||
"moodlit_desc": "Your mood companion",
|
||||
"manacore_desc": "AI productivity suite",
|
||||
"coming_soon": "Coming soon",
|
||||
"download": "Download"
|
||||
}
|
||||
}
|
||||
13
apps/zitare/apps/web/src/lib/i18n/locales/es.json
Normal file
13
apps/zitare/apps/web/src/lib/i18n/locales/es.json
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"app_slider": {
|
||||
"title": "Más Apps de Manacore",
|
||||
"memoro_desc": "Notas de voz con IA",
|
||||
"maerchenzauber_desc": "Cuentos mágicos para dormir",
|
||||
"manadeck_desc": "Flashcards con IA",
|
||||
"picture_desc": "Generación de imágenes con IA",
|
||||
"moodlit_desc": "Tu compañero de ánimo",
|
||||
"manacore_desc": "Suite de productividad IA",
|
||||
"coming_soon": "Próximamente",
|
||||
"download": "Descargar"
|
||||
}
|
||||
}
|
||||
13
apps/zitare/apps/web/src/lib/i18n/locales/fr.json
Normal file
13
apps/zitare/apps/web/src/lib/i18n/locales/fr.json
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"app_slider": {
|
||||
"title": "Autres Apps Manacore",
|
||||
"memoro_desc": "Mémos vocaux avec IA",
|
||||
"maerchenzauber_desc": "Histoires magiques du soir",
|
||||
"manadeck_desc": "Flashcards avec IA",
|
||||
"picture_desc": "Génération d'images avec IA",
|
||||
"moodlit_desc": "Ton compagnon d'humeur",
|
||||
"manacore_desc": "Suite de productivité IA",
|
||||
"coming_soon": "Bientôt disponible",
|
||||
"download": "Télécharger"
|
||||
}
|
||||
}
|
||||
13
apps/zitare/apps/web/src/lib/i18n/locales/it.json
Normal file
13
apps/zitare/apps/web/src/lib/i18n/locales/it.json
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"app_slider": {
|
||||
"title": "Altre App Manacore",
|
||||
"memoro_desc": "Memo vocali con IA",
|
||||
"maerchenzauber_desc": "Storie magiche della buonanotte",
|
||||
"manadeck_desc": "Flashcard con IA",
|
||||
"picture_desc": "Generazione immagini con IA",
|
||||
"moodlit_desc": "Il tuo compagno d'umore",
|
||||
"manacore_desc": "Suite di produttività IA",
|
||||
"coming_soon": "Prossimamente",
|
||||
"download": "Scarica"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,14 @@
|
|||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { locale } from 'svelte-i18n';
|
||||
import { ForgotPasswordPage } from '@manacore/shared-auth-ui';
|
||||
import { ZitareLogo } from '@manacore/shared-branding';
|
||||
import { getForgotPasswordTranslations } from '@manacore/shared-i18n';
|
||||
import { authStore } from '$lib/stores/auth.svelte';
|
||||
import LanguageSelector from '$lib/components/LanguageSelector.svelte';
|
||||
import '$lib/i18n';
|
||||
|
||||
const translations = $derived(getForgotPasswordTranslations($locale || 'de'));
|
||||
|
||||
async function handleForgotPassword(email: string) {
|
||||
return authStore.resetPassword(email);
|
||||
|
|
@ -10,7 +16,7 @@
|
|||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Passwort vergessen - Zitare</title>
|
||||
<title>{translations.titleForm} - Zitare</title>
|
||||
</svelte:head>
|
||||
|
||||
<ForgotPasswordPage
|
||||
|
|
@ -22,4 +28,9 @@
|
|||
loginPath="/login"
|
||||
lightBackground="#fffbeb"
|
||||
darkBackground="#1c1917"
|
||||
/>
|
||||
{translations}
|
||||
>
|
||||
{#snippet headerControls()}
|
||||
<LanguageSelector />
|
||||
{/snippet}
|
||||
</ForgotPasswordPage>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,14 @@
|
|||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { locale } from 'svelte-i18n';
|
||||
import { LoginPage } from '@manacore/shared-auth-ui';
|
||||
import { ZitareLogo } from '@manacore/shared-branding';
|
||||
import { getLoginTranslations } from '@manacore/shared-i18n';
|
||||
import { authStore } from '$lib/stores/auth.svelte';
|
||||
import LanguageSelector from '$lib/components/LanguageSelector.svelte';
|
||||
import '$lib/i18n';
|
||||
|
||||
const translations = $derived(getLoginTranslations($locale || 'de'));
|
||||
|
||||
async function handleSignIn(email: string, password: string) {
|
||||
return authStore.signIn(email, password);
|
||||
|
|
@ -10,7 +16,7 @@
|
|||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Anmelden - Zitare</title>
|
||||
<title>{translations.title} - Zitare</title>
|
||||
</svelte:head>
|
||||
|
||||
<LoginPage
|
||||
|
|
@ -24,4 +30,9 @@
|
|||
forgotPasswordPath="/forgot-password"
|
||||
lightBackground="#fffbeb"
|
||||
darkBackground="#1c1917"
|
||||
/>
|
||||
{translations}
|
||||
>
|
||||
{#snippet headerControls()}
|
||||
<LanguageSelector />
|
||||
{/snippet}
|
||||
</LoginPage>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,14 @@
|
|||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { locale } from 'svelte-i18n';
|
||||
import { RegisterPage } from '@manacore/shared-auth-ui';
|
||||
import { ZitareLogo } from '@manacore/shared-branding';
|
||||
import { getRegisterTranslations } from '@manacore/shared-i18n';
|
||||
import { authStore } from '$lib/stores/auth.svelte';
|
||||
import LanguageSelector from '$lib/components/LanguageSelector.svelte';
|
||||
import '$lib/i18n';
|
||||
|
||||
const translations = $derived(getRegisterTranslations($locale || 'de'));
|
||||
|
||||
async function handleSignUp(email: string, password: string) {
|
||||
return authStore.signUp(email, password);
|
||||
|
|
@ -10,7 +16,7 @@
|
|||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Registrieren - Zitare</title>
|
||||
<title>{translations.title} - Zitare</title>
|
||||
</svelte:head>
|
||||
|
||||
<RegisterPage
|
||||
|
|
@ -23,4 +29,9 @@
|
|||
loginPath="/login"
|
||||
lightBackground="#fffbeb"
|
||||
darkBackground="#1c1917"
|
||||
/>
|
||||
{translations}
|
||||
>
|
||||
{#snippet headerControls()}
|
||||
<LanguageSelector />
|
||||
{/snippet}
|
||||
</RegisterPage>
|
||||
|
|
|
|||
|
|
@ -56,6 +56,8 @@
|
|||
darkBackground?: string;
|
||||
/** App slider snippet */
|
||||
appSlider?: Snippet;
|
||||
/** Header controls snippet (e.g., language selector) */
|
||||
headerControls?: Snippet;
|
||||
/** Translations for i18n support */
|
||||
translations?: Partial<ForgotPasswordTranslations>;
|
||||
}
|
||||
|
|
@ -70,6 +72,7 @@
|
|||
lightBackground = '#f5f5f5',
|
||||
darkBackground = '#121212',
|
||||
appSlider,
|
||||
headerControls,
|
||||
translations = {},
|
||||
}: Props = $props();
|
||||
|
||||
|
|
@ -138,6 +141,12 @@
|
|||
class="flex min-h-screen flex-col justify-between"
|
||||
style="background-color: {getPageBackground()}; max-width: 100vw; overflow-x: hidden;"
|
||||
>
|
||||
{#if headerControls}
|
||||
<div style="position: absolute; top: 1rem; right: 1rem; z-index: 50; opacity: 0.6; display: flex; gap: 0.75rem;">
|
||||
{@render headerControls()}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Top Section - Logo -->
|
||||
<div class="flex flex-col items-center justify-center pt-16 pb-8">
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -74,6 +74,8 @@
|
|||
darkBackground?: string;
|
||||
/** App slider snippet */
|
||||
appSlider?: Snippet;
|
||||
/** Header controls snippet (e.g., language selector) */
|
||||
headerControls?: Snippet;
|
||||
/** Translations for i18n support */
|
||||
translations?: Partial<RegisterTranslations>;
|
||||
}
|
||||
|
|
@ -89,6 +91,7 @@
|
|||
lightBackground = '#f5f5f5',
|
||||
darkBackground = '#121212',
|
||||
appSlider,
|
||||
headerControls,
|
||||
translations = {},
|
||||
}: Props = $props();
|
||||
|
||||
|
|
@ -220,6 +223,12 @@
|
|||
class="flex min-h-screen flex-col justify-between"
|
||||
style="background-color: {getPageBackground()}; max-width: 100vw; overflow-x: hidden;"
|
||||
>
|
||||
{#if headerControls}
|
||||
<div style="position: absolute; top: 1rem; right: 1rem; z-index: 50; opacity: 0.6; display: flex; gap: 0.75rem;">
|
||||
{@render headerControls()}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Top Section - Logo -->
|
||||
<div class="flex flex-col items-center justify-center pt-16 pb-8">
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ export {
|
|||
UloadLogo,
|
||||
ChatLogo,
|
||||
PresiLogo,
|
||||
NutriPhiLogo,
|
||||
ZitareLogo,
|
||||
} from './logos';
|
||||
|
||||
// Configuration
|
||||
|
|
|
|||
15
pnpm-lock.yaml
generated
15
pnpm-lock.yaml
generated
|
|
@ -313,6 +313,9 @@ importers:
|
|||
marked:
|
||||
specifier: ^17.0.0
|
||||
version: 17.0.1
|
||||
svelte-i18n:
|
||||
specifier: ^4.0.1
|
||||
version: 4.0.1(svelte@5.44.0)
|
||||
devDependencies:
|
||||
'@sveltejs/adapter-auto':
|
||||
specifier: ^6.0.0
|
||||
|
|
@ -1776,6 +1779,9 @@ importers:
|
|||
'@manacore/shared-feedback-ui':
|
||||
specifier: workspace:*
|
||||
version: link:../../../../packages/shared-feedback-ui
|
||||
'@manacore/shared-i18n':
|
||||
specifier: workspace:*
|
||||
version: link:../../../../packages/shared-i18n
|
||||
'@manacore/shared-icons':
|
||||
specifier: workspace:*
|
||||
version: link:../../../../packages/shared-icons
|
||||
|
|
@ -1803,6 +1809,9 @@ importers:
|
|||
lucide-svelte:
|
||||
specifier: ^0.460.0
|
||||
version: 0.460.1(svelte@5.44.0)
|
||||
svelte-i18n:
|
||||
specifier: ^4.0.1
|
||||
version: 4.0.1(svelte@5.44.0)
|
||||
devDependencies:
|
||||
'@sveltejs/adapter-auto':
|
||||
specifier: ^3.0.0
|
||||
|
|
@ -2164,6 +2173,9 @@ importers:
|
|||
'@manacore/shared-feedback-ui':
|
||||
specifier: workspace:*
|
||||
version: link:../../../../packages/shared-feedback-ui
|
||||
'@manacore/shared-i18n':
|
||||
specifier: workspace:*
|
||||
version: link:../../../../packages/shared-i18n
|
||||
'@manacore/shared-icons':
|
||||
specifier: workspace:*
|
||||
version: link:../../../../packages/shared-icons
|
||||
|
|
@ -2191,6 +2203,9 @@ importers:
|
|||
'@zitare/web-ui':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/web-ui
|
||||
svelte-i18n:
|
||||
specifier: ^4.0.1
|
||||
version: 4.0.1(svelte@5.44.0)
|
||||
devDependencies:
|
||||
'@sveltejs/adapter-auto':
|
||||
specifier: ^3.0.0
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue