final flows including emails for passwords

This commit is contained in:
JCEEE
2026-09-01 11:58:43 +01:00
parent f491dbfbf1
commit 40d7bf7398
22 changed files with 1977 additions and 859 deletions
+110 -18
View File
@@ -4,28 +4,90 @@
let { form } = $props();
let email = $state('');
let password = $state('');
let showForgot = $state(false);
let forgotEmail = $state('');
let forgotLoading = $state(false);
let forgotSuccess = $state(false);
async function handleForgot() {
if (!forgotEmail || forgotLoading) return;
forgotLoading = true;
try {
const fd = new FormData();
fd.set('email', forgotEmail);
const res = await fetch('/api/email', { method: 'POST', body: fd });
if (res.ok) {
forgotSuccess = true;
}
} catch {
// Silent — generic response
} finally {
forgotLoading = false;
}
}
</script>
<AuthShell title="Log in" subtitle="Welcome back to FamChore.">
{#if form?.error}
<p class="form-error">{form.error}</p>
{/if}
{#if showForgot}
{#if forgotSuccess}
<p class="form-ok">
If an account exists for <strong>{forgotEmail}</strong>, a reset link is on its way.
</p>
<button
class="row-btn centered"
type="button"
onclick={() => {
showForgot = false;
forgotSuccess = false;
forgotEmail = '';
}}
>
Back to log in
</button>
{:else}
<form
onsubmit={(e) => {
e.preventDefault();
handleForgot();
}}
>
<label>
Email
<input type="email" bind:value={forgotEmail} placeholder="you@email.com" required />
</label>
<button type="submit" disabled={forgotLoading}>
{forgotLoading ? 'Sending...' : 'Send reset link'}
</button>
</form>
<button class="row-btn centered" type="button" onclick={() => (showForgot = false)}>
Back to log in
</button>
{/if}
{:else}
{#if form?.error}
<p class="form-error">{form.error}</p>
{/if}
<form method="POST">
<label>
Email
<input type="email" name="email" bind:value={email} placeholder="you@email.com" required />
</label>
<label>
Password
<input type="password" name="password" bind:value={password} required />
</label>
<button type="submit">Log in</button>
</form>
<p class="alt">
Don't have a family yet? <a href="/signup">Create one</a>
</p>
<p>Trying to join as a child? Ask your parent to issue your QR code.</p>
<form method="POST">
<label>
Email
<input type="email" name="email" bind:value={email} placeholder="you@email.com" required />
</label>
<label>
Password
<input type="password" name="password" bind:value={password} required />
</label>
<button class="row-btn" type="button" onclick={() => (showForgot = true)}>
Forgot password?
</button>
<button type="submit">Log in</button>
</form>
<p class="alt">
Don't have a family yet? <a href="/signup">Create one</a>
</p>
<p>Trying to join as a child? Ask your parent to issue your QR code.</p>
{/if}
</AuthShell>
<style>
@@ -66,6 +128,36 @@
button:hover {
background: #3730a3;
}
button:disabled {
opacity: 0.6;
cursor: not-allowed;
}
.row-btn {
background: none;
color: #4338ca;
font-size: 0.85rem;
font-weight: 500;
padding: 0;
text-decoration: underline;
cursor: pointer;
}
.row-btn:hover {
background: none;
}
.row-btn.centered {
display: block;
margin: 1.25rem auto 0;
width: fit-content;
}
.form-ok {
background: #f0fdf4;
color: #166534;
border: 1px solid #bbf7d0;
border-radius: 8px;
padding: 0.6rem 0.75rem;
font-size: 0.85rem;
margin: 0 0 1rem;
}
.form-error {
background: #fef2f2;
color: #b91c1c;