Lekkie zmiany w wyglądzie strony

This commit is contained in:
2020-11-03 22:34:22 +01:00
parent 853dc8e7cf
commit fe3a15c452
11 changed files with 606 additions and 462 deletions
+2 -2
View File
@@ -6,8 +6,8 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" /> <meta name="viewport" content="width=device-width,initial-scale=1.0" />
<link rel="icon" href="<%= BASE_URL %>favicon.ico" /> <link rel="icon" href="<%= BASE_URL %>favicon.ico" />
<link href="https://fonts.googleapis.com/css2?family=Quicksand:wght@400;700&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Quicksand:wght@400;500;700&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600;700&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;60 0;700&display=swap" rel="stylesheet">
<title>Stacjownik</title> <title>Stacjownik</title>
</head> </head>
+13 -20
View File
@@ -13,16 +13,20 @@
<Clock /> <Clock />
<div class="counter"> <div class="counter">
<img src="@/assets/icon-dispatcher.svg" alt="icon dispatcher" /> <img src="@/assets/icon-dispatcher.svg" alt="icon dispatcher" />
<span>{{data.stationCount}}</span> <span>{{ data.stationCount }}</span>
<span>{{data.trainCount}}</span> <span>{{ data.trainCount }}</span>
<img src="@/assets/icon-train.svg" alt="icon train" /> <img src="@/assets/icon-train.svg" alt="icon train" />
</div> </div>
</span> </span>
<span class="header-links"> <span class="header-links">
<router-link class="route" active-class="route-active" to="/" exact>SCENERIE</router-link>/ <router-link class="route" active-class="route-active" to="/" exact
<router-link class="route" active-class="route-active" to="/trains">POCIĄGI</router-link> >SCENERIE</router-link
>/
<router-link class="route" active-class="route-active" to="/trains"
>POCIĄGI</router-link
>
</span> </span>
</div> </div>
</header> </header>
@@ -41,7 +45,9 @@
<transition name="message-anim" mode="out-in"> <transition name="message-anim" mode="out-in">
<span :key="data.dataConnectionStatus"> <span :key="data.dataConnectionStatus">
<div class="message loading" v-if="data.dataConnectionStatus == 0">Pobieranie danych...</div> <div class="message loading" v-if="data.dataConnectionStatus == 0">
Pobieranie danych...
</div>
<div class="message error" v-if="data.dataConnectionStatus == 1"> <div class="message error" v-if="data.dataConnectionStatus == 1">
<img :src="ErrorIcon" alt="Error" /> <img :src="ErrorIcon" alt="Error" />
@@ -68,24 +74,10 @@ export default class App extends Vue {
ErrorIcon = require("@/assets/icon-error.svg"); ErrorIcon = require("@/assets/icon-error.svg");
@Action("synchronizeData") synchronizeData; @Action("synchronizeData") synchronizeData;
@Getter("getAllData") data; @Getter("getAllData") data;
// @Getter("getOnlineInfo") onlineInfo;
// @Getter("getConnectionState") connState;
// @Action("initStations") initStations;
// @Action("fetchOnlineStations") fetchStations;
// @Action("fetchTrainsData") fetchTrainsData;
mounted() { mounted() {
this.synchronizeData(); this.synchronizeData();
// this.initStations();
// this.fetchTrainsData();
// setInterval(this.fetchStations, 15000);
// setInterval(this.fetchTrainsData, 45000);
} }
} }
</script> </script>
@@ -94,6 +86,7 @@ export default class App extends Vue {
@import "./styles/responsive.scss"; @import "./styles/responsive.scss";
@import "./styles/variables.scss"; @import "./styles/variables.scss";
@import "./styles/global.scss"; @import "./styles/global.scss";
@import "./styles/scenery_status.scss";
.view-anim { .view-anim {
&-enter { &-enter {
@@ -183,7 +176,7 @@ export default class App extends Vue {
} }
.header { .header {
background: #333; background: $primaryCol;
padding: 0.15em; padding: 0.15em;
border-radius: 0 0 0.7em 0.7em; border-radius: 0 0 0.7em 0.7em;
+49 -27
View File
@@ -5,18 +5,21 @@
class="schedule-icon" class="schedule-icon"
:src="require('@/assets/icon-clock.svg')" :src="require('@/assets/icon-clock.svg')"
alt="schedule-icon" alt="schedule-icon"
@click="() => cardMode = cardMode == 0 ? 1 : 0" @click="() => (cardMode = cardMode == 0 ? 1 : 0)"
/>
<img
:src="require('@/assets/icon-exit.svg')"
alt="exit-icon"
@click="exit"
/> />
<img :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 <span class="main-level flex" v-if="stationInfo.reqLevel > -1">{{
class="main-level flex" 2 > parseInt(stationInfo.reqLevel) ? "L" : stationInfo.reqLevel
v-if="stationInfo.reqLevel > -1" }}</span>
>{{ 2 > parseInt(stationInfo.reqLevel) ? "L" : stationInfo.reqLevel}}</span>
<span class="main-general"> <span class="main-general">
<div class="main-name"> <div class="main-name">
<a <a
@@ -24,11 +27,12 @@
: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>
<div class="main-hash">{{stationInfo.stationHash}}</div> <div class="main-hash">{{ stationInfo.stationHash }}</div>
</span> </span>
</div> </div>
</div> </div>
@@ -80,30 +84,39 @@
<div class="dispatcher"> <div class="dispatcher">
<div <div
class="dispatcher-level flex" class="dispatcher-level flex"
:style="calculateExpStyle(stationInfo.dispatcherExp, stationInfo.dispatcherIsSupporter)" :style="
>{{stationInfo.online ? computedDispatcherExp : ""}}</div> calculateExpStyle(
stationInfo.dispatcherExp,
stationInfo.dispatcherIsSupporter
)
"
>
{{ stationInfo.online ? computedDispatcherExp : "" }}
</div>
<div class="dispatcher-info"> <div class="dispatcher-info">
<div class="dispatcher-name"> <div class="dispatcher-name">
<a <a
:href="'https://td2.info.pl/profile/?u=' + stationInfo.dispatcherId" :href="
'https://td2.info.pl/profile/?u=' + stationInfo.dispatcherId
"
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">
<img :src="require(`@/assets/icon-like.svg`)" alt="like-icon" /> <img :src="require(`@/assets/icon-like.svg`)" alt="like-icon" />
<span>{{stationInfo.dispatcherRate}}</span> <span>{{ stationInfo.dispatcherRate }}</span>
</div> </div>
</div> </div>
</div> </div>
<div class="hours"> <div class="hours">
<div class="hours-title title">STATUS</div> <div class="hours-title title">STATUS</div>
<span <span class="status" :class="statusClasses(stationInfo.occupiedTo)">{{
class="status" stationInfo.occupiedTo
:class="statusClasses(stationInfo.occupiedTo)" }}</span>
>{{stationInfo.occupiedTo}}</span>
</div> </div>
<div class="spawns flex flex-column"> <div class="spawns flex flex-column">
@@ -113,7 +126,8 @@
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>
@@ -129,24 +143,31 @@
:key="train.trainNo + train.driverName" :key="train.trainNo + train.driverName"
> >
<router-link <router-link
:to="{ name: 'TrainsView', params: { passedSearchedTrain: train.trainNo.toString()}}" :to="{
name: 'TrainsView',
params: { passedSearchedTrain: train.trainNo.toString() },
}"
> >
<span>{{train.trainNo}}</span> <span>{{ train.trainNo }}</span>
| |
<span>{{train.driverName}}</span> <span>{{ train.driverName }}</span>
</router-link> </router-link>
</div> </div>
<span <span
class="user borderless" class="user borderless"
v-if="!stationInfo.stationTrains || stationInfo.stationTrains.length == 0" v-if="
>BRAK</span> !stationInfo.stationTrains ||
stationInfo.stationTrains.length == 0
"
>BRAK</span
>
</div> </div>
</div> </div>
</div> </div>
<StationTimetable <StationTimetable
:class="{show: cardMode == 1}" :class="{ show: cardMode == 1 }"
:scheduledTrains="computedScheduledTrains" :scheduledTrains="computedScheduledTrains"
:stationName="stationInfo.stationName" :stationName="stationInfo.stationName"
/> />
@@ -213,9 +234,10 @@ export default class StationCard extends styleMixin {
} }
</script> </script>
<style lang="scss"> <style lang="scss" scoped>
@import "../../styles/variables.scss"; @import "../../styles/variables.scss";
@import "../../styles/responsive.scss"; @import "../../styles/responsive.scss";
.title { .title {
color: $accentCol; color: $accentCol;
font-weight: 600; font-weight: 600;
+88 -32
View File
@@ -4,11 +4,15 @@
<table class="table"> <table class="table">
<thead class="table-head"> <thead class="table-head">
<tr> <tr>
<th v-for="(head, i) in headTitles" :key="i" @click="() => changeSorter(i)"> <th
v-for="(head, i) in headTitles"
:key="i"
@click="() => changeSorter(i)"
>
<span> <span>
<div> <div>
<div>{{head[0]}}</div> <div>{{ head[0] }}</div>
<div v-if="head.length > 1">{{head[1]}}</div> <div v-if="head.length > 1">{{ head[1] }}</div>
</div> </div>
<img <img
@@ -26,36 +30,64 @@
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="() => { setFocusedStation(station.stationName) }" @click="
() => {
setFocusedStation(station.stationName);
}
"
> >
<td <td
class="item-station-name" class="item-station-name"
:class="{'default-station': station.default, 'online': station.online, 'station-unavailable': station.unavailable}" :class="{
>{{station.stationName}}</td> 'default-station': station.default,
online: station.online,
'station-unavailable': station.unavailable,
}"
>
{{ station.stationName }}
</td>
<td class="item-station-level"> <td class="item-station-level">
<span <span
v-if="station.reqLevel" v-if="station.reqLevel"
:style="calculateExpStyle(station.reqLevel)" :style="calculateExpStyle(station.reqLevel)"
>{{ (station.reqLevel && station.reqLevel > -1) ? (parseInt(station.reqLevel) >= 2 ? station.reqLevel : "L") : "?" }}</span> >{{
station.reqLevel && station.reqLevel > -1
? parseInt(station.reqLevel) >= 2
? station.reqLevel
: "L"
: "?"
}}</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)">{{station.occupiedTo}}</span> <span class="status" :class="statusClasses(station.occupiedTo)">{{
station.occupiedTo
}}</span>
</td> </td>
<td class="item-dispatcher-name">{{station.online ? station.dispatcherName : ""}}</td> <td class="item-dispatcher-name">
{{ station.online ? station.dispatcherName : "" }}
</td>
<td class="item-dispatcher-exp"> <td class="item-dispatcher-exp">
<span <span
v-if="station.online" v-if="station.online"
:style="calculateExpStyle(station.dispatcherExp)" :style="calculateExpStyle(station.dispatcherExp)"
>{{2 > station.dispatcherExp ? 'L' : station.dispatcherExp}}</span> >{{
2 > station.dispatcherExp ? "L" : station.dispatcherExp
}}</span
>
</td>
<td class="item-users">
{{
station.online
? station.currentUsers + "/" + station.maxUsers
: ""
}}
</td> </td>
<td
class="item-users"
>{{station.online ? (station.currentUsers + "/" + station.maxUsers) : ""}}</td>
<td class="item-info"> <td class="item-info">
<img <img
class="icon-info" class="icon-info"
@@ -94,39 +126,59 @@
<span <span
v-if="station.routes && station.routes.twoWay.catenary > 0" v-if="station.routes && station.routes.twoWay.catenary > 0"
class="track catenary" class="track catenary"
:title="'Liczba zelektryfikowanych szlaków dwutorowych: ' + station.routes.twoWay.catenary" :title="
>{{station.routes.twoWay.catenary}}</span> 'Liczba zelektryfikowanych szlaków dwutorowych: ' +
station.routes.twoWay.catenary
"
>{{ 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"
class="track no-catenary" class="track no-catenary"
:title="'Liczba niezelektryfikowanych szlaków dwutorowych: ' + station.routes.twoWay.noCatenary" :title="
>{{station.routes.twoWay.noCatenary}}</span> 'Liczba niezelektryfikowanych szlaków dwutorowych: ' +
station.routes.twoWay.noCatenary
"
>{{ station.routes.twoWay.noCatenary }}</span
>
<span class="separator"></span> <span class="separator"></span>
<span <span
v-if="station.routes && station.routes.oneWay.catenary > 0" v-if="station.routes && station.routes.oneWay.catenary > 0"
class="track catenary" class="track catenary"
:title="'Liczba zelektryfikowanych szlaków jednotorowych: ' + station.routes.oneWay.catenary" :title="
>{{station.routes.oneWay.catenary}}</span> 'Liczba zelektryfikowanych szlaków jednotorowych: ' +
station.routes.oneWay.catenary
"
>{{ 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"
class="track no-catenary" class="track no-catenary"
:title="'Liczba niezelektryfikowanych szlaków jednotorowych: ' + station.routes.oneWay.noCatenary" :title="
>{{station.routes.oneWay.noCatenary}}</span> 'Liczba niezelektryfikowanych szlaków jednotorowych: ' +
station.routes.oneWay.noCatenary
"
>{{ 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">{{ station.scheduledTrains.length}}</span> <span style="color: #eee">{{
station.scheduledTrains.length
}}</span>
/ /
<span <span style="color: #bbb">{{
style="color:#bbb" station.scheduledTrains.filter(
>{{ station.scheduledTrains.filter(train => train.stopInfo.confirmed).length }}</span> (train) => train.stopInfo.confirmed
).length
}}</span>
</span> </span>
<span v-else>...</span> <span v-else>...</span>
@@ -136,7 +188,9 @@
</tr> </tr>
</table> </table>
</div> </div>
<div class="no-stations" v-if="stations.length == 0">Ups! Brak stacji do wyświetlenia!</div> <div class="no-stations" v-if="stations.length == 0">
Ups! Brak stacji do wyświetlenia!
</div>
</section> </section>
</template> </template>
@@ -182,7 +236,8 @@ export default class StationTable extends styleMixin {
<style lang="scss" scoped> <style lang="scss" scoped>
@import "../../styles/responsive.scss"; @import "../../styles/responsive.scss";
@import "../../styles/variables.scss"; @import "../../styles/variables.scss";
@import "../../styles/global.scss";
$rowCol: #4b4b4b;
.change-anim { .change-anim {
&-enter-active, &-enter-active,
@@ -197,7 +252,7 @@ export default class StationTable extends styleMixin {
} }
.station-table { .station-table {
font-size: calc(0.5rem + 0.3vw); font-size: calc(0.5rem + 0.35vw);
overflow: auto; overflow: auto;
overflow-y: hidden; overflow-y: hidden;
} }
@@ -220,6 +275,7 @@ export default class StationTable extends styleMixin {
&-wrapper { &-wrapper {
overflow: auto; overflow: auto;
} }
white-space: nowrap; white-space: nowrap;
border-collapse: collapse; border-collapse: collapse;
@@ -234,7 +290,7 @@ export default class StationTable extends styleMixin {
&-head th { &-head th {
padding: 0.3rem; padding: 0.3rem;
background-color: #444; background-color: $primaryCol;
min-width: 120px; min-width: 120px;
cursor: pointer; cursor: pointer;
@@ -254,16 +310,16 @@ export default class StationTable extends styleMixin {
} }
&-item { &-item {
background-color: #5c5b5b; background-color: $rowCol;
&:nth-child(even) { &:nth-child(even) {
background-color: rgb(102, 101, 101); background-color: lighten($rowCol, 5);
color: white; color: white;
} }
&:hover, &:hover,
&:focus { &:focus {
background-color: #818181; background-color: lighten($rowCol, 20);
} }
& > td { & > td {
@@ -2,32 +2,46 @@
<div class="station-timetable"> <div class="station-timetable">
<div class="timetable-wrapper"> <div class="timetable-wrapper">
<div class="timetable-title title"> <div class="timetable-title title">
<div style="font-size: 1.5em;">{{stationName.toUpperCase()}}</div> <div style="font-size: 1.5em">{{ stationName.toUpperCase() }}</div>
<div style="font-size: 0.7em;">AKTYWNE ROZKŁADY JAZDY</div> <div style="font-size: 0.7em">AKTYWNE ROZKŁADY JAZDY</div>
</div> </div>
<div class="timetable-content"> <div class="timetable-content">
<div class="timetable-item" v-for="(scheduledTrain, i) in computedScheduledTrains" :key="i"> <div
class="timetable-item"
v-for="(scheduledTrain, i) in computedScheduledTrains"
:key="i"
>
<span class="timetable-general"> <span class="timetable-general">
<span class="general-info"> <span class="general-info">
<router-link <router-link
:to="{ name: 'TrainsView', params: { passedSearchedTrain: scheduledTrain.trainNo.toString()}}" :to="{
name: 'TrainsView',
params: {
passedSearchedTrain: scheduledTrain.trainNo.toString(),
},
}"
> >
<span> <span>
<strong>{{scheduledTrain.category}}</strong> <strong>{{ scheduledTrain.category }}</strong>
{{scheduledTrain.trainNo}} {{ scheduledTrain.trainNo }}
</span> </span> </router-link
</router-link>| >|
<span> <span>
<a <a
:href="'https://td2.info.pl/profile/?u=' + scheduledTrain.driverId" :href="
'https://td2.info.pl/profile/?u=' + scheduledTrain.driverId
"
target="_blank" target="_blank"
>{{ scheduledTrain.driverName }}</a> >{{ scheduledTrain.driverName }}</a
>
</span> </span>
</span> </span>
<span class="general-status"> <span class="general-status">
<span :class="scheduledTrain.stopStatus">{{scheduledTrain.stopLabel}}</span> <span :class="scheduledTrain.stopStatus">{{
scheduledTrain.stopLabel
}}</span>
</span> </span>
</span> </span>
@@ -36,29 +50,33 @@
<span <span
class="arrival-time begins" class="arrival-time begins"
v-if="scheduledTrain.stopInfo.beginsHere" v-if="scheduledTrain.stopInfo.beginsHere"
>ROZPOCZYNA BIEG</span> >ROZPOCZYNA BIEG</span
<span >
class="arrival-time" <span class="arrival-time" v-else
v-else >{{ scheduledTrain.stopInfo.arrivalTimeString }} ({{
>{{scheduledTrain.stopInfo.arrivalTimeString}} ({{scheduledTrain.stopInfo.arrivalDelay}})</span> scheduledTrain.stopInfo.arrivalDelay
}})</span
>
</span> </span>
<span class="schedule-stop"> <span class="schedule-stop">
<span <span class="stop-time" v-if="scheduledTrain.stopInfo.stopTime"
class="stop-time" >{{ scheduledTrain.stopInfo.stopTime }}
v-if="scheduledTrain.stopInfo.stopTime" {{ scheduledTrain.stopInfo.stopType }}</span
>{{scheduledTrain.stopInfo.stopTime}} {{scheduledTrain.stopInfo.stopType}}</span> >
<span class="stop-arrow arrow"></span> <span class="stop-arrow arrow"></span>
</span> </span>
<span class="schedule-departure"> <span class="schedule-departure">
<span <span
class="departure-time terminates" class="departure-time terminates"
v-if="scheduledTrain.stopInfo.terminatesHere" v-if="scheduledTrain.stopInfo.terminatesHere"
>KOŃCZY BIEG</span> >KOŃCZY BIEG</span
<span >
class="departure-time" <span class="departure-time" v-else
v-else >{{ scheduledTrain.stopInfo.departureTimeString }} ({{
>{{scheduledTrain.stopInfo.departureTimeString}} ({{scheduledTrain.stopInfo.departureDelay}})</span> scheduledTrain.stopInfo.departureDelay
}})</span
>
</span> </span>
</span> </span>
</div> </div>
+31 -15
View File
@@ -5,7 +5,9 @@
class="stats-btn button" class="stats-btn button"
@click="toggleStats" @click="toggleStats"
v-if="trains.length > 0" v-if="trains.length > 0"
>STATYSTYKI RUCHU</button> >
STATYSTYKI RUCHU
</button>
</div> </div>
<transition name="stats-anim"> <transition name="stats-anim">
@@ -13,36 +15,47 @@
<h2 class="stats-header">STATYSTYKI RUCHU</h2> <h2 class="stats-header">STATYSTYKI RUCHU</h2>
<div class="stats-speed"> <div class="stats-speed">
<div class="title stats-title">PRĘDKOŚCI POCIĄGÓW (MIN | ŚR | MAX) [km/h]</div> <div class="title stats-title">
<div class="stats-content">{{speedStats.min}} | {{speedStats.avg}} | {{speedStats.max}}</div> PRĘDKOŚCI POCIĄGÓW (MIN | ŚR | MAX) [km/h]
</div>
<div class="stats-content">
{{ speedStats.min }} | {{ speedStats.avg }} | {{ speedStats.max }}
</div>
</div> </div>
<div class="stats-length"> <div class="stats-length">
<div class="title stats-title">DŁUGOŚCI ROZKŁADÓW (MIN | ŚR | MAX) [km]</div> <div class="title stats-title">
<div DŁUGOŚCI ROZKŁADÓW (MIN | ŚR | MAX) [km]
class="stats-content" </div>
>{{timetableStats.min}} | {{timetableStats.avg}} | {{timetableStats.max}}</div> <div class="stats-content">
{{ timetableStats.min }} | {{ timetableStats.avg }} |
{{ timetableStats.max }}
</div>
</div> </div>
<div class="stats-categories"> <div class="stats-categories">
<div class="title stats-title">KATEGORIE RJ</div> <div class="title stats-title">KATEGORIE RJ</div>
<div class="category-list"> <div class="category-list">
<span class="category" v-for="[key, value] of categoryList" :key="key"> <span
<span class="category-type">{{key}}</span> class="category"
<span class="category-count">{{value}}</span> v-for="[key, value] of categoryList"
:key="key"
>
<span class="category-type">{{ key }}</span>
<span class="category-count">{{ value }}</span>
</span> </span>
</div> </div>
<div class="special-list"> <div class="special-list">
<span class="special twr"> <span class="special twr">
<span class="special-type">WYSOKIEGO RYZYKA</span> <span class="special-type">WYSOKIEGO RYZYKA</span>
<span class="special-count">{{specialTrainCount[0]}}</span> <span class="special-count">{{ specialTrainCount[0] }}</span>
</span> </span>
<span class="special skr"> <span class="special skr">
<span class="special-type">PRZEKROCZONA SKRAJNIA</span> <span class="special-type">PRZEKROCZONA SKRAJNIA</span>
<span class="special-count">{{specialTrainCount[1]}}</span> <span class="special-count">{{ specialTrainCount[1] }}</span>
</span> </span>
</div> </div>
</div> </div>
@@ -51,7 +64,9 @@
<div class="title stats-title">NAJCZĘSTSZE JEDNOSTKI</div> <div class="title stats-title">NAJCZĘSTSZE JEDNOSTKI</div>
<div class="loco-list stats-content"> <div class="loco-list stats-content">
<div class="loco-item" v-for="(loco,i) in locoList" :key="i">{{loco[0]}} | {{loco[1]}}</div> <div class="loco-item" v-for="(loco, i) in locoList" :key="i">
{{ loco[0] }} | {{ loco[1] }}
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -222,7 +237,7 @@ export default class TrainStats extends Vue {
&-list { &-list {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
font-size: 0.85em; font-size: 0.95em;
} }
margin-right: 0.4em; margin-right: 0.4em;
@@ -235,7 +250,8 @@ export default class TrainStats extends Vue {
} }
&-type { &-type {
background: #888; background: rgb(88, 88, 88);
font-weight: 600;
} }
&-count { &-count {
+37 -23
View File
@@ -1,6 +1,8 @@
<template> <template>
<div class="train-table"> <div class="train-table">
<div class="no-trains" v-if="computedTrains.length == 0">Ups! Brak pociągów do wyświetlenia :/</div> <div class="no-trains" v-if="computedTrains.length == 0">
Ups! Brak pociągów do wyświetlenia :/
</div>
<ul class="train-list"> <ul class="train-list">
<li <li
@@ -8,7 +10,11 @@
v-for="(train, i) in computedTrains" v-for="(train, i) in computedTrains"
:key="i" :key="i"
:id="train.timetableData.timetableId" :id="train.timetableData.timetableId"
@click="() => {changeFocusedTrain(train.trainNo);}" @click="
() => {
changeFocusedTrain(train.trainNo);
}
"
> >
<span class="train-info"> <span class="train-info">
<span class="info"> <span class="info">
@@ -17,43 +23,52 @@
<span> <span>
<strong>{{ train.timetableData.category }}</strong> <strong>{{ train.timetableData.category }}</strong>
{{ train.trainNo }} | {{ train.trainNo }} |
<span <span style="color: gold"
style=" color: gold;" >{{ train.timetableData.routeDistance }} km</span
>{{ train.timetableData.routeDistance }} km</span> >
</span> </span>
<span> <span>
<span class="warning twr" v-if="train.timetableData.TWR">TWR</span> <span class="warning twr" v-if="train.timetableData.TWR"
<span class="warning skr" v-if="train.timetableData.SKR">SKR</span> >TWR</span
>
<span class="warning skr" v-if="train.timetableData.SKR"
>SKR</span
>
</span> </span>
</div> </div>
<div class="info-route"> <div class="info-route">
<strong> <strong>
{{ {{ train.timetableData.route.replace("|", " - ") }}
train.timetableData.route.replace("|", " - ")
}}
</strong> </strong>
</div> </div>
<div class="info-stations"> <div class="info-stations">
<span v-if="train.timetableData.followingStops.length > 2"> <span v-if="train.timetableData.followingStops.length > 2">
Przez: Przez:
<span v-html="generateStopList(train.timetableData.followingStops)"></span> <span
v-html="
generateStopList(train.timetableData.followingStops)
"
></span>
</span> </span>
</div> </div>
</div> </div>
<div class="info-bottom"> <div class="info-bottom">
<span <span class="info-online" :class="{ online: train.online }">{{
class="info-online" train.online ? "ONLINE" : "OFFLINE"
:class="{'online': train.online}" }}</span>
>{{train.online ? "ONLINE" : "OFFLINE"}}</span>
<button <button
class="button" class="button"
@click="changeScheduleShowState(train.timetableData.timetableId)" @click="
>ROZKŁAD JAZDY</button> changeScheduleShowState(train.timetableData.timetableId)
"
>
ROZKŁAD JAZDY
</button>
</div> </div>
</span> </span>
@@ -62,11 +77,10 @@
<a <a
:href="'https://td2.info.pl/profile/?u=' + train.driverId" :href="'https://td2.info.pl/profile/?u=' + train.driverId"
target="_blank" target="_blank"
>{{ train.driverName }}</a> >{{ train.driverName }}</a
<span style="color: #bbb; margin-left: 1em;"> >
{{ <span style="color: #bbb; margin-left: 1em">
train.locoType {{ train.locoType }}
}}
</span> </span>
</span> </span>
<span class="driver-loco"> <span class="driver-loco">
@@ -211,7 +225,7 @@ export default class TrainTable extends Vue {
padding: 1rem; padding: 1rem;
margin-bottom: 1rem; margin-bottom: 1rem;
background-color: #383838; background-color: $primaryCol;
cursor: pointer; cursor: pointer;
} }
+8 -45
View File
@@ -61,50 +61,6 @@ input {
margin: 0; margin: 0;
} }
.status {
border-radius: 1.3rem;
font-weight: 500;
font-size: 0.95em;
padding: 0.25em 0.4em;
background-color: #00be19;
&.free {
background-color: #8a8a8a;
font-size: 0.95em;
}
&.ending {
background-color: $accentCol;
color: black;
font-size: 0.9em;
}
&.no-limit {
background-color: #0077ae;
font-size: 0.85em;
}
&.not-signed,
&.unavailable {
background-color: $accent2Col;
font-size: 0.8em;
}
&.brb {
background-color: $accentCol;
color: black;
font-size: 0.95em;
}
&.no-space {
background-color: #222;
color: white;
font-size: 0.85em;
}
}
.default-station { .default-station {
font-weight: bold; font-weight: bold;
color: $accentCol; color: $accentCol;
@@ -121,7 +77,6 @@ input {
z-index: 4; z-index: 4;
overflow: auto; overflow: auto;
// background: #474747;
background: #262a2e; background: #262a2e;
box-shadow: 0 0 15px 5px #474747; box-shadow: 0 0 15px 5px #474747;
@@ -155,6 +110,14 @@ input {
} }
} }
.title {
color: $accentCol;
font-weight: 600;
padding: .35em 0;
}
.button { .button {
display: flex; display: flex;
align-items: center; align-items: center;
+51
View File
@@ -0,0 +1,51 @@
$free: #8a8a8a;
$ending: #e6c300;
$no-limit: #0077ae;
$unav: #ff3d5d;
$brb: #e6a100;
$no-space: #222;
$taken: #09a116;
.status {
border-radius: 1rem;
font-weight: 500;
font-size: 0.9em;
padding: 0.2em 0.45em;
background-color: $taken;
&.free {
background-color: $free;
font-size: 0.95em;
}
&.ending {
background-color: $ending;
color: black;
font-size: 0.9em;
}
&.no-limit {
background-color: $no-limit;
font-size: 0.85em;
}
&.not-signed,
&.unavailable {
background-color: $unav;
font-size: 0.8em;
}
&.brb {
background-color: $brb;
color: black;
font-size: 0.95em;
}
&.no-space {
background-color: $no-space;
color: white;
font-size: 0.85em;
}
}
+2 -2
View File
@@ -1,7 +1,7 @@
$primaryCol: #333; $primaryCol: #2f2f2f;
$secondaryCol: #01e733; $secondaryCol: #01e733;
$bgCol: #525252; $bgCol: #505050;
$errorCol: #ff1919; $errorCol: #ff1919;
$warningCol: #ff975b; $warningCol: #ff975b;
+282 -271
View File
@@ -4,8 +4,15 @@
<div class="stations-body"> <div class="stations-body">
<div class="options"> <div class="options">
<div class="options-actions"> <div class="options-actions">
<button class="action-btn" :class="{ open: filterCardOpen }" @click="() => toggleCardsState('filter')"> <button
<img :src="require('@/assets/icon-filter2.svg')" alt="icon-filter" /> class="action-btn"
:class="{ open: filterCardOpen }"
@click="() => toggleCardsState('filter')"
>
<img
:src="require('@/assets/icon-filter2.svg')"
alt="icon-filter"
/>
<p>FILTRY</p> <p>FILTRY</p>
</button> </button>
</div> </div>
@@ -21,7 +28,11 @@
</div> </div>
<transition name="card-anim"> <transition name="card-anim">
<StationCard v-if="focusedStationInfo" :stationInfo="focusedStationInfo" :exit="closeCard" /> <StationCard
v-if="focusedStationInfo"
:stationInfo="focusedStationInfo"
:exit="closeCard"
/>
</transition> </transition>
<transition name="card-anim"> <transition name="card-anim">
@@ -36,310 +47,310 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { Vue, Component } from "vue-property-decorator"; import { Vue, Component } from "vue-property-decorator";
import { Getter } from "vuex-class"; import { Getter } from "vuex-class";
import Station from "@/scripts/interfaces/Station"; import Station from "@/scripts/interfaces/Station";
import Train from "@/scripts/interfaces/Train"; import Train from "@/scripts/interfaces/Train";
import inputData from "@/data/options.json"; import inputData from "@/data/options.json";
import StationTable from "@/components/StationsView/StationTable.vue"; import StationTable from "@/components/StationsView/StationTable.vue";
import StationCard from "@/components/StationsView/StationCard.vue"; import StationCard from "@/components/StationsView/StationCard.vue";
import FilterCard from "@/components/StationsView/FilterCard.vue"; import FilterCard from "@/components/StationsView/FilterCard.vue";
const filterInitStates = { const filterInitStates = {
default: false, default: false,
notDefault: false, notDefault: false,
nonPublic: false, nonPublic: false,
SPK: false, SPK: false,
SCS: false, SCS: false,
ręczne: false, ręczne: false,
mechaniczne: false, mechaniczne: false,
współczesna: false, współczesna: false,
kształtowa: false, kształtowa: false,
historyczna: false, historyczna: false,
mieszana: false, mieszana: false,
minLevel: 0, minLevel: 0,
minOneWayCatenary: 0, minOneWayCatenary: 0,
minOneWay: 0, minOneWay: 0,
minTwoWayCatenary: 0, minTwoWayCatenary: 0,
minTwoWay: 0, minTwoWay: 0,
"no-1track": false, "no-1track": false,
"no-2track": false, "no-2track": false,
free: true, free: true,
occupied: false, occupied: false,
ending: false, ending: false,
}; };
@Component({ @Component({
components: { components: {
StationCard, StationCard,
StationTable, StationTable,
FilterCard, FilterCard,
}, },
}) })
export default class StationsView extends Vue { export default class StationsView extends Vue {
STORAGE_KEY: string = "options_saved"; STORAGE_KEY: string = "options_saved";
sorterActive: { index: number; dir: number } = { index: 0, dir: 1 }; sorterActive: { index: number; dir: number } = { index: 0, dir: 1 };
focusedStationName: string = ""; focusedStationName: string = "";
filterCardOpen: boolean = false; filterCardOpen: boolean = false;
filters = { ...filterInitStates }; filters = { ...filterInitStates };
inputs = inputData; inputs = inputData;
@Getter("getStationList") stationList!: Station[]; @Getter("getStationList") stationList!: Station[];
toggleCardsState(name: string): void { toggleCardsState(name: string): void {
if (name == "filter") { if (name == "filter") {
this.filterCardOpen = !this.filterCardOpen; this.filterCardOpen = !this.filterCardOpen;
}
}
changeSorter(index: number) {
if (index > 5) return;
if (index == this.sorterActive.index) this.sorterActive.dir = -1 * this.sorterActive.dir;
else this.sorterActive.dir = 1;
this.sorterActive.index = index;
}
changeFilterValue(filter: { name: string; value: number }) {
this.filters[filter.name] = filter.value;
}
resetFilters() {
this.filters = { ...filterInitStates };
}
get computedStations() {
const dir: number = this.sorterActive.dir;
// const scheduledTrainList = this.scheduledTrains;
return this.stationList
.filter((station) => {
if (!station.reqLevel || station.reqLevel == "-1") return true;
if ((station.nonPublic || !station.reqLevel) && this.filters["nonPublic"]) return false;
if (station.online && station.occupiedTo == "KOŃCZY" && this.filters["ending"]) return false;
if (station.online && this.filters["occupied"]) return false;
if (!station.online && this.filters["free"]) return false;
if (station.default && this.filters["default"]) return false;
if (!station.default && this.filters["notDefault"]) return false;
if (parseInt(station.reqLevel) < this.filters["minLevel"]) return false;
if (
this.filters["no-1track"] &&
(station.routes.oneWay.catenary != 0 || station.routes.oneWay.noCatenary != 0)
)
return false;
if (
this.filters["no-2track"] &&
(station.routes.twoWay.catenary != 0 || station.routes.twoWay.noCatenary != 0)
)
return false;
if (station.routes.oneWay.catenary < this.filters["minOneWayCatenary"]) return false;
if (station.routes.oneWay.noCatenary < this.filters["minOneWay"]) return false;
if (station.routes.twoWay.catenary < this.filters["minTwoWayCatenary"]) return false;
if (station.routes.twoWay.noCatenary < this.filters["minTwoWay"]) return false;
if (this.filters[station.controlType]) return false;
if (this.filters[station.signalType]) return false;
if (this.filters["SPK"] && (station.controlType === "SPK" || station.controlType.includes("+SPK")))
return false;
if (this.filters["SCS"] && (station.controlType === "SCS" || station.controlType.includes("+SCS")))
return false;
if (
this.filters["SCS"] &&
this.filters["SPK"] &&
(station.controlType.includes("SPK") || station.controlType.includes("SCS"))
)
return false;
if (this.filters["mechaniczne"] && station.controlType.includes("mechaniczne")) return false;
if (this.filters["ręczne"] && station.controlType.includes("ręczne")) return false;
return true;
})
.sort((a, b) => {
switch (this.sorterActive.index) {
case 1:
if (parseInt(a.reqLevel) > parseInt(b.reqLevel)) return dir;
if (parseInt(a.reqLevel) < parseInt(b.reqLevel)) return -dir;
break;
case 2:
if (a.statusTimestamp > b.statusTimestamp) return dir;
if (a.statusTimestamp < b.statusTimestamp) return -dir;
break;
case 3:
if (a.dispatcherName.toLowerCase() > b.dispatcherName.toLowerCase()) return dir;
if (a.dispatcherName.toLowerCase() < b.dispatcherName.toLowerCase()) return -dir;
break;
case 4:
if (a.dispatcherExp > b.dispatcherExp) return dir;
if (a.dispatcherExp < b.dispatcherExp) return -dir;
break;
case 5:
if (a.currentUsers > b.currentUsers) return dir;
if (a.currentUsers < b.currentUsers) return -dir;
if (a.maxUsers > b.maxUsers) return dir;
if (a.maxUsers < b.maxUsers) return -dir;
break;
default:
break;
}
if (a.stationName.toLowerCase() >= b.stationName.toLowerCase()) return dir;
return -dir;
});
}
mounted() {
const storage = window.localStorage;
if (storage.getItem(this.STORAGE_KEY) !== "true") return;
this.inputs.options.forEach((option) => {
const value = storage.getItem(option.name) === "true" ? true : false;
this.changeFilterValue({ name: option.name, value: value ? 0 : 1 });
option.value = value;
});
this.inputs.sliders.forEach((slider) => {
const value = parseInt(storage.getItem(slider.name) || "0");
this.changeFilterValue({ name: slider.name, value });
slider.value = value;
});
window.addEventListener("keydown", (e: KeyboardEvent) => {
if (e.keyCode == 27 && this.focusedStationName != "") {
this.focusedStationName = "";
}
});
}
closeCard() {
this.focusedStationName = "";
}
setFocusedStation(name: string) {
if (this.focusedStationName == name) this.focusedStationName = "";
else this.focusedStationName = name;
}
get focusedStationInfo() {
return this.computedStations.find((station) => station.stationName === this.focusedStationName);
} }
} }
changeSorter(index: number) {
if (index > 5) return;
if (index == this.sorterActive.index) this.sorterActive.dir = -1 * this.sorterActive.dir;
else this.sorterActive.dir = 1;
this.sorterActive.index = index;
}
changeFilterValue(filter: { name: string; value: number }) {
this.filters[filter.name] = filter.value;
}
resetFilters() {
this.filters = { ...filterInitStates };
}
get computedStations() {
const dir: number = this.sorterActive.dir;
// const scheduledTrainList = this.scheduledTrains;
return this.stationList
.filter((station) => {
if (!station.reqLevel || station.reqLevel == "-1") return true;
if ((station.nonPublic || !station.reqLevel) && this.filters["nonPublic"]) return false;
if (station.online && station.occupiedTo == "KOŃCZY" && this.filters["ending"]) return false;
if (station.online && this.filters["occupied"]) return false;
if (!station.online && this.filters["free"]) return false;
if (station.default && this.filters["default"]) return false;
if (!station.default && this.filters["notDefault"]) return false;
if (parseInt(station.reqLevel) < this.filters["minLevel"]) return false;
if (
this.filters["no-1track"] &&
(station.routes.oneWay.catenary != 0 || station.routes.oneWay.noCatenary != 0)
)
return false;
if (
this.filters["no-2track"] &&
(station.routes.twoWay.catenary != 0 || station.routes.twoWay.noCatenary != 0)
)
return false;
if (station.routes.oneWay.catenary < this.filters["minOneWayCatenary"]) return false;
if (station.routes.oneWay.noCatenary < this.filters["minOneWay"]) return false;
if (station.routes.twoWay.catenary < this.filters["minTwoWayCatenary"]) return false;
if (station.routes.twoWay.noCatenary < this.filters["minTwoWay"]) return false;
if (this.filters[station.controlType]) return false;
if (this.filters[station.signalType]) return false;
if (this.filters["SPK"] && (station.controlType === "SPK" || station.controlType.includes("+SPK")))
return false;
if (this.filters["SCS"] && (station.controlType === "SCS" || station.controlType.includes("+SCS")))
return false;
if (
this.filters["SCS"] &&
this.filters["SPK"] &&
(station.controlType.includes("SPK") || station.controlType.includes("SCS"))
)
return false;
if (this.filters["mechaniczne"] && station.controlType.includes("mechaniczne")) return false;
if (this.filters["ręczne"] && station.controlType.includes("ręczne")) return false;
return true;
})
.sort((a, b) => {
switch (this.sorterActive.index) {
case 1:
if (parseInt(a.reqLevel) > parseInt(b.reqLevel)) return dir;
if (parseInt(a.reqLevel) < parseInt(b.reqLevel)) return -dir;
break;
case 2:
if (a.statusTimestamp > b.statusTimestamp) return dir;
if (a.statusTimestamp < b.statusTimestamp) return -dir;
break;
case 3:
if (a.dispatcherName.toLowerCase() > b.dispatcherName.toLowerCase()) return dir;
if (a.dispatcherName.toLowerCase() < b.dispatcherName.toLowerCase()) return -dir;
break;
case 4:
if (a.dispatcherExp > b.dispatcherExp) return dir;
if (a.dispatcherExp < b.dispatcherExp) return -dir;
break;
case 5:
if (a.currentUsers > b.currentUsers) return dir;
if (a.currentUsers < b.currentUsers) return -dir;
if (a.maxUsers > b.maxUsers) return dir;
if (a.maxUsers < b.maxUsers) return -dir;
break;
default:
break;
}
if (a.stationName.toLowerCase() >= b.stationName.toLowerCase()) return dir;
return -dir;
});
}
mounted() {
const storage = window.localStorage;
if (storage.getItem(this.STORAGE_KEY) !== "true") return;
this.inputs.options.forEach((option) => {
const value = storage.getItem(option.name) === "true" ? true : false;
this.changeFilterValue({ name: option.name, value: value ? 0 : 1 });
option.value = value;
});
this.inputs.sliders.forEach((slider) => {
const value = parseInt(storage.getItem(slider.name) || "0");
this.changeFilterValue({ name: slider.name, value });
slider.value = value;
});
window.addEventListener("keydown", (e: KeyboardEvent) => {
if (e.keyCode == 27 && this.focusedStationName != "") {
this.focusedStationName = "";
}
});
}
closeCard() {
this.focusedStationName = "";
}
setFocusedStation(name: string) {
if (this.focusedStationName == name) this.focusedStationName = "";
else this.focusedStationName = name;
}
get focusedStationInfo() {
return this.computedStations.find((station) => station.stationName === this.focusedStationName);
}
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.stations-view { @import "../styles/variables.scss";
padding: 1rem 0; @import "../styles/responsive.scss";
min-height: 100%;
font-size: calc(0.6rem + 0.9vw); .stations-view {
position: relative;
position: relative; padding: 1rem 0;
min-height: 100%;
font-size: calc(0.6rem + 0.9vw);
}
.card-anim {
&-enter-active,
&-leave-active {
transition: all 0.25s ease-in-out;
} }
@import "../styles/variables.scss"; &-enter,
@import "../styles/responsive.scss"; &-leave-to {
transform: translate(-45%, -50%);
.card-anim { opacity: 0;
&-enter-active,
&-leave-active {
transition: all 0.25s ease-in-out;
}
&-enter,
&-leave-to {
transform: translate(-45%, -50%);
opacity: 0;
}
} }
}
.options { .options {
&-actions { &-actions {
display: flex;
}
}
.action-btn {
display: flex; display: flex;
align-items: center; }
}
background: #333; .action-btn {
border: none; display: flex;
align-items: center;
color: #e0e0e0; background: #333;
font-size: 0.65em; border: none;
padding: 0.3em; color: #e0e0e0;
font-size: 0.65em;
outline: none; padding: 0.3em;
cursor: pointer;
transition: all 0.3s; outline: none;
cursor: pointer;
img { transition: all 0.3s;
width: 1.3em;
margin-right: 0.2em;
}
p { img {
font-size: 1em; width: 1.3em;
overflow: hidden; margin-right: 0.2em;
transition: max-width 0.35s ease-in-out;
}
&:hover {
color: $accentCol;
background: rgba(#e0e0e0, 0.4);
}
&.open {
color: $accentCol;
}
} }
@include smallScreen { p {
.options { font-size: 1em;
display: flex; overflow: hidden;
justify-content: center;
}
.action-btn { transition: max-width 0.35s ease-in-out;
font-size: 0.75rem;
}
} }
.stations-wrapper { &:hover {
color: $accentCol;
background: rgba(#e0e0e0, 0.4);
}
&.open {
color: $accentCol;
}
}
@include smallScreen {
.options {
display: flex; display: flex;
justify-content: center; justify-content: center;
} }
.stations-body { .action-btn {
margin: 0 auto; font-size: 0.75rem;
overflow: auto;
} }
}
.stations-wrapper {
display: flex;
justify-content: center;
}
.stations-body {
margin: 0 auto;
overflow: auto;
}
</style> </style>