diff options
| author | secondl1ght <[email protected]> | 2022-07-30 06:52:55 -0600 |
|---|---|---|
| committer | secondl1ght <[email protected]> | 2022-07-30 06:52:55 -0600 |
| commit | 8851572f78a70c7bd02a3d669dc103459323ed8d (patch) | |
| tree | 8f2bdce5946ac7a7a81ccdbeaa91191129f39442 /src | |
| parent | fac00131fd980db9513143807fe2d823376e9551 (diff) | |
| download | coinos-ui-8851572f78a70c7bd02a3d669dc103459323ed8d.tar.gz coinos-ui-8851572f78a70c7bd02a3d669dc103459323ed8d.zip | |
add 404 and error page, redirect to login if trying to access w/o user
Diffstat (limited to 'src')
| -rw-r--r-- | src/components/AppHeader.svelte | 4 | ||||
| -rw-r--r-- | src/routes/[...path].svelte | 16 | ||||
| -rw-r--r-- | src/routes/__error.svelte | 16 | ||||
| -rw-r--r-- | src/routes/invoice/[amount].svelte | 224 | ||||
| -rw-r--r-- | src/routes/receive.svelte | 184 |
5 files changed, 245 insertions, 199 deletions
diff --git a/src/components/AppHeader.svelte b/src/components/AppHeader.svelte index 3f8e7e87..6376e27f 100644 --- a/src/components/AppHeader.svelte +++ b/src/components/AppHeader.svelte @@ -1,7 +1,7 @@ <script> // we will want to dynamically use the users avatar on this screen if they have uploaded one - import { user } from "$lib/store"; + import { user } from '$lib/store'; import { goto } from '$app/navigation'; import { Icon } from '$comp'; </script> @@ -15,7 +15,7 @@ ><Icon icon="clock" style="mx-auto" /></button > <button class="bg-white p-2 rounded-full w-12 h-12" - ><Icon icon="profile" style="mx-auto" /> {$user.username}</button + ><Icon icon="profile" style="mx-auto" /></button > <button class="bg-white p-2 rounded-full w-12 h-12" ><Icon icon="menu" style="mx-auto" /></button diff --git a/src/routes/[...path].svelte b/src/routes/[...path].svelte new file mode 100644 index 00000000..503316bb --- /dev/null +++ b/src/routes/[...path].svelte @@ -0,0 +1,16 @@ +<script> + import { Icon } from '$comp'; +</script> + +<div class="flex justify-center items-center mt-20"> + <div class="space-y-5 text-center"> + <a href="/"> + <Icon icon="logo" /> + </a> + + <Icon icon="question" style="mx-auto w-full" /> + + <h1 class="font-bold text-5xl">404</h1> + <p>Page not found.</p> + </div> +</div> diff --git a/src/routes/__error.svelte b/src/routes/__error.svelte new file mode 100644 index 00000000..6cdeeac7 --- /dev/null +++ b/src/routes/__error.svelte @@ -0,0 +1,16 @@ +<script> + import { Icon } from '$comp'; +</script> + +<div class="flex justify-center items-center mt-20"> + <div class="space-y-5 text-center"> + <a href="/"> + <Icon icon="logo" /> + </a> + + <Icon icon="error" style="mx-auto w-full" /> + + <h1 class="font-bold text-5xl">Error</h1> + <p>Please try again or contact support.</p> + </div> +</div> diff --git a/src/routes/invoice/[amount].svelte b/src/routes/invoice/[amount].svelte index 4c1ec199..2cf16e37 100644 --- a/src/routes/invoice/[amount].svelte +++ b/src/routes/invoice/[amount].svelte @@ -8,6 +8,10 @@ export let text; export let amount; + if (!$user && typeof window !== 'undefined') { + window.location = '/login'; + } + let tipPercent = 0; const setRate = ($invoiceAmountFiat / $invoiceAmount) * 100000000; @@ -83,131 +87,133 @@ }); </script> -<button class="ml-5 md:ml-20 mt-5 md:mt-10" on:click={() => goto('/receive')}> - <Icon icon="arrow-left" style="w-10" /> -</button> +{#if $user} + <button class="ml-5 md:ml-20 mt-5 md:mt-10" on:click={() => goto('/receive')}> + <Icon icon="arrow-left" style="w-10" /> + </button> -<div class="flex justify-center items-center mb-20 mt-[20px] px-3"> - <div - class="block lg:flex justify-center items-center space-y-10 lg:space-y-0 space-x-0 lg:space-x-24" - > - {#if $invoiceAmount && $invoiceAmountFiat && $rate && text} - <!-- tipping section --> - <div class="text-center space-y-5"> - <h1 class="text-4xl font-semibold">Add a tip?</h1> + <div class="flex justify-center items-center mb-20 mt-[20px] px-3"> + <div + class="block lg:flex justify-center items-center space-y-10 lg:space-y-0 space-x-0 lg:space-x-24" + > + {#if $invoiceAmount && $invoiceAmountFiat && $rate && text} + <!-- tipping section --> + <div class="text-center space-y-5"> + <h1 class="text-4xl font-semibold">Add a tip?</h1> - <div> - <span class="font-semibold mr-1">{tipAmountFormatted}</span><span - class="text-secondary font-semibold text-sm">{`(${tipAmountSats} SATS)`}</span - > - <span class="block text-secondary text-sm">{tipPercent}%</span> - </div> + <div> + <span class="font-semibold mr-1">{tipAmountFormatted}</span><span + class="text-secondary font-semibold text-sm">{`(${tipAmountSats} SATS)`}</span + > + <span class="block text-secondary text-sm">{tipPercent}%</span> + </div> - <input - id="slider" - type="range" - min="0" - max="100" - value={tipPercent} - class="px-2" - on:input={(e) => { - customTipAmount = ''; - tipPercent = e.target.value; - }} - /> + <input + id="slider" + type="range" + min="0" + max="100" + value={tipPercent} + class="px-2" + on:input={(e) => { + customTipAmount = ''; + tipPercent = e.target.value; + }} + /> - <div> - {#each tipAmounts as amount} - <button - class="bg-primary w-20 py-3 m-1 rounded-2xl font-semibold {tipPercent === - amount.slice(0, 2) || - ((tipPercent === 0 || tipPercent === '0') && amount === 'None') - ? '!bg-black text-white' - : ''}" - on:click={() => handleTipButtonClick(amount)}>{amount}</button - > - {/each} + <div> + {#each tipAmounts as amount} + <button + class="bg-primary w-20 py-3 m-1 rounded-2xl font-semibold {tipPercent === + amount.slice(0, 2) || + ((tipPercent === 0 || tipPercent === '0') && amount === 'None') + ? '!bg-black text-white' + : ''}" + on:click={() => handleTipButtonClick(amount)}>{amount}</button + > + {/each} - <div class="relative"> - <span - class="absolute top-[20px] left-5 font-semibold {!customTipAmount - ? 'opacity-50' - : 'opacity-100'}">$</span - > - <input - type="number" - min="0" - on:input={(e) => handleCustomTipAmount(e)} - class="bg-primary rounded-2xl py-3 px-10 font-semibold mt-2 mr-1 w-full md:w-auto" - placeholder="Other" - /> - <button - class="w-full md:w-auto mt-2 md:mt-0 bg-black text-white font-semibold py-3 px-7 rounded-2xl {!customTipAmount - ? 'opacity-50' - : 'opacity-100'}" - disabled={!customTipAmount}>Done</button - > + <div class="relative"> + <span + class="absolute top-[20px] left-5 font-semibold {!customTipAmount + ? 'opacity-50' + : 'opacity-100'}">$</span + > + <input + type="number" + min="0" + on:input={(e) => handleCustomTipAmount(e)} + class="bg-primary rounded-2xl py-3 px-10 font-semibold mt-2 mr-1 w-full md:w-auto" + placeholder="Other" + /> + <button + class="w-full md:w-auto mt-2 md:mt-0 bg-black text-white font-semibold py-3 px-7 rounded-2xl {!customTipAmount + ? 'opacity-50' + : 'opacity-100'}" + disabled={!customTipAmount}>Done</button + > + </div> </div> </div> - </div> - - <div - class="h-[1px] lg:h-[600px] w-full lg:w-[1px] bg-lightgrey rounded-xl" - id="section-divider" - /> - - <!-- invoice section --> - <div class="text-center space-y-5"> - <span class="text-secondary" - >Scan to pay <span class="text-black font-semibold">insert name here</span></span - > <div - id="qr" - class="border border-lightgrey rounded-3xl lg:p-5 flex justify-center items-center" + class="h-[1px] lg:h-[600px] w-full lg:w-[1px] bg-lightgrey rounded-xl" + id="section-divider" /> - <div class="px-5 space-y-3"> - <div class="flex justify-between"> - <span class="font-semibold text-sm">Invoice</span> - <span class="font-semibold text-sm" - >{invoiceAmountFiatFormatted} - <span class="text-secondary font-normal">{`(${invoiceAmountFormatted} SATS)`}</span - ></span - > - </div> + <!-- invoice section --> + <div class="text-center space-y-5"> + <span class="text-secondary" + >Scan to pay <span class="text-black font-semibold">insert name here</span></span + > - <div class="flex justify-between"> - <span class="font-semibold text-sm">Tip</span> - <span class="font-semibold text-sm" - >{tipAmountFormatted} - <span class="text-secondary font-normal">{`(${tipAmountSats} SATS)`}</span></span - > - </div> + <div + id="qr" + class="border border-lightgrey rounded-3xl lg:p-5 flex justify-center items-center" + /> - <div class="flex justify-between"> - <span class="font-bold">Total</span> - <span class="font-bold" - >{totalAmountFormatted} - <span class="text-secondary font-normal">{`(${totalAmountSats} SATS)`}</span></span - > + <div class="px-5 space-y-3"> + <div class="flex justify-between"> + <span class="font-semibold text-sm">Invoice</span> + <span class="font-semibold text-sm" + >{invoiceAmountFiatFormatted} + <span class="text-secondary font-normal">{`(${invoiceAmountFormatted} SATS)`}</span + ></span + > + </div> + + <div class="flex justify-between"> + <span class="font-semibold text-sm">Tip</span> + <span class="font-semibold text-sm" + >{tipAmountFormatted} + <span class="text-secondary font-normal">{`(${tipAmountSats} SATS)`}</span></span + > + </div> + + <div class="flex justify-between"> + <span class="font-bold">Total</span> + <span class="font-bold" + >{totalAmountFormatted} + <span class="text-secondary font-normal">{`(${totalAmountSats} SATS)`}</span></span + > + </div> </div> </div> - </div> - {:else} - <div - class="w-[94vw] md:w-[375px] h-[381px] md:h-[269px] animate-pulse bg-gray-400 rounded-xl" - /> - <div - class="h-[1px] lg:h-[600px] w-full lg:w-[1px] bg-lightgrey rounded-xl" - id="section-divider" - /> - <div - class="w-full md:w-[342px] h-[454px] md:h-[494px] animate-pulse bg-gray-400 rounded-xl" - /> - {/if} + {:else} + <div + class="w-[94vw] md:w-[375px] h-[381px] md:h-[269px] animate-pulse bg-gray-400 rounded-xl" + /> + <div + class="h-[1px] lg:h-[600px] w-full lg:w-[1px] bg-lightgrey rounded-xl" + id="section-divider" + /> + <div + class="w-full md:w-[342px] h-[454px] md:h-[494px] animate-pulse bg-gray-400 rounded-xl" + /> + {/if} + </div> </div> -</div> +{/if} <style> #slider { diff --git a/src/routes/receive.svelte b/src/routes/receive.svelte index e78934a9..11bafe9a 100644 --- a/src/routes/receive.svelte +++ b/src/routes/receive.svelte @@ -2,7 +2,11 @@ // 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, invoiceAmountFiat, rate } from '$lib/store'; + import { invoiceAmount, invoiceAmountFiat, rate, user } from '$lib/store'; + + if (!$user && typeof window !== 'undefined') { + window.location = '/login'; + } let useFiat = true; let amountFiat = 0; @@ -78,98 +82,102 @@ }; </script> -<AppHeader /> +{#if $user} + <AppHeader /> -<!-- step 1 input amount and generate QR code --> -<div class="flex justify-center items-center mt-20 mb-3 px-3"> - {#if $rate} - <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 + <!-- step 1 input amount and generate QR code --> + <div class="flex justify-center items-center mt-20 mb-3 px-3"> + {#if $rate} + <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) > 0.0 + ? (amountSats * ($rate / 100000000)).toFixed(2).toString() + : 0; + } + useFiat = !useFiat; + }}><Icon icon="swap" style="inline" /></button > </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) > 0.0 - ? (amountSats * ($rate / 100000000)).toFixed(2).toString() - : 0; - } - useFiat = !useFiat; - }}><Icon icon="swap" style="inline" /></button - > - </div> - <!-- 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} + <!-- 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)} - > - <svg - class="w-5" - width="24" - height="24" - viewBox="0 0 24 24" - fill="none" - xmlns="http://www.w3.org/2000/svg" + <!-- 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" - on:click={() => handleInput(value)}>{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 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/${$invoiceAmount}`)} - 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 - > + <!-- 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/${$invoiceAmount}`)} + 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> - {:else} - <div class="w-full md:w-[300px] h-[475px] md:h-[485px] animate-pulse bg-gray-400 rounded-xl" /> - {/if} -</div> + {:else} + <div + class="w-full md:w-[300px] h-[475px] md:h-[485px] animate-pulse bg-gray-400 rounded-xl" + /> + {/if} + </div> +{/if} |
