Files
famdone/frontend/src/routes/[fam]/[username]/preferences/+page.svelte
T
2026-08-25 10:54:18 +01:00

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>