aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorsecondl1ght <[email protected]>2022-07-30 14:00:08 -0600
committersecondl1ght <[email protected]>2022-07-30 14:00:08 -0600
commitdd4f645ba8839de54418b59f36119254338a447c (patch)
tree058ff1e25e77f335d1476852336257378c738e3c /src
parent19ae0d9eb2f1a1c08b04f5c56e8ebd266ef32da8 (diff)
downloadcoinos-ui-dd4f645ba8839de54418b59f36119254338a447c.tar.gz
coinos-ui-dd4f645ba8839de54418b59f36119254338a447c.zip
add 404 component, remove duplicate redirects, loading splash, fix lgout
Diffstat (limited to 'src')
-rw-r--r--src/components/404.svelte16
-rw-r--r--src/components/index.js1
-rw-r--r--src/routes/[username]/index.svelte4
-rw-r--r--src/routes/[username]/receive.svelte16
-rw-r--r--src/routes/__layout.svelte3
-rw-r--r--src/routes/invoice/[amount].svelte336
-rw-r--r--src/routes/invoice/[id].svelte17
-rw-r--r--src/routes/logout/done.svelte2
8 files changed, 36 insertions, 359 deletions
diff --git a/src/components/404.svelte b/src/components/404.svelte
new file mode 100644
index 00000000..503316bb
--- /dev/null
+++ b/src/components/404.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/components/index.js b/src/components/index.js
index e41c3d4c..53f0fe99 100644
--- a/src/components/index.js
+++ b/src/components/index.js
@@ -8,3 +8,4 @@ export { default as Image } from './Image.svelte';
export { default as RegisterOrLogin } from './RegisterOrLogin.svelte';
export { default as AppHeader } from './AppHeader.svelte';
export { default as LoadingSplash } from './LoadingSplash.svelte';
+export { default as PageNotFound } from './404.svelte';
diff --git a/src/routes/[username]/index.svelte b/src/routes/[username]/index.svelte
index 91744aa3..90d0c04a 100644
--- a/src/routes/[username]/index.svelte
+++ b/src/routes/[username]/index.svelte
@@ -1,5 +1,5 @@
<script>
- import { AppHeader, Icon } from '$comp';
+ import { AppHeader, Icon, PageNotFound } from '$comp';
import { user } from '$lib/store';
export let username;
</script>
@@ -22,4 +22,6 @@
</div>
</div>
</div>
+{:else}
+ <PageNotFound />
{/if}
diff --git a/src/routes/[username]/receive.svelte b/src/routes/[username]/receive.svelte
index 5865d5e5..50fddbed 100644
--- a/src/routes/[username]/receive.svelte
+++ b/src/routes/[username]/receive.svelte
@@ -1,23 +1,11 @@
<script>
// in the future we will want to allow users to set their fiat currency in the settings
- import { onMount } from 'svelte';
- import { AppHeader, Icon, LoadingSplash } from '$comp';
+ import { AppHeader, Icon } from '$comp';
import { goto } from '$app/navigation';
import { invoiceAmount, invoiceAmountFiat, rate, user } from '$lib/store';
import { post } from '$lib/utils';
import { page } from '$app/stores';
- onMount(async () => {
- if (browser) {
- let { default: toast } = await import('@zerodevx/svelte-toast');
-
- if (!$user && typeof window !== 'undefined') {
- window.location = '/login';
- toast.push('Please login to continue.');
- }
- }
- });
-
let useFiat = true;
let amountFiat = 0;
let amountSats = 0;
@@ -196,6 +184,4 @@
/>
{/if}
</div>
-{:else}
- <LoadingSplash />
{/if}
diff --git a/src/routes/__layout.svelte b/src/routes/__layout.svelte
index 85f5a817..0b9a9a64 100644
--- a/src/routes/__layout.svelte
+++ b/src/routes/__layout.svelte
@@ -7,6 +7,7 @@
import { page, session } from '$app/stores';
import { browser } from '$app/env';
import { goto } from '$app/navigation';
+ import { LoadingSplash } from '$comp';
browser && ($token ||= $session.token);
let protectedRoutes = [/receive/];
@@ -27,4 +28,6 @@
{#if ready}
<SvelteToast />
<slot />
+{:else}
+ <LoadingSplash />
{/if}
diff --git a/src/routes/invoice/[amount].svelte b/src/routes/invoice/[amount].svelte
deleted file mode 100644
index 27140519..00000000
--- a/src/routes/invoice/[amount].svelte
+++ /dev/null
@@ -1,336 +0,0 @@
-<script>
- import { browser } from '$app/env';
- import { rate, user, invoiceAmount, invoiceAmountFiat } from '$lib/store';
- import { Icon, LoadingSplash } from '$comp';
- import { goto } from '$app/navigation';
- import { onMount } from 'svelte';
-
- export let text;
- export let amount;
-
- let tipPercent = 0;
- const setRate = ($invoiceAmountFiat / $invoiceAmount) * 100000000;
-
- $: tipAmount = customTipAmount
- ? customTipAmount < 0
- ? (customTipAmount = 0)
- : customTipAmount
- : ($invoiceAmountFiat / 100) * tipPercent;
-
- $: tipAmountFormatted = new Intl.NumberFormat('en-US', {
- style: 'currency',
- currency: 'USD'
- }).format(tipAmount);
-
- $: tipAmountSats = new Intl.NumberFormat('en-US', { maximumFractionDigits: 0 }).format(
- tipAmount / (setRate / 100000000)
- );
-
- $: totalAmountSats = new Intl.NumberFormat('en-US', { maximumFractionDigits: 0 }).format(
- $invoiceAmount + parseFloat(tipAmountSats.replace(/,/g, ''))
- );
-
- $: totalAmountFormatted = new Intl.NumberFormat('en-US', {
- style: 'currency',
- currency: 'USD'
- }).format($invoiceAmountFiat + tipAmount);
-
- const invoiceAmountFormatted = new Intl.NumberFormat('en-US', {
- maximumFractionDigits: 0
- }).format($invoiceAmount);
-
- const invoiceAmountFiatFormatted = new Intl.NumberFormat('en-US', {
- style: 'currency',
- currency: 'USD'
- }).format($invoiceAmountFiat);
-
- let customTipAmount;
-
- const tipAmounts = ['None', '10%', '15%', '20%'];
-
- const handleTipButtonClick = (amount) => {
- customTipAmount = '';
- if (amount === 'None') {
- tipPercent = 0;
- } else {
- tipPercent = amount.slice(0, 2);
- }
- };
-
- const handleCustomTipAmount = (e) => {
- tipPercent = 0;
- customTipAmount = e.target.value;
- };
-
- onMount(async () => {
- if (browser) {
- let { default: QRCodeStyling } = await import('qr-code-styling');
- let { default: toast } = await import('@zerodevx/svelte-toast');
-
- if (!$user && typeof window !== 'undefined') {
- toast.push('Please login to continue.');
- window.location = '/login';
- }
-
- const qrCode = new QRCodeStyling({
- width: window.screen.width < 640 ? 250 : 300,
- type: 'svg',
- data: text,
- image: '/images/invoice.svg',
- backgroundOptions: {
- color: 'rgba(0, 0, 0, 0)'
- },
- dotsOptions: {
- type: 'rounded'
- },
- imageOptions: {
- hideBackgroundDots: false
- }
- });
-
- qrCode.append(document.getElementById('qr'));
- }
- });
-
- let showMobileTip = false;
-
- const handleBackButton = () => {
- if (showMobileTip) {
- tipPercent = 0;
- customInput.value = '';
- customTipAmount = 0;
- tipAmount = 0;
- showMobileTip = false;
- } else {
- goto('/receive');
- }
- };
-
- let customInput;
-
- let qrSkeleton = true;
- setTimeout(() => (qrSkeleton = false), 1000);
-</script>
-
-{#if $user}
- <div class:full-shadow={showMobileTip}>
- <button class="ml-5 md:ml-20 mt-5 md:mt-10" on:click={handleBackButton}>
- <Icon icon="arrow-left" style="w-10" />
- </button>
-
- <div class="flex justify-center items-center mb-20 md: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="absolute {showMobileTip
- ? 'bottom-0'
- : '-bottom-full'} bg-white p-6 md:p-0 rounded-t-3xl md:rounded-none transition-all md:transition-none ease-in-out duration-500 left-0 md:static text-center space-y-5"
- >
- <h1 class="hidden md:block 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>
-
- <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-16 md: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
- bind:this={customInput}
- 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 {showMobileTip
- ? !customTipAmount && !tipAmount
- ? 'opacity-50'
- : 'opacity-100'
- : !customTipAmount
- ? 'opacity-50'
- : 'opacity-100'}"
- disabled={showMobileTip ? !customTipAmount && !tipAmount : !customTipAmount}
- >Done</button
- >
- </div>
- </div>
- </div>
-
- <div
- class="hidden md:block 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">
- <button
- class="block md:hidden bg-black {showMobileTip
- ? 'text-white/50'
- : 'text-white'} rounded-xl px-6 py-3 block text-sm font-semibold mx-auto flex justify-center items-center"
- on:click={() => (showMobileTip = true)}
- disabled={showMobileTip}
- >
- <svg
- width="24"
- height="24"
- class="mr-1"
- viewBox="0 0 24 24"
- fill="none"
- xmlns="http://www.w3.org/2000/svg"
- >
- <path
- d="M4.31802 6.31802C2.56066 8.07538 2.56066 10.9246 4.31802 12.682L12.0001 20.364L19.682 12.682C21.4393 10.9246 21.4393 8.07538 19.682 6.31802C17.9246 4.56066 15.0754 4.56066 13.318 6.31802L12.0001 7.63609L10.682 6.31802C8.92462 4.56066 6.07538 4.56066 4.31802 6.31802Z"
- stroke="currentColor"
- stroke-width="2"
- stroke-linecap="round"
- stroke-linejoin="round"
- />
- </svg> Add a tip
- </button>
-
- <span class="text-secondary block"
- >Scan to pay <span class="text-black font-semibold">{$user.username}</span></span
- >
-
- <div
- id="qr"
- class="border {showMobileTip
- ? 'border-gray-400'
- : 'border-lightgrey'} rounded-3xl block md:flex justify-center items-center h-[300px] w-[250px] md:w-[300px] relative"
- >
- <div
- class="z-100 h-[300px] w-[250px] md:w-[300px] animate-pulse absolute top-0 left-0 bg-gray-400 rounded-3xl {qrSkeleton
- ? 'block'
- : 'hidden'}"
- />
- </div>
-
- <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>
- {: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>
-{:else}
- <LoadingSplash />
-{/if}
-
-<style>
- #slider {
- -webkit-appearance: none;
- width: 100%;
- height: 6px;
- border-radius: 5px;
- background: #eaecef;
- outline: none;
- }
-
- #slider:active {
- background-color: black;
- }
-
- #slider::-webkit-slider-thumb {
- -webkit-appearance: none;
- appearance: none;
- width: 25px;
- height: 25px;
- border-radius: 50%;
- background: black;
- cursor: pointer;
- }
-
- #slider::-moz-range-thumb {
- width: 25px;
- height: 25px;
- border-radius: 50%;
- background: black;
- cursor: pointer;
- }
-
- input[type='number']::-webkit-inner-spin-button,
- input[type='number']::-webkit-outer-spin-button {
- -webkit-appearance: none;
- }
-
- input[type='number'] {
- -moz-appearance: textfield;
- }
-
- .full-shadow {
- box-shadow: inset 0 0 0 1000px rgba(0, 0, 0, 0.25);
- }
-</style>
diff --git a/src/routes/invoice/[id].svelte b/src/routes/invoice/[id].svelte
index a9f3cefb..2ed1ba67 100644
--- a/src/routes/invoice/[id].svelte
+++ b/src/routes/invoice/[id].svelte
@@ -7,10 +7,6 @@
export let amount, rate, text;
- if (!$user && typeof window !== 'undefined') {
- window.location = '/login';
- }
-
$: amountFiat = parseFloat(((amount * rate) / 100000000).toFixed(2));
let tipPercent = 0;
@@ -104,6 +100,9 @@
};
let customInput;
+
+ let qrSkeleton = true;
+ setTimeout(() => (qrSkeleton = false), 1000);
</script>
{#if $user}
@@ -225,8 +224,14 @@
id="qr"
class="border {showMobileTip
? 'border-gray-400'
- : 'border-lightgrey'} rounded-3xl block md:flex justify-center items-center"
- />
+ : 'border-lightgrey'} rounded-3xl block md:flex justify-center items-center h-[300px] w-[250px] md:w-[300px] relative"
+ >
+ <div
+ class="z-100 h-[300px] w-[250px] md:w-[300px] animate-pulse absolute top-0 left-0 bg-gray-400 rounded-3xl {qrSkeleton
+ ? 'block'
+ : 'hidden'}"
+ />
+ </div>
<div class="px-5 space-y-3">
<div class="flex justify-between">
diff --git a/src/routes/logout/done.svelte b/src/routes/logout/done.svelte
index 50fb766e..fe526357 100644
--- a/src/routes/logout/done.svelte
+++ b/src/routes/logout/done.svelte
@@ -8,6 +8,6 @@
$token = null;
$user = null;
close();
- goto('/');
});
+ goto('/');
</script>