diff --git a/config/routes/notification.yaml b/config/routes/notification.yaml
new file mode 100644
index 00000000..7bb58aa7
--- /dev/null
+++ b/config/routes/notification.yaml
@@ -0,0 +1,4 @@
+notification_ajax_list:
+ path: /ajax/notifications
+ controller: App\Controller\NotificationController::ajaxList
+ methods: [GET]
diff --git a/config/services.yaml b/config/services.yaml
index 3d9fd7a3..7d585e08 100644
--- a/config/services.yaml
+++ b/config/services.yaml
@@ -221,6 +221,12 @@ services:
event: 'postPersist'
entity: 'App\Entity\JobOrder'
+ App\Service\NotificationManager:
+ arguments:
+ $redis_prov: "@App\\Service\\RedisClientProvider"
+ $redis_mqtt_key: "mqtt_events"
+ $em: "@doctrine.orm.entity_manager"
+
App\Service\JobOrderCache:
arguments:
$redis_prov: "@App\\Service\\RedisClientProvider"
diff --git a/public/assets/js/notification.js b/public/assets/js/notification.js
new file mode 100644
index 00000000..bc1bfc40
--- /dev/null
+++ b/public/assets/js/notification.js
@@ -0,0 +1,95 @@
+class NotificationHandler {
+ constructor(options) {
+ this.options = options;
+ }
+
+ clearAll() {
+ // clear notification count
+ document.getElementById('notif-count').innerHTML = '';
+
+ // remove notifications
+ document.getElementById('notif-body').innerHTML = '';
+ }
+
+ loadAll() {
+ console.log('loading notifications');
+ // ajax load
+ var self = this;
+ var xhr = new XMLHttpRequest();
+ xhr.open('GET', this.options['notif_ajax_url']);
+ xhr.onload = function() {
+ if (xhr.status === 200) {
+ var data = JSON.parse(xhr.responseText);
+ var notifs = data.notifications;
+
+ // update notification count
+ var count_html = data.count;
+ document.getElementById('notif-count').innerHTML = count_html;
+
+ // do we have any notifications?
+ if (notifs.length <= 0)
+ return;
+
+ // add actual notifications
+ var notif_body = document.getElementById('notif-body');
+ notifs.forEach(function(notif) {
+ var notif_date = moment(notif.date).fromNow();
+
+ var notif_html = '
';
+ notif_html += '
';
+ notif_html += '
';
+ notif_html += '' + notif.text + '';
+ notif_html += '';
+ notif_html += '
';
+ notif_html += notif_date;
+ notif_html += '';
+ notif_html += '
';
+
+ notif_body.insertAdjacentHTML('beforeend', notif_html);
+ });
+ }
+
+ };
+ xhr.send();
+ }
+
+ listen(user_id, host, port, use_ssl = false) {
+ var d = new Date();
+ var client_id = "dash-" + user_id + "-" + d.getMonth() + "-" + d.getDate() + "-" + d.getHours() + "-" + d.getMinutes() + "-" + d.getSeconds() + "-" + d.getMilliseconds();
+
+ this.mqtt = new Paho.MQTT.Client(host, port, client_id);
+ var options = {
+ useSSL: use_ssl,
+ timeout: 3,
+ invocationContext: this,
+ onSuccess: this.onConnect.bind(this)
+ }
+
+ this.mqtt.onMessageArrived = this.onMessage.bind(this);
+
+ this.mqtt.connect(options);
+ }
+
+ onConnect(icontext) {
+ console.log('notification mqtt connected');
+ var my = icontext.invocationContext;
+
+ // subscribe to general notifications
+ my.mqtt.subscribe('user/0/notification');
+ }
+
+ onMessage(msg) {
+ console.log('notification event received');
+ // we don't care about messasge, we update
+ this.clearAll();
+ this.loadAll();
+ }
+
+ getIcon(type_id) {
+ if (type_id in this.options['icons']) {
+ return this.options['icons'][type_id];
+ }
+
+ return this.options['default_icon'];
+ }
+}
diff --git a/src/Controller/NotificationController.php b/src/Controller/NotificationController.php
new file mode 100644
index 00000000..54928528
--- /dev/null
+++ b/src/Controller/NotificationController.php
@@ -0,0 +1,80 @@
+sub(new DateInterval('PT10M'));
+ $notifs = [
+ [
+ 'id' => 1,
+ 'type' => 'jo_new',
+ 'date' => $date->format('Y-m-d\TH:i:s.000P'),
+ 'text' => 'Sample incoming job order',
+ 'link' => '#',
+ ], [
+ 'id' => 2,
+ 'type' => 'rider_accept',
+ 'date' => $date->format('Y-m-d\TH:i:s.000P'),
+ 'text' => 'Sample rider has accepted job order',
+ 'link' => '#',
+ ], [
+ 'id' => 3,
+ 'type' => 'jo_cancel',
+ 'date' => $date->format('Y-m-d\TH:i:s.000P'),
+ 'text' => 'Customer has cancelled job order.',
+ 'link' => '#',
+ ], [
+ 'id' => 3,
+ 'type' => 'rider_reject',
+ 'date' => $date->format('Y-m-d\TH:i:s.000P'),
+ 'text' => 'Rider has rejected job order. Job order needs to be reassigned.',
+ 'link' => '#',
+ ],
+ ];
+ $sample_data = [
+ 'count' => 4,
+ 'notifications' => $notifs,
+ ];
+ */
+
+ $notifs = $em->getRepository(Notification::class)->findBy(['user_id' => 0]);
+ $notif_data = [];
+
+ foreach ($notifs as $notif)
+ {
+ $notif_data[] = [
+ 'id' => $notif->getID(),
+ 'type' => 'jo_new',
+ 'date' => $notif->getDateCreate()->format('Y-m-d\TH:i:s.000P'),
+ 'text' => $notif->getMessage(),
+ 'link' => $notif->getURL(),
+ ];
+ }
+
+
+ $sample_data = [
+ 'count' => count($notif_data),
+ 'notifications' => $notif_data,
+ ];
+
+ $res = new JsonResponse($sample_data);
+
+ return $res;
+ }
+}
diff --git a/src/Entity/Notification.php b/src/Entity/Notification.php
new file mode 100644
index 00000000..c702ce25
--- /dev/null
+++ b/src/Entity/Notification.php
@@ -0,0 +1,139 @@
+id;
+ }
+
+ public function getDateCreate()
+ {
+ return $this->date_create;
+ }
+
+ public function setUserID($user_id)
+ {
+ $this->user_id = $user_id;
+ return $this;
+ }
+
+ public function getUserID()
+ {
+ return $this->user_id;
+ }
+
+ public function setIcon($icon)
+ {
+ $this->icon = $icon;
+ return $this;
+ }
+
+ public function getIcon()
+ {
+ return $this->icon;
+ }
+
+ public function setMessage($message)
+ {
+ $this->message = $message;
+ return $this;
+ }
+
+ public function getMessage()
+ {
+ return $this->message;
+ }
+
+ public function setURL($url)
+ {
+ $this->url = $url;
+ return $this;
+ }
+
+ public function getURL()
+ {
+ return $this->url;
+ }
+
+ public function setIsRead($bool = true)
+ {
+ $this->flag_read = $bool;
+ return $this;
+ }
+
+ public function isRead()
+ {
+ return $this->flag_read;
+ }
+
+ public function setIsFresh($bool = true)
+ {
+ $this->flag_fresh = $bool;
+ return $this;
+ }
+
+ public function isFresh()
+ {
+ return $this->flag_fresh;
+ }
+}
diff --git a/src/Service/NotificationManager.php b/src/Service/NotificationManager.php
new file mode 100644
index 00000000..f0a6deec
--- /dev/null
+++ b/src/Service/NotificationManager.php
@@ -0,0 +1,44 @@
+redis = $redis_prov->getRedisClient();
+ $this->redis_mqtt_key = $redis_mqtt_key;
+ $this->em = $em;
+ }
+
+ // set user_id to 0 for all
+ public function sendNotification($user_id, $msg)
+ {
+ // send mqtt
+ $chan = $this->getChannel($user_id);
+ $data = $chan . '|' . $msg;
+ $this->redis->lpush($this->redis_mqtt_key, $data);
+
+ // create notif
+ $notif = new Notification();
+
+ // save to db
+ $this->em->persist($notif);
+ $this->em->flush();
+ }
+
+ protected function getChannel($user_id)
+ {
+ return str_replace('{user_id}', $user_id, self::NOTIF_KEY );
+ }
+}
diff --git a/templates/base.html.twig b/templates/base.html.twig
index 5e5abfc2..21438dca 100644
--- a/templates/base.html.twig
+++ b/templates/base.html.twig
@@ -448,217 +448,50 @@
+
+
@@ -770,6 +605,25 @@
+
+
+
+
{% block scripts %}{% endblock %}