284 lines
8.5 KiB
Vue
284 lines
8.5 KiB
Vue
<template>
|
|
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@5.x/css/materialdesignicons.min.css" rel="stylesheet">
|
|
<div class="search" :class="getDisplayClass()">
|
|
<v-switch label="Mobile" v-model="isMobile"></v-switch>
|
|
<v-select
|
|
v-model="selectedService"
|
|
prepend-icon="mdi mdi-dots-triangle"
|
|
:items="services"
|
|
item-title="name"
|
|
item-value="id"
|
|
:label="$t('search.fields.service')"
|
|
class="inputTextField"
|
|
></v-select>
|
|
<v-text-field
|
|
:active="date.menu"
|
|
v-model="formattedDate"
|
|
:label="$t('search.fields.date')"
|
|
prepend-icon="mdi mdi-calendar-month"
|
|
readonly
|
|
class="inputTextField"
|
|
>
|
|
<v-menu
|
|
v-model="date.menu"
|
|
:close-on-content-click="false"
|
|
activator="parent"
|
|
transition="scale-transition"
|
|
>
|
|
<v-date-picker
|
|
color="green-lighten-1"
|
|
format="24hr"
|
|
v-if="date.menu"
|
|
v-model="date.value"
|
|
full-width
|
|
></v-date-picker>
|
|
</v-menu>
|
|
</v-text-field>
|
|
<v-text-field
|
|
v-model="time.value"
|
|
:active="time.menu"
|
|
:label="$t('search.fields.time')"
|
|
prepend-icon="mdi mdi-clock-outline"
|
|
readonly
|
|
class="inputTextField"
|
|
>
|
|
<v-menu
|
|
v-model="time.menu"
|
|
:close-on-content-click="false"
|
|
activator="parent"
|
|
transition="scale-transition"
|
|
>
|
|
<v-time-picker
|
|
color="green-lighten-1"
|
|
format="24hr"
|
|
v-if="time.menu"
|
|
v-model="time.value"
|
|
full-width
|
|
></v-time-picker>
|
|
</v-menu>
|
|
</v-text-field>
|
|
<v-text-field
|
|
prepend-icon="mdi mdi-ray-start-arrow"
|
|
:active="from.menu"
|
|
:label="$t('search.fields.from')"
|
|
type="text"
|
|
v-model="fromName"
|
|
class="inputTextField"
|
|
@change="loadChoicesFrom()"
|
|
>
|
|
<v-menu
|
|
v-model="from.menu"
|
|
:close-on-content-click="false"
|
|
activator="parent"
|
|
transition="scale-transition"
|
|
>
|
|
<div v-if="from.menu">
|
|
<div class="selectItem" v-for="choice in from.choices" :key="from.choices.indexOf(choice)" @click="chooseFrom(choice)">
|
|
{{ choice.name }}
|
|
</div>
|
|
</div>
|
|
</v-menu>
|
|
</v-text-field>
|
|
<v-text-field
|
|
prepend-icon="mdi mdi-bullseye"
|
|
:active="to.menu"
|
|
:label="$t('search.fields.to')"
|
|
type="text"
|
|
v-model="toName"
|
|
class="inputTextField"
|
|
>
|
|
<v-menu
|
|
v-model="to.menu"
|
|
:close-on-content-click="false"
|
|
activator="parent"
|
|
transition="scale-transition"
|
|
>
|
|
<div v-if="to.menu">
|
|
<div class="selectItem" v-for="choice in to.choices" :key="to.choices.indexOf(choice)" @click="chooseTo(choice)">
|
|
{{ choice.name }}
|
|
</div>
|
|
</div>
|
|
</v-menu>
|
|
</v-text-field>
|
|
<v-btn @click="searchConnection()">{{$t("search.buttons.searchConnection")}}</v-btn>
|
|
</div>
|
|
<routing v-if="showRouting" :connections="connections" :isMobile="isMobile"></routing>
|
|
</template>
|
|
<script>
|
|
import routing from './routing';
|
|
import axios from 'axios';
|
|
import { VTimePicker } from 'vuetify/labs/VTimePicker';
|
|
import { VDatePicker } from 'vuetify/components/VDatePicker';
|
|
const client = axios.create({
|
|
baseURL: process.env.VUE_APP_BASE_URL
|
|
});
|
|
const services = [
|
|
{id:"db", name:"Deutsche Bahn"},
|
|
{id:"vbb", name:"Verkehrsverbund Berlin-Brandenburg"},
|
|
{id:"pkp", name:"Polskie Koleje Panstwowe"},
|
|
{id:"irish", name:"Iarnrod Eireann"},
|
|
{id:"oebb", name:"Oesterreichische Bundesbahnen"},
|
|
{id:"lu", name:"Mobiliteitszentral (Luxembourg)"},
|
|
{id:"bart", name:"Bay Area Rapid Transit (BART)"},
|
|
{id:"dart", name:"Des Moines Area Rapid Transit (DART)"},
|
|
{id:"nrw", name:"mobil.nrw"},
|
|
{id:"danmark", name:"Rejseplanen in Denmark"},
|
|
]
|
|
export default {
|
|
name: 'SearchBahn',
|
|
props: {
|
|
},
|
|
components: {
|
|
routing,
|
|
VTimePicker,
|
|
VDatePicker
|
|
},
|
|
data() {
|
|
return {
|
|
from: {name:"", id:null, choices:[], menu:false, update:null},
|
|
to: {name:"", id:null, choices:[], menu:false, update:null},
|
|
fromName : "",
|
|
toName : "",
|
|
connections: [],
|
|
showRouting: false,
|
|
time: {value:new Date().toLocaleTimeString("de", {hour: '2-digit', minute:'2-digit'}), menu:false},
|
|
date: {value:new Date(), menu:false},
|
|
services: services,
|
|
selectedService: services[0].id,
|
|
isMobile: this.$route.query.m,
|
|
}
|
|
},
|
|
methods: {
|
|
getDisplayClass(){
|
|
return this.isMobile ? "displaytall" : "displaywide";
|
|
},
|
|
searchStationFrom() {
|
|
client.get("/searchStation", {params: {text: this.fromName, service:this.selectedService}}).then(res => this.chooseFrom(res.data));
|
|
},
|
|
searchStationTo() {
|
|
client.get("/searchStation", {params: {text: this.toName, service:this.selectedService}}).then(res => this.chooseTo(res.data));
|
|
},
|
|
searchConnection() {
|
|
if (this.from.id && this.to.id){
|
|
client.get("/searchConnection", {params: {from: this.from.id, to:this.to.id, service:this.selectedService, date:this.getSelectedDate()}}).then(res => {this.connections = res.data;console.log(this.connections)});
|
|
this.showRouting = true;
|
|
}
|
|
},
|
|
getSelectedDate(){
|
|
let timeArray = this.time.value.split(":");
|
|
if (timeArray.length <= 1){
|
|
return new Date(this.date.value.getFullYear(), this.date.value.getMonth(), this.date.value.getDate())
|
|
}
|
|
console.log(this.date.value.getFullYear()+" "+this.date.value.getMonth()+" "+this.date.value.getDate()+" "+timeArray[0]+" "+timeArray[1])
|
|
console.log(new Date(this.date.value.getFullYear(), this.date.value.getMonth(), this.date.value.getDate(), timeArray[0], timeArray[1]))
|
|
return new Date(this.date.value.getFullYear(), this.date.value.getMonth(), this.date.value.getDate(), timeArray[0], timeArray[1])
|
|
},
|
|
timeLoadChoicesFrom(){
|
|
if (this.from.menu){
|
|
let time = Date.now()
|
|
this.from.update = time;
|
|
let timer = setInterval(() => {
|
|
if (time == this.from.update){
|
|
this.loadChoicesFrom();
|
|
}
|
|
clearInterval(timer);
|
|
}, 500);
|
|
}
|
|
},
|
|
timeLoadChoicesTo(){
|
|
if (this.to.menu){
|
|
let time = Date.now()
|
|
this.to.update = time;
|
|
console.log("timeLoadChoicesTo")
|
|
let timer = setInterval(() => {
|
|
if (time == this.to.update){
|
|
this.loadChoicesTo();
|
|
}
|
|
clearInterval(timer);
|
|
}, 500);
|
|
}
|
|
},
|
|
loadChoicesFrom(){
|
|
client.get("/searchStations", {params: {text: this.fromName, service: this.selectedService}}).then(res => this.from.choices = res.data);
|
|
},
|
|
loadChoicesTo(){
|
|
client.get("/searchStations", {params: {text: this.toName, service: this.selectedService}}).then(res => this.to.choices = res.data);
|
|
},
|
|
chooseFrom(choice){
|
|
this.fromName = choice.name;
|
|
this.from.id = choice.id;
|
|
this.from.menu = false;
|
|
},
|
|
chooseTo(choice){
|
|
this.toName = choice.name;
|
|
this.to.id = choice.id;
|
|
this.to.menu = false;
|
|
},
|
|
testAlert(){
|
|
alert("testAlert")
|
|
}
|
|
},
|
|
computed: {
|
|
formattedDate() {
|
|
return this.date.value.toLocaleDateString("de");
|
|
}
|
|
},
|
|
watch: {
|
|
fromName: function() {
|
|
this.timeLoadChoicesFrom();
|
|
},
|
|
toName: function() {
|
|
this.timeLoadChoicesTo();
|
|
},
|
|
selectedService: function() {
|
|
this.searchStationFrom();
|
|
this.searchStationTo();
|
|
},
|
|
|
|
},
|
|
}
|
|
</script>
|
|
|
|
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
<style scoped>
|
|
ul {
|
|
list-style-type: none;
|
|
padding: 0;
|
|
}
|
|
.displaywide {
|
|
display: inline-flex;
|
|
width: 95%;
|
|
}
|
|
.displaytall {
|
|
display: block;
|
|
}
|
|
.search > * {
|
|
padding: 10px;
|
|
}
|
|
div {
|
|
font-family:"Raveo-display-medium";
|
|
}
|
|
.walking > div {
|
|
font-size: 12px;
|
|
}
|
|
.inputTextField{
|
|
flex: 1;
|
|
margin-left: auto;
|
|
margin-right: auto;
|
|
}
|
|
.selectItem{
|
|
padding:7px;
|
|
background-color:white;
|
|
cursor: pointer;
|
|
}
|
|
@font-face {
|
|
font-family: "Raveo-display-bold";
|
|
src: url("../assets/Raveo Display Bold.woff2") format("opentype");
|
|
}
|
|
@font-face {
|
|
font-family: "Raveo-display-medium";
|
|
src: url("../assets/Raveo Display Medium.woff2") format("opentype");
|
|
}
|
|
|
|
</style>
|