diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/socket.js | 13 | ||||
| -rw-r--r-- | src/lib/store.js | 1 | ||||
| -rw-r--r-- | src/routes/(app)/[username]/address/+page.server.js | 13 | ||||
| -rw-r--r-- | src/routes/(app)/[username]/address/+page.svelte (renamed from src/routes/(app)/[username]/bitcoin/+page.svelte) | 0 | ||||
| -rw-r--r-- | src/routes/(app)/[username]/bitcoin/+page.server.js | 4 | ||||
| -rw-r--r-- | src/routes/(app)/[username]/dashboard/+page.svelte | 28 | ||||
| -rw-r--r-- | src/routes/(app)/[username]/receive/[...recipient]/+page.svelte | 2 | ||||
| -rw-r--r-- | src/routes/(app)/[username]/transactions/[...page]/+page.svelte | 96 | ||||
| -rw-r--r-- | src/routes/(app)/invoice/[id]/+page.svelte | 37 | ||||
| -rw-r--r-- | src/routes/(app)/invoice/[id]/pending/+page.svelte | 56 |
10 files changed, 166 insertions, 84 deletions
diff --git a/src/lib/socket.js b/src/lib/socket.js index 079c8f96..6678b979 100644 --- a/src/lib/socket.js +++ b/src/lib/socket.js @@ -1,7 +1,8 @@ import { get } from 'svelte/store'; -import { invoices, invoice, request, newPayment, last, rate, user } from '$lib/store'; +import { invoices, invoice, request, newPayment, last, rate, txns, user } from '$lib/store'; import { success, sat } from '$lib/utils'; import { env } from '$env/dynamic/public'; +import { invalidate } from '$app/navigation'; const socketUrl = env.PUBLIC_SOCKET; const btc = env.PUBLIC_BTC; @@ -41,9 +42,15 @@ export const messages = (data) => ({ if (get(user).account_id !== data.account_id) return; - newPayment.set(true); + let payments = get(txns); + let i = payments.findIndex((p) => p.id === data.id); + if (~i) (payments[i] = data), txns.set(payments); + else newPayment.set(true); + + invalidate((url) => url.pathname === '/payments'); + if (amount > 0) { - success(`Received ${sat(amount)}!`); + success(`${data.confirmed ? 'Received' : 'Detected'} ${sat(amount)}!`); } else { success(`Sent ${sat(amount)}!`); } diff --git a/src/lib/store.js b/src/lib/store.js index 3faa234b..3105419c 100644 --- a/src/lib/store.js +++ b/src/lib/store.js @@ -46,3 +46,4 @@ export const pin = persistSession('pin', undefined, 5 * 60 * 1000); export const last = writable(); export const request = writable(); export const invoice = writable(); +export const txns = persistLocal('transactions', []); diff --git a/src/routes/(app)/[username]/address/+page.server.js b/src/routes/(app)/[username]/address/+page.server.js new file mode 100644 index 00000000..c18bcdba --- /dev/null +++ b/src/routes/(app)/[username]/address/+page.server.js @@ -0,0 +1,13 @@ +import { auth, get, post } from '$lib/utils'; +import { redirect } from '@sveltejs/kit'; + +export async function load({ cookies, params, parent }) { + let user = (await parent()).subject; + let rates = await get('/rates'); + let invoice = { + network: 'bitcoin', + rate: rates[user.currency] + }; + let { uuid } = await post('/invoice', { invoice, user }, auth(cookies)); + throw redirect(307, `/invoice/${uuid}`); +} diff --git a/src/routes/(app)/[username]/bitcoin/+page.svelte b/src/routes/(app)/[username]/address/+page.svelte index e69de29b..e69de29b 100644 --- a/src/routes/(app)/[username]/bitcoin/+page.svelte +++ b/src/routes/(app)/[username]/address/+page.svelte diff --git a/src/routes/(app)/[username]/bitcoin/+page.server.js b/src/routes/(app)/[username]/bitcoin/+page.server.js deleted file mode 100644 index 7ef65346..00000000 --- a/src/routes/(app)/[username]/bitcoin/+page.server.js +++ /dev/null @@ -1,4 +0,0 @@ -import { redirect } from '@sveltejs/kit'; -export async function load({ params }) { - throw redirect(303, `/${params.username}`); -} diff --git a/src/routes/(app)/[username]/dashboard/+page.svelte b/src/routes/(app)/[username]/dashboard/+page.svelte index 93fac986..0ea0e0a8 100644 --- a/src/routes/(app)/[username]/dashboard/+page.svelte +++ b/src/routes/(app)/[username]/dashboard/+page.svelte @@ -52,23 +52,25 @@ </div> <div class="grid sm:grid-cols-2 gap-2 mt-8"> + <a href="/send"> + <button class="rounded-full border py-2 px-5 font-bold hover:opacity-80 w-full mb-2" + >{$t('user.dashboard.withdraw')}</button + > + </a> <a href={`/${user.username}/receive`}> <button class="rounded-full border py-2 px-5 font-bold hover:opacity-80 w-full mb-2" >{$t('user.dashboard.receive')}</button > </a> - {#if user.account.balance > 0} - <a href="/send"> - <button class="rounded-full border py-2 px-5 font-bold hover:opacity-80 w-full mb-2" - >{$t('user.dashboard.withdraw')}</button - > - </a> - {:else} - <a href={`/${user.username}/settings`}> - <button class="rounded-full border py-2 px-5 font-bold hover:opacity-80 w-full mb-2" - >Setup Account</button - > - </a> - {/if} + <a href={`/${user.username}/settings`}> + <button class="rounded-full border py-2 px-5 font-bold hover:opacity-80 w-full mb-2" + >Setup Account</button + > + </a> + <a href={`/${user.username}/address`}> + <button class="rounded-full border py-2 px-5 font-bold hover:opacity-80 w-full mb-2" + >Deposit</button + > + </a> </div> </div> diff --git a/src/routes/(app)/[username]/receive/[...recipient]/+page.svelte b/src/routes/(app)/[username]/receive/[...recipient]/+page.svelte index 634b091a..41958cd0 100644 --- a/src/routes/(app)/[username]/receive/[...recipient]/+page.svelte +++ b/src/routes/(app)/[username]/receive/[...recipient]/+page.svelte @@ -56,7 +56,7 @@ <input type="hidden" name="amount" value={amount} /> <input type="hidden" name="currency" value={currency} /> <input type="hidden" name="username" value={username} /> - <input type="hidden" name="network" value={network} /> + <input type="hidden" name="network" value={network} /> {#if req} <input type="hidden" name="requester" value={req.requester.username} /> diff --git a/src/routes/(app)/[username]/transactions/[...page]/+page.svelte b/src/routes/(app)/[username]/transactions/[...page]/+page.svelte index f5fae1d9..c7007af4 100644 --- a/src/routes/(app)/[username]/transactions/[...page]/+page.svelte +++ b/src/routes/(app)/[username]/transactions/[...page]/+page.svelte @@ -2,7 +2,7 @@ import { Avatar, Icon } from '$comp'; import { onMount } from 'svelte'; import { format, parseISO } from 'date-fns'; - import { newPayment } from '$lib/store'; + import { newPayment, txns } from '$lib/store'; import { t } from '$lib/translations'; import { f, s, sat, sats } from '$lib/utils'; import { page } from '$app/stores'; @@ -31,17 +31,21 @@ pages = []; $: data && ({ page: p, pages, start, end, total, transactions } = data); + $: console.log($txns.length), ($txns = transactions); + $: $page && ($newPayment = false); $: $newPayment && invalidate(`/users/${user.username}`); - $: path = $page.url.pathname.substring(0, $page.url.pathname.lastIndexOf('/')); + $: path = $page.params.page + ? $page.url.pathname.substring(0, $page.url.pathname.lastIndexOf('/')) + : $page.url.pathname; let csv = () => { const keys = ['hash', 'updatedAt', 'rate', 'currency', 'amount', 'fee', 'tip']; const csv = keys.map((k) => `"${k}"`).join(',') + '\n' + - transactions.map((r) => keys.map((k) => `"${r[k]}"`).join(',')).join('\n'); + $txns.map((r) => keys.map((k) => `"${r[k]}"`).join(',')).join('\n'); const filename = 'transactions.csv'; let blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' }); @@ -108,61 +112,59 @@ </div> <div class="space-y-10"> - {#if transactions.length} - {#each transactions as tx} - <div class="grid grid-cols-3 border-b pb-5"> - <div class="whitespace-nowrap"> - <div class="mb-1 font-bold"> - {f(tx.amount * (tx.rate / sats), tx.currency)} + {#each $txns as tx} + <div class="grid grid-cols-3 border-b pb-5"> + <div class="whitespace-nowrap"> + <div class="mb-1 font-bold"> + {f(tx.amount * (tx.rate / sats), tx.currency)} - {#if tx.tip} - <span class="text-sm"> - +{f(tx.tip * (tx.rate / sats), tx.currency)} - </span> - {/if} - </div> + {#if tx.tip} + <span class="text-sm"> + +{f(tx.tip * (tx.rate / sats), tx.currency)} + </span> + {/if} + </div> - <span class="text-secondary" - >{sat(tx.amount)} + <span class="text-secondary" + >{sat(tx.amount)} - {#if tx.tip} - <span class="text-sm"> - +{sat(tx.tip)} - </span> - {/if} - </span> - </div> + {#if tx.tip} + <span class="text-sm"> + +{sat(tx.tip)} + </span> + {/if} + </span> + </div> - <div class="flex"> - {#if tx.with} - <a href={`/${tx.with.username}`} class="mx-auto"> - <div class="flex"> - <div class="my-auto"> - <Avatar user={tx.with} size={12} /> - </div> - <div class="my-auto ml-1 text-secondary">{tx.with.username}</div> + <div class="flex"> + {#if tx.with} + <a href={`/${tx.with.username}`} class="mx-auto"> + <div class="flex"> + <div class="my-auto"> + <Avatar user={tx.with} size={12} /> </div> - </a> - {:else} - <div class="mx-auto text-secondary"> - {tx.amount > 0 ? 'Received' : 'Sent'} + <div class="my-auto ml-1 text-secondary">{tx.with.username}</div> </div> - {/if} - </div> - - <div class="text-secondary text-right"> - <div> - {format(parseISO(tx.createdAt), 'h:mm aaa')} - </div> - <div> - {format(parseISO(tx.createdAt), 'MMM d')} + </a> + {:else} + <div class="mx-auto text-secondary"> + {tx.amount > 0 ? (tx.confirmed ? 'Received' : 'Pending') : 'Sent'} </div> + {/if} + </div> + + <div class="text-secondary text-right"> + <div> + {format(parseISO(tx.createdAt), 'h:mm aaa')} + </div> + <div> + {format(parseISO(tx.createdAt), 'MMM d')} </div> </div> - {/each} + </div> {:else} <p class="text-secondary text-lg text-center">{$t('user.transactions.empty')}</p> - {/if} + {/each} </div> </div> </div> diff --git a/src/routes/(app)/invoice/[id]/+page.svelte b/src/routes/(app)/invoice/[id]/+page.svelte index 463cf31f..dec33b62 100644 --- a/src/routes/(app)/invoice/[id]/+page.svelte +++ b/src/routes/(app)/invoice/[id]/+page.svelte @@ -27,7 +27,7 @@ user: { username, currency } } = invoice; -let src = sm; + let src = sm; let qr; let tipPercent = 0; @@ -51,9 +51,12 @@ let src = sm; $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); @@ -69,13 +72,13 @@ let src = sm; $: link = address ? text : `lightning:${text}`; - let full; - let toggle = () => { - screenfull.toggle(qr); - full = !full; - if (full) src = lg; - else src = sm; - } + let full; + let toggle = () => { + screenfull.toggle(qr); + full = !full; + if (full) src = lg; + else src = sm; + }; </script> <button class="ml-5 md:ml-20 mt-5 md:mt-10 hover:opacity-80" on:click={back}> @@ -101,7 +104,7 @@ let src = sm; <div class="text-center space-y-5"> {#if !user || user.username === username || showQr} <div class="mx-auto"> - <img {src} class:p-4={full} class="w-[300px] mx-auto" bind:this={qr} on:click={toggle} /> + <img {src} class:p-4={full} class="w-[300px] mx-auto" bind:this={qr} on:click={toggle} /> </div> <div class="mb-10 flex gap-2 justify-center"> @@ -133,13 +136,15 @@ let src = sm; </div> {/if} - <div class="flex flex-wrap justify-between font-bold text-2xl !my-8"> - <span class="mr-1">{$t('invoice.total')}</span> - <span - >{f(amountFiat + parseFloat(tipAmount), currency)} - <span class="text-secondary font-normal">{`${sat(tip + amount)}`}</span></span - > - </div> + {#if amount > 0} + <div class="flex flex-wrap justify-between font-bold text-2xl !my-8"> + <span class="mr-1">{$t('invoice.total')}</span> + <span + >{f(amountFiat + parseFloat(tipAmount), currency)} + <span class="text-secondary font-normal">{`${sat(tip + amount)}`}</span></span + > + </div> + {/if} </div> {#if user && user.username !== username} diff --git a/src/routes/(app)/invoice/[id]/pending/+page.svelte b/src/routes/(app)/invoice/[id]/pending/+page.svelte new file mode 100644 index 00000000..d3970dab --- /dev/null +++ b/src/routes/(app)/invoice/[id]/pending/+page.svelte @@ -0,0 +1,56 @@ +<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> |
