migrate auth v2 code

This commit is contained in:
JCEEE
2026-08-16 10:11:39 +01:00
parent 3dd94b8a7c
commit c73ced7894
45 changed files with 1965 additions and 1519 deletions
+176 -34
View File
@@ -1,48 +1,124 @@
<script lang="ts">
import { enhance } from '$app/forms';
import AuthShell from '$lib/components/AuthShell.svelte';
import { slugify, handle } from '@shared/slugify';
let { form } = $props();
let step = $state(1);
let famName = $state('');
let yourName = $state('');
let email = $state('');
let password = $state('');
let famName = $state('');
let parentName = $state('');
let childName = $state('');
let submitting = $state(false);
let localError = $state('');
let famSlugPreview = $derived(slugify(famName) || 'your-family');
let handlePreview = $derived(handle(yourName) || 'your-name');
const enhanceForm = () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- canary $types lacks SubmitFunction
return () =>
async ({ update, result }: any) => {
submitting = true;
localError = '';
try {
await update();
} catch (e) {
localError = e instanceof Error ? e.message : 'Something went wrong. Please try again.';
}
submitting = false;
if (result.type !== 'failure' && result.type !== 'error') step++;
};
};
</script>
<AuthShell title="Create your family" subtitle="Set up in about a minute. Free to get going.">
{#if form?.error}
<p class="form-error">{form.error}</p>
{#if form?.message}
<p class="form-error">{form.message}</p>
{/if}
{#if localError}
<p class="form-error">{localError}</p>
{/if}
<form method="POST">
<label>
Family name
<input name="famName" bind:value={famName} placeholder="The Smiths" required />
</label>
<label>
Your name
<input name="parentName" bind:value={parentName} placeholder="Mum / Dad" required />
</label>
<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}
placeholder="8+ characters"
minlength={8}
required
/>
</label>
<button type="submit">Create my family</button>
</form>
{#if step === 1}
<form method="POST" action="?/signup" use:enhance={enhanceForm()}>
<label>
Family name
<input name="familyName" bind:value={famName} placeholder="The Smiths" required />
{#if famName}
<span class="preview">Family page address: <code>/</code><code class="inline-code">{famSlugPreview}</code></span>
{/if}
</label>
<label>
Your name
<input name="yourName" bind:value={yourName} placeholder="Mum / Dad" required />
{#if yourName}
<span class="preview">
Your address: <code>/</code><code class="inline-code">{famSlugPreview}/{handlePreview}</code>
<small class="preview-hint">(no spaces — {yourName.trim()} → {handlePreview})</small>
</span>
{:else}
<span class="preview-hint">No spaces in your address — e.g. “Joe Edhook” → <code>joeedhook</code></span>
{/if}
</label>
<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}
placeholder="8+ characters"
minlength={8}
required
/>
</label>
<button type="submit" disabled={submitting}>Create my family</button>
</form>
<p class="alt">Already have a family? <a href="/login">Log in</a></p>
{/if}
<p class="alt">
Already have a family? <a href="/login">Log in</a>
</p>
{#if step === 2}
<h3 class="step-title">Add a child now?</h3>
<p class="step-note">We'll create a shareable join code so they can jump in on any device.</p>
<form method="POST" action="?/child" use:enhance={enhanceForm()}>
<label>
Child's name
<input
type="text"
name="member"
bind:value={childName}
placeholder="Their first name"
/>
</label>
<button type="submit" disabled={submitting}>Create join code</button>
</form>
<p class="alt">
<a href="/{form?.famSlug}">Skip for now →</a>
</p>
{/if}
{#if step === 3}
<h3 class="step-title">{childName ? `Nice — share this code with ${childName}:` : 'Your family is ready!'}</h3>
{#if form?.code}
<div class="code">
<span class="code-text">{form.code}</span>
</div>
<p class="step-note">
They open <code class="inline-code">{form?.joinUrl}</code> and enter this code.
</p>
{:else}
<p class="step-note">You can add kids and share join codes any time from Family Settings.</p>
{/if}
<div class="actions">
<a href="/{form?.famSlug}" class="btn-primary">Go to dashboard</a>
</div>
{/if}
</AuthShell>
<style>
@@ -81,6 +157,17 @@
cursor: pointer;
}
button:hover { background: #3730a3; }
button:disabled { opacity: 0.6; cursor: default; }
.step-title {
margin: 0 0 0.25rem;
font-size: 1.1rem;
color: #111827;
}
.step-note {
margin: 0 0 1rem;
font-size: 0.85rem;
color: #6b7280;
}
.form-error {
background: #fef2f2;
color: #b91c1c;
@@ -90,6 +177,23 @@
font-size: 0.85rem;
margin: 0 0 1rem;
}
.preview {
font-size: 0.78rem;
color: #6b7280;
font-weight: 400;
}
.preview-hint {
font-size: 0.75rem;
color: #9ca3af;
font-weight: 400;
}
.preview .inline-code, .preview-hint .inline-code {
font-family: ui-monospace, monospace;
background: #f3f4f6;
border-radius: 4px;
padding: 0.05em 0.3em;
color: #374151;
}
.alt {
margin: 1.25rem 0 0;
font-size: 0.85rem;
@@ -97,4 +201,42 @@
text-align: center;
}
.alt a { color: #4338ca; text-decoration: none; font-weight: 500; }
</style>
.code {
background: #eef2ff;
border: 1px dashed #a5b4fc;
border-radius: 10px;
padding: 1rem;
text-align: center;
margin: 0 0 0.75rem;
}
.code-text {
font-family: ui-monospace, monospace;
font-size: 1.6rem;
letter-spacing: 0.35em;
font-weight: 700;
color: #4338ca;
}
.inline-code {
font-family: ui-monospace, monospace;
font-size: 0.85em;
background: #f3f4f6;
border-radius: 4px;
padding: 0.1em 0.35em;
color: #374151;
}
.actions {
margin-top: 1.25rem;
}
.btn-primary {
display: block;
text-align: center;
background: #4338ca;
color: #fff;
border-radius: 8px;
padding: 0.75rem;
font-size: 1rem;
font-weight: 600;
text-decoration: none;
}
.btn-primary:hover { background: #3730a3; }
</style>