diff options
| author | Adam Soltys <[email protected]> | 2024-11-07 21:16:25 -0800 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2024-11-08 09:27:40 -0800 |
| commit | 32fcc461cd43c8907df5e306d520bb671307eab1 (patch) | |
| tree | 0253780c569998b6c1a5f43026586e94916c3fee /src/routes/(app)/settings | |
| parent | be5aa52cea1d57c875cfb22d25c6a866b8de2239 (diff) | |
| download | coinos-ui-32fcc461cd43c8907df5e306d520bb671307eab1.tar.gz coinos-ui-32fcc461cd43c8907df5e306d520bb671307eab1.zip | |
svelte 5
Diffstat (limited to 'src/routes/(app)/settings')
| -rw-r--r-- | src/routes/(app)/settings/[...tab]/+page.svelte | 53 | ||||
| -rw-r--r-- | src/routes/(app)/settings/[...tab]/_account.svelte | 50 | ||||
| -rw-r--r-- | src/routes/(app)/settings/[...tab]/_pos.svelte | 41 | ||||
| -rw-r--r-- | src/routes/(app)/settings/[...tab]/_security.svelte | 87 | ||||
| -rw-r--r-- | src/routes/(app)/settings/[...tab]/_shopify.svelte | 20 |
5 files changed, 144 insertions, 107 deletions
diff --git a/src/routes/(app)/settings/[...tab]/+page.svelte b/src/routes/(app)/settings/[...tab]/+page.svelte index d2da3722..5b9e048d 100644 --- a/src/routes/(app)/settings/[...tab]/+page.svelte +++ b/src/routes/(app)/settings/[...tab]/+page.svelte @@ -1,4 +1,6 @@ <script> + import { run, preventDefault } from 'svelte/legacy'; + import { browser } from "$app/environment"; import { onMount, tick } from "svelte"; import { fly } from "svelte/transition"; @@ -22,24 +24,20 @@ import { PUBLIC_COINOS_URL } from "$env/static/public"; - export let data; - export let form; + let { data, form } = $props(); - let submit; - let formElement; + let submit = $state(); + let formElement = $state(); - let { user, token, rates, tab, cookies, subscriptions } = data; + let { user, token, rates, tab, cookies, subscriptions } = $state(data); let prev; - $: update(data); let update = () => { ({ user, token, rates, tab, subscriptions } = data); prev = { ...user }; }; - $: form?.user && ({ user } = form); - $: form?.success && throttledSuccess(); let justUpdated; let throttledSuccess = () => { @@ -50,12 +48,7 @@ } }; - $: form?.message && fail(form.message); - $: if (form?.message?.startsWith("Pin")) { - fail("Wrong pin, try again"); - $pin = ""; - } let tabs = [ { name: "account", key: "ACCOUNT", comp: Account }, @@ -64,13 +57,10 @@ { name: "shopify", key: "SHOPIFY", comp: Shopify }, ]; - $: ({ comp } = tabs.find((t) => t.name === tab)); let { address, id, username } = user; - let submitting; + let submitting = $state(); - $: if (!$loading && $page.url.searchParams.get("verified")) - success($t("user.settings.verified")); async function handleSubmit() { try { @@ -191,6 +181,31 @@ submitting = false; } + run(() => { + update(data); + }); + run(() => { + form?.user && ({ user } = form); + }); + run(() => { + form?.success && throttledSuccess(); + }); + run(() => { + form?.message && fail(form.message); + }); + run(() => { + if (form?.message?.startsWith("Pin")) { + fail("Wrong pin, try again"); + $pin = ""; + } + }); + let { comp } = $derived(tabs.find((t) => t.name === tab)); + run(() => { + if (!$loading && $page.url.searchParams.get("verified")) + success($t("user.settings.verified")); + }); + + const SvelteComponent = $derived(comp); </script> {#if user.haspin && $pin?.length !== 6} @@ -200,7 +215,7 @@ <form method="POST" class="mb-[154px] settings" - on:submit|preventDefault={handleSubmit} + onsubmit={preventDefault(handleSubmit)} bind:this={formElement} > <input type="hidden" name="pin" value={$pin} /> @@ -229,7 +244,7 @@ </div> </div> - <svelte:component this={comp} {user} {rates} {submit} {subscriptions} /> + <SvelteComponent {user} {rates} {submit} {subscriptions} /> </div> <div diff --git a/src/routes/(app)/settings/[...tab]/_account.svelte b/src/routes/(app)/settings/[...tab]/_account.svelte index 8537322e..54249265 100644 --- a/src/routes/(app)/settings/[...tab]/_account.svelte +++ b/src/routes/(app)/settings/[...tab]/_account.svelte @@ -4,11 +4,11 @@ import { t } from "$lib/translations"; import { page } from "$app/stores"; - export let user, rates, submit; + let { user = $bindable(), rates, submit } = $props(); let { id } = user; - let avatarFile, avatarInput, bannerFile, bannerInput; + let avatarFile, avatarInput = $state(), bannerFile, bannerInput = $state(); let selectAvatar = () => avatarInput.click(); let selectBanner = () => bannerInput.click(); @@ -18,7 +18,7 @@ percent = Math.round((event.loaded / event.total) * 100); }; - let tooLarge = {}; + let tooLarge = $state({}); let handleFile = async ({ target }, type) => { tooLarge[type] = false; @@ -47,9 +47,9 @@ if (!user.display) user.display = user.username; - $: url = `${$page.url.host}/${user.username}`; - $: full = `${$page.url.protocol}//${url}`; - $: addr = `${user.username}@${$page.url.host}`; + let url = $derived(`${$page.url.host}/${user.username}`); + let full = $derived(`${$page.url.protocol}//${url}`); + let addr = $derived(`${user.username}@${$page.url.host}`); </script> <div> @@ -83,13 +83,13 @@ icon="ph:check-bold" class="text-success ml-auto" width="32" - /> +></iconify-icon> {:else if user.email} <iconify-icon icon="ph:clock-bold" class="text-warning ml-auto" width="32" - /> +></iconify-icon> {/if} </label> </div> @@ -101,8 +101,8 @@ {#if $avatar || user.profile} <div class="relative rounded-full overflow-hidden text-center w-20 h-20 my-auto hover:opacity-80 cursor-pointer" - on:click={selectAvatar} - on:keydown={selectAvatar} + onclick={selectAvatar} + onkeydown={selectAvatar} > <img src={$avatar?.src || `/api/public/${user.profile}.webp`} @@ -113,11 +113,11 @@ {:else} <div class="rounded-full border-4 border-white p-4 bg-gradient-to-r from-primary to-gradient w-24 my-auto hover:opacity-80 cursor-pointer" - on:click={selectAvatar} - on:keydown={selectAvatar} + onclick={selectAvatar} + onkeydown={selectAvatar} > <Icon icon="logo-symbol-white" style="mx-auto" /> - <iconify-icon icon="ph:floppy-disk-bold" width="32" /> + <iconify-icon icon="ph:floppy-disk-bold" width="32"></iconify-icon> </div> {/if} <div class="ml-2 p-2"> @@ -125,14 +125,14 @@ <button type="button" class="btn" - on:click={selectAvatar} - on:keydown={selectAvatar}>{$t("user.settings.select")}</button + onclick={selectAvatar} + onkeydown={selectAvatar}>{$t("user.settings.select")}</button > <input type="file" class="hidden" bind:this={avatarInput} - on:change={(e) => handleFile(e, "profile")} + onchange={(e) => handleFile(e, "profile")} /> </div> </div> @@ -151,30 +151,30 @@ <img src={$banner ? $banner.src : `/api/public/${user.banner}.webp`} class="w-full object-cover object-center visible overflow-hidden h-48 mb-4 hover:opacity-80" - on:click={selectBanner} - on:keydown={selectBanner} + onclick={selectBanner} + onkeydown={selectBanner} alt="Banner" /> {:else} <div class="bg-gradient-to-r from-primary to-gradient w-full h-48 mb-4 cursor-pointer hover:opacity-80" - on:click={selectBanner} - on:keydown={selectBanner} + onclick={selectBanner} + onkeydown={selectBanner} alt="Banner" - /> +></div> {/if} <button type="button" class="btn !w-auto" - on:click={selectBanner} - on:keydown={selectBanner}>{$t("user.settings.select")}</button + onclick={selectBanner} + onkeydown={selectBanner}>{$t("user.settings.select")}</button > <input type="file" class="hidden" bind:this={bannerInput} - on:change={(e) => handleFile(e, "banner")} + onchange={(e) => handleFile(e, "banner")} /> {#if tooLarge["banner"]} @@ -191,5 +191,5 @@ name="address" bind:value={user.address} placeholder={$t("user.settings.aboutPlaceholder")} - /> +></textarea> </div> diff --git a/src/routes/(app)/settings/[...tab]/_pos.svelte b/src/routes/(app)/settings/[...tab]/_pos.svelte index f4a01c09..3f68eebc 100644 --- a/src/routes/(app)/settings/[...tab]/_pos.svelte +++ b/src/routes/(app)/settings/[...tab]/_pos.svelte @@ -1,4 +1,6 @@ <script> + import { run } from 'svelte/legacy'; + import { onMount, tick } from "svelte"; import { browser } from "$app/environment"; import Numpad from "$comp/Numpad.svelte"; @@ -9,16 +11,20 @@ import { page } from "$app/stores"; import { PUBLIC_VAPID_PUBKEY } from "$env/static/public"; - export let user, rates, submit, subscriptions; + let { + user = $bindable(), + rates, + submit, + subscriptions + } = $props(); - let { currency } = user; - let rate = rates[currency]; + let { currency } = $state(user); + let rate = $state(rates[currency]); let fiats = Object.keys(rates).sort((a, b) => a.localeCompare(b)); - $: user.language = $locale; let keypress = (e) => e.key === "Enter" && (e.preventDefault() || el.click()); - let editingReserve, editingThreshold, doneReserve, doneThreshold; + let editingReserve = $state(), editingThreshold = $state(), doneReserve = $state(), doneThreshold; let doneEditing = () => { editingReserve = false; editingThreshold = false; @@ -38,9 +44,9 @@ if (!user.threshold) user.threshold = 1000000; if (!user.reserve) user.reserve = 100000; - let reserveEl, thresholdEl; + let reserveEl = $state(), thresholdEl = $state(); - let push, pm, subscription; + let push = $state(), pm, subscription; onMount(async () => { if (!browser) return; @@ -60,8 +66,7 @@ } }); - let permission; - $: updateNotifications(push); + let permission = $state(); let updateNotifications = async (push) => { if (!browser || !pm) return (push = false); @@ -80,6 +85,12 @@ await post("/subscription", { subscription }); } }; + run(() => { + user.language = $locale; + }); + run(() => { + updateNotifications(push); + }); </script> <div> @@ -154,17 +165,17 @@ <textarea name="destination" placeholder={$t("user.settings.destinationPlaceholder")} - on:keypress={keypress} + onkeypress={keypress} class="w-full p-4 border rounded-xl h-48" bind:value={user.destination} - /> +></textarea> </div> <div> <label for="display" class="font-bold mb-1 block" >{$t("user.settings.threshold")}</label > - <button type="button" class="flex w-full" on:click={editThreshold}> + <button type="button" class="flex w-full" onclick={editThreshold}> <div class="p-4 border rounded-2xl rounded-r-none border-r-0 bg-base-200"> ⚡️ </div> @@ -184,7 +195,7 @@ <label for="display" class="font-bold mb-1 block" >{$t("user.settings.reserve")}</label > - <button type="button" class="flex w-full" on:click={editReserve}> + <button type="button" class="flex w-full" onclick={editReserve}> <div class="p-4 border rounded-2xl rounded-r-none border-r-0 bg-base-200"> ⚡️ </div> @@ -220,7 +231,7 @@ <button bind:this={doneReserve} type="button" - on:click={doneEditing} + onclick={doneEditing} class="btn">Ok</button > </div> @@ -247,7 +258,7 @@ <button bind:this={doneReserve} type="button" - on:click={doneEditing} + onclick={doneEditing} class="btn">Ok</button > </div> diff --git a/src/routes/(app)/settings/[...tab]/_security.svelte b/src/routes/(app)/settings/[...tab]/_security.svelte index d67bda37..8bb8a3fa 100644 --- a/src/routes/(app)/settings/[...tab]/_security.svelte +++ b/src/routes/(app)/settings/[...tab]/_security.svelte @@ -1,4 +1,6 @@ <script> + import { run } from 'svelte/legacy'; + import { getMnemonic, getNsec } from "$lib/nostr"; import { tick } from "svelte"; import { t } from "$lib/translations"; @@ -10,26 +12,26 @@ import { invalidate } from "$app/navigation"; import { page } from "$app/stores"; - export let user, rates, submit; + let { user = $bindable(), rates, submit } = $props(); - let confirming2fa, - disabling2fa, - importing, + let confirming2fa = $state(), + disabling2fa = $state(), + importing = $state(), locked, mnemonic, - newNsec, - nsec, + newNsec = $state(), + nsec = $state(), old, - otp, - password, - pin, - revealPassword, + otp = $state(), + password = $state(), + pin = $state(), + revealPassword = $state(), revealSeed, - revealNsec, - token = "", - setting2fa, - settingPin, - verify; + revealNsec = $state(), + token = $state(""), + setting2fa = $state(), + settingPin = $state(), + verify = $state(); let toggleImporting = () => { revealNsec = false; @@ -56,8 +58,6 @@ } }; - $: verifying = pin?.length > 5; - $: verify && checkPin(pin); let checkPin = async () => { old = $current; @@ -88,7 +88,7 @@ return true; }; - let disablingPin = false; + let disablingPin = $state(false); let togglePin = async () => { if (user.haspin) { @@ -129,7 +129,6 @@ disabling2fa = false; }; - $: enable2fa(token); let enable2fa = async (twoFa) => { try { if (setting2fa && token.length === 6) { @@ -143,7 +142,6 @@ } }; - $: disable2fa(token); let disable2fa = async () => { try { if (disabling2fa && token.length === 6) { @@ -157,6 +155,19 @@ fail("Failed to disable 2FA, try again"); } }; + let verifying; + run(() => { + verifying = pin?.length > 5; + }); + run(() => { + verify && checkPin(pin); + }); + run(() => { + enable2fa(token); + }); + run(() => { + disable2fa(token); + }); </script> <input type="hidden" name="newpin" value={disablingPin ? "delete" : pin} /> @@ -173,14 +184,14 @@ {/if} <button type="button" - on:click={togglePassword} - on:keydown={togglePassword} + onclick={togglePassword} + onkeydown={togglePassword} class="absolute right-5 top-11" > <iconify-icon icon={revealPassword ? "ph:eye-bold" : "ph:eye-slash-bold"} width="32" - /> +></iconify-icon> </button> </div> @@ -203,12 +214,12 @@ notify={false} /> {:else} - <button type="button" class="btn" on:click={togglePin} + <button type="button" class="btn" onclick={togglePin} > <iconify-icon icon={user.haspin ? "ph:lock-key-open-bold" : "ph:lock-key-bold"} width="32" - /> +></iconify-icon> {user.haspin ? $t("user.settings.disablePIN") : $t("user.settings.enablePIN")}</button @@ -232,18 +243,18 @@ <b>{otp.secret}</b> </div> - <button type="button" class="btn" on:click={startConfirming2fa}> - <iconify-icon icon="ph:numpad-bold" width="32" /> + <button type="button" class="btn" onclick={startConfirming2fa}> + <iconify-icon icon="ph:numpad-bold" width="32"></iconify-icon> <div class="my-auto">Confirm</div> </button> {:else if user.twofa} - <button type="button" class="btn" on:click={startDisabling2fa}> - <iconify-icon icon="ph:device-mobile-bold" width="32" /> + <button type="button" class="btn" onclick={startDisabling2fa}> + <iconify-icon icon="ph:device-mobile-bold" width="32"></iconify-icon> <div class="my-auto">{$t("user.settings.twofaDisable")}</div> </button> {:else} - <button type="button" class="btn" on:click={startEnabling2fa}> - <iconify-icon icon="ph:device-mobile-bold" width="32" /> + <button type="button" class="btn" onclick={startEnabling2fa}> + <iconify-icon icon="ph:device-mobile-bold" width="32"></iconify-icon> <div class="my-auto">{$t("user.settings.twofaSetup")}</div> </button> {/if} @@ -269,12 +280,12 @@ </p> <div class="flex gap-2"> - <button type="button" class="btn !w-auto flex-grow" on:click={toggleNsec}> + <button type="button" class="btn !w-auto flex-grow" onclick={toggleNsec}> {#if revealNsec} - <iconify-icon icon="ph:eye-slash-bold" width="32" /> + <iconify-icon icon="ph:eye-slash-bold" width="32"></iconify-icon> {$t("user.settings.hideNsec")} {:else} - <iconify-icon icon="ph:warning-bold" width="32" /> + <iconify-icon icon="ph:warning-bold" width="32"></iconify-icon> {$t("user.settings.revealNsec")} {/if} </button> @@ -282,9 +293,9 @@ <button type="button" class="btn !w-auto flex-grow" - on:click={toggleImporting} + onclick={toggleImporting} > - <iconify-icon icon="ph:floppy-disk-bold" width="32" /> + <iconify-icon icon="ph:floppy-disk-bold" width="32"></iconify-icon> {$t("user.settings.import")} </button> </div> @@ -298,8 +309,8 @@ {nsec} </div> - <button type="button" class="btn" on:click={() => copy(nsec)}> - <iconify-icon icon="ph:copy-bold" width="32" /> + <button type="button" class="btn" onclick={() => copy(nsec)}> + <iconify-icon icon="ph:copy-bold" width="32"></iconify-icon> Copy </button> {/if} diff --git a/src/routes/(app)/settings/[...tab]/_shopify.svelte b/src/routes/(app)/settings/[...tab]/_shopify.svelte index 48fe7718..cc746c49 100644 --- a/src/routes/(app)/settings/[...tab]/_shopify.svelte +++ b/src/routes/(app)/settings/[...tab]/_shopify.svelte @@ -3,22 +3,22 @@ import Icon from "$comp/Icon.svelte"; import { page } from "$app/stores"; - export let user; - $: paymentsUrl = - user.shopifyStore && + let { user = $bindable() } = $props(); + let paymentsUrl = + $derived(user.shopifyStore && "https://admin.shopify.com/store/" + user.shopifyStore + - "/settings/payments"; - $: checkoutUrl = - user.shopifyStore && + "/settings/payments"); + let checkoutUrl = + $derived(user.shopifyStore && "https://admin.shopify.com/store/" + user.shopifyStore + - "/settings/checkout"; - $: appsUrl = - user.shopifyStore && + "/settings/checkout"); + let appsUrl = + $derived(user.shopifyStore && "https://admin.shopify.com/store/" + user.shopifyStore + - "/settings/apps/development"; + "/settings/apps/development"); let script = `<script src="${$page.url.protocol}//${$page.url.host}/${user.username}/shopify.js"><\/script>`; </script> |
