mirror of
https://github.com/Spythere/stacjownik.git
synced 2026-05-04 13:58:12 +00:00
chore: moved station stats to a dropdown
This commit is contained in:
@@ -6,30 +6,11 @@
|
|||||||
<p>[F] {{ $t('options.filters') }}</p>
|
<p>[F] {{ $t('options.filters') }}</p>
|
||||||
<span class="active-indicator" v-if="changedFilters.length != 0"></span>
|
<span class="active-indicator" v-if="changedFilters.length != 0"></span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<label for="scenery-search">
|
|
||||||
<input
|
|
||||||
id="scenery-search"
|
|
||||||
list="sceneries"
|
|
||||||
:placeholder="$t('sceneries.scenery-search')"
|
|
||||||
@focus="preventKeyDown = true"
|
|
||||||
@blur="preventKeyDown = false"
|
|
||||||
v-model="chosenSearchScenery"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<datalist id="sceneries">
|
|
||||||
<option
|
|
||||||
v-for="scenery in sortedStationList"
|
|
||||||
:key="scenery.name"
|
|
||||||
:value="scenery.name"
|
|
||||||
></option>
|
|
||||||
</datalist>
|
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<transition name="card-anim">
|
<transition name="card-anim">
|
||||||
<div class="card" v-if="isVisible" tabindex="0" ref="cardRef" @keydown.r="resetFilters">
|
<div class="card" v-if="isVisible" ref="cardRef" @keydown.r="resetFilters">
|
||||||
<div class="card_content" @scroll="onScroll" ref="cardContentRef">
|
<div class="card_content" tabindex="0" @scroll="onScroll" ref="cardContentRef">
|
||||||
<div class="card_title flex">{{ $t('filters.title') }}</div>
|
<div class="card_title flex">{{ $t('filters.title') }}</div>
|
||||||
<p class="card_info" v-html="$t('filters.desc')"></p>
|
<p class="card_info" v-html="$t('filters.desc')"></p>
|
||||||
|
|
||||||
@@ -40,6 +21,31 @@
|
|||||||
<template v-else>{{ $t('filters.no-changed-filters') }}</template>
|
<template v-else>{{ $t('filters.no-changed-filters') }}</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<section class="card_sceneries-search">
|
||||||
|
<h3 class="section-header">{{ $t('filters.sceneries-search') }}</h3>
|
||||||
|
|
||||||
|
<datalist id="sceneries">
|
||||||
|
<option
|
||||||
|
v-for="scenery in sortedStationList"
|
||||||
|
:key="scenery.name"
|
||||||
|
:value="scenery.name"
|
||||||
|
></option>
|
||||||
|
</datalist>
|
||||||
|
|
||||||
|
<form action="javascript:void(0);" @submit="handleSceneriesInput">
|
||||||
|
<input
|
||||||
|
v-model="chosenSearchScenery"
|
||||||
|
id="scenery-search"
|
||||||
|
list="sceneries"
|
||||||
|
:placeholder="$t('filters.sceneries-placeholder')"
|
||||||
|
@focus="preventKeyDown = true"
|
||||||
|
@blur="preventKeyDown = false"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<button class="btn--action">{{ $t('filters.search-button-title') }}</button>
|
||||||
|
</form>
|
||||||
|
</section>
|
||||||
|
|
||||||
<section class="card_options">
|
<section class="card_options">
|
||||||
<div
|
<div
|
||||||
class="option-section"
|
class="option-section"
|
||||||
@@ -111,7 +117,7 @@
|
|||||||
@blur="preventKeyDown = false"
|
@blur="preventKeyDown = false"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<button class="btn--action">{{ $t('filters.authors-button-title') }}</button>
|
<button class="btn--action">{{ $t('filters.search-button-title') }}</button>
|
||||||
</form>
|
</form>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@@ -269,20 +275,11 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
chosenSearchScenery(value: string) {
|
|
||||||
const chosenStation = this.store.stationList.find(({ name }) => name == value);
|
|
||||||
|
|
||||||
if (chosenStation) {
|
|
||||||
this.$router.push(`/scenery?station=${chosenStation.name.replace(/ /g, '_')}`);
|
|
||||||
this.chosenSearchScenery = '';
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
isVisible(value: boolean) {
|
isVisible(value: boolean) {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
if (value) {
|
if (value) {
|
||||||
(this.$refs['cardRef'] as HTMLDivElement).focus();
|
|
||||||
(this.$refs['cardContentRef'] as HTMLDivElement).scrollTop = this.scrollTop;
|
(this.$refs['cardContentRef'] as HTMLDivElement).scrollTop = this.scrollTop;
|
||||||
|
(this.$refs['cardContentRef'] as HTMLDivElement).focus();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -300,7 +297,18 @@ export default defineComponent({
|
|||||||
|
|
||||||
handleAuthorsInput() {
|
handleAuthorsInput() {
|
||||||
this.filters['authors'] = this.authors;
|
this.filters['authors'] = this.authors;
|
||||||
// if (this.saveOptions) StorageManager.setStringValue('authors', target.value);
|
},
|
||||||
|
|
||||||
|
handleSceneriesInput() {
|
||||||
|
const chosenStation = this.store.stationList.find(
|
||||||
|
({ name }) => name == this.chosenSearchScenery
|
||||||
|
);
|
||||||
|
|
||||||
|
if (chosenStation) {
|
||||||
|
this.$router.push(`/scenery?station=${chosenStation.name.replace(/ /g, '_')}`);
|
||||||
|
this.chosenSearchScenery = '';
|
||||||
|
this.isVisible = false;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
subHour() {
|
subHour() {
|
||||||
@@ -329,6 +337,8 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
resetFilters() {
|
resetFilters() {
|
||||||
|
if (this.preventKeyDown) return;
|
||||||
|
|
||||||
// Reset local model values
|
// Reset local model values
|
||||||
this.minimumHours = 0;
|
this.minimumHours = 0;
|
||||||
this.authors = '';
|
this.authors = '';
|
||||||
@@ -382,6 +392,7 @@ h3.section-header {
|
|||||||
.card {
|
.card {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-rows: 1fr auto;
|
grid-template-rows: 1fr auto;
|
||||||
|
padding: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card_info {
|
.card_info {
|
||||||
@@ -451,8 +462,12 @@ h3.section-header {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.card_authors-search {
|
.card_authors-search,
|
||||||
|
.card_sceneries-search {
|
||||||
margin: 1em 0;
|
margin: 1em 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
form {
|
form {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -1,56 +1,70 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="station-stats">
|
<div
|
||||||
<div class="separator" />
|
class="dropdown"
|
||||||
|
@keydown.esc="showDropdown = false"
|
||||||
|
v-click-outside="() => (showDropdown = false)"
|
||||||
|
>
|
||||||
|
<div class="bg" v-if="showDropdown" @click="showDropdown = false"></div>
|
||||||
|
|
||||||
<div class="stats-row">
|
<button class="filter-button btn--filled btn--image" @click="toggleDropdown" ref="button">
|
||||||
<div>
|
<img src="/images/icon-stats.svg" alt="Open filters icon" />
|
||||||
<span
|
<!-- {{ $t('train-stats.stats-button') }} -->
|
||||||
>{{ $t('station-stats.u-factor') }}
|
STATYSTYKI
|
||||||
<a
|
</button>
|
||||||
href="https://td2.info.pl/dyskusje/wspolczynnik-ugla-czy-to-ma-sens/msg81011/#msg81011"
|
|
||||||
target="_blank"
|
|
||||||
:data-tooltip="$t('station-stats.u-factor-tooltip')"
|
|
||||||
>(?)</a
|
|
||||||
>:
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<b class="u-factor" :style="calculateFactorStyle()">
|
<transition name="dropdown-anim">
|
||||||
{{ uFactor.toFixed(2) }}
|
<div class="dropdown_wrapper" v-if="showDropdown">
|
||||||
</b>
|
<div>
|
||||||
|
<h1 class="text--primary">
|
||||||
|
<img src="/images/icon-stats.svg" alt="Open filters icon" />
|
||||||
|
{{ $t('train-stats.title') }}
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<hr style="margin: 0.5em 0" />
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
<span
|
||||||
|
>{{ $t('station-stats.u-factor') }}
|
||||||
|
<a
|
||||||
|
href="https://td2.info.pl/dyskusje/wspolczynnik-ugla-czy-to-ma-sens/msg81011/#msg81011"
|
||||||
|
target="_blank"
|
||||||
|
:data-tooltip="$t('station-stats.u-factor-tooltip')"
|
||||||
|
>(?)</a
|
||||||
|
>:
|
||||||
|
</span>
|
||||||
|
<b class="u-factor" :style="calculateFactorStyle()">
|
||||||
|
{{ uFactor.toFixed(2) }}
|
||||||
|
</b>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{{ $t('station-stats.avg-timetable-count') }}
|
||||||
|
<b>{{ avgTimetableCount.toFixed(2) }}</b>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{{ $t('station-stats.single-track-count') }}
|
||||||
|
<b>{{ trackCount.oneWay }}</b> (<b>{{ trackCount.oneWayElectric }} ⚡</b>)
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{{ $t('station-stats.double-track-count') }}
|
||||||
|
<b>{{ trackCount.twoWay }}</b>
|
||||||
|
(<b>{{ trackCount.twoWayElectric }} ⚡</b>)
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{{ $t('station-stats.cross-sceneries') }}
|
||||||
|
<b>{{ trackCount.crossTrack }}</b> (<b>{{ trackCount.crossTrackElectric }} ⚡</b>)
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{{ $t('station-stats.open-spawns') }} <b>{{ spawnCount.passenger }}</b> - PAS /
|
||||||
|
<b>{{ spawnCount.freight }}</b> - TOW / <b>{{ spawnCount.loco }}</b> - LUZ /
|
||||||
|
<b>{{ spawnCount.all }}</b> - ALL
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div tabindex="0" @focus="() => (showDropdown = false)"></div>
|
||||||
</div>
|
</div>
|
||||||
|
</transition>
|
||||||
<div>
|
|
||||||
•
|
|
||||||
{{ $t('station-stats.avg-timetable-count') }}
|
|
||||||
<b>{{ avgTimetableCount.toFixed(2) }}</b>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
•
|
|
||||||
{{ $t('station-stats.single-track-count') }}
|
|
||||||
<b>{{ trackCount.oneWay }}</b> (<b>{{ trackCount.oneWayElectric }} ⚡</b>)
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
•
|
|
||||||
{{ $t('station-stats.double-track-count') }}
|
|
||||||
<b>{{ trackCount.twoWay }}</b>
|
|
||||||
(<b>{{ trackCount.twoWayElectric }} ⚡</b>)
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
• {{ $t('station-stats.cross-sceneries') }} <b>{{ trackCount.crossTrack }}</b> (<b
|
|
||||||
>{{ trackCount.crossTrackElectric }} ⚡</b
|
|
||||||
>)
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
•
|
|
||||||
{{ $t('station-stats.open-spawns') }} <b>{{ spawnCount.passenger }}</b> - PAS /
|
|
||||||
<b>{{ spawnCount.freight }}</b> - TOW / <b>{{ spawnCount.loco }}</b> - LUZ /
|
|
||||||
<b>{{ spawnCount.all }}</b> - ALL
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -61,11 +75,16 @@ import { useMainStore } from '../../store/mainStore';
|
|||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
mainStore: useMainStore()
|
mainStore: useMainStore(),
|
||||||
|
showDropdown: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
toggleDropdown() {
|
||||||
|
this.showDropdown = !this.showDropdown;
|
||||||
|
},
|
||||||
|
|
||||||
calculateFactorStyle() {
|
calculateFactorStyle() {
|
||||||
if (this.uFactor == 0) return '';
|
if (this.uFactor == 0) return '';
|
||||||
|
|
||||||
@@ -171,26 +190,24 @@ export default defineComponent({
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.separator {
|
@import '../../styles/dropdown.scss';
|
||||||
width: 100%;
|
|
||||||
height: 2px;
|
h1 img {
|
||||||
|
vertical-align: text-bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
margin: 0.5em 0;
|
margin: 0.5em 0;
|
||||||
background-color: #aaa;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.station-stats {
|
// .stats-row {
|
||||||
text-align: center;
|
// display: flex;
|
||||||
color: #ddd;
|
// justify-content: center;
|
||||||
}
|
// flex-wrap: wrap;
|
||||||
|
// text-wrap: pretty;
|
||||||
.stats-row {
|
// gap: 0.25em;
|
||||||
display: flex;
|
// margin-top: 0.25em;
|
||||||
justify-content: center;
|
// }
|
||||||
flex-wrap: wrap;
|
|
||||||
text-wrap: pretty;
|
|
||||||
gap: 0.25em;
|
|
||||||
margin-top: 0.25em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.u-factor {
|
.u-factor {
|
||||||
[data-factor-low='true'] {
|
[data-factor-low='true'] {
|
||||||
|
|||||||
@@ -414,7 +414,7 @@ export default defineComponent({
|
|||||||
$rowCol: #424242;
|
$rowCol: #424242;
|
||||||
|
|
||||||
.station_table {
|
.station_table {
|
||||||
height: 80vh;
|
height: 85vh;
|
||||||
max-height: 2000px;
|
max-height: 2000px;
|
||||||
min-height: 700px;
|
min-height: 700px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="dropdown" @keydown.esc="showOptions = false" @focusout="showOptions = false">
|
<div
|
||||||
|
class="dropdown"
|
||||||
|
@keydown.esc="showOptions = false"
|
||||||
|
v-click-outside="() => (showOptions = false)"
|
||||||
|
>
|
||||||
<div class="bg" v-if="showOptions" @click="showOptions = false"></div>
|
<div class="bg" v-if="showOptions" @click="showOptions = false"></div>
|
||||||
|
|
||||||
<button class="filter-button btn--filled btn--image" @click="toggleShowOptions" ref="button">
|
<button class="filter-button btn--filled btn--image" @click="toggleShowOptions" ref="button">
|
||||||
@@ -95,6 +99,8 @@
|
|||||||
<div class="no-data" v-else>
|
<div class="no-data" v-else>
|
||||||
{{ $t('train-stats.no-stats') }}
|
{{ $t('train-stats.no-stats') }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div tabindex="0" @focus="() => (showOptions = false)"></div>
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
@@ -236,10 +242,6 @@ h3 {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: 0.5em;
|
gap: 0.5em;
|
||||||
|
|
||||||
// @include smallScreen {
|
|
||||||
// justify-content: center;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.badge {
|
.badge {
|
||||||
@@ -255,24 +257,6 @@ h3 {
|
|||||||
max-width: 600px;
|
max-width: 600px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stats-anim {
|
|
||||||
&-move,
|
|
||||||
&-enter-active,
|
|
||||||
&-leave-active {
|
|
||||||
transition: all 250ms ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-enter-from,
|
|
||||||
&-leave-to {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateX(5px);
|
|
||||||
}
|
|
||||||
|
|
||||||
&-leave-active {
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@include smallScreen {
|
@include smallScreen {
|
||||||
h1,
|
h1,
|
||||||
.no-data {
|
.no-data {
|
||||||
|
|||||||
+3
-1
@@ -292,9 +292,11 @@
|
|||||||
"minTwoWay": "MIN. OTHER DOUBLE TRACK ROUTES"
|
"minTwoWay": "MIN. OTHER DOUBLE TRACK ROUTES"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"sceneries-search": "SCENERY SEARCH:",
|
||||||
|
"sceneries-placeholder": "Enter scenery name...",
|
||||||
"authors-search": "SEARCH BY AUTHOR NAME (other filters apply):",
|
"authors-search": "SEARCH BY AUTHOR NAME (other filters apply):",
|
||||||
"authors-placeholder": "Enter the author nickname...",
|
"authors-placeholder": "Enter the author nickname...",
|
||||||
"authors-button-title": "Search",
|
"search-button-title": "SEARCH",
|
||||||
|
|
||||||
"minimum-hours-title": "SHOW ONLY SCENERIES UNTIL:",
|
"minimum-hours-title": "SHOW ONLY SCENERIES UNTIL:",
|
||||||
"now": "NOW",
|
"now": "NOW",
|
||||||
|
|||||||
+4
-2
@@ -290,9 +290,11 @@
|
|||||||
"minTwoWay": "SZLAKI DWUTOROWE NIEZELEKTR. (MINIMUM)"
|
"minTwoWay": "SZLAKI DWUTOROWE NIEZELEKTR. (MINIMUM)"
|
||||||
},
|
},
|
||||||
|
|
||||||
"authors-search": "SZUKAJ AUTORA (uwzględnia inne filtry):",
|
"sceneries-search": "WYSZUKAJ SCENERIĘ:",
|
||||||
|
"sceneries-placeholder": "Wpisz nazwę scenerii...",
|
||||||
|
"authors-search": "WYSZUKAJ AUTORA (uwzględnia inne filtry):",
|
||||||
"authors-placeholder": "Wpisz nick autora...",
|
"authors-placeholder": "Wpisz nick autora...",
|
||||||
"authors-button-title": "Szukaj",
|
"search-button-title": "SZUKAJ",
|
||||||
"minimum-hours-title": "POKAŻ TYLKO SCENERIE DOSTĘPNE MINIMUM DO:",
|
"minimum-hours-title": "POKAŻ TYLKO SCENERIE DOSTĘPNE MINIMUM DO:",
|
||||||
"now": "TERAZ",
|
"now": "TERAZ",
|
||||||
"hour": " godz.",
|
"hour": " godz.",
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
ref="filterCardRef"
|
ref="filterCardRef"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<StationStats />
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="btn-donation btn--image"
|
class="btn-donation btn--image"
|
||||||
ref="btn"
|
ref="btn"
|
||||||
@@ -21,7 +23,6 @@
|
|||||||
|
|
||||||
<DonationCard :is-card-open="isDonationCardOpen" @toggle-card="toggleDonationCard" />
|
<DonationCard :is-card-open="isDonationCardOpen" @toggle-card="toggleDonationCard" />
|
||||||
<StationTable @toggle-donation-card="toggleDonationCard" />
|
<StationTable @toggle-donation-card="toggleDonationCard" />
|
||||||
<StationStats />
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
@@ -96,14 +97,17 @@ export default defineComponent({
|
|||||||
|
|
||||||
.stations-options {
|
.stations-options {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: 0.5em;
|
gap: 0.5em;
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
|
||||||
margin-bottom: 0.5em;
|
margin-bottom: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
button.btn-donation {
|
button.btn-donation {
|
||||||
|
margin-left: auto;
|
||||||
|
|
||||||
$btnColor: #254069;
|
$btnColor: #254069;
|
||||||
|
|
||||||
background-color: $btnColor;
|
background-color: $btnColor;
|
||||||
|
|||||||
Reference in New Issue
Block a user