diff options
Diffstat (limited to 'website/src/routes/welcome/+page.svelte')
| -rw-r--r-- | website/src/routes/welcome/+page.svelte | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/website/src/routes/welcome/+page.svelte b/website/src/routes/welcome/+page.svelte new file mode 100644 index 0000000..863b69f --- /dev/null +++ b/website/src/routes/welcome/+page.svelte @@ -0,0 +1,219 @@ +<script lang="ts"> + import { enhance } from '$app/forms'; + import type { ActionData } from './$types'; + + type FormFailure = { + errors: { username?: string[]; bio?: string[] }; + data: { username?: string; bio?: string }; + }; + const domain = 'sellershut.com'; + + let { form }: { form: ActionData } = $props(); + + const formError = $derived(form && 'errors' in form ? (form as FormFailure) : null); + const errors = $derived(formError?.errors); + + let username = $state(''); + let bio = $state(''); + let avatarPreview = $state<string | null>(null); + + let canSubmit = $derived(username.trim().length >= 3); + + function handleFileChange(e: Event) { + const target = e.target as HTMLInputElement; + if (target.files && target.files[0]) { + const reader = new FileReader(); + reader.onload = (e) => (avatarPreview = e.target?.result as string); + reader.readAsDataURL(target.files[0]); + } + } + $effect(() => { + if (formError?.data?.username) username = formError.data.username; + if (formError?.data?.bio) bio = formError.data.bio; + }); +</script> + +<form + method="POST" + use:enhance + enctype="multipart/form-data" + class="w-full max-w-md overflow-hidden rounded-3xl border border-rose-100 bg-white shadow-xl" +> + <div class="relative h-32 bg-linear-to-r from-rose-400 to-rose-600"> + <div class="absolute -bottom-12 left-1/2 -translate-x-1/2"> + <div class="group relative cursor-pointer"> + <div + class="h-24 w-24 overflow-hidden rounded-full border-4 border-white bg-rose-100 shadow-md" + > + {#if avatarPreview} + <img src={avatarPreview} alt="Preview" class="h-full w-full object-cover" /> + {:else} + <div class="flex h-full w-full items-center justify-center text-rose-300"> + <svg + xmlns="http://www.w3.org/2000/svg" + class="h-10 w-10" + fill="none" + viewBox="0 0 24 24" + stroke="currentColor" + > + <path + stroke-linecap="round" + stroke-linejoin="round" + stroke-width="2" + d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" + /> + </svg> + </div> + {/if} + </div> + + <div + class="absolute inset-0 flex items-center justify-center rounded-full bg-black/40 opacity-0 transition-opacity duration-200 group-hover:opacity-100" + > + <svg + xmlns="http://www.w3.org/2000/svg" + class="h-6 w-6 text-white" + fill="none" + viewBox="0 0 24 24" + stroke="currentColor" + stroke-width="2" + > + <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" /><polyline + points="17 8 12 3 7 8" + /><line x1="12" y1="3" x2="12" y2="15" /> + </svg> + </div> + <input + type="file" + name="avatar" + onchange={handleFileChange} + class="absolute inset-0 cursor-pointer opacity-0" + accept="image/*" + /> + </div> + </div> + </div> + + <div class="px-8 pt-16 pb-10 text-center"> + <h1 class="text-2xl font-bold text-gray-800">Final Touches</h1> + <p class="mt-1 text-sm text-gray-500">Tell the world a bit about yourself.</p> + + <div class="mt-8 space-y-5 text-left"> + <div> + <label for="email" class="mb-1 ml-1 block text-sm font-semibold text-gray-700"> + Account Email + </label> + + <div + class="flex cursor-not-allowed items-center rounded-xl border border-gray-200 bg-gray-50 transition-colors" + > + <span class="pl-4 text-gray-400"> + <svg + xmlns="http://www.w3.org/2000/svg" + class="h-5 w-5" + fill="none" + viewBox="0 0 24 24" + stroke="currentColor" + > + <path + stroke-linecap="round" + stroke-linejoin="round" + stroke-width="2" + d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" + /> + </svg> + </span> + + <input + id="email" + name="email" + type="email" + value="email@domain.com" + readonly + tabindex="-1" + class="flex-1 cursor-not-allowed border-none bg-transparent py-2.5 pr-4 pl-3 text-sm text-gray-500 outline-none focus:ring-0 md:text-base" + /> + + <span class="pr-4 text-gray-300"> + <svg + xmlns="http://www.w3.org/2000/svg" + class="h-4 w-4" + fill="none" + viewBox="0 0 24 24" + stroke="currentColor" + > + <path + stroke-linecap="round" + stroke-linejoin="round" + stroke-width="2" + d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" + /> + </svg> + </span> + </div> + </div> + <div> + <label for="username" class="mb-1 ml-1 block text-sm font-semibold text-gray-700"> + Username + </label> + + <div + class="group flex items-center rounded-xl border border-gray-200 bg-white transition-all duration-200 + focus-within:border-rose-400 focus-within:ring-4 focus-within:ring-rose-100 + {errors?.username + ? 'border-red-500 focus-within:border-red-500 focus-within:ring-red-100' + : ''}" + > + <span class="pl-4 text-gray-400 select-none">@</span> + + <input + id="username" + name="username" + type="text" + bind:value={username} + placeholder="username" + class="flex-1 border-none bg-transparent py-2.5 pr-2 pl-1 text-sm outline-none placeholder:text-gray-300 focus:ring-0 md:text-base" + /> + + <span + class="-ml-4 border-l border-gray-100 pr-4 pl-2 text-sm font-medium text-gray-400 select-none md:ml-2" + > + @{domain} + </span> + </div> + + {#if errors?.username} + <p class="mt-1 ml-1 text-xs text-red-500">{errors.username[0]}</p> + {/if} + </div> + <div> + <label for="bio" class="mb-1 ml-1 block text-sm font-semibold text-gray-700" + >Bio</label + > + <textarea + id="bio" + name="bio" + bind:value={bio} + rows="3" + placeholder="I build cool things with Svelte..." + class="block w-full resize-none rounded-xl border border-gray-200 px-4 + py-2.5 transition-all duration-200 outline-none + placeholder:text-gray-300 focus:border-rose-400 focus:ring-4 focus:ring-rose-100 focus:ring-offset-0 + {errors?.bio ? 'border-red-500 focus:border-red-500 focus:ring-red-100' : ''}" + ></textarea> + {#if errors?.bio} + <p class="mt-1 ml-1 text-xs text-red-500">{errors.bio[0]}</p> + {/if} + </div> + + <button + disabled={!canSubmit} + class="flex w-full justify-center rounded-md border border-transparent bg-rose-600 px-4 py-2 text-sm font-medium text-white shadow-sm transition-colors hover:bg-rose-700 focus:ring-2 focus:ring-rose-500 focus:ring-offset-2 focus:outline-none disabled:bg-rose-300" + > + Finish Setup + </button> + + <p class="mt-4 text-center text-[10px] tracking-widest text-gray-400">sellershut.com</p> + </div> + </div> +</form> |
