added onride embed and fixed some design errors

This commit is contained in:
2025-05-07 14:33:25 +02:00
parent cfeb4de56a
commit 63ca572109
10 changed files with 321 additions and 112 deletions

View File

@@ -40,7 +40,7 @@ export default {
</div>
</div>
<div>
<h2 class="mb-6 text-sm font-semibold text-gray-900 uppercase dark:text-white">Soziale Medien</h2>
<h2 class="mb-6 text-sm font-semibold text-gray-900 uppercase dark:text-white">Repository</h2>
<ul class="text-gray-600 dark:text-gray-400">
<li class="mb-4">
<a href="https://github.com/MiauRizius/CoasterDB" target="_blank" class="hover:underline ">GitHub</a>

View File

@@ -38,24 +38,24 @@ export default {
}
}
// Reiterzustand wiederherstellen
restoreDropdownState('dropdown-pages-button', 'dropdown-pages', 'dropdown-pages-open');
restoreDropdownState('dropdown-sales-button', 'dropdown-sales', 'dropdown-sales-open');
// Reiterzustand wiederherstellen
restoreDropdownState('dropdown-pages-button', 'dropdown-pages', 'dropdown-pages-open');
restoreDropdownState('dropdown-sales-button', 'dropdown-sales', 'dropdown-sales-open');
restoreDropdownState('dropdown-authentication-button', 'dropdown-authentication', 'dropdown-authentication-open');
// Reiter-Click-Handler
document.getElementById('dropdown-pages-button')?.addEventListener('click', () => {
toggleDropdown('dropdown-pages-button', 'dropdown-pages', 'dropdown-pages-open');
});
document.getElementById('dropdown-sales-button')?.addEventListener('click', () => {
toggleDropdown('dropdown-sales-button', 'dropdown-sales', 'dropdown-sales-open');
});
document.getElementById('dropdown-authentication-button')?.addEventListener('click', () => {
toggleDropdown('dropdown-authentication-button', 'dropdown-authentication', 'dropdown-authentication-open');
});
// Navigation
document.getElementById("help")?.addEventListener("click", () => {
processAjaxData("/app/help")
@@ -226,18 +226,19 @@ export default {
<ul id="dropdown-sales" class="hidden py-2 space-y-2">
<li>
<a
href="/stats"
href="/app/stats"
class="flex items-center p-2 pl-11 w-full text-base font-medium text-gray-900 rounded-lg transition duration-75 group hover:bg-gray-100 dark:text-white dark:hover:bg-gray-700"
>Statistiken</a
>
</li>
<li>
<a
href="/technical-information"
href="/app/technical-information"
class="flex items-center p-2 pl-11 w-full text-base font-medium text-gray-900 rounded-lg transition duration-75 group hover:bg-gray-100 dark:text-white dark:hover:bg-gray-700"
>Technische Infos</a
>
</li>
<!--
<li>
<a
href="/database/admin"
@@ -245,6 +246,7 @@ export default {
>Admin-Panel</a
>
</li>
-->
</ul>
</li>
<!-- <li>

View File

@@ -21,6 +21,14 @@ const routes: Array<RouteRecordRaw> = [
path: '/app',
component: () => import('./views/app/App.vue')
},
{
path: '/app/stats',
component: () => import('./views/Stats.vue')
},
{
path: '/app/technical-information',
component: () => import('./views/TechnicalInformation.vue')
},
//Coaster pages
{

68
src/views/Stats.vue Normal file
View File

@@ -0,0 +1,68 @@
<script lang="ts">
import Header from '../components/app/AppHeader.vue'
import Sidebar from '../components/app/AppSidebar.vue'
export default {
components: {
Header,
Sidebar
},
data() {
return {
stats: {
totalParks: 10,
totalCoasters: 25,
totalVisitorsPerMonth: 500000,
averageTicketPrice: 45.99,
totalInversions: 120
}
}
}
}
</script>
<template>
<title>Datenbank-Statistiken - CoasterDB</title>
<Header />
<div class="flex pt-[63px] h-screen overflow-hidden">
<Sidebar />
<main class="flex-1 overflow-y-auto p-5 bg-gray-50 dark:bg-gray-900">
<div style="margin-top: 63px;"></div>
<div class="mx-auto max-w-screen-xl px-4 lg:px-12">
<div class="bg-white dark:bg-gray-800 shadow-md sm:rounded-lg p-6 mb-6">
<h1 class="text-2xl font-bold text-gray-900 dark:text-white">Datenbank Statistiken</h1>
<p class="text-gray-700 dark:text-gray-300 mb-4">Informationen zur aktuellen Datenbank:</p>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-6 text-gray-700 dark:text-gray-300">
<div class="bg-gray-100 dark:bg-gray-700 p-4 rounded-lg shadow-sm">
<p class="text-gray-600 dark:text-gray-300">Anzahl der Parks:</p>
<p class="text-lg font-semibold text-gray-900 dark:text-white">{{ stats.totalParks }}</p>
</div>
<div class="bg-gray-100 dark:bg-gray-700 p-4 rounded-lg shadow-sm">
<p class="text-gray-600 dark:text-gray-300">Anzahl der Achterbahnen:</p>
<p class="text-lg font-semibold text-gray-900 dark:text-white">{{ stats.totalCoasters }}</p>
</div>
<div class="bg-gray-100 dark:bg-gray-700 p-4 rounded-lg shadow-sm">
<p class="text-gray-600 dark:text-gray-300">Ø Besucher / Monat:</p>
<p class="text-lg font-semibold text-gray-900 dark:text-white">{{ stats.totalVisitorsPerMonth.toLocaleString() }}</p>
</div>
<div class="bg-gray-100 dark:bg-gray-700 p-4 rounded-lg shadow-sm">
<p class="text-gray-600 dark:text-gray-300">Ø Ticketpreis:</p>
<p class="text-lg font-semibold text-gray-900 dark:text-white">{{ stats.averageTicketPrice.toFixed(2) }} </p>
</div>
<div class="bg-gray-100 dark:bg-gray-700 p-4 rounded-lg shadow-sm">
<p class="text-gray-600 dark:text-gray-300">Anzahl der Inversionen:</p>
<p class="text-lg font-semibold text-gray-900 dark:text-white">{{ stats.totalInversions }}</p>
</div>
</div>
</div>
</div>
</main>
</div>
</template>
<style scoped>
</style>

View File

@@ -0,0 +1,78 @@
<script lang="ts">
import Header from '../components/app/AppHeader.vue'
import Sidebar from '../components/app/AppSidebar.vue'
export default {
components: {
Header,
Sidebar
},
data() {
return {
techStats: {
framework: 'Vue.js',
language: 'TypeScript',
backend: 'Node.js (Express)',
database: 'SQLite',
hosting: 'Contabo VPS',
apiVersion: 'v1.0',
buildTool: 'Webpack'
}
}
}
}
</script>
<template>
<title>Technische Infos - CoasterDB</title>
<Header />
<div class="flex pt-[63px] h-screen overflow-hidden">
<Sidebar />
<main class="flex-1 overflow-y-auto p-5 bg-gray-50 dark:bg-gray-900">
<div style="margin-top: 63px;"></div>
<div class="mx-auto max-w-screen-xl px-4 lg:px-12">
<div class="bg-white dark:bg-gray-800 shadow-md sm:rounded-lg p-6 mb-6">
<h1 class="text-2xl font-bold text-gray-900 dark:text-white">Technische Informationen</h1>
<p class="text-gray-700 dark:text-gray-300 mb-4">Daten und Details zum Projekt:</p>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-6 text-gray-700 dark:text-gray-300">
<div class="bg-gray-100 dark:bg-gray-700 p-4 rounded-lg shadow-sm">
<p class="text-gray-600 dark:text-gray-300">Frontend Framework:</p>
<p class="text-lg font-semibold text-gray-900 dark:text-white">{{ techStats.framework }}</p>
</div>
<div class="bg-gray-100 dark:bg-gray-700 p-4 rounded-lg shadow-sm">
<p class="text-gray-600 dark:text-gray-300">Programmiersprache:</p>
<p class="text-lg font-semibold text-gray-900 dark:text-white">{{ techStats.language }}</p>
</div>
<div class="bg-gray-100 dark:bg-gray-700 p-4 rounded-lg shadow-sm">
<p class="text-gray-600 dark:text-gray-300">Backend Technologie:</p>
<p class="text-lg font-semibold text-gray-900 dark:text-white">{{ techStats.backend }}</p>
</div>
<div class="bg-gray-100 dark:bg-gray-700 p-4 rounded-lg shadow-sm">
<p class="text-gray-600 dark:text-gray-300">Datenbank:</p>
<p class="text-lg font-semibold text-gray-900 dark:text-white">{{ techStats.database }}</p>
</div>
<div class="bg-gray-100 dark:bg-gray-700 p-4 rounded-lg shadow-sm">
<p class="text-gray-600 dark:text-gray-300">Hosting-Plattform:</p>
<p class="text-lg font-semibold text-gray-900 dark:text-white">{{ techStats.hosting }}</p>
</div>
<div class="bg-gray-100 dark:bg-gray-700 p-4 rounded-lg shadow-sm">
<p class="text-gray-600 dark:text-gray-300">API Version:</p>
<p class="text-lg font-semibold text-gray-900 dark:text-white">{{ techStats.apiVersion }}</p>
</div>
<div class="bg-gray-100 dark:bg-gray-700 p-4 rounded-lg shadow-sm">
<p class="text-gray-600 dark:text-gray-300">Build Tool:</p>
<p class="text-lg font-semibold text-gray-900 dark:text-white">{{ techStats.buildTool }}</p>
</div>
</div>
</div>
</div>
</main>
</div>
</template>
<style scoped>
</style>

View File

@@ -1,4 +1,5 @@
<script lang="ts">
/**
*
* use this for template:
@@ -52,14 +53,21 @@ export default {
</script>
<template>
<title>App - CoasterDB</title>
<Header />
<title>App - CoasterDB</title>
<!-- Neue Anleitung -->
<div style="margin-top: 63px;">
<section class="dark:bg-gray-900 sm:p-10">
<div class="bg-gray-800 text-white p-8 rounded-lg shadow-lg max-w-4xl mx-auto">
<h2 class="text-2xl font-semibold mb-4">Willkommen auf CoasterDB!</h2>
<!-- Fester Header -->
<Header />
<!-- Flex-Layout für Sidebar + Hauptinhalt -->
<div class="flex pt-[63px] h-screen overflow-hidden">
<!-- Sidebar -->
<Sidebar />
<!-- Hauptinhalt -->
<main class="flex-1 overflow-y-auto p-10 bg-gray-900 text-white">
<div style="margin-top: 63px;"></div>
<section class="max-w-4xl mx-auto bg-gray-800 p-8 rounded-lg shadow-lg">
<h2 class="text-2xl font-semibold mb-4">Willkommen auf CoasterDB!</h2>
<p class="mb-6 text-lg">
Um mit CoasterDB zu arbeiten, kannst du in der Sidebar unter <strong>Kategorien -> Parks/Attraktionen</strong> wählen, um Informationen zu verschiedenen Freizeitparks und deren Attraktionen zu erhalten.
Wähle einfach den gewünschten Park oder die Attraktion aus, um mehr Details zu sehen!
@@ -67,10 +75,7 @@ export default {
<p class="text-lg">
Viel Spaß beim Entdecken der spannendsten Freizeitparks und Achterbahnen!
</p>
</div>
</section>
</div>
<!-- Sidebar -->
<Sidebar />
</template>
</section>
</main>
</div>
</template>

View File

@@ -28,55 +28,64 @@ export default {
<template>
<title>{{ coaster.name }} - CoasterDB</title>
<!-- Fester Header -->
<Header />
<div style="margin-top: 63px;">
<section class="bg-gray-50 dark:bg-gray-900 p-3 sm:p-5">
<div class="mx-auto max-w-screen-xl px-4 lg:px-12">
<div class="bg-white dark:bg-gray-800 relative shadow-md sm:rounded-lg overflow-hidden">
<div class="p-6">
<h1 class="text-2xl font-bold text-gray-900 dark:text-white mb-4">{{ coaster.name }}</h1>
<p class="text-sm text-gray-500 dark:text-gray-400 mb-6">Park: <span class="font-medium text-gray-900 dark:text-white"><a :href="`/app/park/${coaster.park.replace(' ', '_')}`">{{ coaster.park }}</a></span></p>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="bg-gray-100 dark:bg-gray-700 p-4 rounded-lg shadow-sm">
<p class="text-gray-600 dark:text-gray-300">Streckenlänge:</p>
<p class="text-lg font-semibold text-gray-900 dark:text-white">{{ coaster.length }}</p>
</div>
<div class="bg-gray-100 dark:bg-gray-700 p-4 rounded-lg shadow-sm">
<p class="text-gray-600 dark:text-gray-300">Maximale Höhe:</p>
<p class="text-lg font-semibold text-gray-900 dark:text-white">{{ coaster.height }}</p>
</div>
<div class="bg-gray-100 dark:bg-gray-700 p-4 rounded-lg shadow-sm">
<p class="text-gray-600 dark:text-gray-300">Maximale Geschwindigkeit:</p>
<p class="text-lg font-semibold text-gray-900 dark:text-white">{{ coaster.speed }}</p>
</div>
<div class="bg-gray-100 dark:bg-gray-700 p-4 rounded-lg shadow-sm">
<p class="text-gray-600 dark:text-gray-300">Launch-System:</p>
<p class="text-lg font-semibold text-gray-900 dark:text-white">{{ coaster.launch }}</p>
</div>
<div class="bg-gray-100 dark:bg-gray-700 p-4 rounded-lg shadow-sm">
<p class="text-gray-600 dark:text-gray-300">Anzahl Inversionen:</p>
<p class="text-lg font-semibold text-gray-900 dark:text-white">{{ coaster.inversions }}</p>
</div>
<div class="bg-gray-100 dark:bg-gray-700 p-4 rounded-lg shadow-sm">
<p class="text-gray-600 dark:text-gray-300">Fahrtdauer:</p>
<p class="text-lg font-semibold text-gray-900 dark:text-white">{{ coaster.duration }}</p>
</div>
<div class="bg-gray-100 dark:bg-gray-700 p-4 rounded-lg shadow-sm">
<p class="text-gray-600 dark:text-gray-300">Hersteller:</p>
<p class="text-lg font-semibold text-gray-900 dark:text-white">{{ coaster.manufacturer }}</p>
</div>
<div class="bg-gray-100 dark:bg-gray-700 p-4 rounded-lg shadow-sm">
<p class="text-gray-600 dark:text-gray-300">Eröffnet:</p>
<p class="text-lg font-semibold text-gray-900 dark:text-white">{{ coaster.opened }}</p>
</div>
</div>
</div>
<!-- Flex-Layout für Sidebar + Inhalt -->
<div class="flex pt-[63px] h-screen overflow-hidden">
<!-- Sidebar -->
<Sidebar />
<!-- Hauptinhalt -->
<main class="flex-1 overflow-y-auto p-5 bg-gray-50 dark:bg-gray-900">
<div style="margin-top: 63px;"></div>
<div class="mx-auto max-w-screen-xl px-4 lg:px-12">
<div class="bg-white dark:bg-gray-800 relative shadow-md sm:rounded-lg overflow-hidden">
<div class="p-6">
<h1 class="text-2xl font-bold text-gray-900 dark:text-white mb-4">{{ coaster.name }}</h1>
<p class="text-sm text-gray-500 dark:text-gray-400 mb-6">
Park:
<span class="font-medium text-gray-900 dark:text-white">
<a :href="`/app/park/${coaster.park.replace(' ', '_')}`">{{ coaster.park }}</a>
</span>
</p>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div v-for="(value, label) in {
'Streckenlänge': coaster.length,
'Maximale Höhe': coaster.height,
'Maximale Geschwindigkeit': coaster.speed,
'Launch-System': coaster.launch,
'Anzahl Inversionen': coaster.inversions,
'Fahrtdauer': coaster.duration,
'Hersteller': coaster.manufacturer,
'Eröffnet': coaster.opened
}"
:key="label"
class="bg-gray-100 dark:bg-gray-700 p-4 rounded-lg shadow-sm"
>
<p class="text-gray-600 dark:text-gray-300">{{ label }}:</p>
<p class="text-lg font-semibold text-gray-900 dark:text-white">{{ value }}</p>
</div>
</div>
<!-- Embedded YouTube Video -->
<div class="mt-6">
<h2 class="text-xl font-bold text-gray-900 dark:text-white mb-4">On-Ride Video</h2>
<div class="aspect-w-16 aspect-h-9">
<iframe
width="560"
height="315"
src="https://www.youtube.com/embed/P7m8SNRj_hI"
title="Blue Fire On-Ride Video"
frameborder="0"
allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen
></iframe>
</div>
</div>
</div>
</section>
</div>
</div>
</main>
</div>
<Sidebar />
</template>
<style scoped>
</style>
</template>

View File

@@ -22,23 +22,35 @@ export default {
<template>
<title>Coaster Übersicht - CoasterDB</title>
<Header />
<div style="margin-top: 63px;">
<section class="bg-gray-50 dark:bg-gray-900 p-3 sm:p-5">
<div class="mx-auto max-w-screen-xl px-4 lg:px-12">
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-2 gap-6">
<a v-for="coaster in coasters" :key="coaster.name" class="bg-white dark:bg-gray-800 shadow-md sm:rounded-lg p-6" :href="`/app/coaster/${coaster.name.replace(' ', '_')}`">
<h2 class="text-xl font-bold text-gray-900 dark:text-white mb-2">{{ coaster.name }}</h2>
<p class="text-gray-700 dark:text-gray-300">
<span class="font-semibold">Park:</span> {{ coaster.park }}
</p>
</a>
</div>
</div>
</section>
<div class="flex pt-[63px] h-screen overflow-hidden">
<Sidebar />
<main class="flex-1 overflow-y-auto p-5 bg-gray-50 dark:bg-gray-900">
<div style="margin-top: 63px;"></div>
<div class="mx-auto max-w-screen-xl px-4 lg:px-12">
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-2 gap-6">
<a
v-for="coaster in coasters"
:key="coaster.name"
:href="`/app/coaster/${coaster.name.replace(' ', '_')}`"
class="bg-white dark:bg-gray-800 shadow-md sm:rounded-lg p-6 hover:shadow-lg transition-shadow"
>
<h2 class="text-xl font-bold text-gray-900 dark:text-white mb-2">
{{ coaster.name }}
</h2>
<p class="text-gray-700 dark:text-gray-300">
<span class="font-semibold">Park:</span> {{ coaster.park }}
</p>
</a>
</div>
</div>
</main>
</div>
<Sidebar />
</template>
</template>
<style scoped>
</style>

View File

@@ -30,9 +30,14 @@ export default {
<template>
<title>{{ park.name }} - CoasterDB</title>
<Header />
<div style="margin-top: 63px;">
<section class="bg-gray-50 dark:bg-gray-900 p-3 sm:p-5">
<div class="flex pt-[63px] h-screen overflow-hidden">
<Sidebar />
<main class="flex-1 overflow-y-auto p-5 bg-gray-50 dark:bg-gray-900">
<div style="margin-top: 63px;"></div>
<div class="mx-auto max-w-screen-xl px-4 lg:px-12">
<!-- Park Info -->
<div class="bg-white dark:bg-gray-800 shadow-md sm:rounded-lg p-6 mb-6">
@@ -42,10 +47,22 @@ export default {
</p>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4 text-gray-700 dark:text-gray-300 mt-4">
<div><span class="font-semibold">Ø Besucher / Monat:</span> {{ park.averageVisitorsPerMonth.toLocaleString() }}</div>
<div><span class="font-semibold">Ø Ticketpreis:</span> {{ park.averageTicketPrice.toFixed(2) }} </div>
<div><span class="font-semibold">Fläche:</span> {{ park.area }}</div>
<div><span class="font-semibold">Eröffnet:</span> {{ park.openingYear }}</div>
<div>
<span class="font-semibold">Ø Besucher / Monat:</span>
{{ park.averageVisitorsPerMonth.toLocaleString() }}
</div>
<div>
<span class="font-semibold">Ø Ticketpreis:</span>
{{ park.averageTicketPrice.toFixed(2) }}
</div>
<div>
<span class="font-semibold">Fläche:</span>
{{ park.area }}
</div>
<div>
<span class="font-semibold">Eröffnet:</span>
{{ park.openingYear }}
</div>
</div>
</div>
@@ -56,18 +73,18 @@ export default {
<a
v-for="coaster in coasters"
:key="coaster.name"
class="bg-white dark:bg-gray-800 shadow p-4 rounded-lg"
class="bg-white dark:bg-gray-800 shadow p-4 rounded-lg hover:shadow-lg transition-shadow"
:href="`/app/coaster/${coaster.name.replace(' ', '_')}`"
>
<h3 class="text-lg font-semibold text-gray-900 dark:text-white">{{ coaster.name }}</h3>
</a>
</a>
</div>
</div>
</div>
</section>
</main>
</div>
<Sidebar />
</template>
<style scoped>
</style>

View File

@@ -22,23 +22,33 @@ export default {
<template>
<title>Park Übersicht - CoasterDB</title>
<Header />
<div style="margin-top: 63px;">
<section class="bg-gray-50 dark:bg-gray-900 p-3 sm:p-5">
<div class="mx-auto max-w-screen-xl px-4 lg:px-12">
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-2 gap-6">
<a v-for="park in parks" :key="park.name" class="bg-white dark:bg-gray-800 shadow-md sm:rounded-lg p-6" :href="`/app/park/${park.name.replace(' ', '_')}`">
<h2 class="text-xl font-bold text-gray-900 dark:text-white mb-2">{{ park.name }}</h2>
<p class="text-gray-700 dark:text-gray-300">
<span class="font-semibold">Ort:</span> {{ park.location }}
</p>
</a>
</div>
</div>
</section>
<div class="flex pt-[63px] h-screen overflow-hidden">
<Sidebar />
<main class="flex-1 overflow-y-auto p-5 bg-gray-50 dark:bg-gray-900">
<div style="margin-top: 63px;"></div>
<div class="mx-auto max-w-screen-xl px-4 lg:px-12">
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-2 gap-6">
<a
v-for="park in parks"
:key="park.name"
class="bg-white dark:bg-gray-800 shadow-md sm:rounded-lg p-6 hover:shadow-lg transition-shadow"
:href="`/app/park/${park.name.replace(' ', '_')}`"
>
<h2 class="text-xl font-bold text-gray-900 dark:text-white mb-2">{{ park.name }}</h2>
<p class="text-gray-700 dark:text-gray-300">
<span class="font-semibold">Ort:</span> {{ park.location }}
</p>
</a>
</div>
</div>
</main>
</div>
<Sidebar />
</template>
</template>
<style scoped>
</style>