aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2022-11-06 11:24:36 -0800
committerAdam Soltys <[email protected]>2022-11-06 11:24:36 -0800
commit1bda2b36e3f7f6c7f7a85647b2bc4ca308012fbe (patch)
tree29601126a68556d11e5968d15159b5fc066d2e64 /src
parent84e8da3e50ba1a35d254346d8fc92a3795d41670 (diff)
downloadcoinos-ui-1bda2b36e3f7f6c7f7a85647b2bc4ca308012fbe.tar.gz
coinos-ui-1bda2b36e3f7f6c7f7a85647b2bc4ca308012fbe.zip
invoice requests
Diffstat (limited to 'src')
-rw-r--r--src/components/Invoice.svelte34
-rw-r--r--src/components/Numpad.svelte2
-rw-r--r--src/components/Request.svelte37
-rw-r--r--src/components/index.js1
-rw-r--r--src/lib/invoice.js7
-rw-r--r--src/lib/socket.js6
-rw-r--r--src/lib/store.js1
-rw-r--r--src/routes/(app)/+layout.svelte10
-rw-r--r--src/routes/(app)/[username]/+page.svelte12
-rw-r--r--src/routes/(app)/[username]/receive/+page.svelte30
-rw-r--r--src/routes/(app)/[username]/receive/[...recipient]/+page.server.js (renamed from src/routes/(app)/[username]/receive/+page.server.js)0
-rw-r--r--src/routes/(app)/[username]/receive/[...recipient]/+page.svelte70
-rw-r--r--src/routes/(app)/[username]/receive/[network]/[amount]/+page.server.js0
-rw-r--r--src/routes/(app)/[username]/receive/[network]/[amount]/+page.svelte1
-rw-r--r--src/routes/(app)/[username]/request/+page.svelte2
-rw-r--r--src/routes/(app)/invoice/[id]/+page.svelte4
-rw-r--r--src/routes/(app)/invoice/sent/+page.svelte10
-rw-r--r--src/routes/(app)/send/[...text]/+page.server.js4
18 files changed, 179 insertions, 52 deletions
diff --git a/src/components/Invoice.svelte b/src/components/Invoice.svelte
new file mode 100644
index 00000000..4b42f851
--- /dev/null
+++ b/src/components/Invoice.svelte
@@ -0,0 +1,34 @@
+<script>
+ import { fly } from 'svelte/transition';
+ import { Avatar, Icon } from '$comp';
+ import { invoice } from '$lib/store';
+
+ export let user;
+</script>
+
+{#if $invoice}
+ <div
+ class="flex flex-wrap md:flex-nowrap fixed bottom-0 border-t w-full p-4 bg-white z-50"
+ in:fly
+ >
+ <div class="my-auto md:w-1/2">
+ <div class="flex">
+ <Avatar user={$invoice.user.username} size={12} />
+ <h1 class="my-auto"><b>{$invoice.user.username}</b> sent an invoice</h1>
+ </div>
+ </div>
+ <div class="mx-auto my-auto">
+ <a href={`/invoice/${$invoice.uuid}`}>
+ <button class="text-lg rounded-full border py-3 px-7 font-bold hover:opacity-80 w-full">
+ Pay
+ </button>
+ </a>
+ </div>
+ <button
+ class="absolute right-4 top-4 ml-auto mb-auto rounded-full border font-bold hover:opacity-80 p-3"
+ on:click={() => ($invoice = undefined)}
+ >
+ <Icon icon="close" />
+ </button>
+ </div>
+{/if}
diff --git a/src/components/Numpad.svelte b/src/components/Numpad.svelte
index b4f2bbbb..de292f2a 100644
--- a/src/components/Numpad.svelte
+++ b/src/components/Numpad.svelte
@@ -8,7 +8,7 @@
currency,
fiat = !amount;
- export let amountFiat = amount ? amount * ($selectedRate / sats) : 0;
+ export let amountFiat = amount ? amount * ($selectedRate / sats) : 0;
let amountSats = amount;
let loading = false;
diff --git a/src/components/Request.svelte b/src/components/Request.svelte
index ea314f13..2c87d436 100644
--- a/src/components/Request.svelte
+++ b/src/components/Request.svelte
@@ -1,10 +1,37 @@
<script>
import { fly } from 'svelte/transition';
- import { Avatar } from '$comp';
+ import { Avatar, Icon } from '$comp';
import { request } from '$lib/store';
+
+ export let user;
</script>
-<div class="fixed bottom-0 h-24 border-t w-full bg-primary" in:fly>
- <Avatar user={$request.requester} />
- {$request.requester.username} is requesting an invoice
-</div>
+{#if $request}
+ <div
+ class="flex flex-wrap md:flex-nowrap fixed bottom-0 border-t w-full p-4 bg-white z-50"
+ in:fly
+ >
+ <div class="my-auto md:w-1/2">
+ <div class="flex">
+ <Avatar user={$request.requester} size={12} />
+ <h1 class="my-auto"><b>{$request.requester.username}</b> is ready to pay</h1>
+ </div>
+ {#if $request.memo}
+ <div class="border-l-4 pl-4 my-2">{$request.memo}</div>
+ {/if}
+ </div>
+ <div class="mx-auto my-auto">
+ <a href={`/${user.username}/receive`}>
+ <button class="text-lg rounded-full border py-3 px-7 font-bold hover:opacity-80 w-full">
+ Create invoice
+ </button>
+ </a>
+ </div>
+ <button
+ class="absolute right-4 top-4 ml-auto mb-auto rounded-full border font-bold hover:opacity-80 p-3"
+ on:click={() => ($request = undefined)}
+ >
+ <Icon icon="close" />
+ </button>
+ </div>
+{/if}
diff --git a/src/components/index.js b/src/components/index.js
index f3d550ec..07b169bb 100644
--- a/src/components/index.js
+++ b/src/components/index.js
@@ -1,3 +1,4 @@
+export { default as Invoice } from './Invoice.svelte';
export { default as Request } from './Request.svelte';
export { default as Pin } from './Pin.svelte';
export { default as Card } from './Card.svelte';
diff --git a/src/lib/invoice.js b/src/lib/invoice.js
index e8a5f615..5bf05d90 100644
--- a/src/lib/invoice.js
+++ b/src/lib/invoice.js
@@ -5,18 +5,23 @@ export default async ({ cookies, request }) => {
let form = await request.formData();
let rates = await get('/rates');
+ let requester = form.get('requester');
let invoice = {
amount: parseInt(form.get('amount')),
tip: parseInt(form.get('tip')),
network: 'lightning',
prompt: form.get('prompt') === 'true',
- rate: parseFloat(form.get('rate')) || rates[form.get('currency')]
+ rate: parseFloat(form.get('rate')) || rates[form.get('currency')],
+ requester
};
let user = { username: form.get('username') };
let { uuid } = await post('/invoice', { invoice, user }, auth(cookies));
+ console.log('R', requester);
+
+ if (requester) return { requester };
if (invoice.prompt) {
throw redirect(307, `/invoice/${uuid}/tip`);
diff --git a/src/lib/socket.js b/src/lib/socket.js
index d3cc40ea..a5784f19 100644
--- a/src/lib/socket.js
+++ b/src/lib/socket.js
@@ -1,5 +1,5 @@
import { get } from 'svelte/store';
-import { invoices, request, newPayment, last, rate, user } from '$lib/store';
+import { invoices, invoice, request, newPayment, last, rate, user } from '$lib/store';
import { success, sat } from '$lib/utils';
import { env } from '$env/dynamic/public';
@@ -19,6 +19,10 @@ export const messages = (data) => ({
last.set(Date.now());
},
+ invoice() {
+ invoice.set(data);
+ },
+
rate() {
rate.set(data);
},
diff --git a/src/lib/store.js b/src/lib/store.js
index c32ef49b..3faa234b 100644
--- a/src/lib/store.js
+++ b/src/lib/store.js
@@ -45,3 +45,4 @@ export const bannerUpload = writable();
export const pin = persistSession('pin', undefined, 5 * 60 * 1000);
export const last = writable();
export const request = writable();
+export const invoice = writable();
diff --git a/src/routes/(app)/+layout.svelte b/src/routes/(app)/+layout.svelte
index 5bfe7712..36e109e0 100644
--- a/src/routes/(app)/+layout.svelte
+++ b/src/routes/(app)/+layout.svelte
@@ -2,11 +2,11 @@
import { SvelteToast } from '@zerodevx/svelte-toast';
import { onDestroy, onMount } from 'svelte';
import { close, connect, send } from '$lib/socket';
- import { last, selectedRate, rate, user, request } from '$lib/store';
+ import { last, selectedRate, invoice, rate, user, request } from '$lib/store';
import { page } from '$app/stores';
import { browser } from '$app/environment';
import { goto } from '$app/navigation';
- import { LoadingSplash, Request } from '$comp';
+ import { LoadingSplash, Invoice, Request } from '$comp';
import { warning, protectedRoutes } from '$lib/utils';
import { t, locale } from '$lib/translations';
@@ -84,6 +84,10 @@
<slot />
</main>
+{#if $invoice}
+ <Invoice user={u} />
+{/if}
+
{#if $request}
- <Request />
+ <Request user={u} />
{/if}
diff --git a/src/routes/(app)/[username]/+page.svelte b/src/routes/(app)/[username]/+page.svelte
index b9deeb5f..ed11412f 100644
--- a/src/routes/(app)/[username]/+page.svelte
+++ b/src/routes/(app)/[username]/+page.svelte
@@ -48,15 +48,15 @@
<div>
<a href={`/${subject.username}/receive`}>
<button class="rounded-full border py-2 px-5 font-bold hover:opacity-80 w-full mb-2">
- Pay
+ Pay now
</button>
</a>
- <!-- <a href={`/${subject.username}/request`}> -->
- <!-- <button class="rounded-full border py-2 px-5 font-bold hover:opacity-80 w-full mb-2" -->
- <!-- >Request an invoice</button -->
- <!-- > -->
- <!-- </a> -->
+ <a href={`/${subject.username}/request`}>
+ <button class="rounded-full border py-2 px-5 font-bold hover:opacity-80 w-full mb-2"
+ >Ask to pay</button
+ >
+ </a>
</div>
{/if}
</div>
diff --git a/src/routes/(app)/[username]/receive/+page.svelte b/src/routes/(app)/[username]/receive/+page.svelte
deleted file mode 100644
index 11d3a6db..00000000
--- a/src/routes/(app)/[username]/receive/+page.svelte
+++ /dev/null
@@ -1,30 +0,0 @@
-<script>
- import { Icon, Numpad } from '$comp';
- import { t } from '$lib/translations';
- import { enhance } from '$app/forms';
-
- export let data;
- let amount;
-
- let { currency, username } = data.subject;
-</script>
-
-<form method="POST" class="flex justify-center items-center mt-24 mb-3 px-3" use:enhance>
- <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="prompt" value="true" />
-
- <div class="space-y-3 w-full md:w-[300px] mx-auto">
- <Numpad bind:amount bind:currency />
- <button
- type="submit"
- class="bg-black text-white rounded-xl w-full h-[48px] flex justify-center items-center font-semibold {!amount
- ? 'opacity-50'
- : 'opacity-100 hover:opacity-80'}"
- disabled={!amount}
- >
- Next
- </button>
- </div>
-</form>
diff --git a/src/routes/(app)/[username]/receive/+page.server.js b/src/routes/(app)/[username]/receive/[...recipient]/+page.server.js
index 1068f273..1068f273 100644
--- a/src/routes/(app)/[username]/receive/+page.server.js
+++ b/src/routes/(app)/[username]/receive/[...recipient]/+page.server.js
diff --git a/src/routes/(app)/[username]/receive/[...recipient]/+page.svelte b/src/routes/(app)/[username]/receive/[...recipient]/+page.svelte
new file mode 100644
index 00000000..a0f9a1b0
--- /dev/null
+++ b/src/routes/(app)/[username]/receive/[...recipient]/+page.svelte
@@ -0,0 +1,70 @@
+<script>
+ import { Avatar, Icon, Numpad } from '$comp';
+ import { t } from '$lib/translations';
+ import { enhance } from '$app/forms';
+ import { page } from '$app/stores';
+ import { request } from '$lib/store';
+
+ export let data;
+ export let form;
+
+ let req;
+
+ $: load($page);
+ let load = () => {
+ if ($request) {
+ req = { ...$request };
+ $request = null;
+ }
+ };
+
+ let amount;
+
+ let { currency, username } = data.subject;
+ let { user } = data;
+</script>
+
+{#if form}
+ <div class="container px-4 mt-20 max-w-xl mx-auto space-y-8">
+ <div class="text-center mb-8 space-y-5">
+ <p class="text-5xl break-words">
+ <span class="text-xl md:text-2xl">Invoice sent to</span>
+ </p>
+
+ <div class="flex p-1 gap-2 justify-center">
+ <Avatar user={req.requester} size={'20'} />
+ <p class="text-4xl break-words my-auto">{req.requester.username}</p>
+ </div>
+ </div>
+ <a href={`/${user.username}/dashboard`} class="mx-auto">
+ <button class="bg-black text-white rounded-2xl w-20 py-3 font-bold hover:opacity-80">
+ Done
+ </button>
+ </a>
+ </div>
+{:else}
+ <form method="POST" class="flex justify-center items-center mt-24 mb-3 px-3" use:enhance>
+ <input type="hidden" name="amount" value={amount} />
+ <input type="hidden" name="currency" value={currency} />
+ <input type="hidden" name="username" value={username} />
+
+ {#if req}
+ <input type="hidden" name="requester" value={req.requester.username} />
+ {/if}
+
+ <input type="hidden" name="prompt" value="true" />
+
+ <div class="space-y-3 w-full md:w-[300px] mx-auto">
+ <Numpad bind:amount bind:currency />
+ <button
+ type="submit"
+ class="bg-black text-white rounded-xl w-full h-[48px] flex justify-center items-center font-semibold {!amount
+ ? 'opacity-50'
+ : 'opacity-100 hover:opacity-80'}"
+ disabled={!amount}
+ >
+ Next
+ </button>
+ </div>
+ </form>
+{/if}
diff --git a/src/routes/(app)/[username]/receive/[network]/[amount]/+page.server.js b/src/routes/(app)/[username]/receive/[network]/[amount]/+page.server.js
deleted file mode 100644
index e69de29b..00000000
--- a/src/routes/(app)/[username]/receive/[network]/[amount]/+page.server.js
+++ /dev/null
diff --git a/src/routes/(app)/[username]/receive/[network]/[amount]/+page.svelte b/src/routes/(app)/[username]/receive/[network]/[amount]/+page.svelte
deleted file mode 100644
index 45b983be..00000000
--- a/src/routes/(app)/[username]/receive/[network]/[amount]/+page.svelte
+++ /dev/null
@@ -1 +0,0 @@
-hi
diff --git a/src/routes/(app)/[username]/request/+page.svelte b/src/routes/(app)/[username]/request/+page.svelte
index 37fdae96..6e7eb08a 100644
--- a/src/routes/(app)/[username]/request/+page.svelte
+++ b/src/routes/(app)/[username]/request/+page.svelte
@@ -22,7 +22,7 @@
<textarea
name="memo"
- placeholder="(Optionally) use this field to describe your order"
+ placeholder="You can use this field to describe your order"
class="w-full p-4 border rounded-xl h-48"
/>
diff --git a/src/routes/(app)/invoice/[id]/+page.svelte b/src/routes/(app)/invoice/[id]/+page.svelte
index 6de55bae..25ebf227 100644
--- a/src/routes/(app)/invoice/[id]/+page.svelte
+++ b/src/routes/(app)/invoice/[id]/+page.svelte
@@ -3,7 +3,7 @@
import { back, copy, f, get, sat, reverseFormat, s, sats } from '$lib/utils';
import { onMount, onDestroy } from 'svelte';
import { browser } from '$app/environment';
- import { invoices, last } from '$lib/store';
+ import { invoice as inv, invoices, last } from '$lib/store';
import { Icon, Heart, Image, Qr } from '$comp';
import { goto } from '$app/navigation';
import { t } from '$lib/translations';
@@ -24,6 +24,8 @@
let tipPercent = 0;
let refresh = (data) => {
+ $inv = null;
+
({ invoice, id } = data);
({
amount,
diff --git a/src/routes/(app)/invoice/sent/+page.svelte b/src/routes/(app)/invoice/sent/+page.svelte
new file mode 100644
index 00000000..c4cbc5bb
--- /dev/null
+++ b/src/routes/(app)/invoice/sent/+page.svelte
@@ -0,0 +1,10 @@
+<script>
+ import { Avatar, Icon } from '$comp';
+ export let user;
+</script>
+
+Invoice sent to
+<div class="flex">
+ <Avatar user={$request.requester} size={12} />
+ <h1 class="my-auto"><b>{$request.requester.username}</b> is ready to pay</h1>
+</div>
diff --git a/src/routes/(app)/send/[...text]/+page.server.js b/src/routes/(app)/send/[...text]/+page.server.js
index 7d2aa8b0..5e274c67 100644
--- a/src/routes/(app)/send/[...text]/+page.server.js
+++ b/src/routes/(app)/send/[...text]/+page.server.js
@@ -10,7 +10,7 @@ let parse = async (t, r) => {
t.startsWith('bitcoin:') &&
({
- address: t,
+ address: t,
options: { amount }
} = bip21.decode(t));
@@ -46,7 +46,7 @@ let parse = async (t, r) => {
} catch (e) {
let r = `/send/bitcoin/${t}`;
if (amount) r += '/' + amount;
- console.log("AM", amount)
+ console.log('AM', amount);
throw redirect(307, r);
}