This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / web / src / lib / components / welcome / ProfileStep.svelte
2.5 kB 73 lines
1<script module lang="ts"> 2 import { tv, type VariantProps } from "tailwind-variants"; 3 4 export const avatarPicker = tv({ 5 slots: { 6 label: 7 "flex size-40 cursor-pointer flex-col items-center justify-center gap-1 overflow-hidden rounded-full border border-border-default text-foreground-subtle transition-colors hover:bg-background-subtle", 8 image: "size-full rounded-full object-cover", 9 placeholder: "flex flex-col items-center justify-center gap-1" 10 } 11 }); 12 13 export type AvatarPickerVariants = VariantProps<typeof avatarPicker>; 14</script> 15 16<script lang="ts"> 17 import Camera from "$icon/camera"; 18 import Field from "$lib/components/ui/Field.svelte"; 19 import Input from "$lib/components/ui/Input.svelte"; 20 import StepHeader from "./StepHeader.svelte"; 21 import { draft } from "./draft.svelte"; 22 23 const slot = avatarPicker(); 24 25 // no upload endpoint wired up: the preview is a local object url, which is all 26 // the appview shows before its hx-post to /profile/avatar comes back 27 const pick = (event: Event) => { 28 const file = (event.currentTarget as HTMLInputElement).files?.[0]; 29 if (!file) return; 30 if (draft.picture) URL.revokeObjectURL(draft.picture); 31 draft.picture = URL.createObjectURL(file); 32 }; 33</script> 34 35<div class="flex flex-col gap-6"> 36 <StepHeader title="Welcome!" subtitle="Let's get your profile ready. All fields are optional." /> 37 38 <div class="flex flex-col gap-6 md:flex-row"> 39 <div class="flex shrink-0 justify-center md:block"> 40 <label class={slot.label()}> 41 {#if draft.picture} 42 <img src={draft.picture} alt="Your new avatar" class={slot.image()} /> 43 {:else} 44 <span class={slot.placeholder()}> 45 <Camera class="size-6" aria-hidden="true" /> 46 <span class="typography-paragraph-small">Upload picture</span> 47 </span> 48 {/if} 49 <input type="file" accept="image/png,image/jpeg" class="hidden" onchange={pick} /> 50 </label> 51 </div> 52 53 <div class="flex min-w-0 flex-1 flex-col gap-4"> 54 <Field label="Bio" labelCase="normal"> 55 {#snippet children({ id })} 56 <Input {id} placeholder="Tell us about yourself" bind:value={draft.description} /> 57 {/snippet} 58 </Field> 59 60 <Field label="Pronouns" labelCase="normal"> 61 {#snippet children({ id })} 62 <Input {id} placeholder="they/them" bind:value={draft.pronouns} /> 63 {/snippet} 64 </Field> 65 66 <Field label="Website" labelCase="normal"> 67 {#snippet children({ id })} 68 <Input {id} placeholder="example.com" bind:value={draft.website} /> 69 {/snippet} 70 </Field> 71 </div> 72 </div> 73</div>