diff --git a/resources/components/messages.html b/resources/components/messages.html new file mode 100644 index 0000000..bf8a1b0 --- /dev/null +++ b/resources/components/messages.html @@ -0,0 +1,6 @@ +
\ No newline at end of file diff --git a/resources/styles/_common.scss b/resources/styles/_common.scss index f881228..f614019 100644 --- a/resources/styles/_common.scss +++ b/resources/styles/_common.scss @@ -34,7 +34,21 @@ padding-bottom: .5rem; } -%flex { +.flex { display: flex; align-items: center; +} + +.section__title { + @extend .alert; + @extend .alert-dark; + + font-size: medium; + background: transparent; + padding-top: .5rem; + padding-bottom: .5rem; + + &:hover { + background: none; + } } \ No newline at end of file diff --git a/resources/styles/_departure.scss b/resources/styles/_departure.scss index ef0d611..eec0796 100644 --- a/resources/styles/_departure.scss +++ b/resources/styles/_departure.scss @@ -8,7 +8,7 @@ } .departure__stop { - @extend %flex; + @extend .flex; width: 100%; .stop { @@ -27,12 +27,10 @@ } .departures__actions { - display: flex; - align-items: center; + @extend .flex; .departures__auto-refresh { - display: flex; - align-items: center; + @extend .flex; } .form-control { diff --git a/resources/styles/_line.scss b/resources/styles/_line.scss index 48d62f5..3404cdc 100644 --- a/resources/styles/_line.scss +++ b/resources/styles/_line.scss @@ -1,5 +1,5 @@ .line { - @extend %flex; + @extend .flex; .line__symbol { min-width: 4rem; @@ -7,7 +7,7 @@ } .track { - @extend %flex; + @extend .flex; flex-shrink: 0; flex-grow: 0; diff --git a/resources/styles/_stop.scss b/resources/styles/_stop.scss index 23ca5fc..20190d1 100644 --- a/resources/styles/_stop.scss +++ b/resources/styles/_stop.scss @@ -1,5 +1,5 @@ .stop, .stop-group__header { - @extend %flex; + @extend .flex; flex-wrap: wrap; } diff --git a/resources/ts/app.ts b/resources/ts/app.ts index ec9aed6..d1989d0 100644 --- a/resources/ts/app.ts +++ b/resources/ts/app.ts @@ -15,11 +15,23 @@ window['Popper'] = Popper; // dependencies import 'bootstrap' -import Vue from 'vue'; +import { Vue } from "vue-property-decorator"; // here goes "public" API window['czydojade'] = { components }; -window['app'] = new Vue({ el: '#app' }); \ No newline at end of file +window['app'] = new Vue({ + el: '#app', + data: { + messages: { + count: 0, + visible: true + } + }, methods: { + handleMessagesUpdate(messages) { + this.messages.count = messages.length; + } + } +}); \ No newline at end of file diff --git a/resources/ts/components/app.ts b/resources/ts/components/app.ts new file mode 100644 index 0000000..4790a56 --- /dev/null +++ b/resources/ts/components/app.ts @@ -0,0 +1,5 @@ +import Vue from 'vue' + +export class Application extends Vue { + private messages: boolean = true; +} \ No newline at end of file diff --git a/resources/ts/components/index.ts b/resources/ts/components/index.ts index b523d5c..b749140 100644 --- a/resources/ts/components/index.ts +++ b/resources/ts/components/index.ts @@ -1,4 +1,5 @@ export * from './utils' export * from './picker' export * from './departures' -export * from './stop' \ No newline at end of file +export * from './stop' +export * from './messages' \ No newline at end of file diff --git a/resources/ts/components/messages.ts b/resources/ts/components/messages.ts new file mode 100644 index 0000000..996236b --- /dev/null +++ b/resources/ts/components/messages.ts @@ -0,0 +1,45 @@ +import Vue from 'vue'; +import { Component, Prop, Watch } from "vue-property-decorator"; + +import messages = require("../../components/messages.html"); +import { Message } from "../model/message"; +import urls from "../urls"; + +import { faInfoCircle, faExclamationTriangle, faQuestionCircle } from "@fortawesome/pro-light-svg-icons"; + +@Component({ template: messages }) +export class MessagesComponent extends Vue { + public messages: Message[] = []; + + async mounted() { + this.update(); + } + + async update() { + const response = await fetch(urls.prepare(urls.messages)); + + if (response.ok) { + this.messages = await response.json(); + } + + this.$emit('updated', this.messages); + } + + public icon(message: Message) { + switch (message.type) { + case "breakdown": return faExclamationTriangle; + case "info": return faInfoCircle; + case "unknown": return faQuestionCircle; + } + } + + public type(message: Message) { + switch (message.type) { + case "breakdown": return "danger"; + case "info": return "info"; + case "unknown": return "warning"; + } + } +} + +Vue.component('Messages', MessagesComponent); \ No newline at end of file diff --git a/resources/ts/model/message.ts b/resources/ts/model/message.ts new file mode 100644 index 0000000..8a677a0 --- /dev/null +++ b/resources/ts/model/message.ts @@ -0,0 +1,10 @@ +import { Moment } from "moment"; + +export type MessageType = "info" | "breakdown" | "unknown"; +export interface Message { + type: MessageType; + message: string; + + validFrom: Moment; + validTo: Moment; +} \ No newline at end of file diff --git a/resources/ts/urls.ts b/resources/ts/urls.ts index 73c59c8..ca61a30 100644 --- a/resources/ts/urls.ts +++ b/resources/ts/urls.ts @@ -49,6 +49,7 @@ const base = '/{provider}/api/v1'; export default { departures: `${base}/departures`, + messages: `${base}/messages`, stops: { all: `${base}/stops`, search: `${base}/stops/search`, diff --git a/src/Provider/ZtmGdansk/ZtmGdanskMessageRepository.php b/src/Provider/ZtmGdansk/ZtmGdanskMessageRepository.php index ad01c9d..4da037c 100644 --- a/src/Provider/ZtmGdansk/ZtmGdanskMessageRepository.php +++ b/src/Provider/ZtmGdansk/ZtmGdanskMessageRepository.php @@ -18,13 +18,15 @@ class ZtmGdanskMessageRepository implements MessageRepository const MESSAGES_URL = "http://87.98.237.99:88/displayMessages"; private $cache; + private $classifier; /** * ZtmGdanskStopRepository constructor. */ - public function __construct(AdapterInterface $cache) + public function __construct(AdapterInterface $cache, ZtmGdanskMessageTypeClassifier $classifier) { - $this->cache = $cache; + $this->cache = $cache; + $this->classifier = $classifier; } public function getAll(): Collection @@ -32,12 +34,15 @@ class ZtmGdanskMessageRepository implements MessageRepository return collect($this->queryZtmApi())->unique(function ($message) { return $message['messagePart1'] . $message['messagePart2']; })->map(function ($message) { - return Message::createFromArray([ + $message = Message::createFromArray([ 'message' => trim($message['messagePart1'] . $message['messagePart2']), - 'type' => Message::TYPE_UNKNOWN, 'validFrom' => new Carbon($message['startDate']), 'validTo' => new Carbon($message['endDate']), ]); + + $message->setType($this->classifier->classify($message)); + + return $message; }); } diff --git a/src/Provider/ZtmGdansk/ZtmGdanskMessageTypeClassifier.php b/src/Provider/ZtmGdansk/ZtmGdanskMessageTypeClassifier.php new file mode 100644 index 0000000..ca67c54 --- /dev/null +++ b/src/Provider/ZtmGdansk/ZtmGdanskMessageTypeClassifier.php @@ -0,0 +1,22 @@ +getMessage()): + return Message::TYPE_BREAKDOWN; + + case preg_match('#gdansk.pl/powietrze#i', $message->getMessage()): + return Message::TYPE_INFO; + + default: + return Message::TYPE_UNKNOWN; + } + } +} \ No newline at end of file diff --git a/src/Provider/ZtmGdanskProvider.php b/src/Provider/ZtmGdanskProvider.php index 95ba876..fe98a23 100644 --- a/src/Provider/ZtmGdanskProvider.php +++ b/src/Provider/ZtmGdanskProvider.php @@ -20,7 +20,7 @@ class ZtmGdanskProvider implements Provider public function getName() { - return 'MZKZG Trójmiasto'; + return 'MZKZG - Trójmiasto'; } public function getIdentifier() diff --git a/templates/app.html.twig b/templates/app.html.twig index f65462b..5f4c41a 100644 --- a/templates/app.html.twig +++ b/templates/app.html.twig @@ -2,6 +2,18 @@ {% block title "#{parent()} - #{provider.name}" %} {% block body %} +