diff options
| author | Adam Soltys <[email protected]> | 2024-11-08 15:19:04 -0800 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2024-11-08 15:19:04 -0800 |
| commit | 84fb4b209a2650b2a93f3208ee9a23a44d8283c7 (patch) | |
| tree | 8687566bd8eac12de99439d448773d8ce5dc34b4 /src/routes/(app)/settings/preferences | |
| parent | 32fcc461cd43c8907df5e306d520bb671307eab1 (diff) | |
| download | coinos-ui-84fb4b209a2650b2a93f3208ee9a23a44d8283c7.tar.gz coinos-ui-84fb4b209a2650b2a93f3208ee9a23a44d8283c7.zip | |
svelte 5 fixups
Diffstat (limited to 'src/routes/(app)/settings/preferences')
| -rw-r--r-- | src/routes/(app)/settings/preferences/+page.server.ts | 5 | ||||
| -rw-r--r-- | src/routes/(app)/settings/preferences/+page.svelte | 275 |
2 files changed, 280 insertions, 0 deletions
diff --git a/src/routes/(app)/settings/preferences/+page.server.ts b/src/routes/(app)/settings/preferences/+page.server.ts new file mode 100644 index 00000000..4145935e --- /dev/null +++ b/src/routes/(app)/settings/preferences/+page.server.ts @@ -0,0 +1,5 @@ +import updateUser from "$lib/settings"; + +export const actions = { + default: updateUser, +}; diff --git a/src/routes/(app)/settings/preferences/+page.svelte b/src/routes/(app)/settings/preferences/+page.svelte new file mode 100644 index 00000000..762d25f5 --- /dev/null +++ b/src/routes/(app)/settings/preferences/+page.svelte @@ -0,0 +1,275 @@ +<script> + import { run } from "svelte/legacy"; + + import { onMount, tick } from "svelte"; + import { browser } from "$app/environment"; + import Numpad from "$comp/Numpad.svelte"; + import LocaleSelector from "$comp/LocaleSelector.svelte"; + import Toggle from "$comp/Toggle.svelte"; + import { locale, t } from "$lib/translations"; + import { post, success, fail } from "$lib/utils"; + import { page } from "$app/stores"; + import { PUBLIC_VAPID_PUBKEY } from "$env/static/public"; + + let { data } = $props(); + let user = $derived(data.user); + let rates = $derived(data.rates); + let { currency } = $state(user); + let rate = $state(rates[currency]); + + let fiats = Object.keys(rates).sort((a, b) => a.localeCompare(b)); + let keypress = (e) => e.key === "Enter" && (e.preventDefault() || el.click()); + + let editingReserve = $state(), + editingThreshold = $state(), + doneReserve = $state(), + doneThreshold; + let doneEditing = () => { + editingReserve = false; + editingThreshold = false; + }; + + let editReserve = async () => { + editingReserve = true; + await tick(); + reserveEl.focus(); + }; + + let editThreshold = async () => { + editingThreshold = true; + await tick(); + thresholdEl.focus(); + }; + + if (!user.threshold) user.threshold = 1000000; + if (!user.reserve) user.reserve = 100000; + let reserveEl = $state(), + thresholdEl = $state(); + + let push = $state(), + pm, + subscription; + + onMount(async () => { + if (!browser) return; + + pm = + navigator?.serviceWorker && + (await navigator.serviceWorker.getRegistration()).pushManager; + + permission = await pm.permissionState({ + userVisibleOnly: true, + applicationServerKey: PUBLIC_VAPID_PUBKEY, + }); + + if (permission === "granted") { + subscription = await pm.getSubscription(); + if (subscriptions.includes(JSON.stringify(subscription))) push = true; + } + }); + + let permission = $state(); + let updateNotifications = async (push) => { + if (!browser || !pm) return (push = false); + + if (subscription && !push) { + return post("/subscription/delete", { subscription }); + } + + if (push && permission !== "denied") { + subscription = await pm.subscribe({ + userVisibleOnly: true, + applicationServerKey: PUBLIC_VAPID_PUBKEY, + }); + } + + if (subscription) { + await post("/subscription", { subscription }); + } + }; + run(() => { + user.language = $locale; + }); + run(() => { + updateNotifications(push); + }); +</script> + +<div> + <label for="language" class="font-bold block mb-1" + >{$t("user.settings.locale")}</label + > + <LocaleSelector style="select-styles block py-3 w-full" /> +</div> + +<div> + <label for="currency" class="font-bold block mb-1" + >{$t("user.settings.localCurrency")}</label + > + <select name="currency" value={currency}> + {#each fiats as fiat} + <option value={fiat}>{fiat}</option> + {/each} + </select> +</div> + +<div> + <div class="flex justify-between items-center"> + <span class="font-bold">{$t("user.settings.notifications")}</span> + <Toggle id="notify" bind:value={user.notify} /> + </div> + <p class="text-secondary mt-1 w-9/12"> + {$t("user.settings.notificationsDesc")} + </p> +</div> + +<div> + <div class="flex justify-between items-center"> + <span class="font-bold">{$t("user.settings.pushNotifications")}</span> + {#if permission !== "denied"} + <Toggle id="push" bind:value={push} /> + {/if} + </div> + <p class="text-secondary mt-1 w-9/12"> + {#if permission === "denied"} + {$t("user.settings.pushNotificationsDisabled")} + {:else} + {$t("user.settings.pushNotificationsDesc")} + {/if} + </p> +</div> + +<div> + <div class="flex justify-between items-center"> + <span class="font-bold">{$t("user.settings.tipPrompt")}</span> + <Toggle id="prompt" bind:value={user.prompt} /> + </div> + <p class="text-secondary mt-1 w-9/12"> + {$t("user.settings.tipPromptDescription")} + </p> +</div> + +<div> + <div class="flex justify-between items-center"> + <span class="font-bold">{$t("user.settings.autoWithdraw")}</span> + <Toggle id="autowithdraw" bind:value={user.autowithdraw} /> + </div> + <p class="text-secondary mt-1 w-9/12"> + {$t("user.settings.autoWithdrawDescription")} + </p> +</div> + +{#if user.autowithdraw} + <div class="mb-2"> + <label for="display" class="font-bold mb-1 block" + >{$t("user.settings.destination")}</label + > + <textarea + name="destination" + placeholder={$t("user.settings.destinationPlaceholder")} + 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" onclick={editThreshold}> + <div class="p-4 border rounded-2xl rounded-r-none border-r-0 bg-base-200"> + ⚡️ + </div> + <div + class="border-l-0 rounded-l-none pl-2 w-full p-4 border rounded-2xl text-left" + > + {user.threshold} + </div> + <input type="hidden" name="threshold" bind:value={user.threshold} /> + </button> + <p class="text-secondary mt-1"> + {$t("user.settings.thresholdDesc")} + </p> + </div> + + <div> + <label for="display" class="font-bold mb-1 block" + >{$t("user.settings.reserve")}</label + > + <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> + <div + class="border-l-0 rounded-l-none pl-2 w-full p-4 border rounded-2xl text-left" + > + {user.reserve} + </div> + <input type="hidden" name="reserve" bind:value={user.reserve} /> + </button> + <p class="text-secondary mt-1"> + {$t("user.settings.reserveDesc")} + </p> + </div> +{/if} + +{#if editingThreshold} + <div + class="fixed bg-base-100 bg-opacity-90 inset-0 overflow-y-auto h-full w-full z-50 max-w-lg mx-auto" + > + <div class="relative p-5 border shadow-lg rounded-md bg-base-100 space-y-5"> + <h1 class="text-center text-2xl font-semibold"> + {$t("user.settings.threshold")} + </h1> + <Numpad + bind:amount={user.threshold} + {currency} + bind:rate + bind:submit={doneReserve} + bind:element={thresholdEl} + /> + + <button + bind:this={doneReserve} + type="button" + onclick={doneEditing} + class="btn">Ok</button + > + </div> + </div> +{/if} + +{#if editingReserve} + <div + class="fixed bg-base-100 bg-opacity-90 inset-0 overflow-y-auto h-full w-full z-50 mx-auto max-w-lg" + > + <div + class="relative mx-auto p-5 border shadow-lg rounded-md bg-base-100 space-y-5 text-center" + > + <h1 class="text-2xl font-semibold"> + {$t("user.settings.reserve")} + </h1> + <Numpad + bind:amount={user.reserve} + bind:currency + bind:rate + bind:submit={doneReserve} + bind:element={reserveEl} + /> + <button + bind:this={doneReserve} + type="button" + onclick={doneEditing} + class="btn">Ok</button + > + </div> + </div> +{/if} + +<a href="./shopify" class="block"> + <button type="button" class="btn"> + <img src="/icons/shopify.svg" class="w-8" /> + <div class="my-auto">{$t("user.settings.shopify")}</div> + </button> +</a> |
