chore(app): moved options to pragotron view, improved responsiveness

This commit is contained in:
2026-04-12 23:57:08 +02:00
parent 0a88d958da
commit c2ade9f95f
3 changed files with 79 additions and 157 deletions
-129
View File
@@ -1,129 +0,0 @@
<template>
<div class="dropdown" v-click-outside="() => (store.optionsOpen = false)">
<button class="btn--image" @click="store.optionsOpen = !store.optionsOpen">
<img src="/options.svg" alt="options" />
</button>
<transition name="dropdown-anim">
<div class="dropdown-body" v-if="store.optionsOpen">
<h3>{{ $t('options.header') }}</h3>
<hr />
<div class="dropdown-checkboxes">
<label>
<input type="checkbox" v-model="store.filters.nonPassenger" />
{{ $t('options.checkbox-non-passenger') }}
</label>
<label>
<input type="checkbox" v-model="store.filters.terminating" />
{{ $t('options.checkbox-terminating') }}
</label>
<label>
<input type="checkbox" v-model="store.filters.soundsEnabled" />
{{ $t('options.checkbox-sounds') }}
</label>
</div>
<div class="dropdown-checkpoints" v-if="isPragotronOpen">
<label for="checkpoint">
{{ $t('options.checkpoint-name') }}
<select id="checkpoint" v-model="store.selectedCheckpointName">
<option v-for="cp in store.selectedStation?.stationCheckpoints" :value="cp" :key="cp">
{{ cp }}
</option>
</select>
</label>
</div>
<div tabindex="0" @focus="() => (store.optionsOpen = false)"></div>
</div>
</transition>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { useMainStore } from '../stores/mainStore';
export default defineComponent({
data: () => ({
store: useMainStore()
}),
computed: {
isPragotronOpen() {
return this.$route.path == '/board';
}
},
watch: {
'store.filters': {
deep: true,
handler(filters: typeof this.store.filters) {
window.localStorage.setItem('settings', JSON.stringify(filters));
}
}
}
});
</script>
<style lang="scss" scoped>
img {
max-width: 2em;
}
h3 {
font-size: 1.2em;
margin: 0;
}
.dropdown-bg {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
z-index: 100;
}
.dropdown-body {
position: absolute;
top: 100%;
right: 0;
padding: 0.25em;
transform: translateY(0.5em);
width: 500px;
max-width: calc(100% - 0.5em);
z-index: 105;
background-color: #000000e1;
}
.dropdown-checkboxes {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 0.5em;
margin: 0.5em 0;
}
.dropdown-checkpoints {
margin: 0.5em 0;
}
.dropdown-anim {
&-enter-active,
&-leave-active {
transition: all 90ms ease-out;
}
&-enter-from,
&-leave-to {
transform: translateY(20px);
opacity: 0;
}
}
</style>
+1 -7
View File
@@ -4,10 +4,6 @@
<router-link class="brand" to="/">
Pragotron TD2 <span class="text--accent">v{{ version }}</span> <sup>by Spythere</sup>
</router-link>
<div class="options">
<Dropdown />
</div>
</div>
</nav>
</template>
@@ -15,10 +11,8 @@
<script lang="ts">
import { defineComponent } from 'vue';
import { useMainStore } from '../stores/mainStore';
import Dropdown from './Dropdown.vue';
export default defineComponent({
components: { Dropdown },
props: {
version: String
},
@@ -53,7 +47,7 @@ nav.navbar {
position: relative;
margin: 0 auto;
max-width: 1400px;
max-width: 1500px;
font-weight: bold;
}
+78 -21
View File
@@ -1,6 +1,40 @@
<template>
<div class="pragotron">
<div class="pragotron_content">
<div class="pragotron_options">
<div class="options-checkboxes">
<label>
<input type="checkbox" v-model="mainStore.filters.nonPassenger" />
{{ $t('options.checkbox-non-passenger') }}
</label>
<label>
<input type="checkbox" v-model="mainStore.filters.terminating" />
{{ $t('options.checkbox-terminating') }}
</label>
<label>
<input type="checkbox" v-model="mainStore.filters.soundsEnabled" />
{{ $t('options.checkbox-sounds') }}
</label>
</div>
<div class="options-checkpoints">
<label for="checkpoint">
{{ $t('options.checkpoint-name') }}
<select id="checkpoint" v-model="mainStore.selectedCheckpointName">
<option
v-for="cp in mainStore.selectedStation?.stationCheckpoints"
:value="cp"
:key="cp"
>
{{ cp }}
</option>
</select>
</label>
</div>
</div>
<div class="wrapper" ref="pragotron">
<div class="top-pane">
<span class="title">
@@ -327,16 +361,15 @@ export default defineComponent({
methods: {
resizeTable() {
const elRef = this.$refs['pragotron'] as HTMLElement;
if (!elRef) return;
const scale = Math.min(
window.innerWidth / elRef.clientWidth,
window.innerHeight / elRef.clientHeight,
1
);
elRef.style.transform = `scale(${scale})`;
// const elRef = this.$refs['pragotron'] as HTMLElement;
// if (!elRef) return;
// const scale = Math.min(
// window.innerWidth / elRef.clientWidth,
// window.innerHeight / elRef.clientHeight,
// 1
// );
// console.log(elRef.clientWidth);
// elRef.style.transform = `scale(${scale})`;
},
selectDefaultCheckpoint() {
@@ -450,34 +483,58 @@ export default defineComponent({
/* ************** */
.pragotron_content {
.pragotron {
display: flex;
justify-content: center;
padding: 1em;
}
@media only screen and (max-width: 1500px) {
.pragotron {
font-size: calc(0.3em + 0.65vw);
}
}
.pragotron_options {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
width: 100%;
margin-bottom: 0.5em;
}
.pragotron_content {
display: flex;
justify-content: center;
align-items: flex-start;
flex-direction: column;
width: 100%;
max-width: 1500px;
}
.wrapper {
display: flex;
flex-direction: column;
min-width: 1400px;
min-height: 700px;
padding: 2em;
transform-origin: top;
width: 100%;
min-height: 50em;
overflow: auto;
}
.top-pane > .headers,
.row-content {
display: grid;
grid-template-columns: 1fr 1fr 2fr 2fr 1fr;
gap: 0 10px;
padding: 0 10px;
gap: 0 1em;
padding: 0 1em;
}
.top-pane {
background-color: white;
color: black;
height: 180px;
height: 12em;
min-width: 700px;
display: flex;
flex-direction: column;
@@ -485,24 +542,24 @@ export default defineComponent({
.title {
padding: 0;
font-size: 3.5em;
}
.headers {
text-align: center;
font-size: 1.35em;
}
}
.table {
background: white;
flex-grow: 1;
display: grid;
grid-template-rows: repeat(7, 1fr);
gap: 5px 0;
background: white;
min-width: 700px;
}
.row {