diff --git a/package-lock.json b/package-lock.json index 51cc2b2..44fb753 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,19 @@ { "name": "utxo22-web", - "version": "0.0.1", + "version": "0.8.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "utxo22-web", - "version": "0.0.1", + "version": "0.8.1", "dependencies": { "@fontsource/fira-mono": "^4.5.0", "@lukeed/uuid": "^2.0.0", - "cookie": "^0.4.1" + "cookie": "^0.4.1", + "crypto-js": "^4.1.1", + "date-fns": "^2.28.0", + "ethereum-blockies-base64": "^1.0.2" }, "devDependencies": { "@faker-js/faker": "^6.1.2", @@ -556,6 +559,11 @@ "node": ">=10" } }, + "node_modules/crypto-js": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz", + "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==" + }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -568,6 +576,18 @@ "node": ">=4" } }, + "node_modules/date-fns": { + "version": "2.28.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.28.0.tgz", + "integrity": "sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw==", + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -1014,6 +1034,14 @@ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "dev": true }, + "node_modules/ethereum-blockies-base64": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/ethereum-blockies-base64/-/ethereum-blockies-base64-1.0.2.tgz", + "integrity": "sha512-Vg2HTm7slcWNKaRhCUl/L3b4KrB8ohQXdd5Pu3OI897EcR6tVRvUqdTwAyx+dnmoDzj8e2bwBLDQ50ByFmcz6w==", + "dependencies": { + "pnglib": "0.0.1" + } + }, "node_modules/fast-glob": { "version": "3.2.11", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", @@ -1428,6 +1456,11 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pnglib": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/pnglib/-/pnglib-0.0.1.tgz", + "integrity": "sha1-+atvnGiPSp1Xmti+KIeKcW4wwJY=" + }, "node_modules/postcss": { "version": "8.4.12", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.12.tgz", @@ -2233,12 +2266,22 @@ "yaml": "^1.10.0" } }, + "crypto-js": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz", + "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==" + }, "cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "dev": true }, + "date-fns": { + "version": "2.28.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.28.0.tgz", + "integrity": "sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw==" + }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -2478,6 +2521,14 @@ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "dev": true }, + "ethereum-blockies-base64": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/ethereum-blockies-base64/-/ethereum-blockies-base64-1.0.2.tgz", + "integrity": "sha512-Vg2HTm7slcWNKaRhCUl/L3b4KrB8ohQXdd5Pu3OI897EcR6tVRvUqdTwAyx+dnmoDzj8e2bwBLDQ50ByFmcz6w==", + "requires": { + "pnglib": "0.0.1" + } + }, "fast-glob": { "version": "3.2.11", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", @@ -2784,6 +2835,11 @@ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, + "pnglib": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/pnglib/-/pnglib-0.0.1.tgz", + "integrity": "sha1-+atvnGiPSp1Xmti+KIeKcW4wwJY=" + }, "postcss": { "version": "8.4.12", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.12.tgz", diff --git a/package.json b/package.json index afcb8b1..9da9d78 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,9 @@ "dependencies": { "@fontsource/fira-mono": "^4.5.0", "@lukeed/uuid": "^2.0.0", - "cookie": "^0.4.1" + "cookie": "^0.4.1", + "crypto-js": "^4.1.1", + "date-fns": "^2.28.0", + "ethereum-blockies-base64": "^1.0.2" } } diff --git a/src/routes/vstupenky.svelte b/src/routes/vstupenky.svelte index 14c9b01..424fce9 100644 --- a/src/routes/vstupenky.svelte +++ b/src/routes/vstupenky.svelte @@ -8,24 +8,35 @@ import { orderTicketForm, apiStatus, userData } from '$lib/stores'; //import btcPay from 'https://btcpay.utxo.cz/modal/btcpay.js'; import api from '$lib/api.js'; + import makeBlockie from 'ethereum-blockies-base64'; + import sha256 from 'crypto-js/sha256'; + import Base64 from 'crypto-js/enc-base64'; + import { format } from 'date-fns'; const orderTicketFormLS = localStorage.getItem('orderTicketForm') let parsed = JSON.parse(orderTicketFormLS) - if (parsed.__v === $orderTicketForm.__v) { + if (parsed && parsed.__v === $orderTicketForm.__v) { orderTicketForm.set(parsed) } + let showOrder = true let orders = [] - - onMount(async () => { - apiStatus.set(await api.apiCall('status')) + let tickets = [] - // load orders + // load orders + async function loadOrders () { if ($userData.orders && $userData.orders.length > 0) { const resp = await api.apiCall('orders', { method: 'POST' }, { orders: $userData.orders }) orders = resp.orders + tickets = resp.tickets + showOrder = false } + } + + onMount(async () => { + apiStatus.set(await api.apiCall('status')) + await loadOrders() }) faker.locale = 'cz'; @@ -89,6 +100,13 @@ return null } + // reset tickets in form + orderTicketForm.update(of => { + of.count = 1 + of.tickets = [] + return of + }) + // add order to user data userData.update(ud => { if (!ud.orders) { @@ -101,11 +119,11 @@ window.location.replace(resp.payment.url) } - let tickets = 0 + let ticketsNum = 0 orderTicketForm.subscribe(f => { - if (f.count !== tickets) { - tickets = f.count + if (f.count !== ticketsNum) { + ticketsNum = f.count orderTicketForm.update(cf => { f.tickets = f.tickets.slice(0, f.count) for (let i = 0; i < f.count; i++) { @@ -169,6 +187,48 @@ $: tip = roundPrice($orderTicketForm.tipPercent > 0 ? $orderTicketForm.tipPercent * (totalBeforeTip/100) : Number($orderTicketForm.tipCustom)) $: totalPrice = totalBeforeTip + tip + const orderStatuses = { + new: { + name: 'Čeká na platbu', + icon: 'fa-solid fa-clock', + color: 'text-yellow-600', + text: (o) => { + return 'Tato objednávka čeká na platbu' + }, + }, + done: { + name: 'Zaplacená', + icon: 'fa-solid fa-check', + color: 'text-green-600' + }, + cancelled: { + name: 'Zrušená', + icon: 'fa-solid fa-ban', + color: 'text-gray-600' + }, + expired: { + name: 'Expirovaná', + icon: 'fa-solid fa-clock', + color: 'text-gray-600' + } + } + + async function orderActionHandler (id, action) { + const resp = await api.apiCall('updateOrder', { method: 'POST' }, { id, action }) + await loadOrders() + } + + function removeOrder (id) { + userData.update(ud => { + let index = ud.orders.indexOf(id) + if (index >= 0) { + ud.orders.splice(index, 1) + loadOrders() + } + return ud + }) + } + @@ -178,23 +238,81 @@

Vaše vstupenky

-
Nemáte žádnou vstupenku
+ {#if tickets.length > 0} +
+ {#each tickets as ticket} +
+
+
+
+
+
+
+ #{ticket.id} +
+
Běžná vstupenka
+
+
+ {#if ticket.data} +
+ {#if ticket.data.name}{ticket.data.name}{:else}Anonym{/if} {#if ticket.data.org}({ticket.data.org}){/if} + {#if ticket.data.twitter}{/if} +
+ {/if} +
+
+ {/each} +
+ {:else} +
Nemáte žádnou vstupenku
+ {/if}
+ {#if $apiStatus} {#if orders.length > 0}

Vaše objednávky

{#each orders as order} -
- {order.id} - {order.status} +
+ {#if ['expired', 'cancelled'].includes(order.status)} + + {/if} +
+
#{order.id}
+
+ {#if orderStatuses[order.status].icon} + + {/if} + {orderStatuses[order.status].name} +
+
+
+
Vytvořeno: {format(new Date(order.created), 'd.M.y H:mm')}
+
Částka: {order.amount} Kč
+
Platební metoda: {$apiStatus.config.paymentMethods.find(pm => pm.id === order.paymentMethod).shortname}
+
+ {#if orderStatuses[order.status].text} +
{orderStatuses[order.status].text(order)}
+ {#if order.actions} +
+ {#each order.actions as action} + + {/each} +
+ {/if} + {/if}
{/each}
{/if} - {#if $apiStatus}

Nákup vstupenek

+ {#if !showOrder} +
+ +
+ {:else} {#if !$apiStatus.wave}
V současné době nelze zakoupit vstupenky.
{:else} @@ -335,6 +453,7 @@
{/if} + {/if}