diff --git a/src/assets/icon-select.svg b/src/assets/icon-select.svg new file mode 100644 index 0000000..78de7f6 --- /dev/null +++ b/src/assets/icon-select.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/components/TrainsView/TrainSorter.vue b/src/components/TrainsView/TrainSorter.vue new file mode 100644 index 0000000..b7ab535 --- /dev/null +++ b/src/components/TrainsView/TrainSorter.vue @@ -0,0 +1,173 @@ + + + + + diff --git a/src/components/TrainsView/TrainTable.vue b/src/components/TrainsView/TrainTable.vue new file mode 100644 index 0000000..5572fce --- /dev/null +++ b/src/components/TrainsView/TrainTable.vue @@ -0,0 +1,258 @@ + + + + + \ No newline at end of file diff --git a/src/components/ui/Card.vue b/src/components/ui/Card.vue index 74518ec..7281f3c 100644 --- a/src/components/ui/Card.vue +++ b/src/components/ui/Card.vue @@ -132,7 +132,7 @@ import Vue from "vue"; export default Vue.extend({ name: "Card", - props: ["stationInfo", "closeCard"] + props: ["stationInfo", "closeCard"], }); diff --git a/src/scripts/interfaces/Train.ts b/src/scripts/interfaces/Train.ts new file mode 100644 index 0000000..8cea6d3 --- /dev/null +++ b/src/scripts/interfaces/Train.ts @@ -0,0 +1,22 @@ +export default interface Train { + mass: number; + length: number; + speed: number; + signal: string; + distance: number; + connectedTrack: string; + driverId: number; + trainNo: number; + driverName: string; + currentStationName: string; + route: string | null; + timetableId: number | null; + category: string | null; + sceneries: string | null; + TWR: boolean | null; + SKR: boolean | null; + noTimetable: boolean; + locoURL: string; + locoType: string; + routeDistance: number; +} diff --git a/src/styles/global.scss b/src/styles/global.scss index 80ee0a1..8fca973 100644 --- a/src/styles/global.scss +++ b/src/styles/global.scss @@ -29,7 +29,8 @@ body { } button, -input { +input, +select { font-family: "Lato", sans-serif; } @@ -43,6 +44,7 @@ input { margin: 0.2em; max-width: 55px; + outline: none; &::placeholder { color: #bebebe; diff --git a/src/views/TrainsView.vue b/src/views/TrainsView.vue index 27fdabf..dfe024c 100644 --- a/src/views/TrainsView.vue +++ b/src/views/TrainsView.vue @@ -3,98 +3,20 @@
- + +
- + @@ -105,50 +27,35 @@ import { Component } from "vue-property-decorator"; import { Getter } from "vuex-class"; import Station from "@/scripts/interfaces/Station"; +import Train from "@/scripts/interfaces/Train"; import Loading from "@/components/states/Loading.vue"; +import TrainSorter from "@/components/TrainsView/TrainSorter.vue"; +import TrainTable from "@/components/TrainsView/TrainTable.vue"; import axios from "axios"; -const unknownTrainImage = require("@/assets/unknown.png"); - @Component({ components: { Loading, + TrainSorter, + TrainTable, }, }) export default class TrainsView extends Vue { - speedIcon: string = require("@/assets/icon-speed.svg"); - massIcon: string = require("@/assets/icon-mass.svg"); - lengthIcon: string = require("@/assets/icon-length.svg"); - @Getter("getAllStations") stations!: Station[]; - onlineTrainsList: { - mass: number; - length: number; - speed: number; - signal: string; - distance: number; - connectedTrack: string; - driverId: number; - trainNo: number; - driverName: string; - currentStationName: string; - route: string | null; - timetableId: number | null; - category: string | null; - sceneries: string | null; - TWR: boolean | null; - SKR: boolean | null; - noTimetable: boolean; - locoURL: string; - locoType: string; - routeDistance: number; - }[] = []; - + sorterActive: { id: string; dir: number } = { id: "timetable", dir: 1 }; + onlineTrainsList: Train[] = []; listLoaded: boolean = false; + searchedTrain: string = ""; + searchedDriver: string = ""; + + changeSorter(sorter: { id: string; dir: number }) { + this.sorterActive = sorter; + } + async getTrainData() { const response = await axios.get( "https://api.td2.info.pl:9640/?method=getTrainsOnline" @@ -272,12 +179,64 @@ export default class TrainsView extends Vue { return text; } - onImageError(e: Event) { - (e.target as HTMLImageElement).src = unknownTrainImage; - } - get computedTrains() { - return this.onlineTrainsList.filter((train) => !train.noTimetable); + // const trainDetected = this.onlineTrainsList.filter( + // (train) => + // train.trainNo.toString().includes(this.searched) && this.searched != "" + // ); + // const playerDetected = this.onlineTrainsList.filter( + // (train) => + // // this.searched.toLowerCase().includes(train.driverName.toLowerCase()) + // train.driverName.toLowerCase().includes(this.searched.toLowerCase()) && + // this.searched != "" + // ); + + const computed = this.onlineTrainsList.filter( + (train) => + !train.noTimetable && + (this.searchedTrain.length > 0 + ? train.trainNo.toString().includes(this.searchedTrain) + : true) && + (this.searchedDriver.length > 0 + ? train.driverName.includes(this.searchedDriver) + : true) + ); + + computed.sort((a, b) => { + switch (this.sorterActive.id) { + case "mass": + if (a.mass > b.mass) return this.sorterActive.dir; + else return -this.sorterActive.dir; + break; + + case "distance": + if (a.routeDistance > b.routeDistance) return this.sorterActive.dir; + else return -this.sorterActive.dir; + break; + + case "speed": + if (a.speed > b.speed) return this.sorterActive.dir; + else return -this.sorterActive.dir; + break; + + case "timetable": + if (a.trainNo > b.trainNo) return this.sorterActive.dir; + else return -this.sorterActive.dir; + break; + + case "length": + if (a.length > b.length) return this.sorterActive.dir; + else return -this.sorterActive.dir; + break; + + default: + break; + } + + return 0; + }); + + return computed; } mounted() { @@ -297,146 +256,51 @@ export default class TrainsView extends Vue { } .body-wrapper { - margin: 0 auto; + margin: 1rem auto; max-width: 1250px; -} -.list { - overflow: auto; - - @include smallScreen() { - width: 100%; - } -} - -.item { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); + padding: 0 0.5rem; font-size: calc(0.4rem + 0.5vw); +} - background-color: #444; - padding: 1rem; +.options-wrapper { + display: flex; + flex-wrap: wrap; - margin: 1rem 0; - - &:nth-child(even) { - background-color: #666; + & > div { + margin-right: 1rem; } - @include smallScreen() { - grid-template-columns: 1fr; - grid-template-rows: repeat(3, 1fr); + .search { + &-input { + background: #333; + border: none; + border-radius: 0.5em; + padding: 0.5rem 1rem; + margin: 0; + + font-size: 1em; + + min-width: 150px; + } + } +} + +@include bigScreen() { + .body-wrapper { + font-size: 1rem; + } +} + +@include smallScreen { + .body-wrapper { font-size: 0.8rem; - gap: 0.4em 0; - // grid-template-columns: repeat(3, 1fr); + } + + .options-wrapper { + justify-content: center; } } - -.info { - display: flex; - flex-wrap: wrap; - - &-category { - flex-grow: 2; - font-size: 1.05em; - } - - &-route { - width: 100%; - font-size: 1.2em; - } - - &-stations { - margin-top: 0.35em; - font-size: 0.75em; - } -} - -.driver { - display: flex; - align-items: center; - justify-content: center; - flex-wrap: wrap; - - &-exp { - font-size: 1.4em; - padding: 0.3em 0.6em; - - border-radius: 0.4em; - - background-color: red; - } - - &-name { - margin: 0 0.3em; - } - - &-loco { - width: 100%; - text-align: center; - } - - &-loco img { - width: 13em; - max-width: 190px; - } -} - -.stats { - width: 100%; - - &-general { - display: flex; - - span { - display: flex; - justify-content: center; - - width: 100%; - - align-items: center; - } - - img { - margin: 0 0.3em; - width: 1.8em; - } - } - - &-position { - display: flex; - - margin-top: 1em; - text-align: center; - - span { - width: 100%; - font-size: 300; - } - - p { - color: #00cff3; - } - } -} - -.warning { - border-radius: 1em; - padding: 0.1em 1.2em; - margin: 0 0.2em; - - color: black; - font-weight: bold; - font-size: 0.85em; - - &.twr { - background-color: #ffc700; - } - - &.skr { - background-color: #ff4646; - } -} - \ No newline at end of file + diff --git a/vue.config.js b/vue.config.js index 3d0f6ad..cd2b477 100644 --- a/vue.config.js +++ b/vue.config.js @@ -1,3 +1,3 @@ -module.exports = { - publicPath: process.env.NODE_ENV === "production" ? "/dist" : "/", -}; +// module.exports = { +// publicPath: process.env.NODE_ENV === "production" ? "/dist" : "/", +// };