diff options
| author | Adam Soltys <[email protected]> | 2024-11-26 22:35:28 -0800 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2024-11-26 22:35:28 -0800 |
| commit | f99bd15fabd6d7b361794f756a69d6f05a50701f (patch) | |
| tree | 9bb1b14519b34c343ad3bcd001fbd4681a53e447 /src/routes/(static) | |
| parent | f4eb6547d0db5edd0137fdefe461433500515040 (diff) | |
| download | coinos-ui-f99bd15fabd6d7b361794f756a69d6f05a50701f.tar.gz coinos-ui-f99bd15fabd6d7b361794f756a69d6f05a50701f.zip | |
warnings
Diffstat (limited to 'src/routes/(static)')
| -rw-r--r-- | src/routes/(static)/docs/+page.svelte | 37 | ||||
| -rw-r--r-- | src/routes/(static)/forgot/+page.server.ts | 14 | ||||
| -rw-r--r-- | src/routes/(static)/forgot/+page.svelte | 66 | ||||
| -rw-r--r-- | src/routes/(static)/login/+page.svelte | 38 | ||||
| -rw-r--r-- | src/routes/(static)/register/+page.svelte | 50 |
5 files changed, 113 insertions, 92 deletions
diff --git a/src/routes/(static)/docs/+page.svelte b/src/routes/(static)/docs/+page.svelte index 80052805..f4e2ffb9 100644 --- a/src/routes/(static)/docs/+page.svelte +++ b/src/routes/(static)/docs/+page.svelte @@ -18,12 +18,17 @@ : `export token=<your auth token>`; </script> +{#snippet cp(something)} + <button type="button" class="ml-auto" onclick={() => copy(something)}> + <iconify-icon icon="ph:copy-bold" width="42"></iconify-icon> + </button> +{/snippet} + <div class="space-y-8 lg:text-xl mt-20 pt-20 md:pt-0 w-full max-w-full"> <h1 class="text-4xl">Documentation</h1> <p class="text-secondary"> - Coinos is free and open source software. The code is - available at <a + Coinos is free and open source software. The code is available at <a href="https://github.com/coinos" class="text-secondary underline">github.com/coinos</a > @@ -31,19 +36,18 @@ <p class="text-secondary"> Coinos has a REST API that can be used to register accounts and make - payments. The following examples show how you can call the API - with <a href="https://curl.se/" class="text-secondary underline">curl</a> + payments. The following examples show how you can call the API with <a + href="https://curl.se/" + class="text-secondary underline">curl</a + > </p> <h2 class="text-2xl">API Base URL</h2> - <div class="bg-primary text-primary-content rounded-lg p-4 flex gap-4 items-center"> + <div + class="bg-primary text-primary-content rounded-lg p-4 flex gap-4 items-center" + > <div>{api}</div> - <iconify-icon - icon="ph:copy-bold" - onclick={() => copy(api)} - width="42" - class="ml-auto cursor-pointer" - ></iconify-icon> + {@render cp(api)} </div> <h2 class="text-2xl">Auth Token</h2> @@ -58,14 +62,11 @@ Save it in a variable called <b>$token</b> to run the examples. </p> - <div class="bg-primary text-primary-content rounded-lg p-4 flex gap-4 items-center"> + <div + class="bg-primary text-primary-content rounded-lg p-4 flex gap-4 items-center" + > <div class="w-full break-all">{tokenSample}</div> - <iconify-icon - icon="ph:copy-bold" - onclick={() => copy(tokenSample)} - width="42" - class="ml-auto cursor-pointer" - ></iconify-icon> + {@render cp(tokenSample)} </div> <h2 class="text-2xl">POST /register</h2> diff --git a/src/routes/(static)/forgot/+page.server.ts b/src/routes/(static)/forgot/+page.server.ts new file mode 100644 index 00000000..55169a5e --- /dev/null +++ b/src/routes/(static)/forgot/+page.server.ts @@ -0,0 +1,14 @@ +import { fail } from "@sveltejs/kit"; +import { fd, post } from "$lib/utils"; + +export const actions = { + default: async ({ request }) => { + try { + const { email } = await fd(request); + await post("/forgot", { email }); + return { success: true }; + } catch (e: any) { + return fail(400, { error: e.message }); + } + }, +}; diff --git a/src/routes/(static)/forgot/+page.svelte b/src/routes/(static)/forgot/+page.svelte new file mode 100644 index 00000000..45180543 --- /dev/null +++ b/src/routes/(static)/forgot/+page.svelte @@ -0,0 +1,66 @@ +<script> + import { focus } from "$lib/utils"; + import { enhance } from "$app/forms"; + import { t } from "$lib/translations"; + import Icon from "$comp/Icon.svelte"; + import Spinner from "$comp/Spinner.svelte"; + import { fly } from "svelte/transition"; + + let { form } = $props(); + let email = $state(); + let loading; +</script> + +<div + class="mx-auto md:shadow-xl rounded-3xl max-w-xl w-full md:w-[480px] md:p-8 mb-20 space-y-5" +> + <h1 class="text-2xl font-bold text-center">{$t("login.reset")}</h1> + + {#if form?.error} + <div class="text-red-600 text-center" in:fly> + {form.error} + </div> + {/if} + + {#if form?.success} + <div class="text-secondary"> + {$t("login.resetSent")} + </div> + + <div class="flex w-full"> + <a href="/login" class="btn"> + {$t("login.continue")} + </a> + </div> + {:else} + <form class="space-y-5" method="POST" use:enhance> + <div> + <input + placeholder={$t("login.email")} + name="email" + type="text" + required + class="bg-primary" + bind:value={email} + use:focus + autocapitalize="none" + /> + </div> + + <div class="text-secondary"> + {$t("login.resetDesc")} + <a href="mailto:[email protected]" class="font-bold" + >[email protected]</a + > + </div> + + <button type="submit" class="btn" disabled={loading}> + {#if loading} + <Spinner /> + {:else} + {$t("login.submit")} + {/if} + </button> + </form> + {/if} +</div> diff --git a/src/routes/(static)/login/+page.svelte b/src/routes/(static)/login/+page.svelte index 2b36dcfe..5caf48fb 100644 --- a/src/routes/(static)/login/+page.svelte +++ b/src/routes/(static)/login/+page.svelte @@ -8,6 +8,7 @@ import { fly } from "svelte/transition"; import { enhance } from "$app/forms"; import Pinpad from "$comp/Pinpad.svelte"; + import PasswordInput from "$comp/PasswordInput.svelte"; import { focus, fail } from "$lib/utils"; import { password, pin, loginRedirect } from "$lib/store"; import { t } from "$lib/translations"; @@ -105,38 +106,7 @@ placeholder={$t("login.username")} /> - <label - for="password" - class="input flex items-center justify-center gap-2 w-full" - > - {#if revealPassword} - <input - class="clean" - name="password" - type="text" - required - bind:value={$password} - autocapitalize="none" - placeholder={$t("login.password")} - /> - {:else} - <input - class="clean" - name="password" - type="password" - required - bind:value={$password} - autocapitalize="none" - placeholder={$t("login.password")} - /> - {/if} - <iconify-icon - class="cursor-pointer ml-auto" - onclick={() => (revealPassword = !revealPassword)} - icon={revealPassword ? "ph:eye-bold" : "ph:eye-slash-bold"} - width="32" - ></iconify-icon> - </label> + <PasswordInput bind:value={$password} placeholder={$t("login.password")} /> <div class="flex justify-end items-center"> <a href="/forgot" class="underline underline-offset-4 text-secondary" @@ -164,11 +134,13 @@ <div class="fixed bg-base-100 bg-opacity-90 inset-0 h-full w-full z-50 cursor-default" onclick={(e) => e.stopPropagation()} + role="dialog" + aria-labelledby="title" > <div class="mx-auto p-5 border shadow-lg rounded-md bg-base-100 space-y-5 max-w-lg" > - <h1 class="text-center text-2xl font-semibold">2FA</h1> + <h1 id="title" class="text-center text-2xl font-semibold">2FA</h1> <Pinpad bind:v={token} {cancel} /> <div class="w-full flex"> diff --git a/src/routes/(static)/register/+page.svelte b/src/routes/(static)/register/+page.svelte index 8a2a5015..147c361e 100644 --- a/src/routes/(static)/register/+page.svelte +++ b/src/routes/(static)/register/+page.svelte @@ -9,6 +9,7 @@ import Pin from "$comp/Pin.svelte"; import Spinner from "$comp/Spinner.svelte"; + import PasswordInput from "$comp/PasswordInput.svelte"; import { focus, fail } from "$lib/utils"; import { avatar, password, loginRedirect } from "$lib/store"; @@ -27,6 +28,7 @@ let username = $state(); let { index } = $state(data); + let revealPassword = $state(false); let cleared; let clear = () => { @@ -40,6 +42,8 @@ let refresh = async (e) => { e.preventDefault(); + cleared = false; + username = uniqueNamesGenerator({ dictionaries: [animals, NumberDictionary.generate({ min: 10, max: 99 })], length: 2, @@ -73,8 +77,6 @@ let email, btn = $state(); - let revealPassword = $state(); - let loading = $state(); async function handleSubmit(e) { e.preventDefault(); @@ -245,45 +247,11 @@ > </label> - <label - for="password" - class="input flex items-center justify-center gap-2 w-full" - > - {#if revealPassword} - <input - class="clean" - name="password" - type="text" - required - bind:value={$password} - autocapitalize="none" - placeholder={$t("login.password")} - /> - {:else} - <input - class="clean" - name="password" - type="password" - required - bind:value={$password} - autocapitalize="none" - onfocus={clear} - placeholder={$t("login.password")} - /> - {/if} - <button - type="button" - tabindex="-1" - onclick={() => (revealPassword = !revealPassword)} - class="contents" - aria-label="Toggle" - > - <iconify-icon - icon={revealPassword ? "ph:eye-bold" : "ph:eye-slash-bold"} - width="32" - ></iconify-icon></button - > - </label> + <PasswordInput + bind:value={$password} + placeholder={$t("login.password")} + bind:show={revealPassword} + /> <button type="submit" class="btn" disabled={loading} bind:this={btn}> {#if loading} |
