From 0b90be10f70d5532720dd8cde1905d33b217eef2 Mon Sep 17 00:00:00 2001
From: Pascal Syma
Date: Sun, 7 Sep 2025 00:41:39 +0200
Subject: [PATCH] Add input
---
bun.lock | 9 +++
package.json | 1 +
src/App.vue | 28 ++++++--
src/components/StatsBlock.vue | 33 +++++++++
src/main.ts | 3 +-
src/pages/HomeView.vue | 123 +++++++++++++++++++++++++++++++++-
src/stores/counter.ts | 12 ----
src/stores/tram.ts | 89 ++++++++++++++++++++++++
8 files changed, 275 insertions(+), 23 deletions(-)
create mode 100644 src/components/StatsBlock.vue
delete mode 100644 src/stores/counter.ts
create mode 100644 src/stores/tram.ts
diff --git a/bun.lock b/bun.lock
index d8431c3..662baef 100644
--- a/bun.lock
+++ b/bun.lock
@@ -7,6 +7,7 @@
"@tailwindcss/vite": "^4.1.13",
"@vuestic/tailwind": "^0.1.5",
"pinia": "^3.0.3",
+ "pinia-plugin-persistedstate": "^4.5.0",
"tailwind": "^4.0.0",
"vue": "^3.5.18",
"vue-router": "^4.5.1",
@@ -524,6 +525,8 @@
"deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="],
+ "deep-pick-omit": ["deep-pick-omit@1.2.1", "", {}, "sha512-2J6Kc/m3irCeqVG42T+SaUMesaK7oGWaedGnQQK/+O0gYc+2SP5bKh/KKTE7d7SJ+GCA9UUE1GRzh6oDe0EnGw=="],
+
"default-browser": ["default-browser@5.2.1", "", { "dependencies": { "bundle-name": "^4.1.0", "default-browser-id": "^5.0.0" } }, "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg=="],
"default-browser-id": ["default-browser-id@5.0.0", "", {}, "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA=="],
@@ -534,8 +537,12 @@
"define-properties": ["define-properties@1.2.1", "", { "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" } }, "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg=="],
+ "defu": ["defu@6.1.4", "", {}, "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg=="],
+
"depd": ["depd@1.1.2", "", {}, "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ=="],
+ "destr": ["destr@2.0.5", "", {}, "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA=="],
+
"destroy": ["destroy@1.0.4", "", {}, "sha512-3NdhDuEXnfun/z7x9GOElY49LoqVHoGScmOKwmxhsS8N5Y+Z8KyPPDnaSzqWgYt/ji4mqwfTS34Htrk0zPIXVg=="],
"detect-libc": ["detect-libc@2.0.4", "", {}, "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA=="],
@@ -1028,6 +1035,8 @@
"pinia": ["pinia@3.0.3", "", { "dependencies": { "@vue/devtools-api": "^7.7.2" }, "peerDependencies": { "typescript": ">=4.4.4", "vue": "^2.7.0 || ^3.5.11" }, "optionalPeers": ["typescript"] }, "sha512-ttXO/InUULUXkMHpTdp9Fj4hLpD/2AoJdmAbAeW2yu1iy1k+pkFekQXw5VpC0/5p51IOR/jDaDRfRWRnMMsGOA=="],
+ "pinia-plugin-persistedstate": ["pinia-plugin-persistedstate@4.5.0", "", { "dependencies": { "deep-pick-omit": "^1.2.1", "defu": "^6.1.4", "destr": "^2.0.5" }, "peerDependencies": { "@nuxt/kit": ">=3.0.0", "@pinia/nuxt": ">=0.10.0", "pinia": ">=3.0.0" }, "optionalPeers": ["@nuxt/kit", "@pinia/nuxt", "pinia"] }, "sha512-QTkP1xJVyCdr2I2p3AKUZM84/e+IS+HktRxKGAIuDzkyaKKV48mQcYkJFVVDuvTxlI5j6X3oZObpqoVB8JnWpw=="],
+
"pirates": ["pirates@4.0.7", "", {}, "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA=="],
"possible-typed-array-names": ["possible-typed-array-names@1.1.0", "", {}, "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg=="],
diff --git a/package.json b/package.json
index 02854a6..c965167 100644
--- a/package.json
+++ b/package.json
@@ -20,6 +20,7 @@
"@tailwindcss/vite": "^4.1.13",
"@vuestic/tailwind": "^0.1.5",
"pinia": "^3.0.3",
+ "pinia-plugin-persistedstate": "^4.5.0",
"tailwind": "^4.0.0",
"vue": "^3.5.18",
"vue-router": "^4.5.1",
diff --git a/src/App.vue b/src/App.vue
index 74929bc..2173c3a 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -1,12 +1,26 @@
-
+
- You did it!
-
- Visit vuejs.org to read the
- documentation
-
-
+
+
+
+
+ TramTrack
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/StatsBlock.vue b/src/components/StatsBlock.vue
new file mode 100644
index 0000000..4bbfe07
--- /dev/null
+++ b/src/components/StatsBlock.vue
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+ {{ found }}
+ / {{ total }}
+
+
{{ name }}
+
+
+
+
+
diff --git a/src/main.ts b/src/main.ts
index 9295414..a15c9f3 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -1,4 +1,5 @@
import { createPinia } from 'pinia';
+import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';
import { createApp } from 'vue';
import { createVuestic } from 'vuestic-ui';
@@ -10,7 +11,7 @@ import router from './router';
const app = createApp(App);
-app.use(createPinia());
+app.use(createPinia().use(piniaPluginPersistedstate));
app.use(router);
app.use(createVuestic());
diff --git a/src/pages/HomeView.vue b/src/pages/HomeView.vue
index dd4b795..e99dd8a 100644
--- a/src/pages/HomeView.vue
+++ b/src/pages/HomeView.vue
@@ -1,10 +1,127 @@
- home
-
+
+
+ Neues Fahrzeug gefunden?
+
+
+
+
+
+ Gesehen
+
+
+
+
+
+ Quick stats
+
+
+
+
+
+
+
+
+ Mehr Statistiken
+
+
+
diff --git a/src/stores/counter.ts b/src/stores/counter.ts
deleted file mode 100644
index 8fc7634..0000000
--- a/src/stores/counter.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { defineStore } from 'pinia';
-import { computed, ref } from 'vue';
-
-export const useCounterStore = defineStore('counter', () => {
- const count = ref(0);
- const doubleCount = computed(() => count.value * 2);
- function increment() {
- count.value++;
- }
-
- return { count, doubleCount, increment };
-});
diff --git a/src/stores/tram.ts b/src/stores/tram.ts
new file mode 100644
index 0000000..487f582
--- /dev/null
+++ b/src/stores/tram.ts
@@ -0,0 +1,89 @@
+import { defineStore } from 'pinia';
+import { computed, reactive } from 'vue';
+
+export const type: [number, number, boolean, string][] = [
+ [3101, 3143, true, 'GT8N-1 - Bombardier Flexity Classic'],
+ [3201, 3249, true, 'GT8N-2 - Siemens Avenio'],
+ [3401, 3435, true, 'GT8N-2 - Siemens Avenio'],
+ [4001, 4005, false, 'Solobus Mercedes eCitaro O 530 C2'],
+ [4006, 4020, false, 'Solobus Mercedes eCitaro O 530 C2'],
+ [4061, 4075, false, 'Solobus Mercedes Citaro O 530 C2'],
+ [4076, 4090, false, 'Solobus Mercedes Citaro O 530 C2 hybrid'],
+ [4150, 4151, false, 'Solobus MAN Lion´s City A21 NL 280'],
+ [4152, 4152, false, 'Solobus Mercedes Citaro O 530 LE C2'],
+ [4161, 4176, false, 'Solobus Solaris Urbino 12'],
+ [4487, 4487, false, 'Midibus Solaris Urbino 8.9 LE'],
+ [4488, 4489, false, 'Midibus Solaris Alpino 8.6'],
+ [4501, 4515, false, 'Gelenkbus Irizar ieBus 18'],
+ [4575, 4598, false, "Gelenkbus MAN Lion's City GL A23 NG 320"],
+ [4601, 4624, false, 'Gelenkbus Mercedes Citaro O 530 G C2 hybrid'],
+ [4631, 4660, false, "Gelenkbus MAN Lion's City GL A23 NG 320"],
+ [4661, 4693, false, 'Gelenkbus Mercedes Citaro O 530 G C2'],
+ [4694, 4695, false, 'Gelenkbus Mercedes Citaro O 530 G C2'],
+ [4730, 4750, false, "Gelenkbus MAN Lion's City GL A23 NG 320"],
+ [4771, 4798, false, 'Gelenkbus Mercedes Citaro O 530 G C2 hybrid'],
+ [4801, 4835, false, 'Gelenkbus Mercedes eCitaro O 530 G C2'],
+ [4881, 4900, false, 'Gelenkbus Mercedes Citaro O 530 G C2'],
+ [4901, 4922, false, 'Gelenkbus Mercedes Citaro O 530 G C2 hybrid']
+] as const;
+
+const busCount = type.filter((t) => !t[2]).reduce((acc, t) => acc + (t[1] - t[0]) + 1, 0);
+const tramCount = type.filter((t) => t[2]).reduce((acc, t) => acc + (t[1] - t[0]) + 1, 0);
+const totalCount = busCount + tramCount;
+
+export function getType(id: number | string): null | { id: number; isTram: boolean; type: string } {
+ const number = Number(id);
+ const foundType = type.find((t) => number >= t[0] && number <= t[1]);
+ if (!foundType) {
+ return null;
+ }
+
+ return {
+ id: number,
+ isTram: foundType[2],
+ type: foundType[3]
+ };
+}
+
+export const useTramStore = defineStore(
+ 'tram',
+ () => {
+ const trams = reactive<{
+ bsag: number[];
+ }>({
+ bsag: []
+ });
+
+ function addNumber(id: number | string) {
+ const foundType = getType(id);
+ if (!foundType) {
+ return false;
+ }
+
+ if (!trams.bsag.includes(foundType.id)) {
+ trams.bsag.push(foundType.id);
+ }
+
+ return true;
+ }
+
+ const shortStats = computed(() => {
+ const busses = trams.bsag.filter((id) => id > 4000).length;
+
+ const found = trams.bsag.length;
+ return {
+ totalCount,
+ busCount,
+ tramCount,
+ found,
+ busses,
+ trams: found - busses
+ };
+ });
+
+ return { trams, addNumber, shortStats };
+ },
+ {
+ persist: true
+ }
+);