aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2024-11-26 20:54:49 -0800
committerAdam Soltys <[email protected]>2024-11-26 20:54:49 -0800
commit872aa0b3b0b9a847b8afcdee7f1ad53c524ce4f0 (patch)
tree4d505c5b7c3f137b56c84cfaca12ed486aa4972c /src
parentf9300236a3c0227e0eec58326fa322e58613bc2d (diff)
downloadcoinos-ui-872aa0b3b0b9a847b8afcdee7f1ad53c524ce4f0.tar.gz
coinos-ui-872aa0b3b0b9a847b8afcdee7f1ad53c524ce4f0.zip
warnings
Diffstat (limited to 'src')
-rw-r--r--src/components/About.svelte22
-rw-r--r--src/components/Footer.svelte2
-rw-r--r--src/components/LandingHeader.svelte12
-rw-r--r--src/components/Lnurlp.svelte16
-rw-r--r--src/components/Lnurlw.svelte7
-rw-r--r--src/components/LocaleSelector.svelte10
-rw-r--r--src/components/LocationsMap.svelte3
-rw-r--r--src/components/PasswordInput.svelte20
-rw-r--r--src/components/Pinpad.svelte18
-rw-r--r--src/routes/(app)/send/invoice/[id]/+page.svelte19
-rw-r--r--src/routes/(app)/sent/[id]/+page.svelte6
-rw-r--r--src/routes/(app)/settings/security/+page.svelte32
-rw-r--r--src/routes/(static)/register/+page.server.ts13
-rw-r--r--src/routes/(static)/register/+page.svelte86
-rw-r--r--src/routes/+layout.svelte2
15 files changed, 123 insertions, 145 deletions
diff --git a/src/components/About.svelte b/src/components/About.svelte
index 5f87e99a..1f02e20d 100644
--- a/src/components/About.svelte
+++ b/src/components/About.svelte
@@ -2,7 +2,6 @@
import { onMount } from "svelte";
import Icon from "$comp/Icon.svelte";
import Image from "$comp/Image.svelte";
- import LocationsMap from "$comp/LocationsMap.svelte";
import { t } from "$lib/translations";
let team = [
@@ -90,18 +89,17 @@
>
{@html $t("about.locations.description")}
</p>
- <!-- <LocationsMap {locations} /> -->
- <a href="/map">
- <div class="relative">
- <img src="/map.png" class="mx-auto" />
+ <div class="relative">
+ <a href="/map" class="contents">
+ <img src="/map.png" class="mx-auto" alt="Map" />
+ </a>
- <button
- class="bg-black text-white border border-4 rounded-full px-6 py-2 font-bold hover:bg-secondary absolute left-1/2 top-1/2 transform -translate-x-1/2 -translate-y-1/2 text-2xl"
- >
- {$t("about.locations.viewMap")}
- </button>
- </div>
- </a>
+ <button
+ class="bg-black text-white border border-4 rounded-full px-6 py-2 font-bold hover:bg-secondary absolute left-1/2 top-1/2 transform -translate-x-1/2 -translate-y-1/2 text-2xl"
+ >
+ {$t("about.locations.viewMap")}
+ </button>
+ </div>
</div>
{/if}
diff --git a/src/components/Footer.svelte b/src/components/Footer.svelte
index 3af5f6a3..dad8aeab 100644
--- a/src/components/Footer.svelte
+++ b/src/components/Footer.svelte
@@ -23,7 +23,7 @@
>
<div class="space-y-5">
<div class="text-center w-full">
- <a href="/">
+ <a href="/" aria-label="Home">
<iconify-icon icon="coinos:logo" width="224"></iconify-icon>
</a>
</div>
diff --git a/src/components/LandingHeader.svelte b/src/components/LandingHeader.svelte
index c20c80a0..f2c94ade 100644
--- a/src/components/LandingHeader.svelte
+++ b/src/components/LandingHeader.svelte
@@ -7,12 +7,7 @@
import DarkToggle from "$comp/DarkToggle.svelte";
import LocaleSelector from "$comp/LocaleSelector.svelte";
- let {
- howItWorks,
- faq,
- about,
- user
- } = $props();
+ let { howItWorks, faq, about, user } = $props();
let showMobileMenu = $state(false);
let header = $state();
@@ -28,7 +23,7 @@
>
<nav class="block lg:flex justify-between items-center">
<div class="flex justify-start lg:justify-center items-center lg:space-x-5">
- <a href="/" onclick={() => scroll(header)}>
+ <a href="/" onclick={() => scroll(header)} aria-label="Home">
<iconify-icon icon="coinos:logo" width="224"></iconify-icon>
</a>
</div>
@@ -74,13 +69,14 @@
</div>
<button
+ aria-label="Menu"
class="block lg:hidden absolute top-[34.5px] right-10 z"
onclick={() => (showMobileMenu = !showMobileMenu)}
>
<iconify-icon
icon={!showMobileMenu ? "ph:list-bold" : "ph:x-bold"}
width="32"
-></iconify-icon>
+ ></iconify-icon>
</button>
<div
diff --git a/src/components/Lnurlp.svelte b/src/components/Lnurlp.svelte
index 74be0571..6f9a2b26 100644
--- a/src/components/Lnurlp.svelte
+++ b/src/components/Lnurlp.svelte
@@ -1,5 +1,5 @@
<script>
- import { run } from 'svelte/legacy';
+ import { run } from "svelte/legacy";
import { t } from "$lib/translations";
import { enhance } from "$app/forms";
@@ -7,20 +7,12 @@
import Spinner from "$comp/Spinner.svelte";
import { pin } from "$lib/store";
- let {
- data,
- form,
- send = $bindable(),
- comment = $bindable()
- } = $props();
+ let { data, form, send = $bindable(), comment = $bindable() } = $props();
let { currency } = data.user;
let { minSendable, maxSendable, commentAllowed, callback, metadata, rates } =
data;
- let rate;
- run(() => {
- rate = rates[currency];
- });
+ let rate = $derived(rates[currency]);
let amount = $state(Math.round(minSendable / 1000)),
loading = $state();
@@ -63,7 +55,7 @@
class="w-full p-4 border rounded-xl h-32 text-xl"
bind:value={comment}
autocapitalize="none"
-></textarea>
+ ></textarea>
{/if}
<div class="flex w-full">
diff --git a/src/components/Lnurlw.svelte b/src/components/Lnurlw.svelte
index 50aa1488..a9b6695a 100644
--- a/src/components/Lnurlw.svelte
+++ b/src/components/Lnurlw.svelte
@@ -1,6 +1,4 @@
<script>
- import { run } from 'svelte/legacy';
-
import { sats, f, s } from "$lib/utils";
import { t } from "$lib/translations";
import { enhance } from "$app/forms";
@@ -19,10 +17,7 @@
callback,
rates,
} = data;
- let rate;
- run(() => {
- rate = rates[currency];
- });
+ let rate = $derived(rates[currency]);
let amount = $state(Math.round(minWithdrawable / 1000)),
loading = $state();
diff --git a/src/components/LocaleSelector.svelte b/src/components/LocaleSelector.svelte
index cb057dbd..e5d1fdec 100644
--- a/src/components/LocaleSelector.svelte
+++ b/src/components/LocaleSelector.svelte
@@ -1,18 +1,16 @@
<script>
- import { run } from 'svelte/legacy';
+ import { run } from "svelte/legacy";
import { t, locale, locales } from "$lib/translations";
let { style } = $props();
-
- let l;
- run(() => {
- l = $locale;
- });
+ let l = $state($locale);
const handleChange = ({ currentTarget }) => {
const { value } = currentTarget;
document.cookie = `lang=${value}; path=/`;
+ console.log("settinglocale", value);
$locale = value;
+ l = value;
};
</script>
diff --git a/src/components/LocationsMap.svelte b/src/components/LocationsMap.svelte
index 36223b75..c47dbf49 100644
--- a/src/components/LocationsMap.svelte
+++ b/src/components/LocationsMap.svelte
@@ -263,6 +263,7 @@
></div>
<div class="absolute flex top-2 left-2 gap-2">
<button
+ aria-label="Back"
class="rounded-full border-2 border-black bg-base-100 w-16 h-16 flex items-center justify-center bg-opacity-80"
onclick={back}
>
@@ -278,7 +279,7 @@
<input bind:value={search} class="w-full" />
<div class="flex gap-1 absolute right-6 top-3">
{#if search}
- <button onclick={clearSearch}>
+ <button type="button" onclick={clearSearch} aria-label="Clear">
<iconify-icon icon="ph:x-bold" width="32"></iconify-icon>
</button>
{:else}
diff --git a/src/components/PasswordInput.svelte b/src/components/PasswordInput.svelte
new file mode 100644
index 00000000..5885304b
--- /dev/null
+++ b/src/components/PasswordInput.svelte
@@ -0,0 +1,20 @@
+<script>
+ let { value = $bindable() } = $props();
+ let toggle = (e) => (show = !show);
+ let show = $state(false);
+ let icon = $derived(show ? "ph:eye-bold" : "ph:eye-slash-bold");
+</script>
+
+<label
+ for="password"
+ class="input flex items-center justify-center gap-2 w-full"
+>
+ {#if show}
+ <input name="password" type="text" bind:value class="clean" />
+ {:else}
+ <input name="password" type="password" bind:value class="clean" />
+ {/if}
+ <button type="button" aria-label="Toggle" onclick={toggle} class="contents">
+ <iconify-icon {icon} width="32"></iconify-icon>
+ </button>
+</label>
diff --git a/src/components/Pinpad.svelte b/src/components/Pinpad.svelte
index 8f0fc3c2..0efdd471 100644
--- a/src/components/Pinpad.svelte
+++ b/src/components/Pinpad.svelte
@@ -1,6 +1,4 @@
<script>
- import { preventDefault, stopPropagation } from "svelte/legacy";
-
import Left from "$comp/Left.svelte";
import Icon from "$comp/Icon.svelte";
import { focus, post, warning } from "$lib/utils";
@@ -38,6 +36,12 @@
};
let hide = $state(true);
+
+ let toggle = (e) => {
+ e.preventDefault();
+ e.stopPropagation();
+ hide = !hide;
+ };
</script>
<label
@@ -62,12 +66,10 @@
pattern="[0-9]+"
/>
{/if}
- <iconify-icon
- icon={hide ? "ph:eye-slash-bold" : "ph:eye-bold"}
- width="32"
- onclick={stopPropagation(preventDefault(() => (hide = !hide)))}
- class="cursor-pointer"
- ></iconify-icon>
+ <button type="button" class="contents" onclick={toggle}>
+ <iconify-icon icon={hide ? "ph:eye-slash-bold" : "ph:eye-bold"} width="32"
+ ></iconify-icon></button
+ >
</label>
<div class="grid grid-cols-3 gap-2 w-[300px] mx-auto grayscale">
diff --git a/src/routes/(app)/send/invoice/[id]/+page.svelte b/src/routes/(app)/send/invoice/[id]/+page.svelte
index d2b3727c..f0811f2e 100644
--- a/src/routes/(app)/send/invoice/[id]/+page.svelte
+++ b/src/routes/(app)/send/invoice/[id]/+page.svelte
@@ -13,32 +13,23 @@
import Numpad from "$comp/Numpad.svelte";
import Spinner from "$comp/Spinner.svelte";
import { page } from "$app/stores";
- import {
- btc,
- sat,
- post,
- back,
- f,
- toFiat,
- s,
- sats,
- focus,
- } from "$lib/utils";
+ import { btc, sat, post, back, f, toFiat, s, sats, focus } from "$lib/utils";
let { data, form } = $props();
let { invoice, rates, user } = $state(data);
let { address, hash, payreq, user: recipient, tip } = $state(invoice);
let { currency } = $state(user);
+ let { amount } = $state(form || invoice);
- let amount = $state(form?.amount || invoice.amount);
let rate = $derived(
invoice.rate * (rates[user.currency] / rates[invoice.currency]),
);
+
let a = $state(),
af = $state(),
- fiat = $state(!amount);
+ fiat = $state(untrack(() => !amount));
- let amountFiat = $state(amount * (rate / sats));
+ let amountFiat = $state((untrack(() => amount) * untrack(() => rate)) / sats);
let setAmount = () => {
amount = a;
amountFiat = af;
diff --git a/src/routes/(app)/sent/[id]/+page.svelte b/src/routes/(app)/sent/[id]/+page.svelte
index 2eb1f18b..d973d35d 100644
--- a/src/routes/(app)/sent/[id]/+page.svelte
+++ b/src/routes/(app)/sent/[id]/+page.svelte
@@ -4,13 +4,13 @@
import Success from "$comp/Success.svelte";
let { data } = $props();
- let { amount, rate, tip, user } = $state(data);
+ let { rate, tip, user } = $state(data);
let { currency, username } = user;
- amount = Math.abs(amount);
+ let amount = $state(Math.abs(data.amount));
</script>
<Success {amount} {rate} {tip} {currency} title={`${$t("payments.sent")}!`} />
-<a href={`/${username}`} use:focus>
+<a href={`/${username}`} use:focus aria-label="Continue">
<div class="opacity-0 w-screen h-screen fixed top-0 left-0 z-50"></div>
</a>
diff --git a/src/routes/(app)/settings/security/+page.svelte b/src/routes/(app)/settings/security/+page.svelte
index cc988d6c..d40439ac 100644
--- a/src/routes/(app)/settings/security/+page.svelte
+++ b/src/routes/(app)/settings/security/+page.svelte
@@ -1,12 +1,11 @@
<script>
import { getContext } from "svelte";
-
import { getMnemonic, getNsec } from "$lib/nostr";
import { tick } from "svelte";
import { t } from "$lib/translations";
import Pin from "$comp/Pin.svelte";
- import Icon from "$comp/Icon.svelte";
import Qr from "$comp/Qr.svelte";
+ import PasswordInput from "$comp/PasswordInput.svelte";
import { copy, post, success, fail } from "$lib/utils";
import { save, pin as current } from "$lib/store";
import { invalidate } from "$app/navigation";
@@ -48,7 +47,6 @@
}
};
- let togglePassword = () => (revealPassword = !revealPassword);
let toggleSeed = async () => {
try {
mnemonic = await getMnemonic(user);
@@ -168,26 +166,8 @@
<label for="password" class="block font-bold block mb-1"
>{$t("user.settings.newPassword")}</label
>
- <label
- for="password"
- class="input flex items-center justify-center gap-2 w-full"
- >
- {#if revealPassword}
- <input name="password" type="text" bind:value={password} class="clean" />
- {:else}
- <input
- name="password"
- type="password"
- bind:value={password}
- class="clean"
- />
- {/if}
- <iconify-icon
- onclick={togglePassword}
- icon={revealPassword ? "ph:eye-bold" : "ph:eye-slash-bold"}
- width="32"
- ></iconify-icon>
- </label>
+
+ <PasswordInput bind:value={password} />
</div>
<div>
@@ -299,7 +279,11 @@
{/if}
{#if revealNsec}
- <button type="button" class="btn break-all !h-auto font-normal leading-normal flex-nowrap" onclick={() => copy(nsec)}>
+ <button
+ type="button"
+ class="btn break-all !h-auto font-normal leading-normal flex-nowrap"
+ onclick={() => copy(nsec)}
+ >
<div>{nsec}</div>
<iconify-icon icon="ph:copy-bold" width="32"></iconify-icon>
diff --git a/src/routes/(static)/register/+page.server.ts b/src/routes/(static)/register/+page.server.ts
index 2dffef01..1781602f 100644
--- a/src/routes/(static)/register/+page.server.ts
+++ b/src/routes/(static)/register/+page.server.ts
@@ -1,5 +1,5 @@
+import { fd, login, post } from "$lib/utils";
import { fail, redirect } from "@sveltejs/kit";
-import { fd, post, login } from "$lib/utils";
export const load = async ({ parent }) => {
const { user } = await parent();
@@ -24,18 +24,19 @@ export const actions = {
try {
await post("/register", { user }, { "cf-connecting-ip": ip });
- } catch (e: any) {
- error = e.message;
+ } catch (e) {
+ ({ message: error } = e as Error);
}
try {
await login(user, cookies, ip);
error = null;
- } catch (e: any) {
- error ||= e.message;
+ } catch (e) {
+ const { message } = e as Error;
+ error ||= message;
}
if (error) return fail(400, { error });
- redirect(307, loginRedirect || `/${user.username}`);
+ redirect(303, loginRedirect || `/${user.username}`);
},
};
diff --git a/src/routes/(static)/register/+page.svelte b/src/routes/(static)/register/+page.svelte
index c179552c..8a2a5015 100644
--- a/src/routes/(static)/register/+page.svelte
+++ b/src/routes/(static)/register/+page.svelte
@@ -1,6 +1,4 @@
<script>
- import { run, preventDefault } from 'svelte/legacy';
-
import punks from "$lib/punks";
import { upload } from "$lib/upload";
import { afterNavigate, invalidateAll } from "$app/navigation";
@@ -40,7 +38,8 @@
}
};
- let refresh = async () => {
+ let refresh = async (e) => {
+ e.preventDefault();
username = uniqueNamesGenerator({
dictionaries: [animals, NumberDictionary.generate({ min: 10, max: 99 })],
length: 2,
@@ -64,27 +63,27 @@
}
});
- let token = $state(), formElement;
+ let token = $state(),
+ formElement;
let code = [];
let redirect;
let cancel = () => (need2fa = false);
- let email, btn = $state();
-
- let update = (form) => form && ({ username, password: $password } = form);
-
+ let email,
+ btn = $state();
let revealPassword = $state();
let loading = $state();
async function handleSubmit(e) {
+ e.preventDefault();
+
loading = true;
let data = new FormData(this);
let user = Object.fromEntries(data);
- console.log("USER", JSON.stringify(user));
await generate(user);
for (let k in user) {
@@ -144,26 +143,17 @@
reader.readAsDataURL(file);
};
- run(() => {
- data && ($avatar = undefined);
- });
- let need2fa;
- run(() => {
- need2fa = form?.message === "2fa";
- });
- run(() => {
- if (form?.message === "2fa" && form.token === token) token = "";
- });
- run(() => {
- update(form);
+
+ let need2fa = $derived(form?.message === "2fa");
+ let src = $derived(`/api/public/${punks[index]}.webp`);
+
+ $effect(() => {
+ if (need2fa && form.token === token) token = "";
});
- run(() => {
+
+ $effect(() => {
token && token?.length === 6 && tick().then(() => btn.click());
});
- let src;
- run(() => {
- src = `/api/public/${punks[index]}.webp`;
- });
</script>
{#if need2fa}
@@ -185,11 +175,12 @@
<button
class="absolute w-8 h-12 left-12 bg-base-100 rounded top-12"
onclick={decr}
+ aria-label="Previous"
>
<iconify-icon icon="ph:caret-left-bold" width="32"></iconify-icon>
</button>
- <div class="block relative w-32 mx-auto" onclick={selectAvatar}>
- <button
+ <button class="block relative w-32 mx-auto" onclick={selectAvatar}>
+ <div
class="w-32 h-32 rounded-full border-4 border-white overflow-hidden flex mx-auto relative"
>
<img
@@ -197,16 +188,17 @@
class="w-full h-full object-cover object-center overflow-hidden"
alt={username}
/>
- </button>
- <button
+ </div>
+ <div
class="absolute bg-base-100 rounded-full p-2 mx-auto right-0 bottom-0 z-10 w-12"
>
<iconify-icon icon="ph:upload-simple-bold" width="24"></iconify-icon>
- </button>
- </div>
+ </div>
+ </button>
<button
class="absolute w-8 h-12 right-12 bg-base-100 rounded top-12"
onclick={incr}
+ aria-label="Next"
>
<iconify-icon icon="ph:caret-right-bold" width="32"></iconify-icon>
</button>
@@ -218,7 +210,7 @@
</div>
{/if}
- <form class="space-y-5" onsubmit={preventDefault(handleSubmit)} method="POST">
+ <form class="space-y-5" onsubmit={handleSubmit} method="POST">
<input
type="hidden"
name="loginRedirect"
@@ -241,13 +233,16 @@
autocapitalize="none"
placeholder={$t("login.username")}
/>
- <iconify-icon
- class="cursor-pointer"
+ <button
+ type="button"
tabindex="-1"
onclick={refresh}
- icon="ph:dice-three-bold"
- width="32"
-></iconify-icon>
+ aria-label="Randomize"
+ class="contents"
+ >
+ <iconify-icon icon="ph:dice-three-bold" width="32"
+ ></iconify-icon></button
+ >
</label>
<label
@@ -276,13 +271,18 @@
placeholder={$t("login.password")}
/>
{/if}
- <iconify-icon
+ <button
+ type="button"
tabindex="-1"
- class="cursor-pointer"
onclick={() => (revealPassword = !revealPassword)}
- icon={revealPassword ? "ph:eye-bold" : "ph:eye-slash-bold"}
- width="32"
-></iconify-icon>
+ class="contents"
+ aria-label="Toggle"
+ >
+ <iconify-icon
+ icon={revealPassword ? "ph:eye-bold" : "ph:eye-slash-bold"}
+ width="32"
+ ></iconify-icon></button
+ >
</label>
<button type="submit" class="btn" disabled={loading} bind:this={btn}>
diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte
index e7baa137..7cb90195 100644
--- a/src/routes/+layout.svelte
+++ b/src/routes/+layout.svelte
@@ -10,7 +10,7 @@
let { data, children } = $props();
let { pathname, theme } = $state(data);
- $themeStore = theme;
+ $themeStore = data.theme;
$effect(() => (theme = $themeStore));
let host = PUBLIC_DOMAIN.includes("localhost")