This commit is contained in:
tree 2022-04-09 14:29:45 +02:00
rodič 391cb7af3e
revize 608714c4e5
3 změnil soubory, kde provedl 194 přidání a 16 odebrání

62
package-lock.json vygenerováno
Zobrazit soubor

@ -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",

Zobrazit soubor

@ -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"
}
}

Zobrazit soubor

@ -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
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
})
}
</script>
<svelte:head>
@ -178,23 +238,81 @@
<section class="relative mx-auto py-6 sm:py-10 px-6 max-w-6xl text-blue-web">
<div class="">
<h1 class="uppercase text-2xl font-bold">Vaše vstupenky</h1>
<div class="mt-4">Nemáte žádnou vstupenku</div>
{#if tickets.length > 0}
<div class="mt-4 flex flex-wrap gap-3">
{#each tickets as ticket}
<div class="w-full sm:w-80">
<div class="h-2 bg-utxo-gradient rounded-t-md shadow-md"></div>
<div class="border-l border-b border-r p-4 rounded-b-md shadow-md border-blue-web">
<div class="flex gap-3 text-sm">
<div class="w-11 h-11 rounded-md" style="background-image: url({makeBlockie(ticket.avatarHash)}); background-size: 100% 100%;"></div>
<div class="w-auto">
<div class="no-flex">
<span class="font-bold px-2 py-1 bg-gray-200 rounded w-auto">#{ticket.id}</span>
</div>
<div class="mt-1.5">Běžná vstupenka</div>
</div>
</div>
{#if ticket.data}
<div class="mt-2">
{#if ticket.data.name}{ticket.data.name}{:else}<span class="italic">Anonym</span>{/if} {#if ticket.data.org}({ticket.data.org}){/if}
{#if ticket.data.twitter}<a href="https://twitter.com/{ticket.data.twitter}" target="_blank"><i class="fa-brands fa-twitter"></i></a>{/if}
</div>
{/if}
</div>
</div>
{/each}
</div>
{:else}
<div class="mt-4">Nemáte žádnou vstupenku</div>
{/if}
</div>
{#if $apiStatus}
{#if orders.length > 0}
<div class="mt-10">
<h1 class="uppercase text-2xl font-bold">Vaše objednávky</h1>
<div class="mt-4">
{#each orders as order}
<div class="px-3 py-2 border rounded-lg">
{order.id} - {order.status}
<div class="mb-2 px-3 py-2 border rounded-lg">
{#if ['expired', 'cancelled'].includes(order.status)}
<div class="float-right"><a class="cursor-pointer" on:click={() => removeOrder(order.id)}><i class="fa-solid fa-xmark"></i></a></div>
{/if}
<div class="flex flex-wrap gap-3 text-sm">
<div class="px-2 py-1 bg-gray-200 rounded">#{order.id}</div>
<div class="my-auto uppercase {orderStatuses[order.status].color ? (orderStatuses[order.status].color) : ''}">
{#if orderStatuses[order.status].icon}
<i class="{orderStatuses[order.status].icon} mr-0.5"></i>
{/if}
{orderStatuses[order.status].name}
</div>
</div>
<div class="mt-2 text-sm flex gap-2">
<div>Vytvořeno: <span class="font-bold">{format(new Date(order.created), 'd.M.y H:mm')}</span><br/></div>
<div>Částka: <span class="font-bold">{order.amount}</span><br/></div>
<div>Platební metoda: <span class="font-bold">{$apiStatus.config.paymentMethods.find(pm => pm.id === order.paymentMethod).shortname}</span></div>
</div>
{#if orderStatuses[order.status].text}
<div class="mt-2 italic">{orderStatuses[order.status].text(order)}</div>
{#if order.actions}
<div class="flex gap-3">
{#each order.actions as action}
<div class="mt-2"><a href="{action.url}" class="underline hover:no-underline cursor-pointer" on:click={() => orderActionHandler(order.id, action.remote)}>{action.name}</a></div>
{/each}
</div>
{/if}
{/if}
</div>
{/each}
</div>
</div>
{/if}
{#if $apiStatus}
<div class="mt-10 mb-10">
<h1 class="uppercase text-2xl font-bold">Nákup vstupenek</h1>
{#if !showOrder}
<div class="mt-4">
<button class="border rounded-full border-[#E16A61] hover:border-0 hover:p-px hover:bg-utxo-gradient hover:text-white" on:click={() => showOrder = true}><div class="px-6 py-2">Nakoupit další vstupenky</div></button>
</div>
{:else}
{#if !$apiStatus.wave}
<div class="mt-4">V současné době nelze zakoupit vstupenky.</div>
{:else}
@ -335,6 +453,7 @@
</div>
</div>
{/if}
{/if}
</div>
<!--pre>{JSON.stringify($orderTicketForm, null, 2)}</pre>
<pre>{JSON.stringify(extrasStats, null, 2)}</pre -->