aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2023-10-16 15:34:26 -0700
committerAdam Soltys <[email protected]>2023-10-16 15:34:26 -0700
commit829c2efb9c4415c64466988f1e189184ffb88478 (patch)
tree23f9e5fd83be3d4ee3943d254e4d3d2ce194819a /src
parent16475fffdb0d20a2933cfaf6922afc7c137bb7fe (diff)
parent0212fe0032eb0c5d6bfb74ebaab42543b73d6d6b (diff)
downloadcoinos-ui-829c2efb9c4415c64466988f1e189184ffb88478.tar.gz
coinos-ui-829c2efb9c4415c64466988f1e189184ffb88478.zip
Merge branch 'master' into swapee
Diffstat (limited to 'src')
-rw-r--r--src/components/AppHeader.svelte4
-rw-r--r--src/components/Balance.svelte4
-rw-r--r--src/components/Code.svelte4
-rw-r--r--src/components/Footer.svelte2
-rw-r--r--src/components/LocationsMap.svelte268
-rw-r--r--src/components/RegisterOrLogin.svelte6
-rw-r--r--src/lib/invoice.js8
-rw-r--r--src/lib/socket.js20
-rw-r--r--src/lib/store.js1
-rw-r--r--src/locales/en.json2
-rw-r--r--src/locales/fr.json4
-rw-r--r--src/routes/(app)/[username]/(profile)/+layout.svelte20
-rw-r--r--src/routes/(app)/[username]/(profile)/+page.svelte2
-rw-r--r--src/routes/(app)/[username]/card/[serial]/+page.svelte50
-rw-r--r--src/routes/(app)/[username]/generate/+page.svelte8
-rw-r--r--src/routes/(app)/[username]/invoice/[id]/+layout.server.js (renamed from src/routes/(app)/[username]/invoice/[hash]/+layout.server.js)20
-rw-r--r--src/routes/(app)/[username]/invoice/[id]/+layout.svelte (renamed from src/routes/(app)/[username]/invoice/[hash]/+layout.svelte)0
-rw-r--r--src/routes/(app)/[username]/invoice/[id]/+page.server.js (renamed from src/routes/(app)/[username]/invoice/[hash]/+page.server.js)0
-rw-r--r--src/routes/(app)/[username]/invoice/[id]/+page.svelte (renamed from src/routes/(app)/[username]/invoice/[hash]/+page.svelte)4
-rw-r--r--src/routes/(app)/[username]/invoice/[id]/paid/+page.svelte (renamed from src/routes/(app)/[username]/invoice/[hash]/paid/+page.svelte)1
-rw-r--r--src/routes/(app)/[username]/invoice/[id]/tip/+page.server.js (renamed from src/routes/(app)/[username]/invoice/[hash]/tip/+page.server.js)0
-rw-r--r--src/routes/(app)/[username]/invoice/[id]/tip/+page.svelte (renamed from src/routes/(app)/[username]/invoice/[hash]/tip/+page.svelte)0
-rw-r--r--src/routes/(app)/[username]/map/+page.server.js12
-rw-r--r--src/routes/(app)/[username]/map/+page.svelte8
-rw-r--r--src/routes/(app)/[username]/payments/[...page]/+page.server.js4
-rw-r--r--src/routes/(app)/[username]/payments/[...page]/+page.svelte14
-rw-r--r--src/routes/(app)/[username]/receive/[...param]/+page.svelte1
-rw-r--r--src/routes/(app)/[username]/settings/[...tab]/+page.svelte4
-rw-r--r--src/routes/(app)/[username]/settings/[...tab]/_account.svelte36
-rw-r--r--src/routes/(app)/[username]/settings/[...tab]/_pos.svelte4
-rw-r--r--src/routes/(app)/[username]/settings/[...tab]/_security.svelte6
-rw-r--r--src/routes/(app)/[username]/settings/[...tab]/_shopify.svelte57
-rw-r--r--src/routes/(app)/[username]/shopify.js/+server.js4
-rw-r--r--src/routes/(app)/login/+page.svelte2
-rw-r--r--src/routes/(app)/payment/[id]/+page.svelte6
-rw-r--r--src/routes/(app)/pot/[name]/+page.svelte20
-rw-r--r--src/routes/(app)/pot/[name]/sweep/+page.svelte31
-rw-r--r--src/routes/(app)/pot/[name]/withdraw/+page.svelte4
-rw-r--r--src/routes/(app)/qr/[text]/+page.svelte2
-rw-r--r--src/routes/(app)/send/invoice/[id]/+page.svelte15
-rw-r--r--src/routes/(static)/bounties/+page.svelte57
-rw-r--r--src/routes/(static)/docs/+page.svelte12
-rw-r--r--src/routes/+layout.svelte4
-rw-r--r--src/routes/map/+page.svelte4
44 files changed, 366 insertions, 369 deletions
diff --git a/src/components/AppHeader.svelte b/src/components/AppHeader.svelte
index 5f6f02a5..91d31a56 100644
--- a/src/components/AppHeader.svelte
+++ b/src/components/AppHeader.svelte
@@ -17,6 +17,8 @@
menuButtons = [
{ key: 'nav.settings', icon: 'settings', href: `/${user.username}/settings` },
{ key: 'nav.support', icon: 'support', href: `/support` },
+ { key: 'nav.map', icon: 'map', href: `/${user.username}/map` },
+ { key: 'nav.merch', icon: 'shirt', href: `https://coinosmerch.com` },
{ key: 'nav.signOut', icon: 'logout', href: `/logout` }
];
@@ -119,7 +121,7 @@
</OutClick>
</div>
{:else}
- <a href={`/login?redirect=${$page.url.pathname}`}>
+ <a href={`/login?redirect=${$page.url.pathname}`}>
<button class="bg-white px-5 py-2 rounded-xl font-semibold text-sm"
>{$t('nav.signIn')}</button
>
diff --git a/src/components/Balance.svelte b/src/components/Balance.svelte
index 96edf630..0e4f2ec2 100644
--- a/src/components/Balance.svelte
+++ b/src/components/Balance.svelte
@@ -9,14 +9,14 @@
</script>
{#if show && user.haspin && $pin?.length !== 6}
- <Pin cancel={() => (show = false)} />
+ <Pin cancel={() => (show = false)} />
{/if}
<div class="space-y-2">
{#if user.haspin && !$pin}
<button
class="text-sm md:text-lg rounded-full border py-2 px-4 hover:opacity-80 min-w-[72px] bg-black text-white"
- on:click={() => (show = true)}>{$t('user.showBalance')}</button
+ on:click={() => (show = true)}>{$t('user.showBalance')}</button
>
{:else}
<div class="text-5xl font-bold tabular-nums">
diff --git a/src/components/Code.svelte b/src/components/Code.svelte
index dd0cecf2..ffca98a4 100644
--- a/src/components/Code.svelte
+++ b/src/components/Code.svelte
@@ -9,9 +9,7 @@
<div class="overflow-x-scroll max-w-full scrollbar-hide">
<div class="break-all min-w-[800px]">{samples[sample]}</div>
</div>
- <button
- class="ml-auto my-auto invert opacity-90"
- on:click={() => copy(samples[sample])}
+ <button class="ml-auto my-auto invert opacity-90" on:click={() => copy(samples[sample])}
><Icon icon="copy" style="w-10 max-w-none" /></button
>
</div>
diff --git a/src/components/Footer.svelte b/src/components/Footer.svelte
index 7caaccc6..b1d50017 100644
--- a/src/components/Footer.svelte
+++ b/src/components/Footer.svelte
@@ -10,7 +10,7 @@
const companyLinks = [
{ url: '/docs', titleID: 'documentation' },
- { url: '/support', titleID: 'support' },
+ { url: '/support', titleID: 'support' }
];
</script>
diff --git a/src/components/LocationsMap.svelte b/src/components/LocationsMap.svelte
index 277d75a6..7876659a 100644
--- a/src/components/LocationsMap.svelte
+++ b/src/components/LocationsMap.svelte
@@ -1,205 +1,141 @@
<script>
- export let locations;
-
import { onMount, onDestroy } from 'svelte';
import { browser } from '$app/environment';
-
import html2canvas from 'html2canvas';
- function captureHighResMap(mapElement, scale = 2) {
- // Backup original size
- let originalWidth = mapElement.offsetWidth;
- let originalHeight = mapElement.offsetHeight;
-
- // Scale the map element
- mapElement.style.transform = `scale(${scale})`;
- mapElement.style.transformOrigin = 'top left';
- mapElement.style.width = originalWidth * scale + 'px';
- mapElement.style.height = originalHeight * scale + 'px';
-
- return html2canvas(mapElement, {
- width: originalWidth * scale,
- height: originalHeight * scale,
- scale: scale
- }).then((canvas) => {
- // Restore the original size
- mapElement.style.transform = '';
- mapElement.style.width = originalWidth + 'px';
- mapElement.style.height = originalHeight + 'px';
-
- return canvas;
- });
- }
+ import 'maplibre-gl/dist/maplibre-gl.css';
- let mapElement;
+ export let locations;
let map;
+ let mapContainer;
+ let markers = [];
- onMount(async () => {
- if (browser) {
- const L = await import('leaflet');
-
- map = L.map(mapElement, {
- zoomSnap: 0,
- attributionControl: false,
- }).setView([49.26, -123.05], 12);
-
-
- const myCustomColour = '#F7931A';
+ let checkAddress = (location) => {
+ if (location['addr:housenumber'] && location['addr:street'] && location['addr:city']) {
+ return `${
+ location['addr:housenumber'] + ' ' + location['addr:street'] + ', ' + location['addr:city']
+ }`;
+ } else if (location['addr:street'] && location['addr:city']) {
+ return `${location['addr:street'] + ', ' + location['addr:city']}`;
+ } else if (location['addr:city']) {
+ return `${location['addr:city']}`;
+ } else {
+ return '';
+ }
+ };
- const markerHtmlStyles = `
- background-color: ${myCustomColour};
- width: 1.2rem;
- height: 1.2rem;
- display: block;
- position: relative;
- border-radius: 100% 100% 0;
- transform: rotate(45deg);
- opacity: 0.9;
- border: 1px solid #666`;
+ function updateLabelVisibility() {
+ if (!map) return;
+ let zoom = map.getZoom();
+ let bounds = map.getBounds();
- const icon = L.divIcon({
- className: 'my-custom-pin',
- iconAnchor: [0, 24],
- labelAnchor: [-6, 0],
- popupAnchor: [0, -36],
- html: `<span style="${markerHtmlStyles}" />`
- });
+ for (let marker of markers) {
+ let isInView = bounds.contains(marker.getLngLat());
+ let popup = marker.getPopup();
+ let { tags } = marker;
- locations = locations.filter(
- (location) =>
- location['osm_json'].tags &&
- location['osm_json'].tags['payment:swapee'] === 'yes' &&
- location['osm_json'].lat &&
- location['osm_json'].lon
- );
+ if (zoom > 13 && isInView) {
+ popup.setHTML(`<span class='block font-bold'>${tags.name}</span>`).addTo(map);
+ } else {
+ popup.remove();
+ popup.setHTML(html(tags));
+ }
+ }
+ }
- L.tileLayer('https://stamen-tiles-{s}.a.ssl.fastly.net/toner/{z}/{x}/{y}.png', {
- maxZoom: 18,
- subdomains: ['a', 'b', 'c', 'd']
- }).addTo(map);
+ let html = (tags) => `${
+ tags && tags.name ? `<span class='block font-bold'>${tags.name}</span>` : ''
+ }
- const checkAddress = (location) => {
- if (location['addr:housenumber'] && location['addr:street'] && location['addr:city']) {
- return `${
- location['addr:housenumber'] +
- ' ' +
- location['addr:street'] +
- ', ' +
- location['addr:city']
- }`;
- } else if (location['addr:street'] && location['addr:city']) {
- return `${location['addr:street'] + ', ' + location['addr:city']}`;
- } else if (location['addr:city']) {
- return `${location['addr:city']}`;
- } else {
- return '';
- }
- };
+ <span class='block'>${tags && checkAddress(tags)}</span>
- locations.forEach((location) => {
- if (location['deleted_at']) return;
+ ${tags && tags.phone ? `<a href='tel:${tags.phone}' class='block'>${tags.phone}</a>` : ''}
- location = location['osm_json'];
- let marker = L.marker([location.lat, location.lon], { icon });
+ ${
+ tags && tags.website
+ ? `<a href=${tags.website} target="_blank" rel="noreferrer" class='block text-blue-400'>${tags.website}</a>`
+ : ''
+ }`;
- if (location.tags && location.tags.name) {
- marker.bindTooltip(location.tags.name, { permanent: true }).openTooltip();
- }
+ onMount(() => {
+ if (browser) {
+ import('maplibre-gl').then(({ default: maplibre }) => {
+ map = new maplibre.Map({
+ container: mapContainer,
+ style: 'https://tiles.stadiamaps.com/styles/stamen_toner.json',
+ center: [-123.05, 49.26],
+ zoom: 10.5
+ });
- marker.bindPopup(
- `${
- location.tags && location.tags.name
- ? `<span class='block'>${location.tags.name}</span>`
- : ''
- }
+ map.on('load', () => {
+ locations.forEach((location) => {
+ if (location['deleted_at']) return;
- <span class='block'>${location.tags && checkAddress(location.tags)}</span>
+ let { lat, lon, tags } = location['osm_json'];
+ if (!(lat && lon)) return;
- ${
- location.tags && location.tags.phone
- ? `<a href='tel:${location.tags.phone}' class='block'>${location.tags.phone}</a>`
- : ''
- }
+ let element = document.createElement('div');
+ element.className = 'marker';
- ${
- location.tags && location.tags.website
- ? `<a href=${location.tags.website} target="_blank" rel="noreferrer" class='block'>${location.tags.website}</a>`
- : ''
- }
+ let marker = new maplibre.Marker({ color: '#F7931A' })
+ .setLngLat([lon, lat])
+ .setPopup(new maplibre.Popup().setHTML(html(tags)))
+ .addTo(map);
- ${
- location.tags && location.tags['contact:twitter']
- ? `<a href=${
- location.tags['contact:twitter'].startsWith('http')
- ? location.tags['contact:twitter']
- : `https://twitter.com/${location.tags['contact:twitter']}`
- } target="_blank" rel="noreferrer" class='block'>TWT: ${
- location.tags['contact:twitter']
- }</a>`
- : ''
- }
+ marker.getElement().addEventListener('click', () => {
+ let h = html(marker.tags);
+ let popup = marker.getPopup();
+ popup.setHTML(h);
+ });
- ${
- location.tags && location.tags['contact:instagram']
- ? `<a href=${
- location.tags['contact:instagram'].startsWith('http')
- ? location.tags['contact:instagram']
- : `https://instagram.com/${location.tags['contact:instagram']}`
- } target="_blank" rel="noreferrer" class='block'>IG: ${
- location.tags['contact:instagram']
- }</a>`
- : ''
- }
+ marker.tags = tags;
- ${
- location.tags && location.tags['contact:facebook']
- ? `<a href=${
- location.tags['contact:facebook'].startsWith('http')
- ? location.tags['contact:facebook']
- : `https://facebook.com/${location.tags['contact:facebook']}`
- } target="_blank" rel="noreferrer" class='block'>FB: ${
- location.tags['contact:facebook']
- }</a>`
- : ''
- }
+ markers.push(marker);
+ });
- ${
- location.tags && location.tags['contact:linkedin']
- ? `<a href=${
- location.tags['contact:linkedin'].startsWith('http')
- ? location.tags['contact:linkedin']
- : `https://linkedin.com/${location.tags['contact:linkedin']}`
- } target="_blank" rel="noreferrer" class='block'>LI: ${
- location.tags['contact:linkedin']
- }</a>`
- : ''
- }`
- );
- marker.addTo(map);
+ // updateLabelVisibility();
+ // map.on('moveend', updateLabelVisibility);
+ // map.on('zoomend', updateLabelVisibility);
+ });
});
-
- // map.fitBounds(locations.map(({ osm_json: { lat, lon } }) => [lat, lon]));
}
});
- onDestroy(async () => map && map.remove());
+ onDestroy(() => {
+ if (map) {
+ // map.off('moveend', updateLabelVisibility);
+ // map.off('zoomend', updateLabelVisibility);
+ map.remove();
+ }
+ });
</script>
<div class="container mx-auto max-w-4xl">
- <div class="flex w-full">
- <div class="mx-auto h-[550px] w-full z-0" bind:this={mapElement} />
- </div>
+ <div class="flex w-full">
+ <div class="mx-auto h-[550px] w-full z-0" bind:this={mapContainer} />
+ </div>
</div>
<style>
- @import 'leaflet/dist/leaflet.css';
+ :global(.maplibregl-popup-close-button) {
+ font-size: 18px;
+ padding: 8px;
+ }
+
+ :global(.maplibregl-popup :focus) {
+ outline: none;
+ }
+
+ :global(.maplibregl-ctrl-attrib) {
+ display: none;
+ }
- :global(.leaflet-tooltip) {
- border: none;
+ :global(.maplibregl-popup-content) {
+ padding: 0.5em 1em;
border-radius: 4px;
- font-size: 12px;
- font-weight: bolder;
+ font-size: 14px;
color: black;
- background-color: rgba(255, 255, 255, 0.5);
+ background-color: white;
+ overflow: hidden;
}
</style>
diff --git a/src/components/RegisterOrLogin.svelte b/src/components/RegisterOrLogin.svelte
index afe85db5..da6c387d 100644
--- a/src/components/RegisterOrLogin.svelte
+++ b/src/components/RegisterOrLogin.svelte
@@ -88,7 +88,11 @@
{/if}
<form class="space-y-5" on:submit|preventDefault={handleSubmit} method="POST">
- <input type="hidden" name="loginRedirect" value={$loginRedirect || $page.url.searchParams.get('redirect')} />
+ <input
+ type="hidden"
+ name="loginRedirect"
+ value={$loginRedirect || $page.url.searchParams.get('redirect')}
+ />
<input type="hidden" name="token" value={token} />
<div>
diff --git a/src/lib/invoice.js b/src/lib/invoice.js
index 23ce1757..218972c6 100644
--- a/src/lib/invoice.js
+++ b/src/lib/invoice.js
@@ -21,16 +21,16 @@ export default async ({ cookies, request, url }) => {
let user = { username: form.get('username'), currency: form.get('currency') };
invoice = await post('/invoice', { invoice, user }, auth(cookies));
- let { hash } = invoice;
+ let { id } = invoice;
if (request_id) {
if (url.pathname.endsWith('tip')) {
- throw redirect(307, `/send/invoice/${hash}`);
+ throw redirect(307, `/send/invoice/${id}`);
}
throw redirect(307, `/${user.username}/request/${request_id}`);
}
- if (invoice.prompt) throw redirect(307, `/${user.username}/invoice/${hash}/tip`);
- else throw redirect(307, `/${user.username}/invoice/${hash}`);
+ if (invoice.prompt) throw redirect(307, `/${user.username}/invoice/${id}/tip`);
+ else throw redirect(307, `/${user.username}/invoice/${id}`);
};
diff --git a/src/lib/socket.js b/src/lib/socket.js
index e8859fa6..96fde317 100644
--- a/src/lib/socket.js
+++ b/src/lib/socket.js
@@ -1,5 +1,5 @@
import { get } from 'svelte/store';
-import { event, invoice, request, newPayment, last, rate, payments, user } from '$lib/store';
+import { event, invoice, request, newPayment, last, rate, user } from '$lib/store';
import { success, sat } from '$lib/utils';
import { PUBLIC_SOCKET } from '$env/static/public';
import { invalidate } from '$app/navigation';
@@ -34,23 +34,13 @@ export const messages = (data) => ({
},
async payment() {
- let { amount, invoice } = data;
+ let { amount, confirmed } = data;
+ invalidate('app:user');
invalidate('app:invoice');
-
- let p = get(payments);
- let i = p.findIndex((p) => p.id === data.id);
-
- if (~i) {
- p[i] = data;
- payments.set(p);
- } else newPayment.set(true);
-
- invalidate((url) => url.pathname === '/payments');
+ invalidate('app:payments');
if (amount > 0) {
- success(`${data.confirmed ? 'Received' : 'Detected'} ${sat(amount)}!`);
- } else {
- // success(`Sent ${sat(amount)}!`);
+ success(`${confirmed ? 'Received' : 'Detected'} ${sat(amount)}!`);
}
},
diff --git a/src/lib/store.js b/src/lib/store.js
index 923bda52..64cf015e 100644
--- a/src/lib/store.js
+++ b/src/lib/store.js
@@ -45,7 +45,6 @@ export const decrypted = persistLocal('decrypted', {});
export const newPayment = persistLocal('newPayment');
export const password = persistLocal('password');
export const passwordPrompt = writable();
-export const payments = persistLocal('transactions', []);
export const pin = writable();
export const rate = writable();
export const request = writable();
diff --git a/src/locales/en.json b/src/locales/en.json
index 7b3fca1c..463cdcf2 100644
--- a/src/locales/en.json
+++ b/src/locales/en.json
@@ -148,6 +148,8 @@
"failed": "Login failed"
},
"nav": {
+ "map": "Map",
+ "merch": "Merch",
"profile": "Profile",
"startInSeconds": "Start in Seconds",
"account": "Account",
diff --git a/src/locales/fr.json b/src/locales/fr.json
index 8097ce1f..1d0f9fac 100644
--- a/src/locales/fr.json
+++ b/src/locales/fr.json
@@ -135,7 +135,9 @@
"dashboard": "Tableau de bord",
"settings": "Préférences",
"support": "Assistance",
- "profile": "Profil"
+ "profile": "Profil",
+ "map": "Carte",
+ "merch": "Marchandise"
},
"invoice": {
"addTip": "Ajoutez un pourboire",
diff --git a/src/routes/(app)/[username]/(profile)/+layout.svelte b/src/routes/(app)/[username]/(profile)/+layout.svelte
index 0642b6fc..b8059a90 100644
--- a/src/routes/(app)/[username]/(profile)/+layout.svelte
+++ b/src/routes/(app)/[username]/(profile)/+layout.svelte
@@ -51,16 +51,16 @@
<div class="w-[240px] lg:absolute space-y-5 left-20 mx-auto lg:mr-10">
<h1 class="text-3xl font-bold text-center mx-auto">{display || username}</h1>
- {#if subject.address}
- <div
- class="text-secondary mx-auto text-center lg:text-left lg:mx-0"
- class:line-clamp-3={hideBio}
- on:click={toggleBio}
- on:keydown={toggleBio}
- >
- {subject.address}
- </div>
- {/if}
+ {#if subject.address}
+ <div
+ class="text-secondary mx-auto text-center lg:text-left lg:mx-0"
+ class:line-clamp-3={hideBio}
+ on:click={toggleBio}
+ on:keydown={toggleBio}
+ >
+ {subject.address}
+ </div>
+ {/if}
<div class="flex justify-around">
<a href={`/${subject.pubkey}/follows`}
diff --git a/src/routes/(app)/[username]/(profile)/+page.svelte b/src/routes/(app)/[username]/(profile)/+page.svelte
index 798509ed..8ff7ea90 100644
--- a/src/routes/(app)/[username]/(profile)/+page.svelte
+++ b/src/routes/(app)/[username]/(profile)/+page.svelte
@@ -98,7 +98,7 @@
>
<div class="mx-auto flex">
<Icon icon="numpad" style="my-auto h-6 mr-2 invert" />
- <div class="my-auto mt-1">Request Payment</div>
+ <div class="my-auto mt-1">{$t('user.requestPayment')}</div>
</div>
</button>
</a>
diff --git a/src/routes/(app)/[username]/card/[serial]/+page.svelte b/src/routes/(app)/[username]/card/[serial]/+page.svelte
index aee3be28..afdaf65d 100644
--- a/src/routes/(app)/[username]/card/[serial]/+page.svelte
+++ b/src/routes/(app)/[username]/card/[serial]/+page.svelte
@@ -6,30 +6,30 @@
</script>
<div class="space-y-5">
-<div class="relative flex justify-center gap-2">
- <h1 class="text-2xl md:text-3xl font-semibold my-auto">Card {serial}</h1>
-</div>
-<div class="flex justify-center">
- <a href={`/send/pot/${serial}`}>
- <button
- class="rounded-full border py-3 px-6 font-bold hover:opacity-80 flex w-60 bg-black text-white justify-center gap-2"
- >
- <svg
- xmlns="http://www.w3.org/2000/svg"
- class="invert text-black peer-placeholder-shown:text-gray-300 h-6 w-6 my-auto"
- fill="none"
- viewBox="0 0 24 24"
- stroke="currentColor"
+ <div class="relative flex justify-center gap-2">
+ <h1 class="text-2xl md:text-3xl font-semibold my-auto">Card {serial}</h1>
+ </div>
+ <div class="flex justify-center">
+ <a href={`/send/pot/${serial}`}>
+ <button
+ class="rounded-full border py-3 px-6 font-bold hover:opacity-80 flex w-60 bg-black text-white justify-center gap-2"
>
- <path
- stroke-linecap="round"
- stroke-linejoin="round"
- stroke-width="2"
- d="M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z"
- />
- </svg>
- <div class="my-auto">Add Funds</div>
- </button>
- </a>
-</div>
+ <svg
+ xmlns="http://www.w3.org/2000/svg"
+ class="invert text-black peer-placeholder-shown:text-gray-300 h-6 w-6 my-auto"
+ fill="none"
+ viewBox="0 0 24 24"
+ stroke="currentColor"
+ >
+ <path
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ d="M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z"
+ />
+ </svg>
+ <div class="my-auto">Add Funds</div>
+ </button>
+ </a>
+ </div>
</div>
diff --git a/src/routes/(app)/[username]/generate/+page.svelte b/src/routes/(app)/[username]/generate/+page.svelte
index 33bf64c4..b9274434 100644
--- a/src/routes/(app)/[username]/generate/+page.svelte
+++ b/src/routes/(app)/[username]/generate/+page.svelte
@@ -14,10 +14,10 @@
let gen = async () => {
if (!browser) return;
- if (user.pubkey) {
- goto($loginRedirect || `/${user.username}`, { invalidateAll: true });
- return;
- }
+ if (user.pubkey) {
+ goto($loginRedirect || `/${user.username}`, { invalidateAll: true });
+ return;
+ }
if (!$password) $passwordPrompt = true;
diff --git a/src/routes/(app)/[username]/invoice/[hash]/+layout.server.js b/src/routes/(app)/[username]/invoice/[id]/+layout.server.js
index eef24555..4d7fd3b8 100644
--- a/src/routes/(app)/[username]/invoice/[hash]/+layout.server.js
+++ b/src/routes/(app)/[username]/invoice/[id]/+layout.server.js
@@ -6,20 +6,26 @@ export async function load({ depends, params, url, parent }) {
depends('app:invoice');
let { user } = await parent();
- let { hash } = params;
- let invoice = await get(`/invoice/${hash}`);
+ let { id } = params;
+ let invoice = await get(`/invoice/${id}`);
+ let options = !!url.searchParams.get('options');
- if (user && invoice.uid !== user.id && !url.pathname.includes('tip') && !url.searchParams.get('options'))
- throw redirect(307, `/send/invoice/${hash}`);
+ if (user && invoice.uid !== user.id && !url.pathname.includes('tip') && !options) {
+ throw redirect(307, `/send/invoice/${id}`);
+ }
let { amount, pending, received } = invoice;
amount = parseInt(amount);
let paid = (!amount && received) || (amount > 0 && (pending >= amount || received >= amount));
- if (paid && !url.pathname.endsWith('paid'))
- throw redirect(307, `/${params.username}/invoice/${hash}/paid`);
+ if (paid && !url.pathname.endsWith('paid')) {
+ throw redirect(
+ 307,
+ `/${params.username}/invoice/${id}/paid` + (options ? '?options=true' : '')
+ );
+ }
let sm = Qr.drawImg(invoice.text || '', { size: 300 });
- return { hash, invoice, sm, lg: sm };
+ return { id, invoice, sm, lg: sm };
}
diff --git a/src/routes/(app)/[username]/invoice/[hash]/+layout.svelte b/src/routes/(app)/[username]/invoice/[id]/+layout.svelte
index 4fa864ce..4fa864ce 100644
--- a/src/routes/(app)/[username]/invoice/[hash]/+layout.svelte
+++ b/src/routes/(app)/[username]/invoice/[id]/+layout.svelte
diff --git a/src/routes/(app)/[username]/invoice/[hash]/+page.server.js b/src/routes/(app)/[username]/invoice/[id]/+page.server.js
index 1068f273..1068f273 100644
--- a/src/routes/(app)/[username]/invoice/[hash]/+page.server.js
+++ b/src/routes/(app)/[username]/invoice/[id]/+page.server.js
diff --git a/src/routes/(app)/[username]/invoice/[hash]/+page.svelte b/src/routes/(app)/[username]/invoice/[id]/+page.svelte
index 508550ba..2d204255 100644
--- a/src/routes/(app)/[username]/invoice/[hash]/+page.svelte
+++ b/src/routes/(app)/[username]/invoice/[id]/+page.svelte
@@ -101,12 +101,12 @@
let toggleType = async () => {
invoice.type = invoice.type === types.lightning ? types.bitcoin : types.lightning;
- ({ hash } = await post(`/${username}/invoice`, {
+ ({ id } = await post(`/${username}/invoice`, {
invoice,
user: { username, currency }
}));
- goto(`./${hash}`, { invalidateAll: true });
+ goto(`./${id}`, { invalidateAll: true });
};
</script>
diff --git a/src/routes/(app)/[username]/invoice/[hash]/paid/+page.svelte b/src/routes/(app)/[username]/invoice/[id]/paid/+page.svelte
index 969fb6c7..84e493d9 100644
--- a/src/routes/(app)/[username]/invoice/[hash]/paid/+page.svelte
+++ b/src/routes/(app)/[username]/invoice/[id]/paid/+page.svelte
@@ -5,7 +5,6 @@
import { browser } from '$app/environment';
import { t } from '$lib/translations';
import { fiat, f, s, sat, sats } from '$lib/utils';
- import { goto } from '$app/navigation';
export let data;
let amount, currency, rate, received, pending, tip, user, id;
diff --git a/src/routes/(app)/[username]/invoice/[hash]/tip/+page.server.js b/src/routes/(app)/[username]/invoice/[id]/tip/+page.server.js
index 814900fb..814900fb 100644
--- a/src/routes/(app)/[username]/invoice/[hash]/tip/+page.server.js
+++ b/src/routes/(app)/[username]/invoice/[id]/tip/+page.server.js
diff --git a/src/routes/(app)/[username]/invoice/[hash]/tip/+page.svelte b/src/routes/(app)/[username]/invoice/[id]/tip/+page.svelte
index fe6c67be..fe6c67be 100644
--- a/src/routes/(app)/[username]/invoice/[hash]/tip/+page.svelte
+++ b/src/routes/(app)/[username]/invoice/[id]/tip/+page.svelte
diff --git a/src/routes/(app)/[username]/map/+page.server.js b/src/routes/(app)/[username]/map/+page.server.js
new file mode 100644
index 00000000..7936e88b
--- /dev/null
+++ b/src/routes/(app)/[username]/map/+page.server.js
@@ -0,0 +1,12 @@
+import { get } from '$lib/utils';
+
+// export const prerender = true;
+export let load = async () => {
+ let data = { locations: [] };
+
+ try {
+ data = await get('/locations');
+ } catch (e) {}
+
+ return data;
+};
diff --git a/src/routes/(app)/[username]/map/+page.svelte b/src/routes/(app)/[username]/map/+page.svelte
new file mode 100644
index 00000000..99c822d3
--- /dev/null
+++ b/src/routes/(app)/[username]/map/+page.svelte
@@ -0,0 +1,8 @@
+<script>
+ import { LocationsMap } from '$comp';
+ export let data;
+
+ let { locations } = data;
+</script>
+
+<LocationsMap {locations} />
diff --git a/src/routes/(app)/[username]/payments/[...page]/+page.server.js b/src/routes/(app)/[username]/payments/[...page]/+page.server.js
index cb94d71d..a3b0ad6f 100644
--- a/src/routes/(app)/[username]/payments/[...page]/+page.server.js
+++ b/src/routes/(app)/[username]/payments/[...page]/+page.server.js
@@ -2,7 +2,9 @@ import { get, auth } from '$lib/utils';
let limit = 25;
-export async function load({ cookies, params, request }) {
+export async function load({ cookies, depends, params, request }) {
+ depends('app:payments');
+
let parts = params.page.split('/');
let start, end, page;
diff --git a/src/routes/(app)/[username]/payments/[...page]/+page.svelte b/src/routes/(app)/[username]/payments/[...page]/+page.svelte
index 69f51f37..2ea225ad 100644
--- a/src/routes/(app)/[username]/payments/[...page]/+page.svelte
+++ b/src/routes/(app)/[username]/payments/[...page]/+page.svelte
@@ -2,7 +2,7 @@
import { Avatar, Icon } from '$comp';
import { onMount } from 'svelte';
import { format } from 'date-fns';
- import { newPayment, payments } from '$lib/store';
+ import { newPayment } from '$lib/store';
import { t } from '$lib/translations';
import { get, f, s, sat, sats, types } from '$lib/utils';
import { page } from '$app/stores';
@@ -11,7 +11,7 @@
export let data;
- let { start, end, user, rates } = data;
+ let { start, end, user, rates, payments } = data;
let change = ({ target: { value } }) => goto(value);
let link = (p) => {
@@ -34,7 +34,7 @@
let p,
totals,
pages = [];
- $: data && ({ page: p, pages, start, end, totals, payments: $payments } = data);
+ $: data && ({ page: p, pages, start, end, totals, payments } = data);
$: $page && ($newPayment = false);
$: $newPayment && invalidate(`/users/${user.username}`);
@@ -136,7 +136,7 @@
</div>
<div class="text-base">
- {#each $payments as p}
+ {#each payments as p}
<a href={`/payment/${p.id}`}>
<div class="grid grid-cols-3 border-b h-24 hover:bg-gray-100 px-4">
<div class="whitespace-nowrap my-auto">
@@ -216,7 +216,7 @@
</div>
<div class="grid grid-cols-3 w-full text-center">
- <span class="text-lg text-secondary">{$t('payments.total')}</span>
+ <span class="text-lg text-secondary">{$t('payments.total')}</span>
<span class="text-lg text-secondary">{$t('payments.presentValue')}</span>
<span class="text-lg text-secondary">{$t('payments.gainLoss')}</span>
@@ -226,7 +226,9 @@
{@const gain = (pv * 100) / total - 100}
<span class="text-lg"><b>{f(total, c)}</b></span>
<span class="text-lg"><b>{f(pv, c)}</b></span>
- <span class="text-lg" class:text-red-800={gain < 0}><b>{Math.abs(gain).toFixed(2)}%</b></span>
+ <span class="text-lg" class:text-red-800={gain < 0}
+ ><b>{Math.abs(gain).toFixed(2)}%</b></span
+ >
{/each}
</div>
diff --git a/src/routes/(app)/[username]/receive/[...param]/+page.svelte b/src/routes/(app)/[username]/receive/[...param]/+page.svelte
index a97dc776..d7001079 100644
--- a/src/routes/(app)/[username]/receive/[...param]/+page.svelte
+++ b/src/routes/(app)/[username]/receive/[...param]/+page.svelte
@@ -5,7 +5,6 @@
import { page } from '$app/stores';
import { requestRedirect } from '$lib/store';
import { browser } from '$app/environment';
- import { goto } from '$app/navigation';
export let data;
let type = 'lightning';
diff --git a/src/routes/(app)/[username]/settings/[...tab]/+page.svelte b/src/routes/(app)/[username]/settings/[...tab]/+page.svelte
index 842c2eba..762e836e 100644
--- a/src/routes/(app)/[username]/settings/[...tab]/+page.svelte
+++ b/src/routes/(app)/[username]/settings/[...tab]/+page.svelte
@@ -138,7 +138,9 @@
<div class="font-bold flex justify-around items-center border-b pb-3 text-secondary">
{#each tabs.filter((t) => t.name !== 'shopify') as { name, key }}
<a href={`/${user.username}/settings/${name}`}>
- <button class="hover:opacity-80" class:text-black={tab === name || (tab === "shopify" && name === "pos")}
+ <button
+ class="hover:opacity-80"
+ class:text-black={tab === name || (tab === 'shopify' && name === 'pos')}
>{$t(`user.settings.${key}`)}</button
>
</a>
diff --git a/src/routes/(app)/[username]/settings/[...tab]/_account.svelte b/src/routes/(app)/[username]/settings/[...tab]/_account.svelte
index 34399ad5..47c4c4c6 100644
--- a/src/routes/(app)/[username]/settings/[...tab]/_account.svelte
+++ b/src/routes/(app)/[username]/settings/[...tab]/_account.svelte
@@ -64,28 +64,32 @@
$: url = `${$page.url.host}/${user.username}`;
$: full = `${$page.url.protocol}//${url}`;
- $: addr = `${user.username}@${$page.url.host}`;
+ $: addr = `${user.username}@${$page.url.host}`;
</script>
<div>
<label for="username" class="font-bold mb-1 block">{$t('user.settings.username')}</label>
<div class="flex mb-2">
- <input
- type="text"
- name="username"
- bind:value={user.username}
- class="border-r-0 rounded-r-none w-auto min-w-0 pr-1 grow"
- />
- <div class="text-gray-600 p-4 my-auto bg-gray-100 border border-r-0 pl-1">@{$page.url.host}</div>
- <div class="text-gray-600 border-l-0 bg-gray-100 rounded-r-2xl p-4 my-auto border w-16" >
- <a href={`/qr/${encodeURIComponent(addr)}`}>
- <Icon icon="qr" style="invert" />
- </a>
+ <input
+ type="text"
+ name="username"
+ bind:value={user.username}
+ class="border-r-0 rounded-r-none w-auto min-w-0 pr-1 grow"
+ />
+ <div class="text-gray-600 p-4 my-auto bg-gray-100 border border-r-0 pl-1">
+ @{$page.url.host}
+ </div>
+ <div class="text-gray-600 border-l-0 bg-gray-100 rounded-r-2xl p-4 my-auto border w-16">
+ <a href={`/qr/${encodeURIComponent(addr)}`}>
+ <Icon icon="qr" style="invert" />
+ </a>
</div>
</div>
<div class="flex mb-2">
- <div class="text-gray-600 rounded-l-2xl p-4 my-auto border bg-gray-100 pr-1">{$page.url.host}/</div>
+ <div class="text-gray-600 rounded-l-2xl p-4 my-auto border bg-gray-100 pr-1">
+ {$page.url.host}/
+ </div>
<input
type="text"
name="username"
@@ -93,9 +97,9 @@
class="grow border-l-0 rounded-l-none border-r-0 rounded-r-none w-auto pl-1 min-w-0"
/>
<div class="text-gray-600 rounded-r-2xl p-4 my-auto border bg-gray-100 w-16">
- <a href={`/qr/${encodeURIComponent(full)}`}>
- <Icon icon="qr" style="invert" />
- </a>
+ <a href={`/qr/${encodeURIComponent(full)}`}>
+ <Icon icon="qr" style="invert" />
+ </a>
</div>
</div>
</div>
diff --git a/src/routes/(app)/[username]/settings/[...tab]/_pos.svelte b/src/routes/(app)/[username]/settings/[...tab]/_pos.svelte
index ef5b7869..057d8c20 100644
--- a/src/routes/(app)/[username]/settings/[...tab]/_pos.svelte
+++ b/src/routes/(app)/[username]/settings/[...tab]/_pos.svelte
@@ -33,7 +33,9 @@
</div>
<a href="./shopify">
- <button class="flex rounded-full border py-2 px-4 font-bold hover:opacity-80 w-full gap-2 my-5 justify-center">
+ <button
+ class="flex rounded-full border py-2 px-4 font-bold hover:opacity-80 w-full gap-2 my-5 justify-center"
+ >
<img src="/icons/shopify.svg" class="w-8" />
<div class="my-auto">Shopify Integration</div>
</button>
diff --git a/src/routes/(app)/[username]/settings/[...tab]/_security.svelte b/src/routes/(app)/[username]/settings/[...tab]/_security.svelte
index 40947bda..c01db734 100644
--- a/src/routes/(app)/[username]/settings/[...tab]/_security.svelte
+++ b/src/routes/(app)/[username]/settings/[...tab]/_security.svelte
@@ -52,10 +52,12 @@
return true;
};
+ let disablingPin = false;
+
let togglePin = async () => {
if (user.haspin) {
try {
- pin = null;
+ disablingPin = true;
await tick();
submit.click();
} catch (e) {
@@ -120,7 +122,7 @@
};
</script>
-<input type="hidden" name="newpin" value={pin} />
+<input type="hidden" name="newpin" value={disablingPin ? 'delete' : pin} />
<input type="hidden" name="confirm" bind:value={password} />
<div class="relative mb-5">
diff --git a/src/routes/(app)/[username]/settings/[...tab]/_shopify.svelte b/src/routes/(app)/[username]/settings/[...tab]/_shopify.svelte
index 7b9cc40b..aeecc4d7 100644
--- a/src/routes/(app)/[username]/settings/[...tab]/_shopify.svelte
+++ b/src/routes/(app)/[username]/settings/[...tab]/_shopify.svelte
@@ -4,15 +4,23 @@
import { page } from '$app/stores';
export let user;
- $: paymentsUrl = user.shopifyStore && "https://admin.shopify.com/store/" + user.shopifyStore + "/settings/payments";
- $: checkoutUrl = user.shopifyStore && "https://admin.shopify.com/store/" + user.shopifyStore + "/settings/checkout";
- $: appsUrl = user.shopifyStore && "https://admin.shopify.com/store/" + user.shopifyStore + "/settings/apps/development";
+ $: paymentsUrl =
+ user.shopifyStore &&
+ 'https://admin.shopify.com/store/' + user.shopifyStore + '/settings/payments';
+ $: checkoutUrl =
+ user.shopifyStore &&
+ 'https://admin.shopify.com/store/' + user.shopifyStore + '/settings/checkout';
+ $: appsUrl =
+ user.shopifyStore &&
+ 'https://admin.shopify.com/store/' + user.shopifyStore + '/settings/apps/development';
</script>
<div>
<label for="shopifyStore" class="font-bold mb-1 block">Store ID</label>
<div class="flex mb-2">
- <div class="text-gray-600 p-4 my-auto bg-gray-100 border rounded-l-2xl border-r-0 pr-1">admin.shopify.com/store/</div>
+ <div class="text-gray-600 p-4 my-auto bg-gray-100 border rounded-l-2xl border-r-0 pr-1">
+ admin.shopify.com/store/
+ </div>
<input
type="text"
name="shopifyStore"
@@ -21,34 +29,41 @@
/>
</div>
<p class="text-secondary my-2">
- Add Bitcoin under <a class:active={!!paymentsUrl} href={paymentsUrl || undefined}>Payments > Manual payment methods</a> with a description like "Pay with Bitcoin".
+ Add Bitcoin under <a class:active={!!paymentsUrl} href={paymentsUrl || undefined}
+ >Payments > Manual payment methods</a
+ > with a description like "Pay with Bitcoin".
</p>
</div>
<div>
- <label for="shopifyToken" class="font-bold mb-1 block">Admin API token</label>
- <input type="text" name="shopifyToken" bind:value={user.shopifyToken} />
-
-<p class="text-secondary my-2">
-Create an app named Coinos under <a class:active={!!appsUrl} href={appsUrl || undefined}>Apps > App Development</a>
-</p>
-
-<p class="text-secondary my-2">
-Edit the Admin API scopes to enable <code class="text-black">write_orders</code> then
-install the app into your store and copy the Admin API access token here.
+ <label for="display" class="font-bold mb-1 block">Additional scripts</label>
+ <p class="text-secondary my-2">
+ Copy this into <a class:active={!!paymentsUrl} href={checkoutUrl}
+ >Checkout -> Additional scripts</a
+ >
+ </p>
+ <textarea rows={5} type="text" name="shopifyScripts" readonly><script src="{`${$page.url.protocol}//${$page.url.host}/${user.username}/shopify.js`}"> </script></textarea>
</div>
<div>
- <label for="display" class="font-bold mb-1 block">Additional scripts</label>
- <textarea rows={5} type="text" name="shopifyScripts" readonly><script src="{`${$page.url.protocol}//${$page.url.host}/${user.username}/shopify.js`}"> </script></textarea>
+ <label for="shopifyToken" class="font-bold mb-1 block">Admin API token <span class="font-normal">(Optional)</span></label>
+ <p class="text-secondary my-2">Coinos can automatically mark orders as Paid if you provide an API token.
+ <input class="my-4" type="text" name="shopifyToken" bind:value={user.shopifyToken} />
+
+ <p class="text-secondary my-2">
+ Create a new app in <a class:active={!!appsUrl} href={appsUrl || undefined}
+ >Apps > App Development</a
+ >
+ </p>
<p class="text-secondary my-2">
- Copy this into <a class:active={!!paymentsUrl} href={checkoutUrl}>Checkout -> Additional scripts</a>
+ Edit the Admin API scopes to enable <code class="text-black">write_orders</code> permission then install the
+ app into your store and copy the Admin API access token here.
</p>
</div>
<style>
- .active {
- @apply text-blue-500;
- }
+ .active {
+ @apply text-blue-500;
+ }
</style>
diff --git a/src/routes/(app)/[username]/shopify.js/+server.js b/src/routes/(app)/[username]/shopify.js/+server.js
index 963b92a1..7b5c9d41 100644
--- a/src/routes/(app)/[username]/shopify.js/+server.js
+++ b/src/routes/(app)/[username]/shopify.js/+server.js
@@ -46,8 +46,6 @@ window.addEventListener('load', async () => {
let s = (s) => new Intl.NumberFormat('en-US', { maximumFractionDigits: 0 }).format(s);
- let base64 = drawImg('test', { size: 300 });
-
let link = document.createElement('link');
link.setAttribute('rel', 'stylesheet');
link.setAttribute('type', 'text/css');
@@ -92,6 +90,8 @@ window.addEventListener('load', async () => {
})
.catch(console.log);
+ let base64 = drawImg(data.hash, { size: 300 });
+
main.innerHTML = \`<a href="lightning:\${data.hash}">
<div style="display: flex; margin-top: 50px; margin-bottom: 80px; position: relative;">
<img id="qrcode" src="\${base64}" />
diff --git a/src/routes/(app)/login/+page.svelte b/src/routes/(app)/login/+page.svelte
index dce523cb..84ecc3ad 100644
--- a/src/routes/(app)/login/+page.svelte
+++ b/src/routes/(app)/login/+page.svelte
@@ -4,7 +4,7 @@
import { animatedRate, pin } from '$lib/store';
onMount(() => {
- $animatedRate = 0;
+ $animatedRate = 0;
$pin = undefined;
localStorage.clear();
sessionStorage.clear();
diff --git a/src/routes/(app)/payment/[id]/+page.svelte b/src/routes/(app)/payment/[id]/+page.svelte
index 5037eec2..12bb1c2d 100644
--- a/src/routes/(app)/payment/[id]/+page.svelte
+++ b/src/routes/(app)/payment/[id]/+page.svelte
@@ -45,10 +45,10 @@
{#if p.type === types.pot}
<div>
<span class="text-lg text-secondary my-auto mr-2">{amount > 0 ? 'From' : 'To'}</span>
- <a href={`/pot/${p.memo}`}>
+ <a href={`/pot/${p.memo}`}>
<div class="flex">
<div class="my-auto">
- <img src="/images/moneypot.png" class="w-12" alt="Pot" />
+ <img src="/images/moneypot.png" class="w-12" alt="Pot" />
</div>
<div class="my-auto ml-1">{p.memo}</div>
</div>
@@ -126,7 +126,7 @@
</div>
{/if}
- {#if ['laughingbean', 'burnabyartigiano', 'milanowestend', 'eotl', 'bigbite', 'edgemontartigiano'].includes(user.username.toLowerCase()) }
+ {#if ['laughingbean', 'burnabyartigiano', 'milanowestend', 'eotl', 'bigbite', 'edgemontartigiano'].includes(user.username.toLowerCase())}
<button
class="text-sm md:text-lg rounded-full border py-2 px-4 hover:opacity-80 min-w-[72px] bg-black text-white"
on:click={print}>Print Receipt</button
diff --git a/src/routes/(app)/pot/[name]/+page.svelte b/src/routes/(app)/pot/[name]/+page.svelte
index 31e439d3..ea1e45f2 100644
--- a/src/routes/(app)/pot/[name]/+page.svelte
+++ b/src/routes/(app)/pot/[name]/+page.svelte
@@ -30,14 +30,14 @@
<div class="md:shadow-xl rounded-3xl md:px-10 pt-5 pb-10 space-y-5 w-full md:mx-5">
<div class="relative flex justify-center gap-2">
<!-- <p class="absolute right-0 top-1 underline"><Icon icon="settings" /></p> -->
- {#if name.split('-').length === 4}
- <h1 class="text-2xl md:text-3xl font-semibold my-auto">Card {name}</h1>
+ {#if name.split('-').length === 4}
+ <h1 class="text-2xl md:text-3xl font-semibold my-auto">Card {name}</h1>
{:else}
<img src="/images/moneypot.jpg" class="w-24" alt="Pot" />
- <div class="my-auto">
- <h1 class="text-2xl font-semibold my-auto">{$t('payments.moneyPot')}</h1>
- <h1 class="text-secondary my-auto">{name}</h1>
- </div>
+ <div class="my-auto">
+ <h1 class="text-2xl font-semibold my-auto">{$t('payments.moneyPot')}</h1>
+ <h1 class="text-secondary my-auto">{name}</h1>
+ </div>
{/if}
</div>
{#if show}
@@ -60,7 +60,7 @@
class="rounded-full border py-3 px-2 font-bold hover:opacity-80 flex gap-1 w-full justify-center"
>
<Icon icon="plus" />
- {$t('payments.addFunds')}
+ {$t('payments.addFunds')}
</button>
</a>
</div>
@@ -70,7 +70,7 @@
class="rounded-full border py-3 px-2 font-bold hover:opacity-80 flex gap-1 w-full justify-center"
>
<Icon icon="minus" style="rotate-180" />
- {$t('payments.takeFunds')}
+ {$t('payments.takeFunds')}
</button>
</a>
</div>
@@ -85,10 +85,10 @@
</button>
<button
class="rounded-full border py-3 px-2 font-bold hover:opacity-80 flex gap-1 w-full justify-center"
- on:click={() => copy($page.url.host + $page.url.pathname)}
+ on:click={() => copy($page.url.host + $page.url.pathname)}
>
<Icon icon="copy" style="w-6" />
- {$t('payments.copyLink')}
+ {$t('payments.copyLink')}
</button>
</div>
<div class="text-base">
diff --git a/src/routes/(app)/pot/[name]/sweep/+page.svelte b/src/routes/(app)/pot/[name]/sweep/+page.svelte
index 17d707cc..9b473af3 100644
--- a/src/routes/(app)/pot/[name]/sweep/+page.svelte
+++ b/src/routes/(app)/pot/[name]/sweep/+page.svelte
@@ -4,14 +4,13 @@
import { Icon } from '$comp';
import { t } from '$lib/translations';
- export let data;
+ export let data;
- let { amount, name, user, rates } = data;
- let { currency } = user;
- $: rate = rates[currency];
+ let { amount, name, user, rates } = data;
+ let { currency } = user;
+ $: rate = rates[currency];
</script>
-
<div class="container px-4 max-w-xl mx-auto mt-10 space-y-5 text-center">
<div class="w-full flex">
<a href="/" class="mx-auto">
@@ -19,17 +18,17 @@
</a>
</div>
- <div class="flex w-full py-5 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('payments.fundsClaimed')}</h1>
- <h2 class="text-2xl md:text-3xl font-semibold">
- {f(fiat(amount, rate), currency)}
- </h2>
- <h3 class="text-secondary md:text-lg mb-6 mt-1">
- ⚡️{s(amount)}
- </h3>
- </div>
+ <div class="flex w-full py-5 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('payments.fundsClaimed')}</h1>
+ <h2 class="text-2xl md:text-3xl font-semibold">
+ {f(fiat(amount, rate), currency)}
+ </h2>
+ <h3 class="text-secondary md:text-lg mb-6 mt-1">
+ ⚡️{s(amount)}
+ </h3>
+</div>
<a href={`/${user.username}/payments`}>
<div class="opacity-0 w-screen h-screen fixed top-0 left-0 z-50" />
diff --git a/src/routes/(app)/pot/[name]/withdraw/+page.svelte b/src/routes/(app)/pot/[name]/withdraw/+page.svelte
index da564709..7be643a9 100644
--- a/src/routes/(app)/pot/[name]/withdraw/+page.svelte
+++ b/src/routes/(app)/pot/[name]/withdraw/+page.svelte
@@ -9,7 +9,7 @@
export let data;
export let form;
- let { rates } = data;
+ let { rates } = data;
let { amount, name } = $page.params;
let { currency } = data.user;
let loading;
@@ -35,7 +35,7 @@
{/if}
<div class="container px-4 mt-20 max-w-xl mx-auto">
- <Numpad bind:amount bind:currency bind:rate {submit} />
+ <Numpad bind:amount bind:currency bind:rate {submit} />
<form method="POST" use:enhance on:submit={submit}>
<input name="name" value={name} type="hidden" />
diff --git a/src/routes/(app)/qr/[text]/+page.svelte b/src/routes/(app)/qr/[text]/+page.svelte
index d903da0e..9e56ab29 100644
--- a/src/routes/(app)/qr/[text]/+page.svelte
+++ b/src/routes/(app)/qr/[text]/+page.svelte
@@ -7,5 +7,5 @@
<Qr {src} />
<div class="text-center w-full font-bold">
- {text}
+ {text}
</div>
diff --git a/src/routes/(app)/send/invoice/[id]/+page.svelte b/src/routes/(app)/send/invoice/[id]/+page.svelte
index 554eef6f..a558895c 100644
--- a/src/routes/(app)/send/invoice/[id]/+page.svelte
+++ b/src/routes/(app)/send/invoice/[id]/+page.svelte
@@ -28,12 +28,13 @@
let submit = () => (loading = true);
let external = async () => {
- let invoice = { type: 'lightning', amount };
- let { hash } = await post(`/${recipient.username}/invoice`, {
- invoice
+ let invoice = { type: 'lightning', amount, currency };
+ let { id } = await post(`/${recipient.username}/invoice`, {
+ invoice,
+ user: { username: recipient.username }
});
- goto(`/${recipient.username}/invoice/${hash}`, { invalidateAll: true });
+ goto(`/${recipient.username}/invoice/${id}?options=true`, { invalidateAll: true });
};
$: rate = data.rate * (rates[user.currency] / rates[data.currency]);
@@ -139,7 +140,7 @@
{/if}
</div>
</form>
- <div class="flex my-20">
- <button class="mx-auto" on:click={external}>{$t('payments.moreOptions')}</button>
- </div>
+ <div class="flex my-20">
+ <button class="mx-auto" on:click={external}>{$t('payments.moreOptions')}</button>
+ </div>
</div>
diff --git a/src/routes/(static)/bounties/+page.svelte b/src/routes/(static)/bounties/+page.svelte
index 9a7862da..7ce3c6e0 100644
--- a/src/routes/(static)/bounties/+page.svelte
+++ b/src/routes/(static)/bounties/+page.svelte
@@ -2,51 +2,62 @@
<h1 class="text-3xl mb-6 pt-28 md:pt-12">Bounties</h1>
<p>
- We're offering <b>⚡️1,000,000</b> to the first <b>10 people</b> that help us onboard businesses
- in the following categories to take bitcoin payments:
+ We're offering ⚡️1,000,000 to the first 10 people that help us onboard these businesses in
+ Vancouver to take bitcoin payments.
</p>
- <ul>
+ <ul class="text-center text-lg space-y-3">
<li>Grocery / Produce Store</li>
- <li>
- Cafe &mdash; Claimed by <a href="/reverendhodl">ReverendHodl</a> for
- <a href="https://btcmap.org/map?lat=49.2814113&long=-123.049572">Laughing Bean Coffee Co.</a>
+ <li class="leading-3">
+ <span class="line-through">Cafe</span><br />
+ <span class="text-xs"
+ ><a href="/reverendhodl">ReverendHodl</a> for
+ <a href="/laughingbean">Laughing Bean Coffee Co.</a></span
+ >
</li>
<li>Bakery</li>
- <li>Butcher Shop</li>
+ <li class="leading-3">
+ <span class="line-through">Butcher Shop</span><br />
+ <span class="text-xs"
+ ><a href="/danielle">danielle</a> for
+ <a href="/butchersguild">All Natural &amp; Exotic Meats</a></span
+ >
+ </li>
<li>Laundromat / Dry Cleaner</li>
<li>Dollar Store / Book Store / Gift Shop</li>
- <li>Sushi Restaurant</li>
+ <li class="leading-3">
+ <span class="line-through">Sushi Restaurant</span><br />
+ <span class="text-xs"
+ ><a href="/ica547">ica547</a> for <a href="/metallmash">VanLove Sushi</a></span
+ >
+ </li>
<li>Pizza by the Slice</li>
<li>Liquor Store / Gas Station</li>
<li>Bubble Tea / Ice Cream Parlour</li>
</ul>
- <h2 class="text-xl">Terms and Conditions</h2>
+ <p>Eligible businesses:</p>
- <ul>
- <li>The business must have a physical location that takes walk-in customers</li>
+ <ul class="text-sm ml-4 space-y-2">
<li>
- They must be located within Vancouver, North Vancouver, West Vancouver, Burnaby, New
+ Have a physical location in Vancouver, North Vancouver, West Vancouver, Burnaby, New
Westminster, or Richmond
</li>
- <li>They must have regular hours and a website with contact info</li>
- <li>They must have a 3+ star rating on Google Maps</li>
+ <li>Take walk-in customers</li>
+ <li>Have regular hours and a website with contact info</li>
+ <li>Have a 3 star or better rating on Google</li>
<li>
- It must be possible to pay for any of their usual goods/services with bitcoin at any time
- during their posted hours without needing to make any special arrangements
+ Accept bitcoin during their posted hours without needing to make any special arrangements
</li>
<li>They must use Swapee and accept lightning payments</li>
- <li>Each business category can be claimed only once</li>
- <li>One bounty per person</li>
</ul>
+ <p>Each business category can be claimed only once</p>
+ <p>One bounty per person</p>
+
<p>The businesses can expect free ongoing support and promotion from us and our community.</p>
- <p>
- The prize money will be offered to the person who makes the referral/introduction. Whether you
- choose to split some with the business owner is up to you.
- </p>
+ <p>The prize money will be offered to the person who makes the referral.</p>
<p>
<b>⚡️250,000</b> will be awarded once the business has met with us and is ready to take payments
@@ -86,6 +97,6 @@
<style>
a {
- @apply font-bold;
+ @apply text-blue-400;
}
</style>
diff --git a/src/routes/(static)/docs/+page.svelte b/src/routes/(static)/docs/+page.svelte
index 3313e279..34f7344d 100644
--- a/src/routes/(static)/docs/+page.svelte
+++ b/src/routes/(static)/docs/+page.svelte
@@ -30,10 +30,11 @@
{#if user && token}
This token authorizes you to use the API as <b>{user.username}</b>.
{:else}
- <a href="/login" class="font-bold">Sign in</a> to view your auth token here, or get one from the /login endpoint.
+ <a href="/login" class="font-bold">Sign in</a> to view your auth token here, or get one from the
+ /login endpoint.
{/if}
- Save it in a variable called <b>$token</b> to run the examples.
+ Save it in a variable called <b>$token</b> to run the examples.
</p>
<div class="bg-black text-white rounded-lg p-4 flex gap-4">
@@ -68,18 +69,17 @@
</div>
</div>
- <p>Get a lightning invoice to receive funds</p>
+ <p>Get a lightning invoice to receive funds</p>
<Code sample="lightningInvoice" />
- <p>Get a bitcoin address to receive funds</p>
+ <p>Get a bitcoin address to receive funds</p>
<Code sample="bitcoinAddress" />
<p>Sample response</p>
<Code sample="invoiceResponse" />
<p>You can check the <b>received</b> field to see how much has been paid</p>
-
- <p>Specify a webhook to be called when an invoice is paid</p>
+ <p>Specify a webhook to be called when an invoice is paid</p>
<Code sample="webhook" />
<h2 class="text-2xl">GET /invoice/:hash</h2>
diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte
index e50da4b6..d6ea7db7 100644
--- a/src/routes/+layout.svelte
+++ b/src/routes/+layout.svelte
@@ -1,8 +1,8 @@
<script>
import '../app.css';
- export let data;
- let { host, pathname } = data;
+ export let data;
+ let { host, pathname } = data;
</script>
<svelte:head>
diff --git a/src/routes/map/+page.svelte b/src/routes/map/+page.svelte
index b5e4dfad..99c822d3 100644
--- a/src/routes/map/+page.svelte
+++ b/src/routes/map/+page.svelte
@@ -1,6 +1,6 @@
<script>
- import { LocationsMap } from "$comp";
- export let data;
+ import { LocationsMap } from '$comp';
+ export let data;
let { locations } = data;
</script>