Monorepo for Tangled tangled.org
1

Configure Feed

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

core / web / src / routes / login / +page.svelte
3.2 kB 106 lines
1<script lang="ts"> 2 import { browser } from '$app/environment'; 3 import { resolve } from '$app/paths'; 4 import { page } from '$app/state'; 5 import { getAuth } from '$lib/auth.svelte'; 6 import Button from '$lib/components/ui/Button.svelte'; 7 import CircleAlert from '$icon/circle-alert'; 8 import { onMount } from 'svelte'; 9 import { SvelteURL } from 'svelte/reactivity'; 10 11 const appPath = (path: string) => resolve(path as '/'); 12 const auth = getAuth(); 13 const returnTo = $derived(page.url.searchParams.get('return_url') ?? '/'); 14 15 let identifier = $state(page.url.searchParams.get('identifier') ?? ''); 16 let isSubmitting = $state(false); 17 18 onMount(() => { 19 if (browser && location.hostname === 'localhost') { 20 const url = new SvelteURL(location.href); 21 url.hostname = '127.0.0.1'; 22 location.replace(url); 23 } 24 }); 25 26 const submit = async (event: SubmitEvent) => { 27 event.preventDefault(); 28 isSubmitting = true; 29 try { 30 await auth.signIn(identifier, returnTo); 31 } finally { 32 isSubmitting = false; 33 } 34 }; 35</script> 36 37<svelte:head> 38 <title>Login &middot; Tangled</title> 39</svelte:head> 40 41<section class="w-full max-w-md"> 42 <div class="mb-4 flex flex-col items-center"> 43 <a href={appPath('/')} class="flex items-center gap-2 no-underline hover:no-underline"> 44 <img src="/logos/logotype.svg" alt="tangled" class="h-24 w-48 dark:invert" /> 45 </a> 46 <p class="text-center text-xl italic text-fg-strong">tightly-knit social coding.</p> 47 </div> 48 49 <form class="mt-4" onsubmit={submit}> 50 <div class="flex flex-col"> 51 <label for="identifier" class="py-2 text-sm text-fg">Handle</label> 52 <input 53 id="identifier" 54 bind:value={identifier} 55 disabled={isSubmitting} 56 type="text" 57 autocomplete="username" 58 autocapitalize="none" 59 spellcheck="false" 60 inputmode="url" 61 required 62 placeholder="akshay.tngl.sh" 63 class="w-full rounded border border-border bg-surface p-3 text-lg text-fg placeholder:text-fg-faint focus:outline-none focus:ring-1 focus:ring-border-strong md:text-base" 64 /> 65 <p class="mt-1 text-sm text-fg-subtle"> 66 Use your <span class="text-fg">AT Protocol</span> handle to log in. If you're unsure, this 67 is likely your Tangled 68 <code class="rounded bg-surface-muted px-1 font-mono text-xs text-fg">(.tngl.sh)</code> 69 or Bluesky 70 <code class="rounded bg-surface-muted px-1 font-mono text-xs text-fg">(.bsky.social)</code> 71 account. 72 </p> 73 </div> 74 75 <Button 76 type="submit" 77 size="sm" 78 disabled={isSubmitting} 79 loading={isSubmitting} 80 spinnerClass="size-4" 81 aria-label={isSubmitting ? 'Logging in' : undefined} 82 class="my-2 mt-6 w-full text-base disabled:opacity-100" 83 > 84 Login 85 </Button> 86 </form> 87 88 <p class="text-sm text-fg-subtle"> 89 Don't have an account? <a href={appPath('/signup')} class="text-fg underline" 90 >Create an account</a 91 > 92 on Tangled now! 93 </p> 94 95 {#if auth.error} 96 <div 97 class="my-2 flex gap-2 rounded border border-danger bg-danger-soft px-3 py-2 text-danger drop-shadow-sm" 98 > 99 <span class="py-1" aria-hidden="true"><CircleAlert class="size-4" /></span> 100 <div> 101 <h5 class="font-medium">Login error</h5> 102 <p class="text-sm">{auth.error} Please try again.</p> 103 </div> 104 </div> 105 {/if} 106</section>