diff --git a/src/app.css b/src/app.css index a7f6844..89f75e8 100644 --- a/src/app.css +++ b/src/app.css @@ -7,20 +7,12 @@ src: url('/fonts/inter-v18-latin-regular.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ } -* { - --color-primary-a0: #ffffff; - --color-primary-a10: #e1e6fe; - --color-primary-a20: #c2cdfd; - --color-primary-a30: #a1b5fb; - --color-primary-a40: #7d9df9; - --color-primary-a50: #5087f6; - --color-primary-a60: #436bc0; - --color-primary-a70: #364f8c; - --color-primary-a80: #28365c; - --color-primary-a90: #191e2f; - --color-primary-a100: #000000; - --text-color: black; +pre { + max-width: 100%; + overflow: scroll; +} +* { box-sizing: border-box; font-size: inherit; } @@ -29,13 +21,13 @@ html, body { position: relative; margin: 0; padding: 0; - background-color: white; font-size: 1rem; + background-color: var(--tg-theme-bg-color); } p, a, h1, h2, h3, h4, h5, h6 { font-family: Inter, Arial, sans-serif; - color: var(--text-color); + color: var(--tg-theme-text-color); } h1, h2, h3, h4, h5, h6 { @@ -58,3 +50,29 @@ svg { max-width: 100%; height: auto; } + +a { + color: var(--tg-theme-link-color); +} + +button { + padding: 0.45rem 0.65rem; + + background-color: var(--tg-theme-button-color); + color: var(--tg-theme-button-text-color); + font-size: 1.35rem; + border: none; + + &:disabled { + filter: grayscale(1.0); + } +} + +label { + color: var(--tg-theme-text-color); +} + +input { + color: var(--tg-theme-text-color); + background-color: var(--tg-theme-secondary-bg-color); +} \ No newline at end of file diff --git a/src/hooks.client.js b/src/hooks.client.js index 51625bf..d91fbfc 100644 --- a/src/hooks.client.js +++ b/src/hooks.client.js @@ -1,4 +1,4 @@ -import {initializePocketBase} from "$lib/pocketbase.js"; +import { initializePocketBase } from "$lib/pocketbase.js"; export const init = async () => { initializePocketBase() diff --git a/src/lib/components/ContainerGridSingle.svelte b/src/lib/components/ContainerGridSingle.svelte index d8dc5db..3cce760 100644 --- a/src/lib/components/ContainerGridSingle.svelte +++ b/src/lib/components/ContainerGridSingle.svelte @@ -13,6 +13,8 @@ diff --git a/src/lib/components/EventList.svelte b/src/lib/components/EventList.svelte index 1cf288e..18e1381 100644 --- a/src/lib/components/EventList.svelte +++ b/src/lib/components/EventList.svelte @@ -20,8 +20,6 @@ diff --git a/src/lib/components/EventRegisterButton.svelte b/src/lib/components/EventRegisterButton.svelte index e69de29..762d1a8 100644 --- a/src/lib/components/EventRegisterButton.svelte +++ b/src/lib/components/EventRegisterButton.svelte @@ -0,0 +1,39 @@ + + +{#if eventId} + {#if telegram?.initData} +
+ {:else} +Bitte öffne diese Mini App im Telegram Bot um dich anzumelden! Öffnen
+ {/if} +{:else} +Invalide Event-ID
+{/if} + + \ No newline at end of file diff --git a/src/lib/components/FooterNavigation.svelte b/src/lib/components/FooterNavigation.svelte index b578873..4320b33 100644 --- a/src/lib/components/FooterNavigation.svelte +++ b/src/lib/components/FooterNavigation.svelte @@ -7,12 +7,15 @@Du befinest dich auf der Anmeldeseite des Kölner Stammtischs. Schau dir die unteren Menüpunkte an, falls du mehr erfahren möchtest.
+Du befindest dich auf der Mini App des Kölner Stammtischs. Schau dir die unteren Menüpunkte an, falls du mehr erfahren möchtest.
+ {JSON.stringify(telegram.user, null, 4)} +\ No newline at end of file diff --git a/src/routes/events/[slug]/+page.server.js b/src/routes/events/[slug]/+page.server.js index e69de29..30bd42a 100644 --- a/src/routes/events/[slug]/+page.server.js +++ b/src/routes/events/[slug]/+page.server.js @@ -0,0 +1,34 @@ +import { subtle } from 'node:crypto'; +import {PRIVATE_TELEGRAM_BOT_ID, PRIVATE_TELEGRAM_PUBLIC_KEY} from "$env/static/private"; + +export const actions = { + register: async ({ request }) => { + const formData = await request.formData(); + if (!formData) return { success: false, error: "No valid form data was provided" }; + + const initDataUrlEncoded = formData.get('init-data'); + if (!initDataUrlEncoded) return { success: false, error: "No valid form data was provided" }; + + const eventId = formData.get('event-id'); + if (!eventId) return { success: false, error: "Missing event-id" }; + + const dataArrayParams = new URLSearchParams(initDataUrlEncoded) + const initDataArray = [...dataArrayParams]; + const signature = dataArrayParams.get('signature'); + if (!signature) return { success: false, error: "No signature was provided" }; + initDataArray.sort((d1, d2) => d1[0].charCodeAt(0) - d2[0].charCodeAt(0)); + + const checkString = initDataArray.reduce((acc, currentValue) => { + if (['signature', 'hash'].includes(currentValue[0])) return acc; + acc.push(currentValue.join("=")) + return acc; + }, [`${PRIVATE_TELEGRAM_BOT_ID}:WebAppData`]).join("\n") + + const algo = 'Ed25519'; + const key = await subtle.importKey("raw", Buffer.from(PRIVATE_TELEGRAM_PUBLIC_KEY, 'hex'), algo, false, ['verify']); + const validSignature = await subtle.verify(algo, key, Buffer.from(signature, 'base64url'), Buffer.from(checkString)); + if (!validSignature) return { success: false, error: "Invalid signature" } + + return { success: true, error: null } + } +} \ No newline at end of file diff --git a/src/routes/events/[slug]/+page.svelte b/src/routes/events/[slug]/+page.svelte index 782584f..e17578e 100644 --- a/src/routes/events/[slug]/+page.svelte +++ b/src/routes/events/[slug]/+page.svelte @@ -5,9 +5,12 @@ import {Tile} from 'ol/layer'; import {useGeographic} from "ol/proj"; import {onMount} from "svelte"; + import EventRegisterButton from "$lib/components/EventRegisterButton.svelte"; + import {useTelegram} from "$lib/telegram.svelte.js"; const { data } = $props(); const { event } = data; + const telegram = useTelegram(); let mapRef; @@ -43,14 +46,36 @@
{event?.description ?? "No description"}
{/if} + {#if event?.start} + {@const date = new Date(event.start)} +{date.toLocaleDateString(telegram.user.language_code, {dateStyle: 'long'})}
+ {date.toLocaleTimeString(telegram.user.language_code, {timeStyle: 'long'})}
{date.toLocaleDateString('en', {dateStyle: 'long'})}
+ {date.toLocaleTimeString('en', {timeStyle: 'long'})}
{event?.expand?.location?.name}
- {event?.expand?.location?.address}
+ {#each event?.expand?.location?.address.split(', ') as part}
+ {part}
+ {/each}