mirror of
https://github.com/Spythere/stacjownik.git
synced 2026-05-03 21:38:13 +00:00
restruct: added driver view components
This commit is contained in:
@@ -0,0 +1,80 @@
|
|||||||
|
<template>
|
||||||
|
<div class="driver-not-found">
|
||||||
|
<h2>⦻ {{ $t('trains.driver-not-found-header') }}</h2>
|
||||||
|
|
||||||
|
<p class="text--grayed">
|
||||||
|
{{ $t('trains.driver-not-found-desc-1') }} <br />
|
||||||
|
{{ $t('trains.driver-not-found-desc-2') }}
|
||||||
|
<router-link to="/journal/timetables">{{ $t('trains.driver-not-found-journal') }} </router-link>!
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p v-if="props.trainId && otherDriverTrains.length > 0">
|
||||||
|
<i18n-t keypath="trains.driver-not-found-others">
|
||||||
|
<template v-slot:driver>
|
||||||
|
<b>{{ otherDriverTrains[0].driverName }}</b>
|
||||||
|
</template>
|
||||||
|
</i18n-t>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="other-driver-trains">
|
||||||
|
<template v-for="(train, i) in otherDriverTrains">
|
||||||
|
<router-link :to="`/driver?trainId=${train.id}`">
|
||||||
|
{{ train.trainNo }}
|
||||||
|
| {{ regions.find((r) => r.id == train.region)?.name ?? 'PL1' }}
|
||||||
|
</router-link>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="margin-top: 1em">
|
||||||
|
<router-link to="/"><< {{ $t('trains.driver-not-found-return') }}</router-link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed } from 'vue';
|
||||||
|
import { useMainStore } from '../../store/mainStore';
|
||||||
|
import { regions } from '../../data/options.json';
|
||||||
|
|
||||||
|
const mainStore = useMainStore();
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
trainId: {
|
||||||
|
type: String
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const otherDriverTrains = computed(() => {
|
||||||
|
return mainStore.trainList.filter(
|
||||||
|
(train) =>
|
||||||
|
train.driverId == Number(props.trainId?.split('|')[0]) &&
|
||||||
|
(train.timetableData || train.online || train.lastSeen >= Date.now() - 60000)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.driver-not-found {
|
||||||
|
background-color: var(--clr-view-bg);
|
||||||
|
text-align: center;
|
||||||
|
padding: 1em;
|
||||||
|
border-radius: 0.5em 0.5em;
|
||||||
|
|
||||||
|
p {
|
||||||
|
padding: 0.5em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: underline;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.other-driver-trains {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.5em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
<template>
|
||||||
|
<div class="driver-top-actions">
|
||||||
|
<div class="actions-container">
|
||||||
|
<div class="actions actions-left">
|
||||||
|
<button class="a-button btn--filled btn--image" @click="routerReturn">
|
||||||
|
<img src="/images/icon-back.svg" alt="train icon" />
|
||||||
|
<span>
|
||||||
|
{{ t('trains.driver-return-link') }}
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="actions actions-right">
|
||||||
|
<a class="a-button btn--filled btn--image" :href="`https://srjp-td2.web.app/?id=${chosenTrain.id}`"
|
||||||
|
target="_blank">
|
||||||
|
<span class="hidable">
|
||||||
|
{{ t('trains.driver-srjp-link') }}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<img src="/images/icon-srjp.svg" alt="srjp icon" />
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<router-link :to="`/journal/timetables?search-driver=${chosenTrain.driverName}`"
|
||||||
|
class="a-button btn--filled btn--image">
|
||||||
|
<span class="hidable">
|
||||||
|
{{ t('trains.driver-journal-link') }}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<img src="/images/icon-train.svg" alt="train icon" />
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
import { Train } from '../../typings/common';
|
||||||
|
import { PropType } from 'vue';
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
defineProps({
|
||||||
|
chosenTrain: {
|
||||||
|
type: Object as PropType<Train>,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function routerReturn() {
|
||||||
|
router.back();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@use '../../styles/responsive';
|
||||||
|
|
||||||
|
|
||||||
|
.actions-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actions-container>.actions>.a-button {
|
||||||
|
padding: 0.5em;
|
||||||
|
border-radius: 0.5em 0.5em 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include responsive.smallScreen {
|
||||||
|
span.hidable {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
<template>
|
||||||
|
<div class="driver-train-card">
|
||||||
|
<TrainInfo :train="chosenTrain" :extended="true" />
|
||||||
|
|
||||||
|
<!-- Train action buttons -->
|
||||||
|
<div class="train-stock-actions">
|
||||||
|
<button class="btn btn--action" style="margin: 1em 0" @click="copyStockToClipboard()">
|
||||||
|
<i class="fa-regular fa-copy"></i> {{ i18n.t('trains.stock-copy') }}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button class="btn btn--action" style="margin: 1em 0" @click="showNumberPropositions()">
|
||||||
|
<i class="fa-regular fa-lightbulb"></i> {{ i18n.t('trains.number-propositions') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<StockList :trainStockList="chosenTrain.stockList" />
|
||||||
|
<TrainSchedule :train="chosenTrain" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { PropType } from 'vue';
|
||||||
|
import { Train } from '../../typings/common';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
|
import StockList from '../Global/StockList.vue';
|
||||||
|
import TrainSchedule from '../TrainsView/TrainSchedule.vue';
|
||||||
|
import TrainInfo from '../TrainsView/TrainInfo.vue';
|
||||||
|
|
||||||
|
const i18n = useI18n();
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
chosenTrain: {
|
||||||
|
type: Object as PropType<Train>,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function copyStockToClipboard() {
|
||||||
|
const stockString = props.chosenTrain.stockList.join(';');
|
||||||
|
|
||||||
|
if (!stockString) {
|
||||||
|
alert(i18n.t('trains.stock-clipboard-failure'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
navigator.clipboard
|
||||||
|
.writeText(stockString)
|
||||||
|
.then(() => {
|
||||||
|
prompt(i18n.t('trains.stock-clipboard-success'), stockString);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
alert(i18n.t('trains.stock-clipboard-failure'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function showNumberPropositions() {
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.driver-train-card {
|
||||||
|
padding: 1em;
|
||||||
|
background-color: var(--clr-view-bg);
|
||||||
|
border-radius: 0 0 0.5em 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.train-stock-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.5em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -395,6 +395,7 @@
|
|||||||
"driver-not-found-others": "Player {driver} is online as:",
|
"driver-not-found-others": "Player {driver} is online as:",
|
||||||
"driver-not-found-return": "GO BACK TO THE MAIN SITE",
|
"driver-not-found-return": "GO BACK TO THE MAIN SITE",
|
||||||
"stock-copy": "COPY THE STOCK",
|
"stock-copy": "COPY THE STOCK",
|
||||||
|
"number-propositions": "PROPOSE NUMBERS",
|
||||||
"stock-clipboard-success": "Successfully copied the railway stock in a text form to your clipboard!",
|
"stock-clipboard-success": "Successfully copied the railway stock in a text form to your clipboard!",
|
||||||
"stock-clipboard-failure": "Oops! Something happened and the railway stock couldn't be copied to your clipboard! :/"
|
"stock-clipboard-failure": "Oops! Something happened and the railway stock couldn't be copied to your clipboard! :/"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -382,6 +382,7 @@
|
|||||||
"driver-not-found-others": "Gracz {driver} jest online jako:",
|
"driver-not-found-others": "Gracz {driver} jest online jako:",
|
||||||
"driver-not-found-return": "WRÓĆ NA STRONĘ GŁÓWNĄ",
|
"driver-not-found-return": "WRÓĆ NA STRONĘ GŁÓWNĄ",
|
||||||
"stock-copy": "SKOPIUJ SKŁAD",
|
"stock-copy": "SKOPIUJ SKŁAD",
|
||||||
|
"number-propositions": "ZAPROPONUJ NUMERY",
|
||||||
"stock-clipboard-success": "Pomyślnie skopiowano skład w postaci tekstowej do schowka!",
|
"stock-clipboard-success": "Pomyślnie skopiowano skład w postaci tekstowej do schowka!",
|
||||||
"stock-clipboard-failure": "Ups! Nie udało się skopiować składu do schowka! :/"
|
"stock-clipboard-failure": "Ups! Nie udało się skopiować składu do schowka! :/"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
--clr-bg: #4d4d4d;
|
--clr-bg: #4d4d4d;
|
||||||
--clr-bg2: #1b1b1b;
|
--clr-bg2: #1b1b1b;
|
||||||
--clr-bg3: #1d1d1d;
|
--clr-bg3: #1d1d1d;
|
||||||
|
--clr-view-bg: #1a1a1a;
|
||||||
|
|
||||||
--clr-accent: #1085b3;
|
--clr-accent: #1085b3;
|
||||||
--clr-accent2: #ff3d5d;
|
--clr-accent2: #ff3d5d;
|
||||||
@@ -22,6 +23,7 @@
|
|||||||
|
|
||||||
--clr-donator: #f7a4ff;
|
--clr-donator: #f7a4ff;
|
||||||
|
|
||||||
|
|
||||||
--no-scroll-padding: 17px;
|
--no-scroll-padding: 17px;
|
||||||
--max-container-width: 1700px;
|
--max-container-width: 1700px;
|
||||||
|
|
||||||
|
|||||||
+7
-173
@@ -2,103 +2,27 @@
|
|||||||
<section class="driver-view">
|
<section class="driver-view">
|
||||||
<div class="view-wrapper">
|
<div class="view-wrapper">
|
||||||
<div v-if="chosenTrain">
|
<div v-if="chosenTrain">
|
||||||
<div class="actions-container">
|
<DriverTopActions :chosenTrain="chosenTrain" />
|
||||||
<div class="actions actions-left">
|
<DriverTrainCard :chosenTrain="chosenTrain" />
|
||||||
<a class="a-button btn--image" @click="$router.back()">
|
|
||||||
<img src="/images/icon-back.svg" alt="train icon" />
|
|
||||||
<span>
|
|
||||||
{{ $t('trains.driver-return-link') }}
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="actions actions-right">
|
|
||||||
<a
|
|
||||||
class="a-button btn--image"
|
|
||||||
:href="`https://srjp-td2.web.app/?id=${chosenTrain.id}`"
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
<span class="hidable">
|
|
||||||
{{ $t('trains.driver-srjp-link') }}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<img src="/images/icon-srjp.svg" alt="srjp icon" />
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<router-link
|
|
||||||
:to="`/journal/timetables?search-driver=${chosenTrain.driverName}`"
|
|
||||||
class="a-button btn--image"
|
|
||||||
>
|
|
||||||
<span class="hidable">
|
|
||||||
{{ $t('trains.driver-journal-link') }}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<img src="/images/icon-train.svg" alt="train icon" />
|
|
||||||
</router-link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="train-card">
|
|
||||||
<TrainInfo :train="chosenTrain" :extended="true" />
|
|
||||||
|
|
||||||
<button class="btn btn--action" style="margin: 1em 0" @click="copyStockToClipboard()">
|
|
||||||
<i class="fa-regular fa-copy"></i> {{ $t('trains.stock-copy') }}
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<StockList :trainStockList="chosenTrain.stockList" />
|
|
||||||
<TrainSchedule :train="chosenTrain" />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Loading v-else-if="apiStore.dataStatuses.connection == Status.Data.Loading" />
|
<Loading v-else-if="apiStore.dataStatuses.connection == Status.Data.Loading" />
|
||||||
|
|
||||||
<div v-else class="driver-not-found">
|
<DriverNotFound v-else />
|
||||||
<h2>⦻ {{ $t('trains.driver-not-found-header') }}</h2>
|
|
||||||
|
|
||||||
<p class="text--grayed">
|
|
||||||
{{ $t('trains.driver-not-found-desc-1') }} <br />
|
|
||||||
{{ $t('trains.driver-not-found-desc-2') }}
|
|
||||||
<router-link to="/journal/timetables"
|
|
||||||
>{{ $t('trains.driver-not-found-journal') }} </router-link
|
|
||||||
>!
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p v-if="props.trainId && otherDriverTrains.length > 0">
|
|
||||||
<i18n-t keypath="trains.driver-not-found-others">
|
|
||||||
<template v-slot:driver>
|
|
||||||
<b>{{ otherDriverTrains[0].driverName }}</b>
|
|
||||||
</template>
|
|
||||||
</i18n-t>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div class="other-driver-trains">
|
|
||||||
<template v-for="(train, i) in otherDriverTrains">
|
|
||||||
<router-link :to="`/driver?trainId=${train.id}`">
|
|
||||||
{{ train.trainNo }}
|
|
||||||
| {{ regionsJSON.find((r) => r.id == train.region)?.name ?? 'PL1' }}
|
|
||||||
</router-link>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style="margin-top: 1em">
|
|
||||||
<router-link to="/"><< {{ $t('trains.driver-not-found-return') }}</router-link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
import TrainInfo from '../components/TrainsView/TrainInfo.vue';
|
|
||||||
import TrainSchedule from '../components/TrainsView/TrainSchedule.vue';
|
|
||||||
import StockList from '../components/Global/StockList.vue';
|
|
||||||
import Loading from '../components/Global/Loading.vue';
|
import Loading from '../components/Global/Loading.vue';
|
||||||
import { useMainStore } from '../store/mainStore';
|
import { useMainStore } from '../store/mainStore';
|
||||||
import { useApiStore } from '../store/apiStore';
|
import { useApiStore } from '../store/apiStore';
|
||||||
import { Status } from '../typings/common';
|
import { Status } from '../typings/common';
|
||||||
import { regions as regionsJSON } from '../data/options.json';
|
|
||||||
import { useI18n } from 'vue-i18n';
|
import DriverTopActions from '../components/DriverView/DriverTopActions.vue';
|
||||||
|
import DriverTrainCard from '../components/DriverView/DriverTrainCard.vue';
|
||||||
|
import DriverNotFound from '../components/DriverView/DriverNotFound.vue';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
trainId: {
|
trainId: {
|
||||||
@@ -113,106 +37,16 @@ const props = defineProps({
|
|||||||
const mainStore = useMainStore();
|
const mainStore = useMainStore();
|
||||||
const apiStore = useApiStore();
|
const apiStore = useApiStore();
|
||||||
|
|
||||||
const i18n = useI18n();
|
|
||||||
|
|
||||||
const chosenTrain = computed(() =>
|
const chosenTrain = computed(() =>
|
||||||
mainStore.trainList.find((train) => train.id == props.trainId || train.modalId == props.modalId)
|
mainStore.trainList.find((train) => train.id == props.trainId || train.modalId == props.modalId)
|
||||||
);
|
);
|
||||||
|
|
||||||
const otherDriverTrains = computed(() => {
|
|
||||||
return mainStore.trainList.filter(
|
|
||||||
(train) =>
|
|
||||||
train.driverId == Number(props.trainId?.split('|')[0]) &&
|
|
||||||
(train.timetableData || train.online || train.lastSeen >= Date.now() - 60000)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
function copyStockToClipboard() {
|
|
||||||
const stockString = chosenTrain.value?.stockList.join(';');
|
|
||||||
|
|
||||||
if (!stockString) {
|
|
||||||
alert(i18n.t('trains.stock-clipboard-failure'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
navigator.clipboard
|
|
||||||
.writeText(stockString)
|
|
||||||
.then(() => {
|
|
||||||
prompt(i18n.t('trains.stock-clipboard-success'), stockString);
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
alert(i18n.t('trains.stock-clipboard-failure'));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@use '../styles/responsive';
|
|
||||||
@use 'sass:color';
|
|
||||||
|
|
||||||
$viewBgCol: #1a1a1a;
|
|
||||||
|
|
||||||
.driver-view {
|
.driver-view {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 1em 0;
|
padding: 1em 0;
|
||||||
max-width: var(--max-container-width);
|
max-width: var(--max-container-width);
|
||||||
min-height: calc(100vh - 7em);
|
min-height: calc(100vh - 7em);
|
||||||
}
|
}
|
||||||
|
|
||||||
.actions-container {
|
|
||||||
display: flex;
|
|
||||||
align-items: flex-end;
|
|
||||||
justify-content: space-between;
|
|
||||||
gap: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.actions {
|
|
||||||
display: flex;
|
|
||||||
gap: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.actions-container > .actions > a {
|
|
||||||
background-color: $viewBgCol;
|
|
||||||
padding: 0.5em;
|
|
||||||
border-radius: 0.5em 0.5em 0 0;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: color.adjust($viewBgCol, $lightness: 10%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.train-card {
|
|
||||||
padding: 1em;
|
|
||||||
background-color: $viewBgCol;
|
|
||||||
border-radius: 0 0 0.5em 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.driver-not-found {
|
|
||||||
background-color: $viewBgCol;
|
|
||||||
text-align: center;
|
|
||||||
padding: 1em;
|
|
||||||
border-radius: 0.5em 0.5em;
|
|
||||||
|
|
||||||
p {
|
|
||||||
padding: 0.5em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
text-decoration: underline;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.other-driver-trains {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include responsive.smallScreen{
|
|
||||||
span.hidable {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user