mirror of
https://github.com/Spythere/stacjownik.git
synced 2026-05-03 05:18:11 +00:00
Zamiana karty stacji na zakładkę stacji [W.I.P.]
This commit is contained in:
@@ -0,0 +1,3 @@
|
|||||||
|
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M15 15C13.625 15 12.5 13.875 12.5 12.5C12.5 11.125 13.625 10 15 10C16.375 10 17.5 11.125 17.5 12.5C17.5 13.875 16.375 15 15 15ZM22.5 12.75C22.5 8.2125 19.1875 5 15 5C10.8125 5 7.5 8.2125 7.5 12.75C7.5 15.675 9.9375 19.55 15 24.175C20.0625 19.55 22.5 15.675 22.5 12.75ZM15 2.5C20.25 2.5 25 6.525 25 12.75C25 16.9 21.6625 21.8125 15 27.5C8.3375 21.8125 5 16.9 5 12.75C5 6.525 9.75 2.5 15 2.5Z" fill="white"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 519 B |
@@ -0,0 +1,3 @@
|
|||||||
|
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M23.75 3.75H22.5V1.25H20V3.75H10V1.25H7.5V3.75H6.25C4.875 3.75 3.75 4.875 3.75 6.25V23.75C3.75 25.125 4.875 26.25 6.25 26.25H23.75C25.125 26.25 26.25 25.125 26.25 23.75V6.25C26.25 4.875 25.125 3.75 23.75 3.75ZM23.75 23.75H6.25V11.25H23.75V23.75ZM6.25 8.75V6.25H23.75V8.75H6.25ZM8.75 13.75H21.25V16.25H8.75V13.75ZM8.75 18.75H17.5V21.25H8.75V18.75Z" fill="white"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 475 B |
@@ -0,0 +1,3 @@
|
|||||||
|
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M15 15C17.7625 15 20 12.7625 20 10C20 7.2375 17.7625 5 15 5C12.2375 5 10 7.2375 10 10C10 12.7625 12.2375 15 15 15ZM15 17.5C11.6625 17.5 5 19.175 5 22.5V25H25V22.5C25 19.175 18.3375 17.5 15 17.5Z" fill="white"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 323 B |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="white" width="18px" height="18px"><path d="M0 0h24v24H0z" fill="none"/><path d="M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z"/></svg>
|
||||||
|
After Width: | Height: | Size: 285 B |
@@ -7,19 +7,17 @@
|
|||||||
alt="schedule-icon"
|
alt="schedule-icon"
|
||||||
@click="() => (cardMode = cardMode == 0 ? 1 : 0)"
|
@click="() => (cardMode = cardMode == 0 ? 1 : 0)"
|
||||||
/>
|
/>
|
||||||
<img
|
<img :src="require('@/assets/icon-exit.svg')" alt="exit-icon" @click="exit" />
|
||||||
:src="require('@/assets/icon-exit.svg')"
|
|
||||||
alt="exit-icon"
|
|
||||||
@click="exit"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-content" :class="{ offline: !stationInfo.online }">
|
<div class="card-content" :class="{ offline: !stationInfo.online }">
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<div class="main-content">
|
<div class="main-content">
|
||||||
<span class="main-level flex" v-if="stationInfo.reqLevel > -1">{{
|
<span class="main-level flex" v-if="stationInfo.reqLevel > -1">
|
||||||
|
{{
|
||||||
2 > parseInt(stationInfo.reqLevel) ? "L" : stationInfo.reqLevel
|
2 > parseInt(stationInfo.reqLevel) ? "L" : stationInfo.reqLevel
|
||||||
}}</span>
|
}}
|
||||||
|
</span>
|
||||||
<span class="main-general">
|
<span class="main-general">
|
||||||
<div class="main-name">
|
<div class="main-name">
|
||||||
<a
|
<a
|
||||||
@@ -27,8 +25,7 @@
|
|||||||
:href="stationInfo.stationURL"
|
:href="stationInfo.stationURL"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
>{{ stationInfo.stationName }}</a
|
>{{ stationInfo.stationName }}</a>
|
||||||
>
|
|
||||||
|
|
||||||
<span v-else>{{ stationInfo.stationName }}</span>
|
<span v-else>{{ stationInfo.stationName }}</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -90,9 +87,7 @@
|
|||||||
stationInfo.dispatcherIsSupporter
|
stationInfo.dispatcherIsSupporter
|
||||||
)
|
)
|
||||||
"
|
"
|
||||||
>
|
>{{ stationInfo.online ? computedDispatcherExp : "" }}</div>
|
||||||
{{ stationInfo.online ? computedDispatcherExp : "" }}
|
|
||||||
</div>
|
|
||||||
<div class="dispatcher-info">
|
<div class="dispatcher-info">
|
||||||
<div class="dispatcher-name">
|
<div class="dispatcher-name">
|
||||||
<a
|
<a
|
||||||
@@ -101,8 +96,7 @@
|
|||||||
"
|
"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
>{{ stationInfo.dispatcherName || "---" }}</a
|
>{{ stationInfo.dispatcherName || "---" }}</a>
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="dispatcher-rate">
|
<div class="dispatcher-rate">
|
||||||
@@ -114,9 +108,11 @@
|
|||||||
|
|
||||||
<div class="hours">
|
<div class="hours">
|
||||||
<div class="hours-title title">STATUS</div>
|
<div class="hours-title title">STATUS</div>
|
||||||
<span class="status" :class="statusClasses(stationInfo.occupiedTo)">{{
|
<span class="status" :class="statusClasses(stationInfo.occupiedTo)">
|
||||||
|
{{
|
||||||
stationInfo.occupiedTo
|
stationInfo.occupiedTo
|
||||||
}}</span>
|
}}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="spawns flex flex-column">
|
<div class="spawns flex flex-column">
|
||||||
@@ -126,8 +122,7 @@
|
|||||||
class="spawn"
|
class="spawn"
|
||||||
v-for="(spawn, i) in stationInfo.spawnString"
|
v-for="(spawn, i) in stationInfo.spawnString"
|
||||||
:key="spawn + stationInfo.dispatcherName + i"
|
:key="spawn + stationInfo.dispatcherName + i"
|
||||||
>{{ spawn }}</span
|
>{{ spawn }}</span>
|
||||||
>
|
|
||||||
|
|
||||||
<span class="spawn" v-if="!stationInfo.spawnString">BRAK</span>
|
<span class="spawn" v-if="!stationInfo.spawnString">BRAK</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -160,8 +155,7 @@
|
|||||||
!stationInfo.stationTrains ||
|
!stationInfo.stationTrains ||
|
||||||
stationInfo.stationTrains.length == 0
|
stationInfo.stationTrains.length == 0
|
||||||
"
|
"
|
||||||
>BRAK</span
|
>BRAK</span>
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,11 +4,7 @@
|
|||||||
<table class="table">
|
<table class="table">
|
||||||
<thead class="table-head">
|
<thead class="table-head">
|
||||||
<tr>
|
<tr>
|
||||||
<th
|
<th v-for="(head, i) in headTitles" :key="i" @click="() => changeSorter(i)">
|
||||||
v-for="(head, i) in headTitles"
|
|
||||||
:key="i"
|
|
||||||
@click="() => changeSorter(i)"
|
|
||||||
>
|
|
||||||
<span>
|
<span>
|
||||||
<div>
|
<div>
|
||||||
<div>{{ head[0] }}</div>
|
<div>{{ head[0] }}</div>
|
||||||
@@ -30,11 +26,7 @@
|
|||||||
class="table-item"
|
class="table-item"
|
||||||
v-for="(station, i) in stations"
|
v-for="(station, i) in stations"
|
||||||
:key="i + station.stationHash"
|
:key="i + station.stationHash"
|
||||||
@click="
|
@click="setScenery(station.stationHash)"
|
||||||
() => {
|
|
||||||
setFocusedStation(station.stationName);
|
|
||||||
}
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
<td
|
<td
|
||||||
class="item-station-name"
|
class="item-station-name"
|
||||||
@@ -43,49 +35,43 @@
|
|||||||
online: station.online,
|
online: station.online,
|
||||||
'station-unavailable': station.unavailable,
|
'station-unavailable': station.unavailable,
|
||||||
}"
|
}"
|
||||||
>
|
>{{ station.stationName }}</td>
|
||||||
{{ station.stationName }}
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="item-station-level">
|
<td class="item-station-level">
|
||||||
<span
|
<span v-if="station.reqLevel" :style="calculateExpStyle(station.reqLevel)">
|
||||||
v-if="station.reqLevel"
|
{{
|
||||||
:style="calculateExpStyle(station.reqLevel)"
|
station.reqLevel && station.reqLevel > -1
|
||||||
>{{
|
? parseInt(station.reqLevel) >= 2
|
||||||
station.reqLevel && station.reqLevel > -1
|
? station.reqLevel
|
||||||
? parseInt(station.reqLevel) >= 2
|
: "L"
|
||||||
? station.reqLevel
|
: "?"
|
||||||
: "L"
|
}}
|
||||||
: "?"
|
</span>
|
||||||
}}</span
|
|
||||||
>
|
|
||||||
|
|
||||||
<span v-else>?</span>
|
<span v-else>?</span>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td class="item-station-status">
|
<td class="item-station-status">
|
||||||
<span class="status" :class="statusClasses(station.occupiedTo)">{{
|
<span class="status" :class="statusClasses(station.occupiedTo)">
|
||||||
|
{{
|
||||||
station.occupiedTo
|
station.occupiedTo
|
||||||
}}</span>
|
}}
|
||||||
|
</span>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td class="item-dispatcher-name">
|
<td class="item-dispatcher-name">{{ station.online ? station.dispatcherName : "" }}</td>
|
||||||
{{ station.online ? station.dispatcherName : "" }}
|
|
||||||
</td>
|
|
||||||
<td class="item-dispatcher-exp">
|
<td class="item-dispatcher-exp">
|
||||||
<span
|
<span v-if="station.online" :style="calculateExpStyle(station.dispatcherExp)">
|
||||||
v-if="station.online"
|
{{
|
||||||
:style="calculateExpStyle(station.dispatcherExp)"
|
2 > station.dispatcherExp ? "L" : station.dispatcherExp
|
||||||
>{{
|
}}
|
||||||
2 > station.dispatcherExp ? "L" : station.dispatcherExp
|
</span>
|
||||||
}}</span
|
|
||||||
>
|
|
||||||
</td>
|
</td>
|
||||||
<td class="item-users">
|
<td class="item-users">
|
||||||
{{
|
{{
|
||||||
station.online
|
station.online
|
||||||
? station.currentUsers + "/" + station.maxUsers
|
? station.currentUsers + "/" + station.maxUsers
|
||||||
: ""
|
: ""
|
||||||
}}
|
}}
|
||||||
</td>
|
</td>
|
||||||
<td class="item-info">
|
<td class="item-info">
|
||||||
@@ -130,8 +116,7 @@
|
|||||||
'Liczba zelektryfikowanych szlaków dwutorowych: ' +
|
'Liczba zelektryfikowanych szlaków dwutorowych: ' +
|
||||||
station.routes.twoWay.catenary
|
station.routes.twoWay.catenary
|
||||||
"
|
"
|
||||||
>{{ station.routes.twoWay.catenary }}</span
|
>{{ station.routes.twoWay.catenary }}</span>
|
||||||
>
|
|
||||||
|
|
||||||
<span
|
<span
|
||||||
v-if="station.routes && station.routes.twoWay.noCatenary > 0"
|
v-if="station.routes && station.routes.twoWay.noCatenary > 0"
|
||||||
@@ -140,8 +125,7 @@
|
|||||||
'Liczba niezelektryfikowanych szlaków dwutorowych: ' +
|
'Liczba niezelektryfikowanych szlaków dwutorowych: ' +
|
||||||
station.routes.twoWay.noCatenary
|
station.routes.twoWay.noCatenary
|
||||||
"
|
"
|
||||||
>{{ station.routes.twoWay.noCatenary }}</span
|
>{{ station.routes.twoWay.noCatenary }}</span>
|
||||||
>
|
|
||||||
|
|
||||||
<span class="separator"></span>
|
<span class="separator"></span>
|
||||||
|
|
||||||
@@ -152,8 +136,7 @@
|
|||||||
'Liczba zelektryfikowanych szlaków jednotorowych: ' +
|
'Liczba zelektryfikowanych szlaków jednotorowych: ' +
|
||||||
station.routes.oneWay.catenary
|
station.routes.oneWay.catenary
|
||||||
"
|
"
|
||||||
>{{ station.routes.oneWay.catenary }}</span
|
>{{ station.routes.oneWay.catenary }}</span>
|
||||||
>
|
|
||||||
|
|
||||||
<span
|
<span
|
||||||
v-if="station.routes && station.routes.oneWay.noCatenary > 0"
|
v-if="station.routes && station.routes.oneWay.noCatenary > 0"
|
||||||
@@ -162,23 +145,26 @@
|
|||||||
'Liczba niezelektryfikowanych szlaków jednotorowych: ' +
|
'Liczba niezelektryfikowanych szlaków jednotorowych: ' +
|
||||||
station.routes.oneWay.noCatenary
|
station.routes.oneWay.noCatenary
|
||||||
"
|
"
|
||||||
>{{ station.routes.oneWay.noCatenary }}</span
|
>{{ station.routes.oneWay.noCatenary }}</span>
|
||||||
>
|
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td class="active-timetables">
|
<td class="active-timetables">
|
||||||
<transition name="change-anim" mode="out-in">
|
<transition name="change-anim" mode="out-in">
|
||||||
<span :key="station.scheduledTrains.length">
|
<span :key="station.scheduledTrains.length">
|
||||||
<span v-if="station.scheduledTrains">
|
<span v-if="station.scheduledTrains">
|
||||||
<span style="color: #eee">{{
|
<span style="color: #eee">
|
||||||
|
{{
|
||||||
station.scheduledTrains.length
|
station.scheduledTrains.length
|
||||||
}}</span>
|
}}
|
||||||
|
</span>
|
||||||
/
|
/
|
||||||
<span style="color: #bbb">{{
|
<span style="color: #bbb">
|
||||||
|
{{
|
||||||
station.scheduledTrains.filter(
|
station.scheduledTrains.filter(
|
||||||
(train) => train.stopInfo.confirmed
|
(train) => train.stopInfo.confirmed
|
||||||
).length
|
).length
|
||||||
}}</span>
|
}}
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span v-else>...</span>
|
<span v-else>...</span>
|
||||||
@@ -188,9 +174,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div class="no-stations" v-if="stations.length == 0">
|
<div class="no-stations" v-if="stations.length == 0">Ups! Brak stacji do wyświetlenia!</div>
|
||||||
Ups! Brak stacji do wyświetlenia!
|
|
||||||
</div>
|
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -217,6 +201,10 @@ export default class StationTable extends styleMixin {
|
|||||||
@Prop() readonly setFocusedStation!: () => void;
|
@Prop() readonly setFocusedStation!: () => void;
|
||||||
@Prop() readonly changeSorter!: () => void;
|
@Prop() readonly changeSorter!: () => void;
|
||||||
|
|
||||||
|
setScenery(sceneryHash: string) {
|
||||||
|
this.$router.push({ name: "SceneryView", query: { hash: sceneryHash } })
|
||||||
|
}
|
||||||
|
|
||||||
icons: { ascSVG; descSVG } = { ascSVG, descSVG };
|
icons: { ascSVG; descSVG } = { ascSVG, descSVG };
|
||||||
|
|
||||||
headTitles: string[][] = [
|
headTitles: string[][] = [
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
},
|
},
|
||||||
"default": false,
|
"default": false,
|
||||||
"nonPublic": false,
|
"nonPublic": false,
|
||||||
"stops": ["Borowe, podg.", "Wysoka, podg.", "Naprawa, podg."]
|
"stops": ["Borowe, podg.", "Wysoka, podg.", "Naprawa, podg.", "Borowe Towarowe"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"stationName": "LCS Gdańsk",
|
"stationName": "LCS Gdańsk",
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import VueRouter, { RouteConfig } from 'vue-router';
|
|||||||
import StationsView from '../views/StationsView.vue';
|
import StationsView from '../views/StationsView.vue';
|
||||||
import TrainsView from '../views/TrainsView.vue';
|
import TrainsView from '../views/TrainsView.vue';
|
||||||
import TimetableView from '../views/TimetableView.vue';
|
import TimetableView from '../views/TimetableView.vue';
|
||||||
|
import SceneryView from '../views/SceneryView.vue';
|
||||||
|
|
||||||
Vue.use(VueRouter);
|
Vue.use(VueRouter);
|
||||||
|
|
||||||
@@ -24,6 +25,12 @@ const routes: Array<RouteConfig> = [
|
|||||||
name: 'TimetableView',
|
name: 'TimetableView',
|
||||||
component: TimetableView,
|
component: TimetableView,
|
||||||
props: true
|
props: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/scenery',
|
||||||
|
name: "SceneryView",
|
||||||
|
component: SceneryView,
|
||||||
|
props: true
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import TrainStop from "./TrainStop";
|
||||||
|
|
||||||
|
export default interface ScheduledTrain {
|
||||||
|
trainNo: number;
|
||||||
|
driverName: string;
|
||||||
|
driverId: number;
|
||||||
|
currentStationName: string;
|
||||||
|
currentStationHash: string;
|
||||||
|
category: string;
|
||||||
|
stopInfo: TrainStop;
|
||||||
|
|
||||||
|
terminatesAt: string;
|
||||||
|
beginsAt: string;
|
||||||
|
nearestStop: string;
|
||||||
|
|
||||||
|
stopLabel: string;
|
||||||
|
stopStatus: string;
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import Train from '@/scripts/interfaces/Train';
|
import Train from './Train';
|
||||||
import TrainStop from '@/scripts/interfaces/TrainStop';
|
import ScheduledTrain from './ScheduledTrain';
|
||||||
|
|
||||||
export default interface Station {
|
export default interface Station {
|
||||||
stationName: string;
|
stationName: string;
|
||||||
@@ -24,24 +24,12 @@ export default interface Station {
|
|||||||
oneWay: { catenary: number; noCatenary: number };
|
oneWay: { catenary: number; noCatenary: number };
|
||||||
twoWay: { catenary: number; noCatenary: number };
|
twoWay: { catenary: number; noCatenary: number };
|
||||||
};
|
};
|
||||||
|
subStations: {
|
||||||
|
scheduledTrains: ScheduledTrain[],
|
||||||
|
}[];
|
||||||
online: boolean;
|
online: boolean;
|
||||||
occupiedTo: string;
|
occupiedTo: string;
|
||||||
statusTimestamp: number;
|
statusTimestamp: number;
|
||||||
stationTrains: Train[];
|
stationTrains: Train[];
|
||||||
scheduledTrains: {
|
scheduledTrains: ScheduledTrain[];
|
||||||
trainNo: number;
|
|
||||||
driverName: string;
|
|
||||||
driverId: number;
|
|
||||||
currentStationName: string;
|
|
||||||
currentStationHash: string;
|
|
||||||
category: string;
|
|
||||||
stopInfo: TrainStop;
|
|
||||||
|
|
||||||
terminatesAt: string;
|
|
||||||
beginsAt: string;
|
|
||||||
nearestStop: string;
|
|
||||||
|
|
||||||
stopLabel: string;
|
|
||||||
stopStatus: string;
|
|
||||||
}[];
|
|
||||||
}
|
}
|
||||||
|
|||||||
+38
-7
@@ -13,6 +13,21 @@ enum Status {
|
|||||||
Loaded = 2,
|
Loaded = 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface TimetableData {
|
||||||
|
trainNo: number;
|
||||||
|
driverName: string;
|
||||||
|
driverId: number;
|
||||||
|
currentStationName: string;
|
||||||
|
currentStationHash: string;
|
||||||
|
timetableId: number;
|
||||||
|
category: string;
|
||||||
|
route: string;
|
||||||
|
TWR: boolean;
|
||||||
|
SKR: boolean;
|
||||||
|
routeDistance: number;
|
||||||
|
followingStops: TrainStop[];
|
||||||
|
}
|
||||||
|
|
||||||
const URLs = {
|
const URLs = {
|
||||||
stations: 'https://api.td2.info.pl:9640/?method=getStationsOnline',
|
stations: 'https://api.td2.info.pl:9640/?method=getStationsOnline',
|
||||||
trains: 'https://api.td2.info.pl:9640/?method=getTrainsOnline',
|
trains: 'https://api.td2.info.pl:9640/?method=getTrainsOnline',
|
||||||
@@ -96,6 +111,7 @@ export default class Store extends VuexModule {
|
|||||||
// private dataConnectionStatus: Status = Status.Loading;
|
// private dataConnectionStatus: Status = Status.Loading;
|
||||||
|
|
||||||
private dataConnectionStatus: Status = Status.Loading;
|
private dataConnectionStatus: Status = Status.Loading;
|
||||||
|
private timetableLoaded: Status = Status.Loading;
|
||||||
|
|
||||||
private stationList: Station[] = [];
|
private stationList: Station[] = [];
|
||||||
private trainList: Train[] = [];
|
private trainList: Train[] = [];
|
||||||
@@ -119,6 +135,14 @@ export default class Store extends VuexModule {
|
|||||||
return this.trainList;
|
return this.trainList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get getTimetableDataStatus() {
|
||||||
|
return this.timetableLoaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
get getDataStatus() {
|
||||||
|
return this.dataConnectionStatus;
|
||||||
|
}
|
||||||
|
|
||||||
//ACTIONS
|
//ACTIONS
|
||||||
@Action
|
@Action
|
||||||
async synchronizeData() {
|
async synchronizeData() {
|
||||||
@@ -135,10 +159,9 @@ export default class Store extends VuexModule {
|
|||||||
const timetable = await (await axios.get(timetableURL(train.trainNo))).data.message;
|
const timetable = await (await axios.get(timetableURL(train.trainNo))).data.message;
|
||||||
const trainInfo = timetable.trainInfo;
|
const trainInfo = timetable.trainInfo;
|
||||||
|
|
||||||
let timetableData;
|
|
||||||
|
|
||||||
if (timetable && trainInfo) {
|
if (timetable && trainInfo) {
|
||||||
timetableData = {};
|
let timetableData!: TimetableData;
|
||||||
|
|
||||||
const followingStops: TrainStop[] = timetable.stopPoints.reduce((acc: TrainStop[], point) => {
|
const followingStops: TrainStop[] = timetable.stopPoints.reduce((acc: TrainStop[], point) => {
|
||||||
const arrivalTimestamp = getTimestamp(point.arrivalTime);
|
const arrivalTimestamp = getTimestamp(point.arrivalTime);
|
||||||
@@ -192,9 +215,11 @@ export default class Store extends VuexModule {
|
|||||||
routeDistance: timetable.stopPoints[timetable.stopPoints.length - 1].pointDistance,
|
routeDistance: timetable.stopPoints[timetable.stopPoints.length - 1].pointDistance,
|
||||||
followingStops,
|
followingStops,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return timetableData;
|
||||||
}
|
}
|
||||||
|
|
||||||
return timetableData;
|
return null;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -295,6 +320,7 @@ export default class Store extends VuexModule {
|
|||||||
statusTimestamp: -3,
|
statusTimestamp: -3,
|
||||||
stationTrains: [],
|
stationTrains: [],
|
||||||
scheduledTrains: [],
|
scheduledTrains: [],
|
||||||
|
subStations: [],
|
||||||
...stationData,
|
...stationData,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@@ -303,15 +329,17 @@ export default class Store extends VuexModule {
|
|||||||
private updateOnlineStations(updatedStationList: any[]) {
|
private updateOnlineStations(updatedStationList: any[]) {
|
||||||
this.stationList = this.stationList.reduce((acc, station) => {
|
this.stationList = this.stationList.reduce((acc, station) => {
|
||||||
const onlineStationData = updatedStationList.find(updatedStation => updatedStation.stationName === station.stationName);
|
const onlineStationData = updatedStationList.find(updatedStation => updatedStation.stationName === station.stationName);
|
||||||
const isRegistered = JSONStationData.some(data => data.stationName === station.stationName);
|
const registeredStation = JSONStationData.find(data => data.stationName === station.stationName);
|
||||||
|
const subStations = registeredStation?.stops && registeredStation.stops;
|
||||||
|
|
||||||
if (onlineStationData)
|
if (onlineStationData)
|
||||||
acc.push({
|
acc.push({
|
||||||
...station,
|
...station,
|
||||||
...onlineStationData,
|
...onlineStationData,
|
||||||
|
subStations,
|
||||||
online: true,
|
online: true,
|
||||||
});
|
});
|
||||||
else if (isRegistered)
|
else if (registeredStation)
|
||||||
acc.push({
|
acc.push({
|
||||||
...station,
|
...station,
|
||||||
stationProject: '',
|
stationProject: '',
|
||||||
@@ -329,6 +357,7 @@ export default class Store extends VuexModule {
|
|||||||
statusTimestamp: -3,
|
statusTimestamp: -3,
|
||||||
stationTrains: [],
|
stationTrains: [],
|
||||||
scheduledTrains: [],
|
scheduledTrains: [],
|
||||||
|
subStations: []
|
||||||
});
|
});
|
||||||
|
|
||||||
return acc;
|
return acc;
|
||||||
@@ -370,7 +399,7 @@ export default class Store extends VuexModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Mutation
|
@Mutation
|
||||||
private updateTimetableData(timetableList: any[]) {
|
private updateTimetableData(timetableList: TimetableData[]) {
|
||||||
this.stationList = this.stationList.map(station => {
|
this.stationList = this.stationList.map(station => {
|
||||||
const scheduledTrains: Station['scheduledTrains'] = timetableList.reduce((acc: Station['scheduledTrains'], timetableData: any, index) => {
|
const scheduledTrains: Station['scheduledTrains'] = timetableList.reduce((acc: Station['scheduledTrains'], timetableData: any, index) => {
|
||||||
const scheduledIndex = timetableData
|
const scheduledIndex = timetableData
|
||||||
@@ -447,5 +476,7 @@ export default class Store extends VuexModule {
|
|||||||
|
|
||||||
return acc;
|
return acc;
|
||||||
}, [] as Train[]);
|
}, [] as Train[]);
|
||||||
|
|
||||||
|
this.timetableLoaded = Status.Loaded;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ $secondaryCol: #01e733;
|
|||||||
$bgCol: #505050;
|
$bgCol: #505050;
|
||||||
|
|
||||||
$errorCol: #ff1919;
|
$errorCol: #ff1919;
|
||||||
$warningCol: #ff975b;
|
$warningCol: #ffe15b;
|
||||||
|
|
||||||
$accentCol: #ffc014;
|
$accentCol: #ffc014;
|
||||||
$accent2Col: #ff3d5d;
|
$accent2Col: #ff3d5d;
|
||||||
|
|||||||
@@ -0,0 +1,678 @@
|
|||||||
|
<template>
|
||||||
|
<div class="scenery-view">
|
||||||
|
<div class="scenery-offline" v-if="!stationInfo && dataStatus == 2">
|
||||||
|
Ups! Nie znaleziono danej stacji bądź jest ona offline!
|
||||||
|
<button class="button">
|
||||||
|
<a href="https://stacjownik-td2.web.app">Wróć na stronę główną</a>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="scenery-wrapper" v-if="stationInfo">
|
||||||
|
<div class="scenery-header">
|
||||||
|
<div class="station-name">{{ stationInfo.stationName }}</div>
|
||||||
|
<div class="station-hash">#{{ stationInfo.stationHash }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<section v-if="!timetableOnly">
|
||||||
|
<div class="scenery-stats">
|
||||||
|
<span class="likes">
|
||||||
|
<img :src="likeIcon" alt="icon-like" />
|
||||||
|
<span>{{ stationInfo.dispatcherRate }}</span>
|
||||||
|
</span>
|
||||||
|
<span class="users">
|
||||||
|
<img :src="userIcon" alt="icon-user" />
|
||||||
|
<span>{{ stationInfo.currentUsers }}</span>
|
||||||
|
/
|
||||||
|
<span>{{ stationInfo.maxUsers }}</span>
|
||||||
|
</span>
|
||||||
|
<span class="spawns">
|
||||||
|
<img :src="spawnIcon" alt="icon-spawn" />
|
||||||
|
<span>{{ stationInfo.spawnString.length }}</span>
|
||||||
|
</span>
|
||||||
|
<span class="schedules">
|
||||||
|
<img :src="timetableIcon" alt="icon-timetable" />
|
||||||
|
<span v-if="stationInfo.scheduledTrains">
|
||||||
|
<span style="color: #eee">{{stationInfo.scheduledTrains.length}}</span>
|
||||||
|
/
|
||||||
|
<span
|
||||||
|
style="color: #bbb"
|
||||||
|
>{{ stationInfo.scheduledTrains.filter(train => train.stopInfo.confirmed).length }}</span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="scenery-brief">
|
||||||
|
<img
|
||||||
|
v-if="stationInfo.controlType"
|
||||||
|
:src="require(`@/assets/icon-${stationInfo.controlType}.svg`)"
|
||||||
|
:alt="stationInfo.controlType"
|
||||||
|
:title="'Sterowanie ' + stationInfo.controlType"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<img
|
||||||
|
v-if="stationInfo.signalType"
|
||||||
|
:src="require(`@/assets/icon-${stationInfo.signalType}.svg`)"
|
||||||
|
:alt="stationInfo.signalType"
|
||||||
|
:title="'Sygnalizacja ' + stationInfo.signalType"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<img
|
||||||
|
v-if="stationInfo.SBL && stationInfo.SBL !== ''"
|
||||||
|
:src="require(`@/assets/icon-SBL.svg`)"
|
||||||
|
alt="SBL"
|
||||||
|
title="Sceneria posiada SBL na przynajmniej jednym ze szlaków"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<img
|
||||||
|
v-if="stationInfo.default"
|
||||||
|
:src="require(`@/assets/icon-td2.svg`)"
|
||||||
|
alt="default-pack"
|
||||||
|
title="Sceneria domyślnie dostępna w grze"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<img
|
||||||
|
v-if="stationInfo.nonPublic || !stationInfo.reqLevel"
|
||||||
|
:src="require(`@/assets/icon-lock.svg`)"
|
||||||
|
alt="non-public"
|
||||||
|
title="Sceneria niepubliczna"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<img
|
||||||
|
v-if="stationInfo.unavailable"
|
||||||
|
:src="require(`@/assets/icon-unavailable.svg`)"
|
||||||
|
alt="icon-unavailable"
|
||||||
|
title="Sceneria niedostępna"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="scenery-dispatcher">
|
||||||
|
<div>
|
||||||
|
<span
|
||||||
|
class="level"
|
||||||
|
:style="calculateExpStyle(stationInfo.dispatcherExp, stationInfo.dispatcherIsSupporter)"
|
||||||
|
>{{ stationInfo.dispatcherExp > 1 ? stationInfo.dispatcherExp : "L"}}</span>
|
||||||
|
|
||||||
|
<span class="name">{{ stationInfo.dispatcherName }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span
|
||||||
|
class="status"
|
||||||
|
:class="statusClasses(stationInfo.occupiedTo)"
|
||||||
|
>{{ stationInfo.occupiedTo }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="scenery-info">
|
||||||
|
<div class="user-list">
|
||||||
|
<h3 class="user-header">
|
||||||
|
GRACZE ONLINE
|
||||||
|
<img :src="userIcon" alt="icon-user" />
|
||||||
|
</h3>
|
||||||
|
<ul>
|
||||||
|
<li
|
||||||
|
class="user user-badge"
|
||||||
|
:class="train.stopStatus"
|
||||||
|
v-for="train in computedStationTrains"
|
||||||
|
:key="train.trainNo + train.driverName"
|
||||||
|
>
|
||||||
|
<router-link
|
||||||
|
:to="{
|
||||||
|
name: 'TrainsView',
|
||||||
|
params: { passedSearchedTrain: train.trainNo.toString() },
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<span>{{ train.trainNo }}</span>
|
||||||
|
|
|
||||||
|
<span>{{ train.driverName }}</span>
|
||||||
|
</router-link>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<span
|
||||||
|
class="user offline"
|
||||||
|
v-if="
|
||||||
|
!stationInfo.stationTrains ||
|
||||||
|
stationInfo.stationTrains.length == 0
|
||||||
|
"
|
||||||
|
>BRAK</span>
|
||||||
|
</div>
|
||||||
|
<div class="spawn-list">
|
||||||
|
<h3 class="spawn-header">
|
||||||
|
OTWARTE SPAWNY
|
||||||
|
<img :src="spawnIcon" alt="icon-spawn" />
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<span
|
||||||
|
class="spawn"
|
||||||
|
v-for="(spawn, i) in stationInfo.spawnString"
|
||||||
|
:key="spawn + stationInfo.dispatcherName + i"
|
||||||
|
>{{ spawn }}</span>
|
||||||
|
</div>
|
||||||
|
<span class="spawn" v-if="!stationInfo.spawnString">BRAK</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div class="scenery-timetables">
|
||||||
|
<h3 class="timetable-header">
|
||||||
|
<span>AKTYWNE ROZKŁADY JAZDY</span>
|
||||||
|
<a v-if="!timetableOnly" :href="currentURL + '&timetable_only=1'" target="_blank">
|
||||||
|
<img :src="viewIcon" alt="icon-view" title="Wyodrębnij rozkłady jazdy" />
|
||||||
|
</a>
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<span class="timetable-item loading" v-if="timetableDataStatus == 0">Ładowanie...</span>
|
||||||
|
|
||||||
|
<span
|
||||||
|
class="timetable-item empty"
|
||||||
|
v-else-if="computedScheduledTrains.length == 0"
|
||||||
|
>Brak aktywnych rozkładów!</span>
|
||||||
|
|
||||||
|
<div class="timetable-item" v-for="(scheduledTrain, i) in computedScheduledTrains" :key="i">
|
||||||
|
<span class="timetable-general">
|
||||||
|
<span class="general-info">
|
||||||
|
<router-link
|
||||||
|
:to="{
|
||||||
|
name: 'TrainsView',
|
||||||
|
params: {
|
||||||
|
passedSearchedTrain: scheduledTrain.trainNo.toString(),
|
||||||
|
},
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
<strong>{{ scheduledTrain.category }}</strong>
|
||||||
|
{{ scheduledTrain.trainNo }}
|
||||||
|
</span>
|
||||||
|
</router-link>|
|
||||||
|
<span>
|
||||||
|
<a
|
||||||
|
:href="
|
||||||
|
'https://td2.info.pl/profile/?u=' + scheduledTrain.driverId
|
||||||
|
"
|
||||||
|
target="_blank"
|
||||||
|
>{{ scheduledTrain.driverName }}</a>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<div class="info-route">
|
||||||
|
<strong>{{ scheduledTrain.beginsAt }} - {{ scheduledTrain.terminatesAt }}</strong>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span class="general-status">
|
||||||
|
<span :class="scheduledTrain.stopStatus">{{scheduledTrain.stopLabel}}</span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span class="timetable-schedule">
|
||||||
|
<span class="schedule-arrival">
|
||||||
|
<span class="arrival-time begins" v-if="scheduledTrain.stopInfo.beginsHere">
|
||||||
|
ROZPOCZYNA
|
||||||
|
<div>BIEG</div>
|
||||||
|
</span>
|
||||||
|
<span class="arrival-time" v-else>
|
||||||
|
{{ scheduledTrain.stopInfo.arrivalTimeString }} ({{
|
||||||
|
scheduledTrain.stopInfo.arrivalDelay
|
||||||
|
}})
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span class="schedule-stop">
|
||||||
|
<span class="stop-time" v-if="scheduledTrain.stopInfo.stopTime">
|
||||||
|
{{ scheduledTrain.stopInfo.stopTime }}
|
||||||
|
{{ scheduledTrain.stopInfo.stopType }}
|
||||||
|
</span>
|
||||||
|
<span class="stop-arrow arrow"></span>
|
||||||
|
</span>
|
||||||
|
<span class="schedule-departure">
|
||||||
|
<span
|
||||||
|
class="departure-time terminates"
|
||||||
|
v-if="scheduledTrain.stopInfo.terminatesHere"
|
||||||
|
>KOŃCZY BIEG</span>
|
||||||
|
<span class="departure-time" v-else>
|
||||||
|
{{ scheduledTrain.stopInfo.departureTimeString }} ({{
|
||||||
|
scheduledTrain.stopInfo.departureDelay
|
||||||
|
}})
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { Component, Prop, Watch } from "vue-property-decorator";
|
||||||
|
|
||||||
|
import { Getter } from "vuex-class";
|
||||||
|
|
||||||
|
import styleMixin from "@/mixins/styleMixin";
|
||||||
|
|
||||||
|
import Station from "@/scripts/interfaces/Station";
|
||||||
|
import Train from "@/scripts/interfaces/Train";
|
||||||
|
|
||||||
|
import StationTimetable from "@/components/StationsView/StationTimetable.vue";
|
||||||
|
|
||||||
|
|
||||||
|
@Component
|
||||||
|
export default class SceneryView extends styleMixin {
|
||||||
|
@Getter('getStationList') storeStationList!: Station[];
|
||||||
|
@Getter('getTimetableDataStatus') timetableDataStatus!: number;
|
||||||
|
@Getter('getDataStatus') dataStatus!: number;
|
||||||
|
|
||||||
|
likeIcon: string = require('@/assets/icon-like.svg');
|
||||||
|
spawnIcon: string = require("@/assets/icon-spawn.svg")
|
||||||
|
timetableIcon: string = require("@/assets/icon-timetable.svg")
|
||||||
|
userIcon: string = require("@/assets/icon-user.svg")
|
||||||
|
|
||||||
|
viewIcon: string = require("@/assets/icon-view.svg");
|
||||||
|
|
||||||
|
timetableOnly: boolean = false;
|
||||||
|
|
||||||
|
activated() {
|
||||||
|
this.timetableOnly = this.$route.query['timetable_only'] == "1" ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
get dataLoaded() {
|
||||||
|
return this.storeStationList ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
get currentURL() {
|
||||||
|
return `${location.origin}/scenery?hash=${this.stationInfo?.stationHash}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
get stationInfo(): Station | null {
|
||||||
|
if (!this.$route.query.hash || !this.storeStationList) return null;
|
||||||
|
|
||||||
|
return this.storeStationList.find(station => station.stationHash === this.$route.query.hash.toString()) || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
get computedDispatcherExp(): string {
|
||||||
|
if (!this.stationInfo) return "";
|
||||||
|
|
||||||
|
|
||||||
|
return this.stationInfo.dispatcherExp < 2
|
||||||
|
? "L"
|
||||||
|
: `${this.stationInfo.dispatcherExp}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
get computedStationTrains() {
|
||||||
|
if (!this.stationInfo) return null;
|
||||||
|
|
||||||
|
return this.stationInfo.stationTrains.map(stationTrain => {
|
||||||
|
const scheduledData = this.stationInfo?.scheduledTrains.find(scheduledTrain => scheduledTrain.trainNo === stationTrain.trainNo);
|
||||||
|
|
||||||
|
return {
|
||||||
|
...stationTrain,
|
||||||
|
stopStatus: scheduledData?.stopStatus || "no-timetable"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
get computedScheduledTrains() {
|
||||||
|
return this.stationInfo?.scheduledTrains.sort((a, b) => {
|
||||||
|
if (a.stopInfo.arrivalTimestamp > b.stopInfo.arrivalTimestamp) return 1;
|
||||||
|
else if ((a.stopInfo.arrivalTimestamp < b.stopInfo.arrivalTimestamp)) return -1;
|
||||||
|
|
||||||
|
return a.stopInfo.departureTimestamp > b.stopInfo.departureTimestamp ? 1 : -1;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "../styles/responsive.scss";
|
||||||
|
@import "../styles/variables.scss";
|
||||||
|
@import "../styles/user_badge.scss";
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
margin: 0.5em 0;
|
||||||
|
padding: 0.3em;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
font-size: 1.2em;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 1.1em;
|
||||||
|
margin-left: 0.5em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.scenery {
|
||||||
|
&-offline {
|
||||||
|
align-self: center;
|
||||||
|
font-size: 2em;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
color: $warningCol;
|
||||||
|
|
||||||
|
button {
|
||||||
|
margin: 1em auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-view {
|
||||||
|
min-height: 100%;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: flex-start;
|
||||||
|
|
||||||
|
font-size: calc(0.5rem + 0.65vw);
|
||||||
|
|
||||||
|
@include bigScreen() {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include smallScreen {
|
||||||
|
font-size: calc(0.5rem + 1vw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-wrapper {
|
||||||
|
// background: #555;
|
||||||
|
max-width: 950px;
|
||||||
|
width: 75%;
|
||||||
|
|
||||||
|
@include smallScreen {
|
||||||
|
width: 95%;
|
||||||
|
}
|
||||||
|
|
||||||
|
// max-height: 100vh;
|
||||||
|
// overflow: auto;
|
||||||
|
|
||||||
|
background: #333;
|
||||||
|
padding: 1em;
|
||||||
|
margin: 1rem 0;
|
||||||
|
|
||||||
|
border-radius: 1.5em;
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-header {
|
||||||
|
padding: 1rem;
|
||||||
|
|
||||||
|
& > .station-name {
|
||||||
|
font-size: 3em;
|
||||||
|
font-weight: bold;
|
||||||
|
color: $accentCol;
|
||||||
|
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > .station-hash {
|
||||||
|
font-size: 1em;
|
||||||
|
line-height: 0.8em;
|
||||||
|
color: #aaa;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-stats {
|
||||||
|
font-size: 1.3em;
|
||||||
|
padding: 1rem 0;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
& > span {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
margin: 0 0.6em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.likes,
|
||||||
|
.spawns {
|
||||||
|
color: $accentCol;
|
||||||
|
}
|
||||||
|
|
||||||
|
span > img {
|
||||||
|
width: 1.2em;
|
||||||
|
margin-right: 0.5em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-brief {
|
||||||
|
padding: 1rem 0;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 2.5em;
|
||||||
|
margin: 0 0.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-dispatcher {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.level {
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 0.3em;
|
||||||
|
background: firebrick;
|
||||||
|
|
||||||
|
border-radius: 0.1em;
|
||||||
|
|
||||||
|
width: 1.5em;
|
||||||
|
height: 1.5em;
|
||||||
|
line-height: 1.5em;
|
||||||
|
font-size: 2em;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name {
|
||||||
|
font-size: 1.6em;
|
||||||
|
margin-right: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status {
|
||||||
|
font-size: 1em;
|
||||||
|
border-radius: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-info {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
& > .user-list {
|
||||||
|
ul {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-timetables {
|
||||||
|
margin: 1em 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.user {
|
||||||
|
font-size: 0.85em;
|
||||||
|
|
||||||
|
@include smallScreen() {
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.spawn,
|
||||||
|
.user.offline {
|
||||||
|
padding: 0.3em 0.4em;
|
||||||
|
background: #585858;
|
||||||
|
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
|
||||||
|
font-size: 0.8em;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
@include smallScreen() {
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.timetable {
|
||||||
|
&-header {
|
||||||
|
a {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-item {
|
||||||
|
margin: 1em auto;
|
||||||
|
font-size: 0.8em;
|
||||||
|
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
|
||||||
|
|
||||||
|
padding: 0 0.5rem;
|
||||||
|
|
||||||
|
background: #555;
|
||||||
|
|
||||||
|
@include smallScreen() {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.loading,
|
||||||
|
&.empty {
|
||||||
|
padding: 1rem;
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.empty {
|
||||||
|
color: $accentCol;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-general {
|
||||||
|
padding: 0.5rem 0.3rem;
|
||||||
|
border-radius: 10px;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
text-align: left;
|
||||||
|
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
@include smallScreen() {
|
||||||
|
width: 95%;
|
||||||
|
font-size: 1.3em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-schedule {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(50px, 1fr));
|
||||||
|
font-size: 1.2em;
|
||||||
|
|
||||||
|
@include smallScreen() {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0.7em 0;
|
||||||
|
font-size: 1.8em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.arrow {
|
||||||
|
border: solid white;
|
||||||
|
border-width: 0 2px 2px 0;
|
||||||
|
display: inline-block;
|
||||||
|
padding: 2px;
|
||||||
|
margin-left: 50px;
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
transform: rotate(-45deg);
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
display: block;
|
||||||
|
width: 55px;
|
||||||
|
height: 3px;
|
||||||
|
top: 4px;
|
||||||
|
left: 4px;
|
||||||
|
|
||||||
|
transform: translate(-100%, -1px) rotate(45deg);
|
||||||
|
transform-origin: right bottom;
|
||||||
|
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.general-info {
|
||||||
|
span {
|
||||||
|
color: $accentCol;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-route {
|
||||||
|
margin-top: 0.5em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.general-status {
|
||||||
|
span.arriving {
|
||||||
|
color: #aaa;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.departed {
|
||||||
|
color: lime;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.stopped {
|
||||||
|
color: #ffa600;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.online {
|
||||||
|
color: gold;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.terminated {
|
||||||
|
color: red;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.schedule {
|
||||||
|
&-arrival,
|
||||||
|
&-stop,
|
||||||
|
&-departure {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
margin: 0 0.3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-stop {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
.stop-time {
|
||||||
|
font-size: 0.7em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.arrival-time.begins,
|
||||||
|
.departure-time.terminates {
|
||||||
|
font-size: 0.75em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user