login now username+password based

This commit is contained in:
user
2026-02-28 19:39:21 +02:00
parent 0265d6e774
commit cf8d72cac3
14 changed files with 245 additions and 1128 deletions

View File

@@ -10,7 +10,7 @@
import { accountVM } from "$lib/domains/account/account.vm.svelte";
import { breadcrumbs } from "$lib/global.stores";
import AtSign from "@lucide/svelte/icons/at-sign";
import Mail from "@lucide/svelte/icons/mail";
import KeyRound from "@lucide/svelte/icons/key-round";
import Save from "@lucide/svelte/icons/save";
import Upload from "@lucide/svelte/icons/upload";
import User from "@lucide/svelte/icons/user";
@@ -22,14 +22,15 @@
const user = $state(data.user!);
// Separate form state for profile and email
// Separate form state for profile and password
let profileData = $state({
name: user.name ?? "",
username: user.username ?? "",
});
let emailData = $state({
email: user.email,
let passwordData = $state({
password: "",
confirmPassword: "",
});
// Handle profile form submission (name, username)
@@ -38,11 +39,20 @@
await accountVM.updateProfile(profileData);
}
// Handle email form submission
async function handleEmailSubmit(e: SubmitEvent) {
// Handle password form submission
async function handlePasswordSubmit(e: SubmitEvent) {
e.preventDefault();
if (user.email !== emailData.email) {
await accountVM.changeEmail(emailData.email);
if (
passwordData.password.length >= 6 &&
passwordData.password === passwordData.confirmPassword
) {
const didChange = await accountVM.changePassword(
passwordData.password,
);
if (didChange) {
passwordData.password = "";
passwordData.confirmPassword = "";
}
}
}
@@ -171,67 +181,72 @@
</Card.Footer>
</Card.Root>
<!-- Email Settings -->
<!-- Password Settings -->
<Card.Root>
<Card.Header>
<Card.Title>Email Settings</Card.Title>
<Card.Title>Password Settings</Card.Title>
<Card.Description>
Manage your email address and verification status.
Update your account password.
</Card.Description>
</Card.Header>
<Card.Content>
<form onsubmit={handleEmailSubmit} class="space-y-4">
<!-- Email -->
<form onsubmit={handlePasswordSubmit} class="space-y-4">
<div class="grid grid-cols-1 gap-1.5">
<Label for="email" class="flex items-center gap-1.5">
<Label for="password" class="flex items-center gap-1.5">
<Icon
icon={Mail}
icon={KeyRound}
cls="h-3.5 w-3.5 text-muted-foreground"
/>
Email Address
New Password
</Label>
<Input
id="email"
type="email"
bind:value={emailData.email}
placeholder="your.email@example.com"
id="password"
type="password"
bind:value={passwordData.password}
placeholder="Enter new password"
minlength={6}
/>
</div>
<div class="grid grid-cols-1 gap-1.5">
<Label
for="confirm-password"
class="flex items-center gap-1.5"
>
<Icon
icon={KeyRound}
cls="h-3.5 w-3.5 text-muted-foreground"
/>
Confirm Password
</Label>
<Input
id="confirm-password"
type="password"
bind:value={passwordData.confirmPassword}
placeholder="Re-enter new password"
minlength={6}
maxlength={128}
/>
<div class="flex items-center gap-1.5">
<span
class={user.emailVerified
? "text-xs text-emerald-600 dark:text-emerald-400"
: "text-xs text-amber-600"}
>
{user.emailVerified
? "Email verified"
: "Email not verified"}
</span>
{#if !user.emailVerified}
<Button
variant="link"
size="sm"
class="h-auto p-0 text-xs">Verify now</Button
>
{/if}
</div>
</div>
<div class="flex justify-end">
<Button
type="submit"
disabled={accountVM.emailLoading ||
user.email === emailData.email}
disabled={accountVM.passwordLoading ||
passwordData.password.length < 6 ||
passwordData.password !==
passwordData.confirmPassword}
variant="outline"
class="w-full sm:w-auto"
>
{#if accountVM.emailLoading}
<Icon icon={Mail} cls="h-4 w-4 mr-2 animate-spin" />
Sending...
{#if accountVM.passwordLoading}
<Icon
icon={KeyRound}
cls="h-4 w-4 mr-2 animate-spin"
/>
Updating...
{:else}
<Icon icon={Mail} cls="h-4 w-4 mr-2" />
Update Email
<Icon icon={KeyRound} cls="h-4 w-4 mr-2" />
Update Password
{/if}
</Button>
</div>
@@ -239,8 +254,7 @@
</Card.Content>
<Card.Footer>
<p class="text-muted-foreground text-xs">
Changing your email will require verification of the new
address.
Choose a strong password with at least 6 characters.
</p>
</Card.Footer>
</Card.Root>