{error}
diff --git a/apps/presi/apps/web/src/routes/(auth)/login/+page.svelte b/apps/presi/apps/web/src/routes/(auth)/login/+page.svelte
index 1de53fb3b..7d6ee56af 100644
--- a/apps/presi/apps/web/src/routes/(auth)/login/+page.svelte
+++ b/apps/presi/apps/web/src/routes/(auth)/login/+page.svelte
@@ -16,6 +16,10 @@
// Get translations based on current locale
const translations = $derived(getLoginTranslations($locale || 'de'));
+ // Read verification status from query params (set after email verification)
+ const verified = $derived($page.url.searchParams.get('verified') === 'true');
+ const initialEmail = $derived($page.url.searchParams.get('email') || '');
+
async function handleSignIn(email: string, password: string) {
return auth.login(email, password);
}
@@ -39,6 +43,8 @@
lightBackground="#fff7ed"
darkBackground="#1c1210"
{translations}
+ {verified}
+ {initialEmail}
>
{#snippet headerControls()}
diff --git a/apps/todo/apps/web/src/routes/(auth)/login/+page.svelte b/apps/todo/apps/web/src/routes/(auth)/login/+page.svelte
index 80b915def..9b33bf625 100644
--- a/apps/todo/apps/web/src/routes/(auth)/login/+page.svelte
+++ b/apps/todo/apps/web/src/routes/(auth)/login/+page.svelte
@@ -31,6 +31,10 @@
// Get translations based on current locale
const translations = $derived(getLoginTranslations($locale || 'de'));
+ // Read verification status from query params (set after email verification)
+ const verified = $derived($page.url.searchParams.get('verified') === 'true');
+ const initialEmail = $derived($page.url.searchParams.get('email') || '');
+
async function handleSignIn(email: string, password: string) {
return authStore.signIn(email, password);
}
@@ -54,6 +58,8 @@
lightBackground="#f3e8ff"
darkBackground="#1e1b4b"
{translations}
+ {verified}
+ {initialEmail}
>
{#snippet headerControls()}
diff --git a/packages/shared-auth-ui/src/pages/LoginPage.svelte b/packages/shared-auth-ui/src/pages/LoginPage.svelte
index 82d1523e4..34adc287d 100644
--- a/packages/shared-auth-ui/src/pages/LoginPage.svelte
+++ b/packages/shared-auth-ui/src/pages/LoginPage.svelte
@@ -29,6 +29,7 @@
googleSignInFailed: string;
signInSuccess: string;
googleSignInSuccess: string;
+ emailVerified?: string;
}
const defaultTranslations: LoginTranslations = {
@@ -54,6 +55,7 @@
googleSignInFailed: 'Google sign in failed',
signInSuccess: 'Successfully signed in. Redirecting...',
googleSignInSuccess: 'Successfully signed in with Google. Redirecting...',
+ emailVerified: 'Email successfully verified! Please sign in.',
};
interface Props {
@@ -74,6 +76,10 @@
appSlider?: Snippet;
headerControls?: Snippet;
translations?: Partial
;
+ /** Show email verified success banner */
+ verified?: boolean;
+ /** Pre-fill email field (e.g., after email verification) */
+ initialEmail?: string;
}
let {
@@ -94,6 +100,8 @@
appSlider,
headerControls,
translations = {},
+ verified = false,
+ initialEmail = '',
}: Props = $props();
const t = $derived({ ...defaultTranslations, ...translations });
@@ -101,7 +109,7 @@
let loading = $state(false);
let error = $state(null);
let errorField = $state<'email' | 'password' | 'general' | null>(null);
- let email = $state('');
+ let email = $state(initialEmail);
let password = $state('');
let showPassword = $state(false);
let rememberMe = $state(false);
@@ -110,6 +118,7 @@
let emailInput: HTMLInputElement;
let passwordInput: HTMLInputElement;
let successAnnouncement = $state('');
+ let showVerifiedBanner = $state(verified);
// Theme state - can be toggled manually, defaults to system preference
let userThemePreference = $state<'light' | 'dark' | null>(null);
@@ -145,7 +154,12 @@
}
$effect(() => {
- if (emailInput) emailInput.focus();
+ // Focus password field if email is pre-filled, otherwise focus email
+ if (initialEmail && passwordInput) {
+ passwordInput.focus();
+ } else if (emailInput) {
+ emailInput.focus();
+ }
});
function isValidEmail(email: string): boolean {
@@ -296,6 +310,21 @@