Skip to content

Commit

Permalink
✨ Improve StationAutocomplete + Departures in experimental (#2574)
Browse files Browse the repository at this point in the history
  • Loading branch information
HerrLevin authored May 20, 2024
1 parent 1735a9f commit 4187053
Show file tree
Hide file tree
Showing 11 changed files with 441 additions and 84 deletions.
2 changes: 0 additions & 2 deletions app/Http/Controllers/Frontend/VueFrontendController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

namespace App\Http\Controllers\Frontend;



use Illuminate\View\View;

class VueFrontendController
Expand Down
6 changes: 5 additions & 1 deletion lang/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -790,5 +790,9 @@
"trip_creation.limitations.2.small": "(wir versuchen, eine Route über Brouter zu finden, aber das funktioniert nicht immer zuverlässig)",
"trip_creation.limitations.3": "Der Trip wird öffentlich erstellt - wenn du also eincheckst, kann jeder, der deinen Status sehen kann, ebenfalls in diesen Trip einchecken.",
"trip_creation.limitations.4": "Der Betreiber kann in diesem Formular nicht festgelegt werden (über API möglich)",
"trip_creation.limitations.5": "Es gibt keine sichtbaren Fehlermeldungen für dieses Formular. Wenn also beim Absenden nichts passiert, liegt irgendwo ein Fehler vor."
"trip_creation.limitations.5": "Es gibt keine sichtbaren Fehlermeldungen für dieses Formular. Wenn also beim Absenden nichts passiert, liegt irgendwo ein Fehler vor.",
"action.error": "Diese Aktion konnte leider nicht ausgeführt werden. Bitte versuche es später noch einmal.",
"action.like": "Status liken",
"action.dislike": "Status nicht mehr liken",
"action.set-home": "Heimathaltestelle setzen"
}
6 changes: 5 additions & 1 deletion lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -790,5 +790,9 @@
"trip_creation.limitations.2.small": "(we try to approximate a route via Brouter, but this may not always work properly)",
"trip_creation.limitations.3": "The trip is created public - so if you check in to a trip, everyone who can see your status can also check in to this trip.",
"trip_creation.limitations.4": "The operator can't be set in this form (possible via API)",
"trip_creation.limitations.5": "There are no visible error messages for this form. So, if nothing happens on submit... sorry. There is an error."
"trip_creation.limitations.5": "There are no visible error messages for this form. So, if nothing happens on submit... sorry. There is an error.",
"action.error": "This action could not be executed. Please try again later.",
"action.like": "Like status",
"action.dislike": "Dislike status",
"action.set-home": "Set home station"
}
87 changes: 87 additions & 0 deletions resources/types/Departure.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
export type departureEntry = {
tripId: string;
stop: HafasStop;
when: string | null;
plannedWhen: string | null;
delay: number | null;
platform: string | null;
prognosisType: string;
direction: string;
provenance: any | null;
line: HafasLine;
remarks: any[];
origin: any;
destination: HafasDestination;
currentTripPosition: {
type: string;
latitude: number;
longitude: number
}
cancelled: boolean|null|undefined;
station: {
id: number;
ibnr: number;
wikidata_id: null|any;
ifopt_a: any|null;
ifopt_b: any|null;
ifopt_c: any|null;
ifopt_d: any|null;
ifopt_e: any|null;
rilIdentifier: string|null;
name: string;
latitude: number|null;
longitude: number|null;
ifopt: any|null;
}
}

export type HafasDestination = {
type: string;
id: string;
name: string;
location: HafasLocation;
products: {
[key: string]: boolean;
}
station: HafasStation;
}

export type HafasLine = {
type: string;
id: string;
fahrtNr: string;
name: string;
public: any;
adminCode: any;
productName: any;
mode: any;
product: any;
operator: any;
}

export type HafasStop = {
type: string;
id: string;
name: string;
location: HafasLocation;
products: {
[key: string]: boolean;
}
station: HafasStation
}
export type HafasStation = {
type: string;
id: string;
name: string;
location: HafasLocation;
products: {
[key: string]: boolean;
}
}

export type HafasLocation = {
type: string;
id: string;
latitude: number;
longitude: number;
}
17 changes: 17 additions & 0 deletions resources/types/User.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {ShortStation} from "./Station";

export type User = {
displayName: string,
username: string,
profilePicture: string,
trainDistance: number,
trainDuration: number,
points: number,
mastodonUrl: string|null,
privateProfile: boolean,
privacyHideDays: number,
preventIndex: boolean,
role: number,
home: ShortStation,
language: string
};
35 changes: 35 additions & 0 deletions resources/vue/components/Checkin/AutocompleteListEntry.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<script lang="ts">
import {defineComponent} from 'vue'
import {ShortStation} from "../../../types/Station";
export default defineComponent({
name: "AutocompleteListEntry",
props: {
station: {
type: Object () as ShortStation,
required: false
},
text: {
type: String,
required: false
},
prefix: {
type: String,
required: false
}
},
})
</script>

<template>
<li class="list-group-item autocomplete-item">
<a href="#" class="text-trwl">
<i v-show="prefix" :class="prefix"></i>
{{ station?.name || text }} <span v-if="station?.rilIdentifier">({{ station.rilIdentifier }})</span>
</a>
</li>
</template>

