diff options
| author | Adam Soltys <[email protected]> | 2022-10-03 23:13:49 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2022-10-03 23:13:49 -0700 |
| commit | 63f1a6780bab85ebb48ca1fc142cc6beaf772faa (patch) | |
| tree | b498ac8dd1a8ac5ffd517e6a8050399d9d7a86a1 | |
| parent | 8906099f391acf19f7b8eb91527b027cedd65b5e (diff) | |
| download | coinos-ui-63f1a6780bab85ebb48ca1fc142cc6beaf772faa.tar.gz coinos-ui-63f1a6780bab85ebb48ca1fc142cc6beaf772faa.zip | |
refactoring
42 files changed, 252 insertions, 541 deletions
diff --git a/package.json b/package.json index f707385e..5663853d 100644 --- a/package.json +++ b/package.json @@ -26,8 +26,8 @@ "prettier-plugin-svelte": "^2.7.1", "qr-code-styling": "1.6.0-rc.1", "qr-scanner": "^1.4.1", + "screenfull": "^6.0.2", "svelte": "^3.50.1", - "svelte-fullscreen": "^2.0.0", "svelte-outclick": "^3.1.0", "svelte-pincode": "^2.1.2", "svelte-preprocess": "^4.10.7", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 578f5590..4538dda2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,8 +17,8 @@ specifiers: prettier-plugin-svelte: ^2.7.1 qr-code-styling: 1.6.0-rc.1 qr-scanner: ^1.4.1 + screenfull: ^6.0.2 svelte: ^3.50.1 - svelte-fullscreen: ^2.0.0 svelte-outclick: ^3.1.0 svelte-pincode: ^2.1.2 svelte-preprocess: ^4.10.7 @@ -43,8 +43,8 @@ devDependencies: prettier-plugin-svelte: 2.7.1_nk6d2fkgcllkkdynqbuearcure qr-code-styling: 1.6.0-rc.1 qr-scanner: 1.4.1 + screenfull: 6.0.2 svelte: 3.50.1 - svelte-fullscreen: 2.0.0 svelte-outclick: 3.1.0 svelte-pincode: 2.1.2 svelte-preprocess: 4.10.7_r763xggw3my2ousygwguxmp6ru @@ -1438,9 +1438,9 @@ packages: rimraf: 2.7.1 dev: true - /screenfull/5.2.0: - resolution: {integrity: sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==} - engines: {node: '>=0.10.0'} + /screenfull/6.0.2: + resolution: {integrity: sha512-AQdy8s4WhNvUZ6P8F6PB21tSPIYKniic+Ogx0AacBMjKP1GUHN2E9URxQHtCusiwxudnCKkdy4GrHXPPJSkCCw==} + engines: {node: ^14.13.1 || >=16.0.0} dev: true /secp256k1/4.0.3: @@ -1528,12 +1528,6 @@ packages: engines: {node: '>= 0.4'} dev: true - /svelte-fullscreen/2.0.0: - resolution: {integrity: sha512-Sg03gZAyYtW7gqTA9WoFXY2m4CkFmRFu/+n7bmGJnYt/qxtO0N2tdQ61lZwbgN2AAMh2zF/185CTBI9vv3zvKQ==} - dependencies: - screenfull: 5.2.0 - dev: true - /svelte-hmr/[email protected]: resolution: {integrity: sha512-Aw21SsyoohyVn4yiKXWPNCSW2DQNH/76kvUnE9kpt4h9hcg9tfyQc6xshx9hzgMfGF0kVx0EGD8oBMWSnATeOg==} engines: {node: ^12.20 || ^14.13.1 || >= 16} diff --git a/src/components/AppHeader.svelte b/src/components/AppHeader.svelte index 62cfd940..fca11272 100644 --- a/src/components/AppHeader.svelte +++ b/src/components/AppHeader.svelte @@ -1,13 +1,16 @@ <script> import OutClick from 'svelte-outclick'; - import { subject, user, newPayment, colorTheme, tempProfileFiles } from '$lib/store'; + import { newPayment, colorTheme, tempProfileFiles } from '$lib/store'; import { goto } from '$app/navigation'; import { Icon } from '$comp'; import { t } from '$lib/translations'; import { page } from '$app/stores'; + export let data; export let avatarPosition = 'left-[calc(50vw-64px)] bottom-[-64px]'; + let { subject, user } = data; + const menuButtons = [ { stringID: 'nav.dashboard', icon: 'dash', goto: 'dashboard' }, { stringID: 'nav.settings', icon: 'settings', goto: 'settings' }, @@ -22,34 +25,34 @@ goto('/logout'); } else { showMenu = false; - goto(`/${$user.username + '/' + item}`); + goto(`/${user.username + '/' + item}`); } }; $: background = $tempProfileFiles && $tempProfileFiles.banner ? `url(${$tempProfileFiles.banner})` - : $subject?.banner - ? `url(/api/public/${$subject.username}-banner.png)` + : subject?.banner + ? `url(/api/public/${subject.username}-banner.png)` : undefined; </script> <header class="bg-gradient-to-r {$colorTheme} h-[175px] w-full relative" style:background> <nav class="flex justify-end items-center space-x-4 p-5"> - {#if $user} - <a href={`/${$user.username}/receive`}> + {#if user} + <a href={`/${user.username}/receive`}> <button class="bg-white p-2 rounded-full w-12 h-12 drop-shadow-xl border border-black/10 {$page - .url.pathname === `/${$user.username}/receive` + .url.pathname === `/${user.username}/receive` ? 'opacity-100' : 'opacity-70 hover:opacity-80'}" ><Icon icon="numpad" style="mx-auto" /> </button> </a> - <a href={`/${$user.username}/transactions`}> + <a href={`/${user.username}/transactions`}> <button class="bg-white p-2 rounded-full w-12 h-12 drop-shadow-xl border border-black/10 {$page - .url.pathname === `/${$user.username}/transactions` + .url.pathname === `/${user.username}/transactions` ? 'opacity-100' : 'opacity-70 hover:opacity-80'} relative" ><Icon icon="clock" style="mx-auto" /> @@ -65,10 +68,10 @@ {/if} </button> </a> - <a href={`/${$user.username}`}> + <a href={`/${user.username}`}> <button class="bg-white p-2 rounded-full w-12 h-12 drop-shadow-xl border border-black/10 {$page - .url.pathname === `/${$user.username}` + .url.pathname === `/${user.username}` ? 'opacity-100' : 'opacity-70 hover:opacity-80'}" ><Icon icon="profile" style="mx-auto" /> @@ -78,9 +81,9 @@ <OutClick on:outclick={() => (showMenu = false)}> <button class="bg-white p-2 rounded-full w-12 h-12 drop-shadow-xl border border-black/10 {$page - .url.pathname === `/${$user.username}/dashboard` || - $page.url.pathname === `/${$user.username}/settings` || - $page.url.pathname === `/${$user.username}/support` + .url.pathname === `/${user.username}/dashboard` || + $page.url.pathname === `/${user.username}/settings` || + $page.url.pathname === `/${user.username}/support` ? 'opacity-100' : `opacity-70 hover:opacity-80 ${showMenu ? 'opacity-80' : ''}`}" on:click={() => (showMenu = !showMenu)} @@ -114,18 +117,18 @@ </a> {/if} </nav> - {#if $subject?.profile} + {#if subject?.profile} <div class="absolute top-[111px] {avatarPosition} rounded-full border-4 border-white overflow-hidden w-32 h-32" > - <a href={`/${$subject.username}`}> - <img - src={$tempProfileFiles && $tempProfileFiles.profile - ? $tempProfileFiles.profile - : `/api/public/${$subject.username}-profile.png`} - class="w-full h-full object-cover object-center overflow-hidden" - /> - </a> + <a href={`/${subject.username}`}> + <img + src={$tempProfileFiles && $tempProfileFiles.profile + ? $tempProfileFiles.profile + : `/api/public/${subject.username}-profile.png`} + class="w-full h-full object-cover object-center overflow-hidden" + /> + </a> </div> {:else} <div diff --git a/src/components/LandingHeader.svelte b/src/components/LandingHeader.svelte index adeac98e..1f12e049 100644 --- a/src/components/LandingHeader.svelte +++ b/src/components/LandingHeader.svelte @@ -2,7 +2,6 @@ import { goto } from '$app/navigation'; import { scroll } from '$lib/utils'; import { Icon } from '$comp'; - import { user } from '$lib/store'; import { t } from '$lib/translations'; export let howItWorks; @@ -32,7 +31,7 @@ > <button class="hover:opacity-80" on:click={() => scroll(faq)}>{$t('faq.header')}</button> <button class="hover:opacity-80" on:click={() => scroll(about)}>{$t('about.header')}</button> - {#if !$user} + {#if !user} <button class="border rounded-full px-6 py-2 font-bold hover:opacity-80" on:click={() => goto('/register')} @@ -47,7 +46,7 @@ {:else} <button class="border rounded-full px-6 py-2 font-bold" - on:click={() => goto(`/${$user.username}/dashboard`)} + on:click={() => goto(`/${user.username}/dashboard`)} >{$t('nav.account')} </button> <button @@ -80,7 +79,7 @@ <button on:click={() => mobileMenuButtonClick(about)} class="block" >{$t('about.header')}</button > - {#if !$user} + {#if !user} <button class="border rounded-full px-6 py-2 font-bold block w-full" on:click={() => goto('/register')} @@ -95,7 +94,7 @@ {:else} <button class="border rounded-full px-6 py-2 font-bold block" - on:click={() => goto(`/${$user.username}/dashboard`)} + on:click={() => goto(`/${user.username}/dashboard`)} >{$t('nav.account')} </button> <button diff --git a/src/components/LandingHero.svelte b/src/components/LandingHero.svelte index 466a6194..74c192fb 100644 --- a/src/components/LandingHero.svelte +++ b/src/components/LandingHero.svelte @@ -1,8 +1,9 @@ <script> import { goto } from '$app/navigation'; import { Icon, Image } from '$comp'; - import { user } from '$lib/store'; import { t } from '$lib/translations'; + + export let user; </script> <div class="mt-[96.88px] md:mt-0"> @@ -22,18 +23,18 @@ > {$t('landing.subheader')} </h2> - {#if !$user} + {#if !user} <div class="flex justify-center"> - <button - class="bg-black text-white border rounded-full px-6 py-2 font-bold hover:opacity-80" - on:click={() => goto('/register')} - > - {$t('nav.startInSeconds')} - </button> + <a href="/register"> + <button + class="bg-black text-white border rounded-full px-6 py-2 font-bold hover:opacity-80" + > + {$t('nav.startInSeconds')} + </button> + </a> </div> {/if} </div> - <!-- hero image --> <Image image="hero-image" style="w-full md:w-2/3 max-w-5xl mx-auto mt-20" /> </div> diff --git a/src/components/LocationsMap.svelte b/src/components/LocationsMap.svelte index 8a8599c4..6d0b086e 100644 --- a/src/components/LocationsMap.svelte +++ b/src/components/LocationsMap.svelte @@ -77,7 +77,7 @@ locations.forEach(({ lat, lng, info }) => { let marker = L.marker([lat, lng]); - marker.bindPopup(info); + marker.bindPopup(info); markers.addLayer(marker); }); diff --git a/src/components/Numpad.svelte b/src/components/Numpad.svelte index 3555688c..9de4a0dc 100644 --- a/src/components/Numpad.svelte +++ b/src/components/Numpad.svelte @@ -1,6 +1,6 @@ <script> import { Left, Icon } from '$comp'; - import { selectedRate, user } from '$lib/store'; + import { selectedRate } from '$lib/store'; import { f, s, post, warning, sats } from '$lib/utils'; import { t } from '$lib/translations'; @@ -32,7 +32,7 @@ $: amountSatsFormatted = s(amountSats); - $: amountFiatConverted = f(amountSats * ($selectedRate / sats), $user.currency); + $: amountFiatConverted = f(amountSats * ($selectedRate / sats), currency); $: amountSatsConverted = s(amountFiat / ($selectedRate / sats)); @@ -90,13 +90,14 @@ <div class="text-center"> <div class="text-5xl md:text-6xl font-semibold tracking-widest mb-1"> {useFiat ? `${symbol}${amountFiat}` : amountSatsFormatted}<span - class="tracking-normal text-base font-normal">{useFiat ? $user.currency : 'SAT'}</span + class="tracking-normal text-base font-normal">{useFiat ? currency : 'SAT'}</span > </div> <span class="text-secondary mr-1" >{useFiat ? `${amountSatsConverted} SAT` : amountFiatConverted}</span > <button + type="button" on:click={() => { if (useFiat) { amountSats = parseInt((amountFiat / ($selectedRate / sats)).toFixed(0)); @@ -115,13 +116,15 @@ {#each numPad as value} {#if value === '<'} <button + type="button" class="bg-primary rounded-xl py-4 px-8 font-semibold active:bg-black active:text-white flex justify-center items-center hover:opacity-80" on:click={() => handleInput(value)} > - <Left /> + <Left /> </button> {:else} <button + type="button" class="bg-primary rounded-xl py-4 px-8 font-semibold active:bg-black active:text-white hover:opacity-80" on:click={() => handleInput(value)}>{value}</button > diff --git a/src/components/Qr.svelte b/src/components/Qr.svelte index 35146ec3..988faf25 100644 --- a/src/components/Qr.svelte +++ b/src/components/Qr.svelte @@ -1,17 +1,20 @@ <script> + import screenfull from 'screenfull'; import { browser } from '$app/environment'; import { onMount } from 'svelte'; import { copy } from '$lib/utils'; export let image, text, qr, disabled; + let toggle = () => screenfull.toggle(qr.firstChild); + $: update(text); - let update = async (text) => { + let update = async (text, fullscreen) => { if (!(browser && text)) return; let { default: QRCodeStyling } = await import('qr-code-styling'); const qrCode = new QRCodeStyling({ - width: window.screen.width < 640 ? 250 : 300, + width: 300, type: 'canvas', data: text, backgroundOptions: { @@ -35,22 +38,14 @@ }; </script> -<div - bind:this={qr} - on:click={() => { - if (!disabled) copy(text); - }} -/> +<div bind:this={qr} on:click={toggle} /> <style> div { - @apply px-5 - md:px-0 - w-[300px] + @apply w-[300px] h-[300px] rounded-3xl block - md:flex justify-center items-center cursor-pointer diff --git a/src/components/RegisterOrLogin.svelte b/src/components/RegisterOrLogin.svelte index 8f10fadd..de886314 100644 --- a/src/components/RegisterOrLogin.svelte +++ b/src/components/RegisterOrLogin.svelte @@ -1,14 +1,11 @@ <script> - import { browser } from '$app/environment'; - import { page } from '$app/stores'; - import { tick } from 'svelte'; + import { enhance } from '$app/forms'; import { Icon } from '$comp'; - import { focus, post, failure } from '$lib/utils'; - import { redirect, user, token } from '$lib/store'; - import { auth } from '$lib/socket'; - import { goto } from '$app/navigation'; + import { focus } from '$lib/utils'; + import { redirect } from '$lib/store'; import { t } from '$lib/translations'; + export let form; export let pageID; let username, @@ -22,9 +19,6 @@ register: '/register', signIn: '/login' }[pageID]; - - // TODO: move to server side - $: if (browser && $user) goto(`/${$user.username}/receive`); </script> <div class="pt-10"> @@ -38,7 +32,11 @@ <div class="shadow-xl rounded-3xl p-10 pb-12 space-y-5 w-full mx-5 md:mx-0 md:w-[400px]"> <h1 class="text-2xl font-bold text-center">{$t('login.' + pageID)}</h1> - <form class="space-y-5" {action} method="POST"> + {#if form?.error} + Login failed + {/if} + + <form class="space-y-5" {action} method="POST" use:enhance> {#if $redirect} <input type="hidden" name="redirect" value={$redirect} /> {/if} diff --git a/src/lib/parse.js b/src/lib/parse.js index 95d0a8b6..e69de29b 100644 --- a/src/lib/parse.js +++ b/src/lib/parse.js @@ -1,37 +0,0 @@ -// import bolt11 from 'bolt11'; -import validate from 'bitcoin-address-validation'; -import bip21 from 'bip21'; -import { get } from '$lib/utils'; -import { goto } from '$app/navigation'; - -let debounce; -export default async (t) => { - if (!t) return; - console.log('parsing'); - - // lightning - if (t.startsWith('ln')) { - goto(`/send/lightning/${t}`); - } - - // bitcoin - if (validate(t)) { - console.log('bitcoin'); - goto(`/send/bitcoin/${t}`); - } - - // ln address - if (t.includes('@') && t.includes('.')) { - console.log('ln address'); - let [name, domain] = t.split('@'); - try { - clearTimeout(debounce); - await new Promise((r) => (debounce = setTimeout(r, 1500))); - let lnurl = await get(`/encode?domain=${domain}&name=${name}`); - console.log('lnurl', lnurl); - } catch (e) {} - } - - // user - console.log('username'); -}; diff --git a/src/lib/socket.js b/src/lib/socket.js index ed3fa02e..dac2935e 100644 --- a/src/lib/socket.js +++ b/src/lib/socket.js @@ -1,16 +1,13 @@ import { get } from 'svelte/store'; -import { rate, user, token, invoices, newPayment } from '$lib/store'; +import { invoices, newPayment, rate } from '$lib/store'; import { success } from '$lib/utils'; import { env } from '$env/dynamic/public'; const socketUrl = env.PUBLIC_SOCKET; -let interval, socket; +let interval, socket, token; -export const auth = () => { - let t = get(token); - if (t) send('login', t); -}; +export const auth = () => token && send('login', token); export const send = (type, data) => { socket?.readyState === 1 && socket.send(JSON.stringify({ type, data })); @@ -31,11 +28,7 @@ export const messages = (data) => ({ } }, - connected: auth, - - login() { - user.set(data); - } + connected: auth }); const initialReconnectDelay = 1000; @@ -43,7 +36,9 @@ const maxReconnectDelay = 16000; let currentReconnectDelay = initialReconnectDelay; -export function connect() { +export function connect(t) { + token = t; + clearInterval(interval); if (socket) return auth(); diff --git a/src/lib/store.js b/src/lib/store.js index e7228158..c64ad39f 100644 --- a/src/lib/store.js +++ b/src/lib/store.js @@ -27,14 +27,9 @@ const persistLocal = (key, defaultValue) => { return s; }; -export const rate = writable(); export const redirect = writable(); -export const rates = writable(); +export const rate = writable(); export const selectedRate = writable(); -export const user = writable(); -export const subject = writable(); -export const invoiceAmount = writable(); -export const invoiceAmountFiat = writable(); export const token = persistSession('token'); export const invoices = writable({}); export const newPayment = persistLocal('newPayment'); diff --git a/src/lib/utils.js b/src/lib/utils.js index a7d0adaa..a4c77d58 100644 --- a/src/lib/utils.js +++ b/src/lib/utils.js @@ -109,11 +109,14 @@ export const info = (m) => { export const login = async (user, cookies) => { let maxAge = 30 * 24 * 60 * 60; let { token } = await post('/login', user); + console.log('logged in', token); let expires = new Date(); expires.setSeconds(expires.getSeconds() + maxAge); + console.log('cs'); cookies.set('token', token, { path: '/' }); + console.log('bs'); }; export const auth = (cookies) => ({ authorization: `Bearer ${cookies.get('token')}` }); @@ -128,11 +131,6 @@ export const f = (s, currency) => export const s = (s) => new Intl.NumberFormat('en-US', { maximumFractionDigits: 0 }).format(s); -export const toggleFullscreen = (el) => - document.fullscreenElement - ? document.exitFullscreen() - : el.requestFullscreen().catch(console.log); - export const sats = 100000000; export const back = () => { diff --git a/src/locales/en.json b/src/locales/en.json index 8ed35f47..1d1a9749 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -152,7 +152,7 @@ "settings": "Settings", "support": "Support" }, - "newSiteHeader": "Welcome to the <a href=\"/news\" class=\"underline underline-offset-4 text-black hover:opacity-80\" >new and improved coinos</a>, focused on merchant adoption! Looking for the old coinos? Visit <a href=\"https://classic.coinos.io\" class=\"underline underline-offset-4 text-black hover:opacity-80\">classic.coinos.io</a>.", + "newSiteHeader": "Welcome to the <a href=\"/news\" class=\"underline underline-offset-4 text-black hover:opacity-80\" >new and improved coinos</a>, focused on merchant adoption! Looking for the old coinos? Visit <a href=\"https://classic.coinos.io\" class=\"underline underline-offset-4 text-black hover:opacity-80\">classic.coinos.io</a>.", "news": { "header": "News", "subheader": "Latest Updates", diff --git a/src/routes/+layout.server.js b/src/routes/+layout.server.js index f5fa1059..4beaad93 100644 --- a/src/routes/+layout.server.js +++ b/src/routes/+layout.server.js @@ -16,7 +16,7 @@ export async function load({ cookies, request, url, params }) { subject = await get(`/users/${params.username}`); } - if (token) { + if (token && token !== 'undefined') { try { user = await get('/me', { accept: 'application/json', authorization: `Bearer ${token}` }); } catch (e) { @@ -36,7 +36,7 @@ export async function load({ cookies, request, url, params }) { } } - let rate = await get('/rate'); + let rate = await get('/rate'); rates = await get('/rates'); return { subject, user, token, rate, rates }; diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index f3a03440..118caa48 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -3,7 +3,7 @@ import '../app.css'; import { onMount } from 'svelte'; import { connect } from '$lib/socket'; - import { user, subject, token, rate, rates, selectedRate } from '$lib/store'; + import { selectedRate, rate } from '$lib/store'; import { page } from '$app/stores'; import { browser } from '$app/environment'; import { goto } from '$app/navigation'; @@ -14,14 +14,10 @@ const localeLocalStorageKey = 'sveltekit-i18n-locale'; export let data; + let { user, rate: r, token, rates } = data; + $rate = r; - $: $subject = data.subject; - $: $token = data.token; - $: $user = data.user; - $: $rate = data.rate; - - $rates = data.rates; - $: $selectedRate = data.user && $rate * (data.rates[data.user.currency] / data.rates.USD); + $: $selectedRate = user && $rate * (rates[user.currency] / rates.USD); onMount(() => { let localStorageLocale = localStorage.getItem(localeLocalStorageKey); @@ -32,13 +28,13 @@ }); if (protectedRoutes.find((p) => $page.url.pathname.match(p))) { - if (!$token) { + if (!token) { goto('/login'); warning($t('error.signIn')); } } - connect(); + connect(token); }); </script> diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index d7df57d8..872348fd 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -12,6 +12,9 @@ import { t } from '$lib/translations'; + export let data; + let { user } = data; + let howItWorks; let faq; let about; @@ -28,24 +31,20 @@ <!-- banner --> <div class="mt-[101.7px] md:mt-0 w-full text-center py-4 border border-b-black text-secondary"> <p> - {@html $t('newSiteHeader')} + {@html $t('newSiteHeader')} </p> </div> -<LandingHeader {howItWorks} {faq} {about} /> +<LandingHeader {howItWorks} {faq} {about} {user} /> <main class="space-y-40 py-20 md:py-32 lg:py-36 xl:py-40 px-5 md:px-0"> - <!-- hero --> - <LandingHero /> - - <!-- landing info 1 --> + <LandingHero {user} /> <LandingInfoCard image="lightning-qr" title={$t('landing.info1.title')} description={$t('landing.info1.description')} /> - <!-- landing info 2 --> <LandingInfoCard image="phone-checkout" title={$t('landing.info2.title')} order="reverse"> {$t('landing.info2.description1')} <br /><br /> @@ -54,7 +53,6 @@ {@html $t('landing.info2.description3')} </LandingInfoCard> - <!-- landing info 3 --> <div> <LandingInfoCard image="customize" @@ -64,7 +62,6 @@ <div bind:this={howItWorks} /> </div> - <!-- how it works --> <div> <h3 class="text-5xl font-medium mb-10 text-center">{$t('howItWorks.header')}</h3> <div class="grid lg:grid-cols-3 space-y-10 lg:space-y-0 text-center"> @@ -75,7 +72,6 @@ <div bind:this={faq} /> </div> - <!-- faq --> <div> <div class="space-y-10"> <h3 class="text-5xl font-medium text-center">{$t('faq.header')}</h3> @@ -86,7 +82,6 @@ <div bind:this={about} /> </div> - <!-- about --> <div> <About /> </div> diff --git a/src/routes/[username]/+layout.svelte b/src/routes/[username]/+layout.svelte new file mode 100644 index 00000000..b2efa894 --- /dev/null +++ b/src/routes/[username]/+layout.svelte @@ -0,0 +1,7 @@ +<script> + import { AppHeader } from '$comp'; + export let data; +</script> + +<AppHeader {data} /> +<slot /> diff --git a/src/routes/[username]/+page.svelte b/src/routes/[username]/+page.svelte index d1b6d223..5eab4ad2 100644 --- a/src/routes/[username]/+page.svelte +++ b/src/routes/[username]/+page.svelte @@ -1,7 +1,7 @@ <script> import { browser } from '$app/environment'; import { onMount } from 'svelte'; - import { AppHeader, Icon, PageNotFound } from '$comp'; + import { Icon, PageNotFound } from '$comp'; import { subject, user } from '$lib/store'; import { copy } from '$lib/utils'; import { t } from '$lib/translations'; @@ -35,8 +35,6 @@ let followed = false; </script> -<AppHeader /> - <div class="flex xl:block justify-center items-center my-20 px-3"> <div class="space-y-10 xl:space-y-0"> <div class="xl:ml-[calc(15vw-64px)] space-y-2 w-full md:w-72"> diff --git a/src/routes/[username]/customers/+page.svelte b/src/routes/[username]/customers/+page.svelte index 1935b156..e69de29b 100644 --- a/src/routes/[username]/customers/+page.svelte +++ b/src/routes/[username]/customers/+page.svelte @@ -1,5 +0,0 @@ -<script> - import { AppHeader } from '$comp'; -</script> - -<AppHeader /> diff --git a/src/routes/[username]/dashboard/+page.svelte b/src/routes/[username]/dashboard/+page.svelte index 1e55867d..c017fdc0 100644 --- a/src/routes/[username]/dashboard/+page.svelte +++ b/src/routes/[username]/dashboard/+page.svelte @@ -1,7 +1,7 @@ <script> import { f, s, post, failure, sats } from '$lib/utils'; import { tick } from 'svelte'; - import { AppHeader, Icon } from '$comp'; + import { Icon } from '$comp'; import { rate, selectedRate } from '$lib/store'; import { goto } from '$app/navigation'; import { t } from '$lib/translations'; @@ -43,8 +43,6 @@ $: accountBalanceSats = s(user.account.balance); </script> -<AppHeader avatarPosition="left-[calc(50vw-64px)] lg:left-[calc(15vw-64px)]" /> - <div class="text-center mx-auto lg:text-left lg:mx-0 lg:ml-[calc(15vw-64px)] mt-20 w-full md:w-72"> <h2 class="text-3xl font-semibold">{user.username}</h2> diff --git a/src/routes/[username]/receive/+page.server.js b/src/routes/[username]/receive/+page.server.js new file mode 100644 index 00000000..8d523213 --- /dev/null +++ b/src/routes/[username]/receive/+page.server.js @@ -0,0 +1,12 @@ +import { auth, post } from '$lib/utils'; + +export const actions = { + default: async ({ cookies, request, parent }) => { + let { rate, user } = await parent(); + let invoice = Object.fromEntries(await request.formData()); + invoice.rate = rate; + + let { uuid } = await post('/invoice', { invoice, user }, auth(cookies)); + throw redirect(303, `/invoice/${uuid}`); + } +}; diff --git a/src/routes/[username]/receive/+page.svelte b/src/routes/[username]/receive/+page.svelte index f79e2df5..3c65279d 100644 --- a/src/routes/[username]/receive/+page.svelte +++ b/src/routes/[username]/receive/+page.svelte @@ -1,216 +1,29 @@ <script> - import { AppHeader, Icon } from '$comp'; - import { goto } from '$app/navigation'; - import { invoiceAmount, invoiceAmountFiat, selectedRate, user } from '$lib/store'; - import { f, s, post, warning, sats } from '$lib/utils'; - import { page } from '$app/stores'; + import { Icon, Numpad } from '$comp'; import { t } from '$lib/translations'; + import { enhance } from '$app/forms'; - let useFiat = true; - let amountFiat = 0; - let amountSats = 0; - let loading = false; + export let data; + let amount; - $: amount = parseInt(useFiat ? Math.round(amountFiat / ($selectedRate / sats)) : amountSats); - - $: $invoiceAmount = parseInt(!amountSats ? amountFiat / ($selectedRate / sats) : amountSats); - - $: $invoiceAmountFiat = parseInt( - amountFiat === 0 ? amountSats * ($selectedRate / sats) : amountFiat - ); - - $: amountSatsFormatted = s(amountSats); - - $: amountFiatConverted = f(amountSats * ($selectedRate / sats), $user.currency); - - $: amountSatsConverted = s(amountFiat / ($selectedRate / sats)); - - const numPad = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '0', '<']; - - const handleInput = (value) => { - if (useFiat) { - if (amountFiat === 0 && value !== '.' && value !== '<' && value !== '0') { - amountFiat = value; - } else if ((amountFiat === 0 || amountFiat === '0') && value === '0') { - return; - } 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; - amountSats = 0; - } - } - } else if (value !== '.' && value !== '<' && parseInt(amountFiat + value) > $selectedRate) { - warning($t('user.receive.lessThan1BTCWarning')); - } else if (amountFiat !== 0 && amountFiat.match(/\.../)) { - return; - } else { - amountFiat = amountFiat + value; - } - } else { - if (value === '.') { - return; - } else if (!amountSats && value !== '<' && value !== '0') { - amountSats = parseInt(value); - } else if (value === '<') { - if (amountSats !== 0) { - amountSats = Math.floor(amountSats / 10); - if (amountSats.length === 0) { - amountSats = 0; - amountFiat = 0; - } - } - } else if (value !== '<' && parseInt(amountSats + value) > sats) { - warning($t('user.receive.lessThan1BTCWarning')); - } else { - amountSats = parseInt(amountSats + value); - } - } - }; - - let submit = async () => { - loading = true; - let { uuid } = await post('/invoice', { - amount, - rate: $selectedRate, - prompt: true, - username: $page.params.username - }); - goto(`/invoice/${uuid}`); - }; + let { currency } = data.user; </script> -{#if $user} - <AppHeader /> - - <div class="flex justify-center items-center mt-24 mb-3 px-3"> - {#if $selectedRate} - <div class="space-y-5"> - <!-- amounts --> - <div class="text-center"> - <div class="text-5xl md:text-6xl font-semibold tracking-widest mb-1"> - {useFiat - ? `${ - $user.currency === 'USD' || - $user.currency === 'CAD' || - $user.currency === 'AUD' || - $user.currency === 'NZD' || - $user.currency === 'MXN' || - $user.currency === 'BRL' || - $user.currency === 'HKD' || - $user.currency === 'TWD' - ? '$' - : $user.currency === 'JPY' || $user.currency === 'CNY' - ? '¥' - : $user.currency === 'GBP' - ? '£' - : $user.currency === 'EUR' - ? '€' - : $user.currency === 'KRW' - ? '₩' - : '' - }${amountFiat}` - : amountSatsFormatted}<span class="tracking-normal text-base font-normal" - >{useFiat ? $user.currency : 'SAT'}</span - > - </div> - <span class="text-secondary mr-1" - >{useFiat ? `${amountSatsConverted} SAT` : amountFiatConverted}</span - > - <button - on:click={() => { - if (useFiat) { - amountSats = parseInt((amountFiat / ($selectedRate / sats)).toFixed(0)); - } else { - amountFiat = - (amountSats * ($selectedRate / sats)).toFixed(2) > 0.0 - ? (amountSats * ($selectedRate / sats)).toFixed(2) - : 0; - } - useFiat = !useFiat; - }}><Icon icon="swap" style="inline hover:opacity-80" /></button - > - </div> - - <!-- 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 hover:opacity-80" - 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" - > - <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 hover:opacity-80" - on:click={() => handleInput(value)}>{value}</button - > - {/if} - {/each} - </div> +<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="prompt" value="true" /> - <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 {$invoiceAmount === - 0 || loading - ? 'opacity-50' - : 'opacity-100 hover:opacity-80'}" - on:click={submit} - disabled={$invoiceAmount === 0 || loading} - > - {#if loading} - <svg - class="mx-auto h-6 w-6 animate-spin text-white" - xmlns="http://www.w3.org/2000/svg" - fill="none" - viewBox="0 0 24 24" - > - <circle - class="opacity-25" - cx="12" - cy="12" - r="10" - stroke="currentColor" - stroke-width="4" - /> - <path - class="opacity-75" - fill="currentColor" - d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" - /> - </svg> - {:else} - <Icon icon="qr" style="mr-2" /> {$t('user.receive.showQR')} - {/if} - </button> - </div> - </div> - {:else} - <div - class="w-full md:w-[300px] h-[475px] md:h-[485px] animate-pulse bg-gray-400 rounded-xl" - /> - {/if} + <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} + > + <Icon icon="qr" style="mr-2" /> + {$t('user.receive.showQR')} + </button> </div> -{/if} +</form> diff --git a/src/routes/[username]/settings/+page.svelte b/src/routes/[username]/settings/+page.svelte index 978f537a..410ed1bf 100644 --- a/src/routes/[username]/settings/+page.svelte +++ b/src/routes/[username]/settings/+page.svelte @@ -3,7 +3,7 @@ import Pos from './_pos.svelte'; import Security from './_security.svelte'; - import { AppHeader, Icon } from '$comp'; + import { Icon } from '$comp'; import { t } from '$lib/translations'; import { failure, success, put } from '$lib/utils'; import { user, avatarUpload, bannerUpload } from '$lib/store'; @@ -35,8 +35,6 @@ }; </script> -<AppHeader /> - <form on:submit|preventDefault={save} class="mb-[154px]"> <div class="mt-24 mb-20 px-3 md:px-0 w-full md:w-[400px] mx-auto space-y-8"> <h1 class="text-center text-3xl md:text-4xl font-semibold mb-10"> diff --git a/src/routes/[username]/settings/_account.svelte b/src/routes/[username]/settings/_account.svelte index ff7676f4..8a20df43 100644 --- a/src/routes/[username]/settings/_account.svelte +++ b/src/routes/[username]/settings/_account.svelte @@ -1,13 +1,6 @@ <script> import { tick } from 'svelte'; - import { - user, - colorTheme, - rates, - tempProfileFiles, - avatarUpload, - bannerUpload - } from '$lib/store'; + import { colorTheme, tempProfileFiles, avatarUpload, bannerUpload } from '$lib/store'; import { Icon, Toggle, LocaleSelector } from '$comp'; import { t } from '$lib/translations'; import { upload } from '$lib/upload'; @@ -58,7 +51,7 @@ } }; - $: $user.password = $user.confirm = password; + $: user.password = user.confirm = password; </script> <div> @@ -69,13 +62,13 @@ <!-- TODO <div> <label for="email" class="font-bold mb-1 block">{$t('user.settings.email')}</label> - <input type="email" name="email" bind:value={$user.email} /> + <input type="email" name="email" bind:value={user.email} /> </div> --> <!-- TODO fix breaking changes when user updates this field --> <div> <label for="username" class="font-bold mb-1 block">{$t('user.settings.username')}</label> - <input disabled type="text" name="username" bind:value={$user.username} /> + <input disabled type="text" name="username" bind:value={user.username} /> </div> <div class="relative"> @@ -96,7 +89,7 @@ <div> <label for="address" class="font-bold mb-1 block">{$t('user.settings.businessAddress')}</label> - <input type="text" name="address" bind:value={$user.address} /> + <input type="text" name="address" bind:value={user.address} /> </div> <!-- TODO --> @@ -133,13 +126,13 @@ class="absolute w-full h-full object-cover object-center visible overflow-hidden" /> </div> - {:else if $user.profile} + {:else if user.profile} <div class="relative rounded-full overflow-hidden text-center w-20 h-20 my-auto hover:opacity-80 cursor-pointer" on:click={() => select('profile')} > <img - src={`/api/public/${$user.username}-profile.png`} + src={`/api/public/${user.username}-profile.png`} class="absolute w-full h-full object-cover object-center visible overflow-hidden" /> </div> @@ -183,9 +176,9 @@ class="w-full object-cover object-center visible overflow-hidden h-48 mb-4 hover:opacity-80" on:click={() => select('banner')} /> - {:else if $user.banner} + {:else if user.banner} <img - src={`/api/public/${$user.username}-banner.png`} + src={`/api/public/${user.username}-banner.png`} class="w-full object-cover object-center visible overflow-hidden h-48 mb-4 hover:opacity-80" on:click={() => select('banner')} /> diff --git a/src/routes/[username]/settings/_pos.svelte b/src/routes/[username]/settings/_pos.svelte index 3310e426..edf54d91 100644 --- a/src/routes/[username]/settings/_pos.svelte +++ b/src/routes/[username]/settings/_pos.svelte @@ -1,5 +1,4 @@ <script> - import { rates, user } from '$lib/store'; import { Icon, Toggle } from '$comp'; import { t } from '$lib/translations'; import { success, failure, put } from '$lib/utils'; diff --git a/src/routes/[username]/settings/_security.svelte b/src/routes/[username]/settings/_security.svelte index 1b8fb125..3c0009dc 100644 --- a/src/routes/[username]/settings/_security.svelte +++ b/src/routes/[username]/settings/_security.svelte @@ -32,7 +32,7 @@ if (setting2fa && token.length === 6) { await put('/enable2fa', { token }); success('2FA enabled'); - $user.twofa = 1; + user.twofa = 1; toggleEnabling(); } } catch (e) { @@ -46,7 +46,7 @@ if (disabling2fa && token.length === 6) { await put('/disable2fa', { token }); success('2FA disabled'); - $user.twofa = 0; + user.twofa = 0; toggleDisabling(); } } catch (e) { @@ -54,7 +54,7 @@ } }; - $: otpUri = `otpauth://totp/coinos:${$user.username}?secret=${$user.otpsecret}&period=30&digits=6&algorithm=SHA1&issuer=coinos`; + $: otpUri = `otpauth://totp/coinos:${user.username}?secret=${user.otpsecret}&period=30&digits=6&algorithm=SHA1&issuer=coinos`; </script> <!-- TODO @@ -66,7 +66,7 @@ {#if settingPin} <div class="flex my-4"> <div class="mx-auto"> - <Pincode bind:code bind:value={$user.pin} bind:this={pinInput}> + <Pincode bind:code bind:value={user.pin} bind:this={pinInput}> <PincodeInput /> <PincodeInput /> <PincodeInput /> @@ -110,7 +110,7 @@ <div class="text-center my-4"> {$t('user.settings.accountId')}<br /> - <b>{$user.otpsecret}</b> + <b>{user.otpsecret}</b> </div> <div class="text-center my-4"> @@ -136,7 +136,7 @@ <PincodeInput /> </Pincode> </div> - {:else if $user.twofa} + {:else if user.twofa} <button type="button" class="primary" on:click={toggleDisabling}> <Icon icon="mobile" style="mr-1" /> {$t('user.settings.twofaDisable')} diff --git a/src/routes/[username]/support/+page.svelte b/src/routes/[username]/support/+page.svelte index 663ba8a6..796f72ec 100644 --- a/src/routes/[username]/support/+page.svelte +++ b/src/routes/[username]/support/+page.svelte @@ -1,65 +1,58 @@ <script> - // this needs to be hooked up to the backend - import { AppHeader } from '$comp'; - import { user } from '$lib/store'; import { t } from '$lib/translations'; let email; let message; </script> -{#if $user} - <AppHeader /> +<div class="mt-24 mb-20"> + <h1 class="text-center text-3xl md:text-4xl font-semibold mb-10"> + {$t('user.support.header')} + </h1> - <div class="mt-24 mb-20"> - <h1 class="text-center text-3xl md:text-4xl font-semibold mb-10"> - {$t('user.support.header')} - </h1> + <form class="space-y-5 mx-auto w-11/12 md:w-[350px]"> + <div> + <label for="email" class="font-semibold">{$t('user.support.email')}</label> + <input + class="block border rounded-xl p-2 w-full" + type="email" + name="email" + bind:value={email} + required + /> + </div> - <form class="space-y-5 mx-auto w-11/12 md:w-[350px]"> - <div> - <label for="email" class="font-semibold">{$t('user.support.email')}</label> - <input - class="block border rounded-xl p-2 w-full" - type="email" - name="email" - bind:value={email} - required - /> - </div> + <div> + <label for="account" class="font-semibold">{$t('user.support.accountName')}</label> + <input + class="block border rounded-xl p-2 w-full" + type="text" + name="account" + required + disabled + value={user.username} + /> + </div> - <div> - <label for="account" class="font-semibold">{$t('user.support.accountName')}</label> - <input - class="block border rounded-xl p-2 w-full" - type="text" - name="account" - required - disabled - value={$user.username} - /> - </div> + <div> + <label for="message" class="font-semibold">{$t('user.support.message')}</label> + <textarea + rows={5} + class="block border rounded-xl p-2 w-full" + type="text" + name="message" + bind:value={message} + required + /> + </div> - <div> - <label for="message" class="font-semibold">{$t('user.support.message')}</label> - <textarea - rows={5} - class="block border rounded-xl p-2 w-full" - type="text" - name="message" - bind:value={message} - required - /> - </div> - - <button - disabled={!email || !message} - class="{!email || !message - ? 'opacity-50' - : 'opacity-100'} bg-black text-white font-bold rounded-xl py-3 w-full mx-auto {email && - message - ? 'hover:opacity-80' - : ''}">{$t('user.support.send')}</button - > - </form> - </div> -{/if} + <button + disabled={!email || !message} + class="{!email || !message + ? 'opacity-50' + : 'opacity-100'} bg-black text-white font-bold rounded-xl py-3 w-full mx-auto {email && + message + ? 'hover:opacity-80' + : ''}">{$t('user.support.send')}</button + > + </form> +</div> diff --git a/src/routes/[username]/transactions/[...page]/+page.svelte b/src/routes/[username]/transactions/[...page]/+page.svelte index a3e6850a..223418a3 100644 --- a/src/routes/[username]/transactions/[...page]/+page.svelte +++ b/src/routes/[username]/transactions/[...page]/+page.svelte @@ -1,5 +1,4 @@ <script> - import { AppHeader } from '$comp'; import { newPayment } from '$lib/store'; import { t } from '$lib/translations'; import { f, s, sats } from '$lib/utils'; @@ -15,8 +14,6 @@ $: data && ({ page, pages, total, transactions } = data); </script> -<AppHeader /> - <div class="mt-24 mb-20"> <h1 class="px-3 md:px-0 text-center text-3xl md:text-4xl font-semibold mb-10"> {$t('user.transactions.header')} @@ -27,7 +24,9 @@ {#if pages.length > 1} {#each pages as _, i} <a href={`/${user.username}/transactions/${i + 1}`} class:active={page === i + 1}> - <div class="border py-2 px-4 rounded-full border-2 w-12 h-12 hover:opacity-80 mr-1 text-center my-auto"> + <div + class="border py-2 px-4 rounded-full border-2 w-12 h-12 hover:opacity-80 mr-1 text-center my-auto" + > {i + 1} </div> </a> @@ -76,6 +75,6 @@ <style> .active div { - @apply bg-gray-100; + @apply bg-gray-100; } </style> diff --git a/src/routes/invoice/+server.js b/src/routes/invoice/+server.js index 5b2f2b39..e69de29b 100644 --- a/src/routes/invoice/+server.js +++ b/src/routes/invoice/+server.js @@ -1,10 +0,0 @@ -import { auth, get, post } from '$lib/utils'; - -export async function POST({ cookies, request }) { - let { amount, currency, network = 'lightning', prompt, rate, tip, user } = await request.json(); - let invoice = { amount, currency, network, prompt, rate, tip }; - - return new Response(JSON.stringify(await post('/invoice', { invoice, user }, auth(cookies))), { - headers: { 'content-type': 'application/json' } - }); -} diff --git a/src/routes/invoice/[id]/+page.svelte b/src/routes/invoice/[id]/+page.svelte index 7ff63862..9e0f9654 100644 --- a/src/routes/invoice/[id]/+page.svelte +++ b/src/routes/invoice/[id]/+page.svelte @@ -1,14 +1,14 @@ <script> - import { copy, f, get, reverseFormat, s, toggleFullscreen, sats } from '$lib/utils'; + import { copy, f, get, reverseFormat, s, sats } from '$lib/utils'; import { browser } from '$app/environment'; - import { invoices, user } from '$lib/store'; + import { invoices } from '$lib/store'; import { Icon, Heart, Image, Qr, Tip } from '$comp'; import { goto } from '$app/navigation'; import { t } from '$lib/translations'; export let data; $: refresh(data); - let { invoice, id } = data; + let { invoice, id, user } = data; let { amount, rate, @@ -25,6 +25,8 @@ let qr; let tipPercent = 0; + let fullscreen; + let refresh = (data) => { ({ invoice, id } = data); ({ @@ -57,7 +59,7 @@ <div class:full-shadow={showMobileTip}> <button class="ml-5 md:ml-20 mt-5 md:mt-10 hover:opacity-80" - class:invisible={!$user} + class:invisible={!user} disabled={showMobileTip} on:click={() => goto(`/${username}/receive`)} > @@ -109,12 +111,10 @@ <div> <button - class="border border-lightgrey rounded-md p-2 mx-2 hover:opacity-80" - on:click={() => toggleFullscreen(qr)}><Icon icon="expand" /></button - > - <button - class="border border-lightgrey rounded-md p-2 mx-2 hover:opacity-80" - on:click={() => copy(text)}><Icon icon="copy" /></button + class="flex rounded-full border py-2 px-5 font-bold hover:opacity-80 mb-2 mx-auto" + on:click={() => copy(text)} + ><Icon icon="copy" style="mr-1" /> + <div>Copy</div></button > </div> diff --git a/src/routes/login/+page.server.js b/src/routes/login/+page.server.js index 28f72712..28a5d78a 100644 --- a/src/routes/login/+page.server.js +++ b/src/routes/login/+page.server.js @@ -1,11 +1,15 @@ -import { redirect } from '@sveltejs/kit'; +import { invalid, redirect } from '@sveltejs/kit'; import { login } from '$lib/utils'; export const actions = { default: async ({ cookies, request }) => { let user = Object.fromEntries(await request.formData()); - await login(user, cookies); - - throw redirect(303, `/${user.username}/dashboard`); + try { + await login(user, cookies); + throw redirect(303, `/${user.username}/dashboard`); + } catch (e) { + console.log('OW'); + return invalid(403, { error: 'Login failed' }); + } } }; diff --git a/src/routes/logout/+page.server.js b/src/routes/logout/+page.server.js index 6d863cb1..d51dcfbc 100644 --- a/src/routes/logout/+page.server.js +++ b/src/routes/logout/+page.server.js @@ -2,12 +2,12 @@ import { redirect } from '@sveltejs/kit'; import cookie from 'cookie'; const opts = { - expires: new Date(0), + expires: new Date(0), path: '/' }; export async function load({ cookies }) { - cookies.set('token', '', opts); - cookies.set('refresh_token', '', opts); - throw redirect(302, '/logout/done'); + cookies.set('token', '', opts); + cookies.set('refresh_token', '', opts); + throw redirect(303, '/logout/done'); } diff --git a/src/routes/logout/+page.svelte b/src/routes/logout/+page.svelte index 5fd88bec..e69de29b 100644 --- a/src/routes/logout/+page.svelte +++ b/src/routes/logout/+page.svelte @@ -1,10 +0,0 @@ -<script> - import { onMount } from 'svelte'; - import { browser } from '$app/environment'; - import { user, token } from '$lib/store'; - - onMount(() => { - $user = null; - $token = null; - }); -</script> diff --git a/src/routes/logout/done/+page.svelte b/src/routes/logout/done/+page.svelte index 50fb766e..47d48c54 100644 --- a/src/routes/logout/done/+page.svelte +++ b/src/routes/logout/done/+page.svelte @@ -1,12 +1,9 @@ <script> import { onMount } from 'svelte'; - import { user, token } from '$lib/store'; import { goto } from '$app/navigation'; import { close } from '$lib/socket'; onMount(() => { - $token = null; - $user = null; close(); goto('/'); }); diff --git a/src/routes/scan/+page.svelte b/src/routes/scan/+page.svelte index 0acebb26..3e024bc8 100644 --- a/src/routes/scan/+page.svelte +++ b/src/routes/scan/+page.svelte @@ -17,9 +17,9 @@ </button> <div class="flex w-full mb-4 px-4"> - <div class="bg-black mx-auto rounded-3xl"> - <video bind:this={vid} class="border-4 rounded-3xl border-black md:max-w-[600px]" /> - </div> + <div class="bg-black mx-auto rounded-3xl"> + <video bind:this={vid} class="border-4 rounded-3xl border-black md:max-w-[600px]" /> + </div> </div> <div class="flex w-full"> diff --git a/src/routes/send/+page.server.js b/src/routes/send/+page.server.js index 837060f2..d0fefdee 100644 --- a/src/routes/send/+page.server.js +++ b/src/routes/send/+page.server.js @@ -1,7 +1,7 @@ import validate from 'bitcoin-address-validation'; import bip21 from 'bip21'; import { get } from '$lib/utils'; -import { invalid, redirect } from "@sveltejs/kit"; +import { invalid, redirect } from '@sveltejs/kit'; export const actions = { default: async ({ request }) => { diff --git a/src/routes/send/+page.svelte b/src/routes/send/+page.svelte index 8963345a..8a695ac6 100644 --- a/src/routes/send/+page.svelte +++ b/src/routes/send/+page.svelte @@ -1,16 +1,16 @@ <script> + import { enhance } from '$app/forms'; import { onMount } from 'svelte'; import { browser } from '$app/environment'; import { t } from '$lib/translations'; - import { AppHeader, Icon, Spinner } from '$comp'; + import { Icon, Spinner } from '$comp'; import { back, failure } from '$lib/utils'; export let form; let el; let placeholder = 'Address, Invoice, Username'; - let text = placeholder, - loading; + let text = placeholder; let focus = () => text === placeholder && (text = ''); let keypress = (e) => e.key === 'Enter' && e.preventDefault() && el.submit(); @@ -26,7 +26,7 @@ <Icon icon="arrow-left" style="w-10" /> </button> -<form method="POST" class="container px-4 mt-20 max-w-xl mx-auto" bind:this={el}> +<form method="POST" class="container px-4 mt-20 max-w-xl mx-auto" bind:this={el} use:enhance> <div class="mb-2"> <label for="invoice" class="font-bold mb-1 block">Destination</label> <input type="hidden" name="text" bind:value={text} /> @@ -70,11 +70,7 @@ ? 'opacity-50' : 'opacity-100 hover:opacity-80'} bg-black text-white border rounded-full px-6 py-2 font-bold" > - {#if loading} - <Spinner /> - {:else} - Next - {/if} + Next </button> </div> </form> diff --git a/src/routes/send/bitcoin/[address]/+page.svelte b/src/routes/send/bitcoin/[address]/+page.svelte index 2b472124..2de624ce 100644 --- a/src/routes/send/bitcoin/[address]/+page.svelte +++ b/src/routes/send/bitcoin/[address]/+page.svelte @@ -1,5 +1,6 @@ <script> - import { AppHeader, Icon, Numpad, Spinner } from '$comp'; + import { enhance } from '$app/forms'; + import { Icon, Numpad, Spinner } from '$comp'; import { page } from '$app/stores'; import { back } from '$lib/utils'; export let data; @@ -20,7 +21,7 @@ </div> <Numpad bind:amount {currency} /> - <form method="POST"> + <form method="POST" use:enhance> <input name="address" value={address} type="hidden" /> <input name="amount" value={amount} type="hidden" /> <div class="flex w-full"> diff --git a/src/routes/send/lightning/[payreq]/+page.server.js b/src/routes/send/lightning/[payreq]/+page.server.js index 885222c1..f17d6a60 100644 --- a/src/routes/send/lightning/[payreq]/+page.server.js +++ b/src/routes/send/lightning/[payreq]/+page.server.js @@ -8,7 +8,7 @@ export async function load({ params }) { export const actions = { default: async ({ cookies, request }) => { let body = Object.fromEntries(await request.formData()); - let { amount, confirmed } = body; + let { amount, confirmed } = body; if (!confirmed) { return invalid(403, { amount, confirm: true }); diff --git a/src/routes/send/lightning/[payreq]/+page.svelte b/src/routes/send/lightning/[payreq]/+page.svelte index a2a07a98..65e8989e 100644 --- a/src/routes/send/lightning/[payreq]/+page.svelte +++ b/src/routes/send/lightning/[payreq]/+page.svelte @@ -1,5 +1,6 @@ <script> - import { AppHeader, Icon, Numpad, Spinner } from '$comp'; + import { enhance } from '$app/forms'; + import { Icon, Numpad, Spinner } from '$comp'; import { page } from '$app/stores'; import { back, s } from '$lib/utils'; export let data; @@ -9,9 +10,7 @@ let { alias } = data; let { currency } = data.user; - let amount = form?.amount || data.amount; - - let loading; + let amount = form?.amount || data.amount; </script> <button class="ml-5 md:ml-20 mt-5 md:mt-10 hover:opacity-80" on:click={back}> @@ -30,21 +29,17 @@ <Numpad bind:amount {currency} /> {/if} - <form method="POST"> + <form method="POST" use:enhance> <input name="payreq" value={payreq} type="hidden" /> <input name="amount" value={amount} type="hidden" /> - <input name="confirmed" value={form?.confirm} type="hidden" /> + <input name="confirmed" value={form?.confirm} type="hidden" /> <div class="flex w-full"> <button type="submit" class="opacity-100 hover:opacity-80'} rounded-2xl border py-3 font-bold mx-auto mt-2 bg-black text-white px-4 w-24" > - {#if loading} - <Spinner /> - {:else} - Send - {/if} + Send </button> </div> </form> diff --git a/src/routes/sent/+page.svelte b/src/routes/sent/+page.svelte index de61fd41..95bce839 100644 --- a/src/routes/sent/+page.svelte +++ b/src/routes/sent/+page.svelte @@ -14,11 +14,9 @@ <Icon icon="check" style="mx-auto" /> </div> <h1 class="text-3xl md:text-4xl font-bold mb-6">{$t('invoice.paymentSuccessful')}</h1> - <a href={`/${user.username}/transactions`}> - <button - class="bg-black text-white rounded-2xl w-20 py-3 font-bold hover:opacity-80" - > - {$t('invoice.done')} - </button> - </a> + <a href={`/${user.username}/transactions`}> + <button class="bg-black text-white rounded-2xl w-20 py-3 font-bold hover:opacity-80"> + {$t('invoice.done')} + </button> + </a> </div> |
