diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/components/AppHeader.svelte | 4 | ||||
| -rw-r--r-- | src/lib/socket.js | 3 | ||||
| -rw-r--r-- | src/lib/store.js | 1 | ||||
| -rw-r--r-- | src/routes/invoice.js | 3 | ||||
| -rw-r--r-- | src/routes/invoice.svelte | 23 | ||||
| -rw-r--r-- | src/routes/receive.svelte | 194 |
6 files changed, 157 insertions, 71 deletions
diff --git a/src/components/AppHeader.svelte b/src/components/AppHeader.svelte index 9998a4f6..bbe2e05e 100644 --- a/src/components/AppHeader.svelte +++ b/src/components/AppHeader.svelte @@ -14,10 +14,10 @@ ><Icon icon="clock" style="mx-auto" /></button > <button class="bg-white p-2 rounded-full w-12 h-12" - ><Icon icon="menu" style="mx-auto" /></button + ><Icon icon="profile" style="mx-auto" /></button > <button class="bg-white p-2 rounded-full w-12 h-12" - ><Icon icon="profile" style="mx-auto" /></button + ><Icon icon="menu" style="mx-auto" /></button > </nav> <div diff --git a/src/lib/socket.js b/src/lib/socket.js index 38efd2ec..ea6d7a8c 100644 --- a/src/lib/socket.js +++ b/src/lib/socket.js @@ -1,7 +1,6 @@ import { rate, user, ws } from '$lib/store'; -const token = - 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImJvYiIsImlhdCI6MTY1ODc5NDkxMX0._zFTEADrbLffcXa5sIMrJtJ483VdIiYmsdt2ofibxu4'; +const token = import.meta.env.VITE_COINOS_TOKEN; let interval, socket; diff --git a/src/lib/store.js b/src/lib/store.js index 120acc77..125ebc42 100644 --- a/src/lib/store.js +++ b/src/lib/store.js @@ -3,3 +3,4 @@ import { writable } from 'svelte/store'; export const rate = writable(); export const user = writable(); export const ws = writable(); +export const invoiceAmount = writable(); diff --git a/src/routes/invoice.js b/src/routes/invoice.js index 49bcfe70..147da2b7 100644 --- a/src/routes/invoice.js +++ b/src/routes/invoice.js @@ -1,4 +1,5 @@ import got from 'got'; +import { invoiceAmount } from '$lib/store'; const username = 'bob', network = 'lightning'; @@ -6,7 +7,7 @@ const username = 'bob', export async function GET({ params }) { let text = await got .post('http://localhost:3119/lightning/invoice', { - json: { amount: 100 } + json: { amount: invoiceAmount } }) .text(); diff --git a/src/routes/invoice.svelte b/src/routes/invoice.svelte index b8f9e54b..567aefbb 100644 --- a/src/routes/invoice.svelte +++ b/src/routes/invoice.svelte @@ -1,18 +1,15 @@ <script> - import { rate, user } from '$lib/store'; - import { onMount } from 'svelte'; + import { rate, user, invoiceAmount } from '$lib/store'; export let text; </script> -QR code - -{text} - -{$rate} - -{$user?.username} - -{#each $user.payments as p} - {p.amount}<br /> -{/each} +{#if $user} + {text} + {$invoiceAmount} + {$rate} + {$user.username} + {#each $user.payments as p} + {p.amount}<br /> + {/each} +{/if} diff --git a/src/routes/receive.svelte b/src/routes/receive.svelte index 73d3cc06..8cc49de2 100644 --- a/src/routes/receive.svelte +++ b/src/routes/receive.svelte @@ -2,74 +2,162 @@ // in the future we will want to allow users to set their fiat currency in the settings import { AppHeader, Icon } from '$comp'; import { goto } from '$app/navigation'; + import { invoiceAmount, rate } from '$lib/store'; let useFiat = true; let amountFiat = 0; let amountSats = 0; + let message = ''; + + $: $invoiceAmount = parseInt(amountSats === 0 ? amountFiat / ($rate / 100000000) : amountSats); + $: amountSatsFormatted = new Intl.NumberFormat('en-US', { maximumFractionDigits: 0 }).format( + amountSats + ); + + $: amountFiatConverted = new Intl.NumberFormat('en-US', { + style: 'currency', + currency: 'USD' + }).format(amountSats * ($rate / 100000000)); + + $: amountSatsConverted = new Intl.NumberFormat('en-US', { maximumFractionDigits: 0 }).format( + amountFiat / ($rate / 100000000) + ); const numPad = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '0', '<']; + + const handleInput = (value) => { + if (message) { + message = ''; + } + if (useFiat) { + if (amountFiat === 0 && value !== '.' && value !== '<' && value !== '0') { + amountFiat = value; + } else if (amountFiat === 0 && value === '.') { + amountFiat = '0.'; + } else if (amountFiat !== 0 && amountFiat.includes('.') && value === '.') { + return; + } else if (value === '<') { + if (amountFiat !== 0) { + amountFiat = amountFiat.slice(0, amountFiat.length - 1); + if (amountFiat.length === 0) { + amountFiat = 0; + } + } + } else if (value !== '.' && value !== '<' && parseInt(amountFiat + value) > $rate) { + message = 'Please enter an amount less than 1 bitcoin.'; + } else if (amountFiat !== 0 && amountFiat.match(/\.../)) { + return; + } else { + amountFiat = amountFiat + value; + } + } else { + if (value === '.') { + return; + } else if (amountSats === 0 && value !== '<' && value !== '0') { + amountSats = value; + } else if (value === '<') { + if (amountSats !== 0) { + amountSats = amountSats.slice(0, amountSats.length - 1); + if (amountSats.length === 0) { + amountSats = 0; + } + } + } else if (value !== '<' && parseInt(amountSats + value) > 100000000) { + message = 'Please enter an amount less than 1 bitcoin.'; + } else { + amountSats = amountSats + value; + } + } + }; </script> <AppHeader /> <!-- step 1 input amount and generate QR code --> -<div class="flex justify-center items-center mt-20 mb-3 px-3"> - <div class="space-y-5"> - <!-- amounts --> - <div class="text-center"> - <div class="text-6xl font-semibold tracking-widest mb-1"> - {useFiat ? `$${amountFiat}` : amountSats}<span class="tracking-normal text-base font-normal" - >{useFiat ? 'CAD' : 'SATS'}</span +{#if $rate} + <div class="flex justify-center items-center mt-20 mb-3 px-3"> + <div class="space-y-5"> + <!-- amounts --> + <div class="text-center"> + <div class="text-5xl md:text-6xl font-semibold tracking-widest mb-1"> + {useFiat ? `$${amountFiat}` : amountSatsFormatted}<span + class="tracking-normal text-base font-normal">{useFiat ? 'USD' : 'SATS'}</span + > + </div> + <span class="text-secondary mr-1" + >{useFiat ? `${amountSatsConverted} SATS` : `${amountFiatConverted} USD`}</span + > + <button + on:click={() => { + if (useFiat) { + amountSats = (amountFiat / ($rate / 100000000)).toFixed(0).toString(); + } else { + amountFiat = (amountSats * ($rate / 100000000)).toFixed(2).toString(); + } + useFiat = !useFiat; + }}><Icon icon="swap" style="inline" /></button > </div> - <span class="text-secondary mr-1" - >{useFiat ? `${amountSats} SATS` : `$${amountFiat} CAD`}</span - > <button on:click={() => (useFiat = !useFiat)}><Icon icon="swap" style="inline" /></button> - </div> - <!-- numpad --> - <div class="grid grid-cols-3 gap-2"> - {#each numPad as value} - {#if value === '<'} - <button - class="bg-primary rounded-xl py-4 px-8 font-semibold active:bg-black active:text-white" - > - <svg - class="w-5" - width="24" - height="24" - viewBox="0 0 24 24" - fill="none" - xmlns="http://www.w3.org/2000/svg" + <!-- error message --> + {#if message} + <div + class="text-orange-500 text-sm text-center font-bold bg-primary p-2 rounded-xl flex justify-center items-center space-x-1" + > + <Icon icon="info" style="w-5" /> + <p>{message}</p> + </div> + {/if} + + <!-- numpad --> + <div class="grid grid-cols-3 gap-2 w-full md:w-[300px] mx-auto"> + {#each numPad as value} + {#if value === '<'} + <button + class="bg-primary rounded-xl py-4 px-8 font-semibold active:bg-black active:text-white flex justify-center items-center" + on:click={() => handleInput(value)} > - <path - d="M15 19L8 12L15 5" - stroke="currentColor" - stroke-width="2" - stroke-linecap="round" - stroke-linejoin="round" - /> - </svg></button - > - {:else} - <button - class="bg-primary rounded-xl py-4 px-8 font-semibold active:bg-black active:text-white" - >{value}</button - > - {/if} - {/each} - </div> + <svg + class="w-5" + width="24" + height="24" + viewBox="0 0 24 24" + fill="none" + xmlns="http://www.w3.org/2000/svg" + > + <path + d="M15 19L8 12L15 5" + stroke="currentColor" + stroke-width="2" + stroke-linecap="round" + stroke-linejoin="round" + /> + </svg> + </button> + {:else} + <button + class="bg-primary rounded-xl py-4 px-8 font-semibold active:bg-black active:text-white" + on:click={() => handleInput(value)}>{value}</button + > + {/if} + {/each} + </div> - <!-- buttons --> - <div class="space-y-3"> - <button - class="bg-black text-white rounded-xl w-full h-[48px] flex justify-center items-center font-semibold text-sm" - on:click={() => goto('/invoice')}><Icon icon="qr" style="mr-2" /> Show QR</button - > - <button - class="bg-primary rounded-xl w-full h-[48px] flex justify-center items-center font-semibold text-sm" - ><Icon icon="send" style="mr-2" /> Send Invoice</button - > + <!-- buttons --> + <div class="space-y-3 w-full md:w-[300px] mx-auto"> + <button + class="bg-black text-white rounded-xl w-full h-[48px] flex justify-center items-center font-semibold text-sm {$invoiceAmount === + 0 + ? 'opacity-50' + : 'opacity-100'}" + on:click={() => goto('/invoice')} + disabled={$invoiceAmount === 0}><Icon icon="qr" style="mr-2" /> Show QR</button + > + <button + class="bg-primary rounded-xl w-full h-[48px] flex justify-center items-center font-semibold text-sm" + disabled={true}><Icon icon="send" style="mr-2" /> Send Invoice</button + > + </div> </div> </div> -</div> +{/if} |