<style scoped lang="scss">

</style>
97 changes: 97 additions & 0 deletions resources/vue/components/Checkin/StationBoardEntry.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<script lang="ts">
import {defineComponent} from 'vue'
import ProductIcon from "../ProductIcon.vue";
import LineIndicator from "../LineIndicator.vue";
import {DateTime} from "luxon";
import {trans} from "laravel-vue-i18n";
import {departureEntry} from "../../../types/Departure";
export default defineComponent({
name: "StationBoardEntry",
components: {LineIndicator, ProductIcon},
props: {
item: {
type: Object() as departureEntry,
required: true
},
station: {
type: Object,
required: true
}
},
methods: {
trans,
formatTime(time: any) {
return DateTime.fromISO(time).toFormat("HH:mm");
},
},
computed: {
isPast(): boolean {
const when = this.item.when || this.item.plannedWhen;
if (!when) {
return false;
}
return DateTime.fromISO(when) < DateTime.now();
},
cancelled(): boolean {
return this.item.cancelled || false;
}
},
})
</script>

<template>
<div class="card mb-1 dep-card" :class="{'past-card': isPast, 'cancelled-card': cancelled}">
<div class="card-body d-flex py-0">
<div class="col-1 align-items-center d-flex justify-content-center">
<ProductIcon :product="item.line.product"/>
</div>
<div class="col-2 align-items-center d-flex me-3 justify-content-center">
<span class="sr-only" v-if="cancelled">{{ trans("stationboard.stop-cancelled") }}</span>
<LineIndicator
:productName="item.line.product"
:number="item.line.name !== null ? item.line.name : item.line.fahrtNr"
/>
</div>
<div class="col align-items-center d-flex second-stop">
<div>
<span class="fw-bold fs-6">{{ item.direction }}</span><br>
<span v-if="item.stop.name !== station.name" class="text-muted small font-italic">
{{ trans("stationboard.dep") }} {{ item.stop.name }}
</span>
</div>
</div>
<div class="col-auto ms-auto align-items-center d-flex">
<div v-if="item.delay">
<span class="text-muted text-decoration-line-through">
{{ formatTime(item.plannedWhen) }}<br>
</span>
<span>{{ formatTime(item.when) }}</span>
</div>
<div v-else>
<span>{{ formatTime(item.plannedWhen) }}</span>
</div>
</div>
</div>
</div>

</template>

<style scoped lang="scss">
@import "../../../sass/_variables.scss";
.dep-card {
min-height: 4.25rem;
}
.past-card {
opacity: 50%;
}
.cancelled-card {
opacity: 50%;
background-color: $red !important;
color: $white;
text-decoration: line-through;
text-decoration-thickness: 2px;
}
</style>
40 changes: 27 additions & 13 deletions resources/vue/components/CheckinLineRun.vue
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,16 @@ export default {
});
fetch(`/api/v1/trains/trip?${params.toString()}`).then((response) => {
response.json().then((result) => {
this.lineRun = result.data;
let remove = true;
this.lineRun = result.data;
let remove = true;
this.lineRun.stopovers = this.lineRun.stopovers.filter((item) => {
if (remove && item.evaIdentifier === Number(this.$props.selectedTrain.stop.id)) {
remove = false;
return false;
}
return !remove;
});
this.loading = false;
this.loading = false;
if (this.$props.fastCheckinIbnr) {
this.fastCheckin();
}
Expand Down Expand Up @@ -90,19 +90,33 @@ export default {
<ul class="timeline" v-else>
<li v-for="item in lineRun.stopovers" :key="item" @click.prevent="handleSetDestination(item)">
<i class="trwl-bulletpoint" aria-hidden="true"></i>
<span class="text-trwl float-end">
<small
class="text-muted text-decoration-line-through"
v-if="item.isArrivalDelayed || item.isDepartureDelayed">
{{
<span class="float-end" :class="{'text-trwl': !item.cancelled, 'cancelled-stop': item.cancelled}">
<small
:class="{'text-muted': !item.cancelled}"
class="text-decoration-line-through"
v-if="item.isArrivalDelayed || item.isDepartureDelayed">
{{
item.isArrivalDelayed ? formatTime(item.arrivalPlanned) : formatTime(item.departurePlanned)
}}
</small>
&nbsp;
<span>{{ formatTime(getTime(item)) }}</span>
</span>
</small>
&nbsp;
<span>{{ formatTime(getTime(item)) }}</span>
</span>

<a href="#" class="text-trwl clearfix">{{ item.name }}</a>
<a href="#" class="clearfix"
:class="{'text-trwl': !item.cancelled, 'cancelled-stop': item.cancelled}">{{ item.name }}</a>
</li>
</ul>
</template>

<style scoped lang="scss">
@import "../../sass/_variables.scss";
.cancelled-stop {
color: white !important;
opacity: 75%;
text-decoration-color: $red !important;
text-decoration-thickness: 2px !important;
text-decoration: line-through;
}
</style>
Loading

0 comments on commit 4187053

Please sign in to comment.