123 lines
3.6 KiB
Svelte
123 lines
3.6 KiB
Svelte
<script lang="ts">
|
|
import { enhance, applyAction } from '$app/forms';
|
|
import { ViewHeader, CardGrid, Card, Button } from '$lib/components';
|
|
|
|
let { data, form } = $props();
|
|
|
|
let memberName = $state(data.memberName || '');
|
|
let memberColor = $state(data.memberColor || '#6366f1');
|
|
let memberEmail = $state(data.email || '');
|
|
|
|
const colors = ['#6366f1', '#ec4899', '#f59e0b', '#10b981', '#3b82f6', '#ef4444', '#8b5cf6', '#14b8a6'];
|
|
</script>
|
|
|
|
<ViewHeader title="Preferences" subtitle={data.verified ? data.memberName : ''} hero />
|
|
|
|
{#if !data.verified}
|
|
<CardGrid>
|
|
<Card cols={3}>
|
|
<p style="color:#9ca3af;text-align:center;padding:2rem">
|
|
Not authenticated. Use the link from your invite.
|
|
</p>
|
|
</Card>
|
|
</CardGrid>
|
|
{:else}
|
|
<CardGrid>
|
|
<Card cols={2} title="Appearance">
|
|
<form
|
|
method="POST"
|
|
action="?/update"
|
|
use:enhance={() => {
|
|
return async ({ result }) => {
|
|
// Apply the action result (so the success/error message
|
|
// shows) WITHOUT resetting the form — the default enhance
|
|
// clears name/email inputs on a successful submit.
|
|
if (result.type === 'success' || result.type === 'failure') {
|
|
await applyAction(result);
|
|
}
|
|
};
|
|
}}
|
|
>
|
|
<div style="margin-bottom:1rem">
|
|
<label style="display:block;font-size:0.85rem;color:#374151;margin-bottom:0.25rem">
|
|
Display Name
|
|
</label>
|
|
<input
|
|
type="text"
|
|
name="name"
|
|
bind:value={memberName}
|
|
required
|
|
style="padding:0.5rem;border:1px solid #d1d5db;border-radius:6px;font-size:0.9rem;width:100%;box-sizing:border-box"
|
|
/>
|
|
</div>
|
|
|
|
<div style="margin-bottom:1rem">
|
|
<label style="display:block;font-size:0.85rem;color:#374151;margin-bottom:0.25rem">
|
|
Color
|
|
</label>
|
|
<div style="display:flex;gap:0.4rem;flex-wrap:wrap">
|
|
{#each colors as c}
|
|
<button
|
|
type="button"
|
|
style="width:2rem;height:2rem;border-radius:50%;border:{c === memberColor ? '3px solid #111827' : '2px solid transparent'};background:{c};cursor:pointer"
|
|
onclick={() => memberColor = c}
|
|
></button>
|
|
{/each}
|
|
</div>
|
|
<input type="hidden" name="color" value={memberColor} />
|
|
</div>
|
|
|
|
<div style="margin-bottom:1rem">
|
|
<label style="display:block;font-size:0.85rem;color:#374151;margin-bottom:0.25rem">
|
|
Email
|
|
</label>
|
|
{#if data.session}
|
|
<input
|
|
type="email"
|
|
name="email"
|
|
bind:value={memberEmail}
|
|
style="padding:0.5rem;border:1px solid #d1d5db;border-radius:6px;font-size:0.9rem;width:100%;box-sizing:border-box"
|
|
/>
|
|
{:else}
|
|
<input
|
|
type="email"
|
|
name="email"
|
|
value={memberEmail}
|
|
disabled
|
|
style="padding:0.5rem;border:1px solid #d1d5db;border-radius:6px;font-size:0.9rem;width:100%;box-sizing:border-box;background:#f3f4f6;color:#9ca3af"
|
|
/>
|
|
{/if}
|
|
</div>
|
|
|
|
{#if form?.error}
|
|
<p style="color:#dc2626;font-size:0.85rem;margin-bottom:0.5rem">{form.error}</p>
|
|
{/if}
|
|
{#if form?.success}
|
|
<p style="color:#059669;font-size:0.85rem;margin-bottom:0.5rem">Saved!</p>
|
|
{/if}
|
|
|
|
<div class="form-actions">
|
|
<Button type="submit" variant="primary">Update preferences</Button>
|
|
</div>
|
|
</form>
|
|
</Card>
|
|
|
|
<Card cols={1} title="Account">
|
|
<p style="font-size:0.85rem;color:#6b7280">
|
|
To change your device or sign in on a new device, use your invite link.
|
|
</p>
|
|
<p style="font-size:0.85rem;color:#6b7280;margin-top:0.5rem">
|
|
Contact your family admin to change your token or reset your account.
|
|
</p>
|
|
</Card>
|
|
</CardGrid>
|
|
{/if}
|
|
|
|
<style>
|
|
.form-actions {
|
|
margin-top: 1.25rem;
|
|
padding-top: 1.25rem;
|
|
border-top: 1px solid #e5e7eb;
|
|
}
|
|
</style>
|