aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2022-11-09 14:26:05 -0800
committerAdam Soltys <[email protected]>2022-11-09 14:26:05 -0800
commit2be0c31d324e312f7d0b59e910d864d6a1ae99ff (patch)
tree8ca8d3af860f371c256df2c1c1e087acbc1841ba /src
parent692ffd2b6819f6254f77f819a4072eae61a1d638 (diff)
parentc31cfed30e022acf1c58d8594a1027524f3079da (diff)
downloadcoinos-ui-2be0c31d324e312f7d0b59e910d864d6a1ae99ff.tar.gz
coinos-ui-2be0c31d324e312f7d0b59e910d864d6a1ae99ff.zip
Merge branch 'master' into maven
Diffstat (limited to 'src')
-rw-r--r--src/components/AppHeader.svelte4
-rw-r--r--src/components/Footer.svelte2
-rw-r--r--src/components/Numpad.svelte6
-rw-r--r--src/components/Pin.svelte3
-rw-r--r--src/lib/socket.js7
-rw-r--r--src/lib/utils.js7
-rw-r--r--src/routes/(app)/[username]/+page.svelte6
-rw-r--r--src/routes/(app)/[username]/dashboard/+page.svelte2
-rw-r--r--src/routes/(app)/[username]/settings/[...tab]/+page.server.js (renamed from src/routes/(app)/[username]/settings/+page.server.js)10
-rw-r--r--src/routes/(app)/[username]/settings/[...tab]/+page.svelte (renamed from src/routes/(app)/[username]/settings/+page.svelte)37
-rw-r--r--src/routes/(app)/[username]/settings/[...tab]/_account.svelte (renamed from src/routes/(app)/[username]/settings/_account.svelte)0
-rw-r--r--src/routes/(app)/[username]/settings/[...tab]/_pos.svelte (renamed from src/routes/(app)/[username]/settings/_pos.svelte)0
-rw-r--r--src/routes/(app)/[username]/settings/[...tab]/_security.svelte (renamed from src/routes/(app)/[username]/settings/_security.svelte)8
-rw-r--r--src/routes/(app)/disable2fa/+server.js13
-rw-r--r--src/routes/(app)/invoice/[id]/+layout.server.js10
-rw-r--r--src/routes/(app)/invoice/[id]/+page.svelte20
-rw-r--r--src/routes/(app)/invoice/[id]/paid/+page.svelte68
-rw-r--r--src/routes/(app)/invoice/[id]/pending/+page.svelte56
-rw-r--r--src/routes/(app)/otpsecret/+server.js11
-rw-r--r--src/routes/(app)/support/+page.server.js (renamed from src/routes/(app)/[username]/support/+page.server.js)5
-rw-r--r--src/routes/(app)/support/+page.svelte (renamed from src/routes/(app)/[username]/support/+page.svelte)26
21 files changed, 158 insertions, 143 deletions
diff --git a/src/components/AppHeader.svelte b/src/components/AppHeader.svelte
index ec0f5174..728b025a 100644
--- a/src/components/AppHeader.svelte
+++ b/src/components/AppHeader.svelte
@@ -17,7 +17,7 @@
menuButtons = [
{ key: 'nav.profile', icon: 'profile', href: `/${user.username}` },
{ key: 'nav.settings', icon: 'settings', href: `/${user.username}/settings` },
- { key: 'nav.support', icon: 'support', href: `/${user.username}/support` },
+ { key: 'nav.support', icon: 'support', href: `/support` },
{ key: 'nav.signOut', icon: 'logout', href: `/logout` }
];
@@ -80,7 +80,7 @@
class="bg-white p-2 rounded-full w-12 h-12 drop-shadow-xl border border-black/10 {$page
.url.pathname === `/${user.username}` ||
$page.url.pathname === `/${user.username}/settings` ||
- $page.url.pathname === `/${user.username}/support`
+ $page.url.pathname === `/support`
? 'opacity-100'
: `opacity-70 hover:opacity-80 ${showMenu ? 'opacity-80' : ''}`}"
on:click={() => (showMenu = !showMenu)}
diff --git a/src/components/Footer.svelte b/src/components/Footer.svelte
index 8ef97e65..bf8b8810 100644
--- a/src/components/Footer.svelte
+++ b/src/components/Footer.svelte
@@ -10,7 +10,7 @@
const companyLinks = [
{ url: '/news', titleID: 'news' },
- { url: 'mailto:[email protected]', titleID: 'support' },
+ { url: '/support', titleID: 'support' },
{ url: '/jobs', titleID: 'jobs' }
];
</script>
diff --git a/src/components/Numpad.svelte b/src/components/Numpad.svelte
index 55ce96d4..4f546499 100644
--- a/src/components/Numpad.svelte
+++ b/src/components/Numpad.svelte
@@ -1,7 +1,7 @@
<script>
import { Left, Icon } from '$comp';
import { selectedRate } from '$lib/store';
- import { f, s, post, warning, sats } from '$lib/utils';
+ import { f, s, post, warning, sat, sats } from '$lib/utils';
import { t } from '$lib/translations';
export let amount,
@@ -36,7 +36,7 @@
$: amountFiatConverted = f(amountSats * ($selectedRate / sats), currency);
- $: amountSatsConverted = s(amountFiat / ($selectedRate / sats));
+ $: amountSatsConverted = sat(amountFiat / ($selectedRate / sats));
const numPad = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '0', '<'];
@@ -94,7 +94,7 @@
{fiat ? `${symbol}${amountFiat}` : '⚡️' + amountSatsFormatted}
</div>
<span class="text-secondary mr-1"
- >{fiat ? `⚡️${amountSatsConverted}` : amountFiatConverted}</span
+ >{fiat ? amountSatsConverted : amountFiatConverted}</span
>
<button
type="button"
diff --git a/src/components/Pin.svelte b/src/components/Pin.svelte
index 2a6bf977..80e003b9 100644
--- a/src/components/Pin.svelte
+++ b/src/components/Pin.svelte
@@ -1,5 +1,6 @@
<script>
import { pin } from '$lib/store';
+
let pinCode = '';
let pinInput;
@@ -9,7 +10,7 @@
<div class="fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full z-20">
<div class="relative top-1/3 mx-auto p-5 border w-96 shadow-lg rounded-md bg-white space-y-5">
<h1 class="text-center text-2xl font-semibold">Please enter your PIN</h1>
- <input bind:value={pinCode} />
+ <input bind:value={pinCode} autofocus />
<div class="w-full flex">
<button
type="submit"
diff --git a/src/lib/socket.js b/src/lib/socket.js
index 6678b979..8d84073c 100644
--- a/src/lib/socket.js
+++ b/src/lib/socket.js
@@ -36,11 +36,8 @@ export const messages = (data) => ({
async payment() {
let { amount, invoice } = data;
- if (invoice) {
- invoices.set({ ...get(invoices), [invoice.uuid]: invoice });
- }
-
- if (get(user).account_id !== data.account_id) return;
+ if (invoice) invalidate('app:invoice');
+ if (get(user)?.account_id !== data.account_id) return;
let payments = get(txns);
let i = payments.findIndex((p) => p.id === data.id);
diff --git a/src/lib/utils.js b/src/lib/utils.js
index 7e0b8e4f..2bf6b800 100644
--- a/src/lib/utils.js
+++ b/src/lib/utils.js
@@ -37,7 +37,10 @@ export const get = (url, headers = {}) =>
export const post = (url, body, headers) => {
headers = { ...headers, 'content-type': 'application/json', accept: 'application/json' };
return fetch(base + url, { method: 'POST', body: JSON.stringify(body), headers })
- .then((r) => r.text())
+ .then(async (r) => {
+ if (r.ok) return r.text();
+ throw new Error(await r.text());
+ })
.then((body) => {
try {
body = JSON.parse(body);
@@ -67,7 +70,7 @@ export function reverseFormat(val, locale) {
return Number.isNaN(reversedVal) ? 0 : +reversedVal;
}
-export let protectedRoutes = [/customers/, /dashboard/, /settings/, /transactions/, /support/];
+export let protectedRoutes = [/customers/, /dashboard/, /settings/, /transactions/];
export const success = (m) => {
toast.pop();
diff --git a/src/routes/(app)/[username]/+page.svelte b/src/routes/(app)/[username]/+page.svelte
index 960cf897..8afb5280 100644
--- a/src/routes/(app)/[username]/+page.svelte
+++ b/src/routes/(app)/[username]/+page.svelte
@@ -59,6 +59,12 @@
>
</a>
{/if}
+
+ <a href={`/${subject.username}/address`}>
+ <button class="rounded-full border py-2 px-5 font-bold hover:opacity-80 w-full mb-2">
+ Bitcoin address
+ </button>
+ </a>
</div>
{/if}
</div>
diff --git a/src/routes/(app)/[username]/dashboard/+page.svelte b/src/routes/(app)/[username]/dashboard/+page.svelte
index 0ea0e0a8..43879fcb 100644
--- a/src/routes/(app)/[username]/dashboard/+page.svelte
+++ b/src/routes/(app)/[username]/dashboard/+page.svelte
@@ -48,7 +48,7 @@
</div>
<div class="text-secondary text-2xl">
- {sat(user.account.balance)}
+ ⚡️{s(user.account.balance)}
</div>
<div class="grid sm:grid-cols-2 gap-2 mt-8">
diff --git a/src/routes/(app)/[username]/settings/+page.server.js b/src/routes/(app)/[username]/settings/[...tab]/+page.server.js
index 482b70b1..dcaa26b4 100644
--- a/src/routes/(app)/[username]/settings/+page.server.js
+++ b/src/routes/(app)/[username]/settings/[...tab]/+page.server.js
@@ -1,5 +1,11 @@
-import { invalid } from '@sveltejs/kit';
+import { invalid, redirect } from '@sveltejs/kit';
import { auth, get, post } from '$lib/utils';
+
+export function load({ params, url }) {
+ if (url.pathname.endsWith('settings')) throw redirect(307, url.pathname + '/account');
+ return params;
+}
+
export const actions = {
default: async ({ cookies, locals, request }) => {
let form = Object.fromEntries(await request.formData());
@@ -10,7 +16,7 @@ export const actions = {
};
try {
- await post(`/user`, user, auth(cookies));
+ ({ user } = await post(`/user`, user, auth(cookies)));
} catch (e) {
return invalid(400, { message: e.message });
}
diff --git a/src/routes/(app)/[username]/settings/+page.svelte b/src/routes/(app)/[username]/settings/[...tab]/+page.svelte
index 250087c1..d546e817 100644
--- a/src/routes/(app)/[username]/settings/+page.svelte
+++ b/src/routes/(app)/[username]/settings/[...tab]/+page.svelte
@@ -2,31 +2,36 @@
import { onMount } from 'svelte';
import { fly } from 'svelte/transition';
import { enhance } from '$app/forms';
- import Account from './_account.svelte';
- import Pos from './_pos.svelte';
- import Security from './_security.svelte';
import { Icon, Spinner, Pin } from '$comp';
import { t } from '$lib/translations';
import { failure, success } from '$lib/utils';
import { avatarUpload, bannerUpload, pin } from '$lib/store';
import { upload } from '$lib/upload';
+ import { page } from '$app/stores';
+
+ import Account from './_account.svelte';
+ import Pos from './_pos.svelte';
+ import Security from './_security.svelte';
export let data;
export let form;
- let { user, token } = data;
+ let submit;
+
+ let { user, token, tab } = data;
+
$: update(data);
- let update = () => ({ user, token } = data);
+ let update = () => ({ user, token, tab } = data);
$: form?.user && ({ user } = form);
- $: if (form?.message?.startsWith('Pin')) {
- failure('Wrong pin, try again');
- $pin = '';
- }
+ $: form?.success && success('Settings saved!');
- let tab = 'account';
+ // $: if (form?.message?.startsWith('Pin')) {
+ // failure('Wrong pin, try again');
+ // $pin = '';
+ // }
let tabs = [
{ name: 'account', key: 'ACCOUNT', comp: Account },
@@ -36,7 +41,7 @@
$: ({ comp } = tabs.find((t) => t.name === tab));
- let loading, submit;
+ let loading;
let save = async (msg) => {
loading = true;
@@ -74,11 +79,11 @@
<div class="font-bold flex justify-between items-center border-b pb-3 text-secondary">
{#each tabs as { name, key }}
- <button
- class="hover:opacity-80"
- class:text-black={tab === name}
- on:click|preventDefault={() => (tab = name)}>{$t(`user.settings.${key}`)}</button
- >
+ <a href={`/${user.username}/settings/${name}`}>
+ <button class="hover:opacity-80" class:text-black={tab === name}
+ >{$t(`user.settings.${key}`)}</button
+ >
+ </a>
{/each}
</div>
diff --git a/src/routes/(app)/[username]/settings/_account.svelte b/src/routes/(app)/[username]/settings/[...tab]/_account.svelte
index e49205ca..e49205ca 100644
--- a/src/routes/(app)/[username]/settings/_account.svelte
+++ b/src/routes/(app)/[username]/settings/[...tab]/_account.svelte
diff --git a/src/routes/(app)/[username]/settings/_pos.svelte b/src/routes/(app)/[username]/settings/[...tab]/_pos.svelte
index ccbeeff4..ccbeeff4 100644
--- a/src/routes/(app)/[username]/settings/_pos.svelte
+++ b/src/routes/(app)/[username]/settings/[...tab]/_pos.svelte
diff --git a/src/routes/(app)/[username]/settings/_security.svelte b/src/routes/(app)/[username]/settings/[...tab]/_security.svelte
index 4bdb00d4..0ffb7834 100644
--- a/src/routes/(app)/[username]/settings/_security.svelte
+++ b/src/routes/(app)/[username]/settings/[...tab]/_security.svelte
@@ -27,7 +27,11 @@
let otp;
$: pinChange($current);
let pinChange = async (pin) => {
- otp = await post('/otpsecret', { pin });
+ try {
+ otp = await post('/otpsecret', { pin });
+ } catch (e) {
+ console.log(e);
+ }
};
let locked;
@@ -78,6 +82,7 @@
pin = null;
submit.click();
} catch (e) {
+ console.log(e);
failure('Failed to disable pin');
}
} else {
@@ -112,6 +117,7 @@
toggleDisabling();
}
} catch (e) {
+ console.log(e);
failure('Failed to disable 2FA, try again');
}
};
diff --git a/src/routes/(app)/disable2fa/+server.js b/src/routes/(app)/disable2fa/+server.js
index 237da445..13fcb2b9 100644
--- a/src/routes/(app)/disable2fa/+server.js
+++ b/src/routes/(app)/disable2fa/+server.js
@@ -1,8 +1,13 @@
+import { error } from '@sveltejs/kit';
import { auth, post } from '$lib/utils';
-export async function PUT({ cookies, request }) {
- let body = await request.json();
- let res = await post('/disable2fa', body, auth(cookies));
+export async function POST({ cookies, request }) {
+ try {
+ let body = await request.json();
+ let res = await post('/disable2fa', body, auth(cookies));
- return new Response(JSON.stringify(res));
+ return new Response(JSON.stringify(res));
+ } catch (e) {
+ throw error(500, 'Problem disabling 2fa');
+ }
}
diff --git a/src/routes/(app)/invoice/[id]/+layout.server.js b/src/routes/(app)/invoice/[id]/+layout.server.js
index 4b6cf97e..dacc44e6 100644
--- a/src/routes/(app)/invoice/[id]/+layout.server.js
+++ b/src/routes/(app)/invoice/[id]/+layout.server.js
@@ -1,9 +1,17 @@
import Qr from 'qrcode-base64';
import { get } from '$lib/utils';
+import { redirect } from '@sveltejs/kit';
+
+export async function load({ depends, params, url }) {
+ depends('app:invoice');
-export async function load({ params }) {
let { id } = params;
let invoice = await get(`/invoice?uuid=${id}`);
+ let { amount, received, pending } = invoice;
+
+ let paid = (!amount && (received || pending)) || (amount > 0 && received + pending >= amount);
+ if (paid && !url.pathname.endsWith('paid')) throw redirect(307, `/invoice/${id}/paid`);
+
let sm = Qr.drawImg(invoice.text, { size: 300 });
let lg = Qr.drawImg(invoice.text, { size: 1200 });
diff --git a/src/routes/(app)/invoice/[id]/+page.svelte b/src/routes/(app)/invoice/[id]/+page.svelte
index dec33b62..569d1430 100644
--- a/src/routes/(app)/invoice/[id]/+page.svelte
+++ b/src/routes/(app)/invoice/[id]/+page.svelte
@@ -1,7 +1,7 @@
<script>
import { send } from '$lib/socket';
import { back, copy, f, get, sat, reverseFormat, s, sats } from '$lib/utils';
- import { onMount, onDestroy } from 'svelte';
+ import { tick, onMount, onDestroy } from 'svelte';
import { browser } from '$app/environment';
import { invoices, last } from '$lib/store';
import { Avatar, Icon, Heart, Image, Qr } from '$comp';
@@ -11,8 +11,6 @@
export let data;
- let showQr;
-
$: refresh(data);
let { invoice, id, user, sm, lg } = data;
let {
@@ -27,6 +25,8 @@
user: { username, currency }
} = invoice;
+ let showQr = !amount;
+
let src = sm;
let qr;
@@ -49,14 +49,6 @@
tipPercent = (tip / amount) * 100;
};
- $invoices[id] = { amount, id, rate, received, text, tip, username };
- $: browser &&
- $invoices[id].amount > 0 &&
- $invoices[id]?.received >= $invoices[id]?.amount &&
- goto(($invoices[id].memo === 'launch' && '/launch/purchase') || `/invoice/${id}/paid`);
-
- $: browser && $invoices[id].pending > 0 && goto(`/invoice/${id}/pending`);
-
$: amountFiat = parseFloat(((amount * rate) / sats).toFixed(2));
$: tipAmount = ((tip * rate) / sats).toFixed(2);
@@ -88,7 +80,7 @@
<div class="container mx-auto max-w-lg px-4 space-y-5">
<div class="w-full flex">
<h1 class="text-secondary block text-2xl flex mx-auto">
- <div class="my-auto">Pay</div>
+ <div class="my-auto">Send to</div>
<div>
<a href="/{username}" class="text-black font-semibold hover:opacity-80 mx-auto">
@@ -107,6 +99,10 @@
<img {src} class:p-4={full} class="w-[300px] mx-auto" bind:this={qr} on:click={toggle} />
</div>
+ {#if address}
+ <div>{address}</div>
+ {/if}
+
<div class="mb-10 flex gap-2 justify-center">
<button
class="flex rounded-full border py-2 px-5 font-bold hover:opacity-80 mb-2"
diff --git a/src/routes/(app)/invoice/[id]/paid/+page.svelte b/src/routes/(app)/invoice/[id]/paid/+page.svelte
index 4f0a8ed1..60bc4592 100644
--- a/src/routes/(app)/invoice/[id]/paid/+page.svelte
+++ b/src/routes/(app)/invoice/[id]/paid/+page.svelte
@@ -9,41 +9,55 @@
import { invoices } from '$lib/store';
export let data;
- let { invoice } = data;
- let { amount, currency, rate, tip } = invoice;
+ let amount, currency, rate, received, pending, tip, user, uuid;
+ $: data && ({ amount, currency, rate, received, pending, tip, user, uuid } = data.invoice);
toast.pop(0);
- $: amountFiat = parseFloat(((amount * rate) / sats).toFixed(2));
+ $: amountFiat = parseFloat(((received * rate) / sats).toFixed(2));
+ $: pendingFiat = parseFloat(((pending * rate) / sats).toFixed(2));
$: tipFiat = parseFloat(((tip * rate) / sats).toFixed(2));
-
- const handleDoneClick = () => {
- delete $invoices[invoice.uuid];
- goto(`/${invoice.user.username}/receive`);
- };
</script>
<div class="container px-4 text-center mx-auto">
<div class="flex w-full py-20 max-w-[200px] mx-auto" in:scale={{ start: 0.5 }}>
<Icon icon="check" style="mx-auto" />
</div>
- <h1 class="text-3xl md:text-4xl font-bold mb-6">{$t('invoice.paymentSuccessful')}</h1>
- <h2 class="text-2xl md:text-3xl font-semibold">
- {f(amountFiat, currency)}
- {#if tip}
- + {f(tipFiat, currency)}
- {/if}
- </h2>
- <h3 class="text-secondary md:text-lg mb-6 mt-1">
- {sat(amount)}
- {#if tip}
- +{sat(tip)}
- {/if}
- </h3>
- <button
- class="bg-black text-white rounded-2xl w-20 py-3 font-bold hover:opacity-80"
- on:click={handleDoneClick}
- >
- {$t('invoice.done')}
- </button>
+ {#if received}
+ <h1 class="text-3xl md:text-4xl font-bold mb-6">{$t('invoice.paymentSuccessful')}</h1>
+ <h2 class="text-2xl md:text-3xl font-semibold">
+ {f(amountFiat, currency)}
+ {#if tip}
+ + {f(tipFiat, currency)}
+ {/if}
+ </h2>
+ <h3 class="text-secondary md:text-lg mb-6 mt-1">
+ {sat(received)}
+ {#if tip}
+ +{sat(tip)}
+ {/if}
+ </h3>
+ {/if}
+
+ {#if pending}
+ <h1 class="text-3xl md:text-4xl font-bold mb-6">Payment detected</h1>
+ <h2 class="text-2xl md:text-3xl font-semibold">
+ {f(pendingFiat, currency)}
+ {#if tip}
+ + {f(tipFiat, currency)}
+ {/if}
+ </h2>
+ <h3 class="text-secondary md:text-lg mb-6 mt-1">
+ {sat(pending)}
+ {#if tip}
+ +{sat(tip)}
+ {/if}
+ </h3>
+ {/if}
+
+ <a href={`/${user.username}/receive`}>
+ <button class="bg-black text-white rounded-2xl w-20 py-3 font-bold hover:opacity-80">
+ {$t('invoice.done')}
+ </button>
+ </a>
</div>
diff --git a/src/routes/(app)/invoice/[id]/pending/+page.svelte b/src/routes/(app)/invoice/[id]/pending/+page.svelte
deleted file mode 100644
index d3970dab..00000000
--- a/src/routes/(app)/invoice/[id]/pending/+page.svelte
+++ /dev/null
@@ -1,56 +0,0 @@
-<script>
- import { scale } from 'svelte/transition';
- import { Icon } from '$comp';
- import { toast } from '@zerodevx/svelte-toast';
- import { browser } from '$app/environment';
- import { t } from '$lib/translations';
- import { f, s, sat, sats } from '$lib/utils';
- import { goto } from '$app/navigation';
- import { invoices } from '$lib/store';
-
- export let data;
- let { invoice } = data;
- let { pending, currency, rate, tip } = invoice;
-
- toast.pop(0);
-
- $: pendingFiat = parseFloat(((pending * rate) / sats).toFixed(2));
- $: tipFiat = parseFloat(((tip * rate) / sats).toFixed(2));
-
- const handleDoneClick = () => {
- delete $invoices[invoice.uuid];
- goto(`/${invoice.user.username}/receive`);
- };
-</script>
-
-<div class="container px-4 text-center mx-auto space-y-5">
- <div class="flex w-full py-20 max-w-[200px] mx-auto" in:scale={{ start: 0.5 }}>
- <Icon icon="check" style="mx-auto" />
- </div>
-
- <h1 class="text-3xl md:text-4xl font-bold">Payment detected</h1>
-
- <div>
- <h2 class="text-2xl md:text-3xl font-semibold">
- {f(pendingFiat, currency)}
- {#if tip}
- + {f(tipFiat, currency)}
- {/if}
- </h2>
- <h3 class="text-secondary md:text-lg mt-1">
- {sat(pending)}
- {#if tip}
- +{sat(tip)}
- {/if}
- </h3>
- </div>
-
- <p class="text-xl text-red-600">Pending confirmation</p>
-
- <button
- class="bg-black text-white rounded-2xl w-20 py-3 font-bold hover:opacity-80"
- on:click={handleDoneClick}
- >
- {$t('invoice.done')}
- </button>
-</div>
diff --git a/src/routes/(app)/otpsecret/+server.js b/src/routes/(app)/otpsecret/+server.js
index 8dec7778..cdd050c8 100644
--- a/src/routes/(app)/otpsecret/+server.js
+++ b/src/routes/(app)/otpsecret/+server.js
@@ -1,8 +1,13 @@
import { auth, post } from '$lib/utils';
import Qr from 'qrcode-base64';
+import { error } from '@sveltejs/kit';
export async function POST({ cookies, locals, request }) {
- let { secret } = await post('/otpsecret', await request.json(), auth(cookies));
- let uri = `otpauth://totp/coinos:${locals.user.username}?secret=${secret}&period=30&digits=6&algorithm=SHA1&issuer=coinos`;
- return new Response(JSON.stringify({ secret, uri, qr: Qr.drawImg(uri, { size: 600 }) }));
+ try {
+ let { secret } = await post('/otpsecret', await request.json(), auth(cookies));
+ let uri = `otpauth://totp/coinos:${locals.user.username}?secret=${secret}&period=30&digits=6&algorithm=SHA1&issuer=coinos`;
+ return new Response(JSON.stringify({ secret, uri, qr: Qr.drawImg(uri, { size: 600 }) }));
+ } catch (e) {
+ throw new error(500, 'Problem saving secret');
+ }
}
diff --git a/src/routes/(app)/[username]/support/+page.server.js b/src/routes/(app)/support/+page.server.js
index a335ec96..78c640e3 100644
--- a/src/routes/(app)/[username]/support/+page.server.js
+++ b/src/routes/(app)/support/+page.server.js
@@ -1,3 +1,6 @@
+import { post } from "$lib/utils";
+import { invalid } from '@sveltejs/kit';
+
export const actions = {
default: async ({ cookies, request }) => {
let form = Object.fromEntries(await request.formData());
@@ -5,7 +8,7 @@ export const actions = {
try {
await post('/email', form);
} catch (e) {
- return invalid(400, { failed: true });
+ return invalid(400, { error: e.message });
}
return { success: true };
diff --git a/src/routes/(app)/[username]/support/+page.svelte b/src/routes/(app)/support/+page.svelte
index cd1cc69f..690e4770 100644
--- a/src/routes/(app)/[username]/support/+page.svelte
+++ b/src/routes/(app)/support/+page.svelte
@@ -1,22 +1,36 @@
<script>
import { enhance } from '$app/forms';
import { scale } from 'svelte/transition';
- import { Icon } from '$comp';
+ import { AppHeader, Icon } from '$comp';
import { t } from '$lib/translations';
export let data, form;
let { user } = data;
+ $: if (user) {
+ data.subject = { ...user };
+ }
+
let email;
let message;
</script>
-<div class="container px-4 max-w-lg mx-auto mt-20">
+{#if user}
+ <AppHeader {data} />
+{/if}
+
+{#if form?.error}
+ <div class="text-red-600 text-center">
+ {form.error}
+ </div>
+{/if}
+
+<div class="container px-4 max-w-lg mx-auto mt-20 space-y-5">
{#if form?.success}
<h1 class="text-center text-3xl md:text-4xl font-semibold mb-8">Thank you!</h1>
<p class="text-center mb-8">Someone will be in touch shortly.</p>
- <a href={`/${user.username}/dashboard`}>
+ <a href={user ? `/${user.username}/dashboard` : '/'}>
<button class="rounded-full border py-2 px-5 font-bold hover:opacity-80 w-full mb-2"
>Done</button
>
@@ -25,6 +39,9 @@
<h1 class="text-center text-3xl md:text-4xl font-semibold mb-8">
{$t('user.support.header')}
</h1>
+
+ <p class="text-secondary">Fill out this form or email us directly at <a class="underline" href="mailto:[email protected]">[email protected]</a> and we'll do our best to get back to you in a timely manner.</p>
+
<form method="POST" use:enhance>
<div class="mb-4">
<label for="account" class="font-semibold">{$t('user.support.accountName')}</label>
@@ -33,8 +50,7 @@
type="text"
name="account"
required
- disabled
- value={user.username}
+ value={user?.username || ''}
/>
</div>