aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2022-11-09 09:53:33 -0800
committerAdam Soltys <[email protected]>2022-11-09 09:53:33 -0800
commitccc13974d22a47995b5f9f674891a39d54aa0620 (patch)
tree57ace0c3dbcdcb9e7a4472478068b102406ee99e
parent695d2d6788752cd4f0695686f3acf7ca2099e3a9 (diff)
downloadcoinos-ui-ccc13974d22a47995b5f9f674891a39d54aa0620.tar.gz
coinos-ui-ccc13974d22a47995b5f9f674891a39d54aa0620.zip
refactor settings
-rw-r--r--src/components/Pin.svelte3
-rw-r--r--src/lib/socket.js7
-rw-r--r--src/routes/(app)/[username]/+page.svelte6
-rw-r--r--src/routes/(app)/[username]/settings/+page.svelte104
-rw-r--r--src/routes/(app)/[username]/settings/[...tab]/+page.server.js (renamed from src/routes/(app)/[username]/settings/+page.server.js)8
-rw-r--r--src/routes/(app)/[username]/settings/[...tab]/+page.svelte109
-rw-r--r--src/routes/(app)/[username]/settings/[...tab]/_account.svelte (renamed from src/routes/(app)/[username]/settings/_account.svelte)2
-rw-r--r--src/routes/(app)/[username]/settings/[...tab]/_pos.svelte (renamed from src/routes/(app)/[username]/settings/_pos.svelte)0
-rw-r--r--src/routes/(app)/[username]/settings/[...tab]/_security.svelte (renamed from src/routes/(app)/[username]/settings/_security.svelte)5
-rw-r--r--src/routes/(app)/invoice/[id]/+layout.server.js10
-rw-r--r--src/routes/(app)/invoice/[id]/+page.svelte21
-rw-r--r--src/routes/(app)/invoice/[id]/paid/+page.svelte68
-rw-r--r--src/routes/(app)/invoice/[id]/pending/+page.svelte56
13 files changed, 189 insertions, 210 deletions
diff --git a/src/components/Pin.svelte b/src/components/Pin.svelte
index 2a6bf977..80e003b9 100644
--- a/src/components/Pin.svelte
+++ b/src/components/Pin.svelte
@@ -1,5 +1,6 @@
<script>
import { pin } from '$lib/store';
+
let pinCode = '';
let pinInput;
@@ -9,7 +10,7 @@
<div class="fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full z-20">
<div class="relative top-1/3 mx-auto p-5 border w-96 shadow-lg rounded-md bg-white space-y-5">
<h1 class="text-center text-2xl font-semibold">Please enter your PIN</h1>
- <input bind:value={pinCode} />
+ <input bind:value={pinCode} autofocus />
<div class="w-full flex">
<button
type="submit"
diff --git a/src/lib/socket.js b/src/lib/socket.js
index 6678b979..9b4a8dce 100644
--- a/src/lib/socket.js
+++ b/src/lib/socket.js
@@ -36,11 +36,8 @@ export const messages = (data) => ({
async payment() {
let { amount, invoice } = data;
- if (invoice) {
- invoices.set({ ...get(invoices), [invoice.uuid]: invoice });
- }
-
- if (get(user).account_id !== data.account_id) return;
+ if (invoice) invalidate("app:invoice");
+ if (get(user)?.account_id !== data.account_id) return;
let payments = get(txns);
let i = payments.findIndex((p) => p.id === data.id);
diff --git a/src/routes/(app)/[username]/+page.svelte b/src/routes/(app)/[username]/+page.svelte
index 960cf897..8afb5280 100644
--- a/src/routes/(app)/[username]/+page.svelte
+++ b/src/routes/(app)/[username]/+page.svelte
@@ -59,6 +59,12 @@
>
</a>
{/if}
+
+ <a href={`/${subject.username}/address`}>
+ <button class="rounded-full border py-2 px-5 font-bold hover:opacity-80 w-full mb-2">
+ Bitcoin address
+ </button>
+ </a>
</div>
{/if}
</div>
diff --git a/src/routes/(app)/[username]/settings/+page.svelte b/src/routes/(app)/[username]/settings/+page.svelte
deleted file mode 100644
index 250087c1..00000000
--- a/src/routes/(app)/[username]/settings/+page.svelte
+++ /dev/null
@@ -1,104 +0,0 @@
-<script>
- import { onMount } from 'svelte';
- import { fly } from 'svelte/transition';
- import { enhance } from '$app/forms';
- import Account from './_account.svelte';
- import Pos from './_pos.svelte';
- import Security from './_security.svelte';
-
- import { Icon, Spinner, Pin } from '$comp';
- import { t } from '$lib/translations';
- import { failure, success } from '$lib/utils';
- import { avatarUpload, bannerUpload, pin } from '$lib/store';
- import { upload } from '$lib/upload';
-
- export let data;
- export let form;
-
- let { user, token } = data;
- $: update(data);
- let update = () => ({ user, token } = data);
-
- $: form?.user && ({ user } = form);
-
- $: if (form?.message?.startsWith('Pin')) {
- failure('Wrong pin, try again');
- $pin = '';
- }
-
- let tab = 'account';
-
- let tabs = [
- { name: 'account', key: 'ACCOUNT', comp: Account },
- { name: 'pos', key: 'POINT_OF_SALE', comp: Pos },
- { name: 'security', key: 'SECURITY', comp: Security }
- ];
-
- $: ({ comp } = tabs.find((t) => t.name === tab));
-
- let loading, submit;
- let save = async (msg) => {
- loading = true;
-
- try {
- if ($avatarUpload) {
- await upload($avatarUpload.file, $avatarUpload.type, $avatarUpload.progress, token);
- }
-
- if ($bannerUpload) {
- await upload($bannerUpload.file, $bannerUpload.type, $bannerUpload.progress, token);
- }
- } catch (e) {
- console.log(e);
- failure('Something went wrong');
- }
-
- loading = false;
- };
-
- let loaded;
- onMount(() => setTimeout(() => (loaded = true), 50));
-</script>
-
-{#if loaded && user.haspin && $pin?.length !== 6}
- <Pin />
-{/if}
-
-<form method="POST" class="mb-[154px]" use:enhance on:submit={save}>
- <input type="hidden" name="pin" value={$pin} />
-
- <div class="mt-24 mb-20 px-3 md:px-0 w-full md:w-[400px] mx-auto space-y-8">
- <h1 class="text-center text-3xl md:text-4xl font-semibold mb-10">
- {$t('user.settings.header')}
- </h1>
-
- <div class="font-bold flex justify-between items-center border-b pb-3 text-secondary">
- {#each tabs as { name, key }}
- <button
- class="hover:opacity-80"
- class:text-black={tab === name}
- on:click|preventDefault={() => (tab = name)}>{$t(`user.settings.${key}`)}</button
- >
- {/each}
- </div>
-
- <svelte:component this={comp} {user} {submit} />
- </div>
-
- <div
- class="z-10 fixed bottom-0 bg-white shadow border-t w-full flex justify-center items-center py-3"
- >
- <button
- bind:this={submit}
- type="submit"
- class="border-2 border-black rounded-xl font-semibold mx-auto py-3 w-40 hover:opacity-80"
- class:bg-black={loading}
- >
- {#if loading}
- <Spinner />
- {:else}
- <div class="my-auto">Save Settings</div>
- {/if}
- </button>
- </div>
-</form>
diff --git a/src/routes/(app)/[username]/settings/+page.server.js b/src/routes/(app)/[username]/settings/[...tab]/+page.server.js
index 482b70b1..a6fbd9bf 100644
--- a/src/routes/(app)/[username]/settings/+page.server.js
+++ b/src/routes/(app)/[username]/settings/[...tab]/+page.server.js
@@ -1,5 +1,11 @@
-import { invalid } from '@sveltejs/kit';
+import { invalid, redirect } from '@sveltejs/kit';
import { auth, get, post } from '$lib/utils';
+
+export function load({ params, url }) {
+ if (url.pathname.endsWith('settings')) throw redirect(307, url.pathname + '/account');
+ return params;
+}
+
export const actions = {
default: async ({ cookies, locals, request }) => {
let form = Object.fromEntries(await request.formData());
diff --git a/src/routes/(app)/[username]/settings/[...tab]/+page.svelte b/src/routes/(app)/[username]/settings/[...tab]/+page.svelte
new file mode 100644
index 00000000..20e1fd8f
--- /dev/null
+++ b/src/routes/(app)/[username]/settings/[...tab]/+page.svelte
@@ -0,0 +1,109 @@
+<script>
+ import { onMount } from 'svelte';
+ import { fly } from 'svelte/transition';
+ import { enhance } from '$app/forms';
+
+ import { Icon, Spinner, Pin } from '$comp';
+ import { t } from '$lib/translations';
+ import { failure, success } from '$lib/utils';
+ import { avatarUpload, bannerUpload, pin } from '$lib/store';
+ import { upload } from '$lib/upload';
+ import { page } from '$app/stores';
+
+ import Account from './_account.svelte';
+ import Pos from './_pos.svelte';
+ import Security from './_security.svelte';
+
+ export let data;
+ export let form;
+
+ let submit;
+
+ let { user, token, tab } = data;
+ console.log("TAB", tab)
+
+ $: update(data);
+ let update = () => ({ user, token } = data);
+
+ $: form?.user && ({ user } = form);
+
+ // $: if (form?.message?.startsWith('Pin')) {
+ // failure('Wrong pin, try again');
+ // $pin = '';
+ // }
+
+ let tabs = [
+ { name: 'account', key: 'ACCOUNT', comp: Account },
+ { name: 'pos', key: 'POINT_OF_SALE', comp: Pos },
+ { name: 'security', key: 'SECURITY', comp: Security }
+ ];
+
+ $: ({ comp } = tabs.find((t) => t.name === tab));
+
+ let loading;
+ let save = async (msg) => {
+ loading = true;
+
+ try {
+ if ($avatarUpload) {
+ await upload($avatarUpload.file, $avatarUpload.type, $avatarUpload.progress, token);
+ }
+
+ if ($bannerUpload) {
+ await upload($bannerUpload.file, $bannerUpload.type, $bannerUpload.progress, token);
+ }
+ } catch (e) {
+ console.log(e);
+ failure('Something went wrong');
+ }
+
+ loading = false;
+ };
+
+ let loaded;
+ onMount(() => setTimeout(() => (loaded = true), 50));
+</script>
+
+{#if loaded && user.haspin && $pin?.length !== 6}
+ <Pin />
+{/if}
+
+<form method="POST" class="mb-[154px]" use:enhance on:submit={save}>
+ <input type="hidden" name="pin" value={$pin} />
+
+ <div class="mt-24 mb-20 px-3 md:px-0 w-full md:w-[400px] mx-auto space-y-8">
+ <h1 class="text-center text-3xl md:text-4xl font-semibold mb-10">
+ {$t('user.settings.header')}
+ </h1>
+
+ <div class="font-bold flex justify-between items-center border-b pb-3 text-secondary">
+ {#each tabs as { name, key }}
+ <a href={`/${user.username}/settings/${name}`}>
+ <button class="hover:opacity-80" class:text-black={tab === name}
+ >{$t(`user.settings.${key}`)}</button
+ >
+ </a>
+ {/each}
+ </div>
+
+ <svelte:component this={comp} {user} {submit} />
+ </div>
+
+ <div
+ class="z-10 fixed bottom-0 bg-white shadow border-t w-full flex justify-center items-center py-3"
+ >
+ <button
+ bind:this={submit}
+ type="submit"
+ class="border-2 border-black rounded-xl font-semibold mx-auto py-3 w-40 hover:opacity-80"
+ class:bg-black={loading}
+ >
+ {#if loading}
+ <Spinner />
+ {:else}
+ <div class="my-auto">Save Settings</div>
+ {/if}
+ </button>
+ </div>
+</form>
+
diff --git a/src/routes/(app)/[username]/settings/_account.svelte b/src/routes/(app)/[username]/settings/[...tab]/_account.svelte
index e49205ca..5d5f731f 100644
--- a/src/routes/(app)/[username]/settings/_account.svelte
+++ b/src/routes/(app)/[username]/settings/[...tab]/_account.svelte
@@ -5,7 +5,7 @@
import { t } from '$lib/translations';
import { upload } from '$lib/upload';
- export let user;
+ export let user;
let selectedTheme = 1;
let revealPassword = false;
diff --git a/src/routes/(app)/[username]/settings/_pos.svelte b/src/routes/(app)/[username]/settings/[...tab]/_pos.svelte
index ccbeeff4..ccbeeff4 100644
--- a/src/routes/(app)/[username]/settings/_pos.svelte
+++ b/src/routes/(app)/[username]/settings/[...tab]/_pos.svelte
diff --git a/src/routes/(app)/[username]/settings/_security.svelte b/src/routes/(app)/[username]/settings/[...tab]/_security.svelte
index 4bdb00d4..0f45966d 100644
--- a/src/routes/(app)/[username]/settings/_security.svelte
+++ b/src/routes/(app)/[username]/settings/[...tab]/_security.svelte
@@ -8,7 +8,7 @@
import { invalidate } from '$app/navigation';
import { page } from '$app/stores';
- export let user, submit;
+ export let user, submit;
let settingPin, setting2fa, disabling2fa;
let token = '';
@@ -27,7 +27,7 @@
let otp;
$: pinChange($current);
let pinChange = async (pin) => {
- otp = await post('/otpsecret', { pin });
+ // otp = await post('/otpsecret', { pin });
};
let locked;
@@ -78,6 +78,7 @@
pin = null;
submit.click();
} catch (e) {
+ console.log(e)
failure('Failed to disable pin');
}
} else {
diff --git a/src/routes/(app)/invoice/[id]/+layout.server.js b/src/routes/(app)/invoice/[id]/+layout.server.js
index 4b6cf97e..dacc44e6 100644
--- a/src/routes/(app)/invoice/[id]/+layout.server.js
+++ b/src/routes/(app)/invoice/[id]/+layout.server.js
@@ -1,9 +1,17 @@
import Qr from 'qrcode-base64';
import { get } from '$lib/utils';
+import { redirect } from '@sveltejs/kit';
+
+export async function load({ depends, params, url }) {
+ depends('app:invoice');
-export async function load({ params }) {
let { id } = params;
let invoice = await get(`/invoice?uuid=${id}`);
+ let { amount, received, pending } = invoice;
+
+ let paid = (!amount && (received || pending)) || (amount > 0 && received + pending >= amount);
+ if (paid && !url.pathname.endsWith('paid')) throw redirect(307, `/invoice/${id}/paid`);
+
let sm = Qr.drawImg(invoice.text, { size: 300 });
let lg = Qr.drawImg(invoice.text, { size: 1200 });
diff --git a/src/routes/(app)/invoice/[id]/+page.svelte b/src/routes/(app)/invoice/[id]/+page.svelte
index dec33b62..fadf7270 100644
--- a/src/routes/(app)/invoice/[id]/+page.svelte
+++ b/src/routes/(app)/invoice/[id]/+page.svelte
@@ -1,7 +1,7 @@
<script>
import { send } from '$lib/socket';
import { back, copy, f, get, sat, reverseFormat, s, sats } from '$lib/utils';
- import { onMount, onDestroy } from 'svelte';
+ import { tick, onMount, onDestroy } from 'svelte';
import { browser } from '$app/environment';
import { invoices, last } from '$lib/store';
import { Avatar, Icon, Heart, Image, Qr } from '$comp';
@@ -11,8 +11,6 @@
export let data;
- let showQr;
-
$: refresh(data);
let { invoice, id, user, sm, lg } = data;
let {
@@ -27,6 +25,8 @@
user: { username, currency }
} = invoice;
+ let showQr = !amount;
+
let src = sm;
let qr;
@@ -49,14 +49,6 @@
tipPercent = (tip / amount) * 100;
};
- $invoices[id] = { amount, id, rate, received, text, tip, username };
- $: browser &&
- $invoices[id].amount > 0 &&
- $invoices[id]?.received >= $invoices[id]?.amount &&
- goto(($invoices[id].memo === 'launch' && '/launch/purchase') || `/invoice/${id}/paid`);
-
- $: browser && $invoices[id].pending > 0 && goto(`/invoice/${id}/pending`);
-
$: amountFiat = parseFloat(((amount * rate) / sats).toFixed(2));
$: tipAmount = ((tip * rate) / sats).toFixed(2);
@@ -66,6 +58,7 @@
last.subscribe((v) => {
if (!v || subbed) return;
subbed = true;
+ console.log('SUBBING', invoice.uuid);
send('subscribe', invoice);
});
});
@@ -88,7 +81,7 @@
<div class="container mx-auto max-w-lg px-4 space-y-5">
<div class="w-full flex">
<h1 class="text-secondary block text-2xl flex mx-auto">
- <div class="my-auto">Pay</div>
+ <div class="my-auto">Send to</div>
<div>
<a href="/{username}" class="text-black font-semibold hover:opacity-80 mx-auto">
@@ -107,6 +100,10 @@
<img {src} class:p-4={full} class="w-[300px] mx-auto" bind:this={qr} on:click={toggle} />
</div>
+ {#if address}
+ <div>{address}</div>
+ {/if}
+
<div class="mb-10 flex gap-2 justify-center">
<button
class="flex rounded-full border py-2 px-5 font-bold hover:opacity-80 mb-2"
diff --git a/src/routes/(app)/invoice/[id]/paid/+page.svelte b/src/routes/(app)/invoice/[id]/paid/+page.svelte
index 4f0a8ed1..60bc4592 100644
--- a/src/routes/(app)/invoice/[id]/paid/+page.svelte
+++ b/src/routes/(app)/invoice/[id]/paid/+page.svelte
@@ -9,41 +9,55 @@
import { invoices } from '$lib/store';
export let data;
- let { invoice } = data;
- let { amount, currency, rate, tip } = invoice;
+ let amount, currency, rate, received, pending, tip, user, uuid;
+ $: data && ({ amount, currency, rate, received, pending, tip, user, uuid } = data.invoice);
toast.pop(0);
- $: amountFiat = parseFloat(((amount * rate) / sats).toFixed(2));
+ $: amountFiat = parseFloat(((received * rate) / sats).toFixed(2));
+ $: pendingFiat = parseFloat(((pending * rate) / sats).toFixed(2));
$: tipFiat = parseFloat(((tip * rate) / sats).toFixed(2));
-
- const handleDoneClick = () => {
- delete $invoices[invoice.uuid];
- goto(`/${invoice.user.username}/receive`);
- };
</script>
<div class="container px-4 text-center mx-auto">
<div class="flex w-full py-20 max-w-[200px] mx-auto" in:scale={{ start: 0.5 }}>
<Icon icon="check" style="mx-auto" />
</div>
- <h1 class="text-3xl md:text-4xl font-bold mb-6">{$t('invoice.paymentSuccessful')}</h1>
- <h2 class="text-2xl md:text-3xl font-semibold">
- {f(amountFiat, currency)}
- {#if tip}
- + {f(tipFiat, currency)}
- {/if}
- </h2>
- <h3 class="text-secondary md:text-lg mb-6 mt-1">
- {sat(amount)}
- {#if tip}
- +{sat(tip)}
- {/if}
- </h3>
- <button
- class="bg-black text-white rounded-2xl w-20 py-3 font-bold hover:opacity-80"
- on:click={handleDoneClick}
- >
- {$t('invoice.done')}
- </button>
+ {#if received}
+ <h1 class="text-3xl md:text-4xl font-bold mb-6">{$t('invoice.paymentSuccessful')}</h1>
+ <h2 class="text-2xl md:text-3xl font-semibold">
+ {f(amountFiat, currency)}
+ {#if tip}
+ + {f(tipFiat, currency)}
+ {/if}
+ </h2>
+ <h3 class="text-secondary md:text-lg mb-6 mt-1">
+ {sat(received)}
+ {#if tip}
+ +{sat(tip)}
+ {/if}
+ </h3>
+ {/if}
+
+ {#if pending}
+ <h1 class="text-3xl md:text-4xl font-bold mb-6">Payment detected</h1>
+ <h2 class="text-2xl md:text-3xl font-semibold">
+ {f(pendingFiat, currency)}
+ {#if tip}
+ + {f(tipFiat, currency)}
+ {/if}
+ </h2>
+ <h3 class="text-secondary md:text-lg mb-6 mt-1">
+ {sat(pending)}
+ {#if tip}
+ +{sat(tip)}
+ {/if}
+ </h3>
+ {/if}
+
+ <a href={`/${user.username}/receive`}>
+ <button class="bg-black text-white rounded-2xl w-20 py-3 font-bold hover:opacity-80">
+ {$t('invoice.done')}
+ </button>
+ </a>
</div>
diff --git a/src/routes/(app)/invoice/[id]/pending/+page.svelte b/src/routes/(app)/invoice/[id]/pending/+page.svelte
deleted file mode 100644
index d3970dab..00000000
--- a/src/routes/(app)/invoice/[id]/pending/+page.svelte
+++ /dev/null
@@ -1,56 +0,0 @@
-<script>
- import { scale } from 'svelte/transition';
- import { Icon } from '$comp';
- import { toast } from '@zerodevx/svelte-toast';
- import { browser } from '$app/environment';
- import { t } from '$lib/translations';
- import { f, s, sat, sats } from '$lib/utils';
- import { goto } from '$app/navigation';
- import { invoices } from '$lib/store';
-
- export let data;
- let { invoice } = data;
- let { pending, currency, rate, tip } = invoice;
-
- toast.pop(0);
-
- $: pendingFiat = parseFloat(((pending * rate) / sats).toFixed(2));
- $: tipFiat = parseFloat(((tip * rate) / sats).toFixed(2));
-
- const handleDoneClick = () => {
- delete $invoices[invoice.uuid];
- goto(`/${invoice.user.username}/receive`);
- };
-</script>
-
-<div class="container px-4 text-center mx-auto space-y-5">
- <div class="flex w-full py-20 max-w-[200px] mx-auto" in:scale={{ start: 0.5 }}>
- <Icon icon="check" style="mx-auto" />
- </div>
-
- <h1 class="text-3xl md:text-4xl font-bold">Payment detected</h1>
-
- <div>
- <h2 class="text-2xl md:text-3xl font-semibold">
- {f(pendingFiat, currency)}
- {#if tip}
- + {f(tipFiat, currency)}
- {/if}
- </h2>
- <h3 class="text-secondary md:text-lg mt-1">
- {sat(pending)}
- {#if tip}
- +{sat(tip)}
- {/if}
- </h3>
- </div>
-
- <p class="text-xl text-red-600">Pending confirmation</p>
-
- <button
- class="bg-black text-white rounded-2xl w-20 py-3 font-bold hover:opacity-80"
- on:click={handleDoneClick}
- >
- {$t('invoice.done')}
- </button>
-</div>