From 3c6af6d3f433070c3117fa0b605845099975746d Mon Sep 17 00:00:00 2001
From: Adam Stachowicz <adam.stachowicz@fingo.info>
Date: Tue, 27 Jul 2021 19:33:44 +0200
Subject: [PATCH 1/6] Add ESLint and StyleLint

---
 .eslintrc.js | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 .stylelintrc |  3 +++
 package.json | 13 +++++++---
 3 files changed, 85 insertions(+), 4 deletions(-)
 create mode 100644 .eslintrc.js
 create mode 100644 .stylelintrc

diff --git a/.eslintrc.js b/.eslintrc.js
new file mode 100644
index 00000000..cc0f1186
--- /dev/null
+++ b/.eslintrc.js
@@ -0,0 +1,73 @@
+module.exports = {
+    env: {
+        browser: true,
+        commonjs: true,
+        es2017: true,
+        node: true,
+    },
+    extends: [
+        "eslint:recommended",
+        "plugin:vue/vue3-recommended",
+    ],
+    parserOptions: {
+        ecmaVersion: 2018,
+        sourceType: "module",
+    },
+    rules: {
+        // override/add rules settings here, such as:
+        // 'vue/no-unused-vars': 'error'
+        indent: ["error", 4],
+        quotes: ["warn", "double"],
+        //semi: ['off', 'never'],
+        "vue/html-indent": ["warn", 4], // default: 2
+        "vue/max-attributes-per-line": "off",
+        "no-multi-spaces": ["error", {
+            ignoreEOLComments: true,
+        }],
+        "curly": "error",
+        "object-curly-spacing": ["error", "always"],
+        "object-curly-newline": ["error", {
+            "ObjectExpression": {
+                "minProperties": 1,
+            },
+            "ObjectPattern": {
+                "multiline": true,
+                "minProperties": 2,
+            },
+            "ImportDeclaration": {
+                "multiline": true,
+            },
+            "ExportDeclaration": {
+                "multiline": true,
+                //'minProperties': 2,
+            },
+        }],
+        "object-property-newline": "error",
+        "comma-spacing": "error",
+        "brace-style": "error",
+        "no-var": "error",
+        "key-spacing": "warn",
+        "keyword-spacing": "warn",
+        "space-infix-ops": "warn",
+        "arrow-spacing": "warn",
+        "no-trailing-spaces": "warn",
+        "space-before-blocks": "warn",
+        //'no-console': 'warn',
+        "no-extra-boolean-cast": "off",
+        "no-multiple-empty-lines": ["warn", {
+            "max": 1,
+            "maxBOF": 0,
+        }],
+        "lines-between-class-members": ["warn", "always", {
+            exceptAfterSingleLine: true,
+        }],
+        "no-unneeded-ternary": "error",
+        "no-else-return": ["error", {
+            "allowElseIf": false,
+        }],
+        "array-bracket-newline": ["error", "consistent"],
+        "eol-last": ["error", "always"],
+        //'prefer-template': 'error',
+        "comma-dangle": ["warn", "always-multiline"],
+    },
+}
diff --git a/.stylelintrc b/.stylelintrc
new file mode 100644
index 00000000..4d3d9d1f
--- /dev/null
+++ b/.stylelintrc
@@ -0,0 +1,3 @@
+{
+  "extends": "stylelint-config-recommended",
+}
diff --git a/package.json b/package.json
index d4fe6888..7069e3ed 100644
--- a/package.json
+++ b/package.json
@@ -45,11 +45,16 @@
         "vue-toastification": "^2.0.0-rc.1"
     },
     "devDependencies": {
-        "@vitejs/plugin-legacy": "^1.4.4",
-        "@vitejs/plugin-vue": "^1.2.5",
+        "@vitejs/plugin-legacy": "^1.5.0",
+        "@vitejs/plugin-vue": "^1.3.0",
         "@vue/compiler-sfc": "^3.1.5",
         "core-js": "^3.15.2",
-        "sass": "^1.35.2",
-        "vite": "^2.4.2"
+        "eslint": "^7.31.0",
+        "eslint-plugin-vue": "^7.14.0",
+        "sass": "^1.36.0",
+        "stylelint": "^13.13.1",
+        "stylelint-config-recommended": "^5.0.0",
+        "stylelint-config-standard": "^22.0.0",
+        "vite": "^2.4.4"
     }
 }

From 9648d700d7e6c8a8754ae7cbc0a4788354fa28f9 Mon Sep 17 00:00:00 2001
From: Adam Stachowicz <adam.stachowicz@fingo.info>
Date: Tue, 27 Jul 2021 19:47:13 +0200
Subject: [PATCH 2/6] Autofix on save

---
 server/auth.js                        |  16 +-
 server/model/heartbeat.js             |   7 +-
 server/notification.js                | 204 ++++----
 server/password-hash.js               |   8 +-
 server/ping-lite.js                   |  83 +--
 server/server.js                      | 138 +++--
 server/util-server.js                 |  17 +-
 server/util.js                        |   1 -
 src/App.vue                           |   4 +-
 src/components/Confirm.vue            |  32 +-
 src/components/CountUp.vue            |  22 +-
 src/components/Datetime.vue           |  10 +-
 src/components/HeartbeatBar.vue       |  71 ++-
 src/components/Login.vue              |  19 +-
 src/components/NotificationDialog.vue | 265 +++++-----
 src/components/Status.vue             |  20 +-
 src/components/Uptime.vue             |  26 +-
 src/icon.js                           |  10 +-
 src/layouts/EmptyLayout.vue           |   4 +-
 src/layouts/Layout.vue                |  51 +-
 src/main.js                           |  57 +-
 src/mixins/socket.js                  |  56 +-
 src/pages/Dashboard.vue               |  36 +-
 src/pages/DashboardHome.vue           |  64 +--
 src/pages/Details.vue                 | 101 ++--
 src/pages/EditMonitor.vue             | 129 +++--
 src/pages/Settings.vue                |  76 +--
 src/pages/Setup.vue                   |  28 +-
 src/util-frontend.js                  | 716 +++++++++++++-------------
 29 files changed, 1182 insertions(+), 1089 deletions(-)

diff --git a/server/auth.js b/server/auth.js
index b4d13d68..54182bde 100644
--- a/server/auth.js
+++ b/server/auth.js
@@ -1,6 +1,6 @@
-const basicAuth = require('express-basic-auth')
-const passwordHash = require('./password-hash');
-const {R} = require("redbean-node");
+const basicAuth = require("express-basic-auth")
+const passwordHash = require("./password-hash");
+const { R } = require("redbean-node");
 
 /**
  *
@@ -10,7 +10,7 @@ const {R} = require("redbean-node");
  */
 exports.login = async function (username, password) {
     let user = await R.findOne("user", " username = ? AND active = 1 ", [
-        username
+        username,
     ])
 
     if (user && passwordHash.verify(password, user.password)) {
@@ -18,13 +18,13 @@ exports.login = async function (username, password) {
         if (passwordHash.needRehash(user.password)) {
             await R.exec("UPDATE `user` SET password = ? WHERE id = ? ", [
                 passwordHash.generate(password),
-                user.id
+                user.id,
             ]);
         }
         return user;
-    } else {
-        return null;
     }
+
+    return null;
 }
 
 function myAuthorizer(username, password, callback) {
@@ -36,5 +36,5 @@ function myAuthorizer(username, password, callback) {
 exports.basicAuth = basicAuth({
     authorizer: myAuthorizer,
     authorizeAsync: true,
-    challenge: true
+    challenge: true,
 });
diff --git a/server/model/heartbeat.js b/server/model/heartbeat.js
index 01fb71ff..0e492ada 100644
--- a/server/model/heartbeat.js
+++ b/server/model/heartbeat.js
@@ -1,10 +1,9 @@
 const dayjs = require("dayjs");
-const utc = require('dayjs/plugin/utc')
-var timezone = require('dayjs/plugin/timezone')
+const utc = require("dayjs/plugin/utc")
+let timezone = require("dayjs/plugin/timezone")
 dayjs.extend(utc)
 dayjs.extend(timezone)
-const {BeanModel} = require("redbean-node/dist/bean-model");
-
+const { BeanModel } = require("redbean-node/dist/bean-model");
 
 /**
  * status:
diff --git a/server/notification.js b/server/notification.js
index 9da8a0dc..f4cd08af 100644
--- a/server/notification.js
+++ b/server/notification.js
@@ -1,6 +1,6 @@
 const axios = require("axios");
-const {R} = require("redbean-node");
-const FormData = require('form-data');
+const { R } = require("redbean-node");
+const FormData = require("form-data");
 const nodemailer = require("nodemailer");
 const child_process = require("child_process");
 
@@ -24,7 +24,7 @@ class Notification {
                     params: {
                         chat_id: notification.telegramChatID,
                         text: msg,
-                    }
+                    },
                 })
                 return okMsg;
 
@@ -41,7 +41,7 @@ class Notification {
                 await axios.post(`${notification.gotifyserverurl}/message?token=${notification.gotifyapplicationToken}`, {
                     "message": msg,
                     "priority": notification.gotifyPriority || 8,
-                    "title": "Uptime-Kuma"
+                    "title": "Uptime-Kuma",
                 })
 
                 return okMsg;
@@ -62,10 +62,10 @@ class Notification {
 
                 if (notification.webhookContentType === "form-data") {
                     finalData = new FormData();
-                    finalData.append('data', JSON.stringify(data));
+                    finalData.append("data", JSON.stringify(data));
 
                     config = {
-                        headers: finalData.getHeaders()
+                        headers: finalData.getHeaders(),
                     }
 
                 } else {
@@ -84,63 +84,68 @@ class Notification {
 
         } else if (notification.type === "discord") {
             try {
-              // If heartbeatJSON is null, assume we're testing.
-              if(heartbeatJSON == null) {
+                // If heartbeatJSON is null, assume we're testing.
+                if (heartbeatJSON == null) {
+                    let data = {
+                        username: "Uptime-Kuma",
+                        content: msg,
+                    }
+                    await axios.post(notification.discordWebhookUrl, data)
+                    return okMsg;
+                }
+                // If heartbeatJSON is not null, we go into the normal alerting loop.
+                if (heartbeatJSON["status"] == 0) {
+                    var alertColor = "16711680";
+                } else if (heartbeatJSON["status"] == 1) {
+                    var alertColor = "65280";
+                }
                 let data = {
-                  username: 'Uptime-Kuma',
-                  content: msg
+                    username: "Uptime-Kuma",
+                    embeds: [{
+                        title: "Uptime-Kuma Alert",
+                        color: alertColor,
+                        fields: [
+                            {
+                                name: "Time (UTC)",
+                                value: heartbeatJSON["time"],
+                            },
+                            {
+                                name: "Message",
+                                value: msg,
+                            },
+                        ],
+                    }],
                 }
                 await axios.post(notification.discordWebhookUrl, data)
                 return okMsg;
-              }
-              // If heartbeatJSON is not null, we go into the normal alerting loop.
-              if(heartbeatJSON['status'] == 0) {
-                var alertColor = "16711680";
-              } else if(heartbeatJSON['status'] == 1) {
-                var alertColor = "65280";
-              }
-              let data = {
-                username: 'Uptime-Kuma',
-                embeds: [{
-                  title: "Uptime-Kuma Alert",
-                  color: alertColor,
-                  fields: [
-                    {
-                      name: "Time (UTC)",
-                      value: heartbeatJSON["time"]
-                    },
-                    {
-                      name: "Message",
-                      value: msg
-                    }
-                  ]
-                }]
-              }
-              await axios.post(notification.discordWebhookUrl, data)
-              return okMsg;
-            } catch(error) {
-              throwGeneralAxiosError(error)
+            } catch (error) {
+                throwGeneralAxiosError(error)
             }
 
         } else if (notification.type === "signal") {
-          try {
-            let data = {
-              "message": msg,
-              "number": notification.signalNumber,
-              "recipients": notification.signalRecipients.replace(/\s/g, '').split(",")
-            };
-            let config = {};
+            try {
+                let data = {
+                    "message": msg,
+                    "number": notification.signalNumber,
+                    "recipients": notification.signalRecipients.replace(/\s/g, "").split(","),
+                };
+                let config = {};
 
-            await axios.post(notification.signalURL, data, config)
-            return okMsg;
-        } catch (error) {
-              throwGeneralAxiosError(error)
-        }
+                await axios.post(notification.signalURL, data, config)
+                return okMsg;
+            } catch (error) {
+                throwGeneralAxiosError(error)
+            }
 
         } else if (notification.type === "slack") {
             try {
                 if (heartbeatJSON == null) {
-                    let data = {'text': "Uptime Kuma Slack testing successful.", 'channel': notification.slackchannel, 'username': notification.slackusername, 'icon_emoji': notification.slackiconemo}
+                    let data = {
+                        "text": "Uptime Kuma Slack testing successful.",
+                        "channel": notification.slackchannel,
+                        "username": notification.slackusername,
+                        "icon_emoji": notification.slackiconemo,
+                    }
                     await axios.post(notification.slackwebhookURL, data)
                     return okMsg;
                 }
@@ -148,44 +153,42 @@ class Notification {
                 const time = heartbeatJSON["time"];
                 let data = {
                     "text": "Uptime Kuma Alert",
-                    "channel":notification.slackchannel,
+                    "channel": notification.slackchannel,
                     "username": notification.slackusername,
                     "icon_emoji": notification.slackiconemo,
                     "blocks": [{
-                            "type": "header",
-                            "text": {
-                                "type": "plain_text",
-                                "text": "Uptime Kuma Alert"
-                            }
+                        "type": "header",
+                        "text": {
+                            "type": "plain_text",
+                            "text": "Uptime Kuma Alert",
+                        },
+                    },
+                    {
+                        "type": "section",
+                        "fields": [{
+                            "type": "mrkdwn",
+                            "text": "*Message*\n" + msg,
                         },
                         {
-                            "type": "section",
-                            "fields": [{
-                                    "type": "mrkdwn",
-                                    "text": '*Message*\n'+msg
+                            "type": "mrkdwn",
+                            "text": "*Time (UTC)*\n" + time,
+                        }],
+                    },
+                    {
+                        "type": "actions",
+                        "elements": [
+                            {
+                                "type": "button",
+                                "text": {
+                                    "type": "plain_text",
+                                    "text": "Visit Uptime Kuma",
                                 },
-                                {
-                                    "type": "mrkdwn",
-                                    "text": "*Time (UTC)*\n"+time
-                                }
-                            ]
-                        },
-                        {
-                            "type": "actions",
-                            "elements": [
-                                {
-                                    "type": "button",
-                                    "text": {
-                                            "type": "plain_text",
-                                            "text": "Visit Uptime Kuma",
-                                        },
-                                    "value": "Uptime-Kuma",
-                                    "url": notification.slackbutton || "https://github.com/louislam/uptime-kuma"
-                                }
-                                ]
-                            }
-                        ]
-                    }
+                                "value": "Uptime-Kuma",
+                                "url": notification.slackbutton || "https://github.com/louislam/uptime-kuma",
+                            },
+                        ],
+                    }],
+                }
                 await axios.post(notification.slackwebhookURL, data)
                 return okMsg;
             } catch (error) {
@@ -193,27 +196,35 @@ class Notification {
             }
 
         } else if (notification.type === "pushover") {
-                    var pushoverlink = 'https://api.pushover.net/1/messages.json'
+            let pushoverlink = "https://api.pushover.net/1/messages.json"
             try {
                 if (heartbeatJSON == null) {
-                    let data = {'message': "<b>Uptime Kuma Pushover testing successful.</b>",
-                    'user': notification.pushoveruserkey, 'token': notification.pushoverapptoken, 'sound':notification.pushoversounds,
-                    'priority': notification.pushoverpriority, 'title':notification.pushovertitle, 'retry': "30", 'expire':"3600", 'html': 1}
+                    let data = {
+                        "message": "<b>Uptime Kuma Pushover testing successful.</b>",
+                        "user": notification.pushoveruserkey,
+                        "token": notification.pushoverapptoken,
+                        "sound": notification.pushoversounds,
+                        "priority": notification.pushoverpriority,
+                        "title": notification.pushovertitle,
+                        "retry": "30",
+                        "expire": "3600",
+                        "html": 1,
+                    }
                     await axios.post(pushoverlink, data)
                     return okMsg;
                 }
 
                 let data = {
-                    "message": "<b>Uptime Kuma Alert</b>\n\n<b>Message</b>:"+msg+ '\n<b>Time (UTC)</b>:' +heartbeatJSON["time"],
-                    "user":notification.pushoveruserkey,
+                    "message": "<b>Uptime Kuma Alert</b>\n\n<b>Message</b>:" + msg + "\n<b>Time (UTC)</b>:" + heartbeatJSON["time"],
+                    "user": notification.pushoveruserkey,
                     "token": notification.pushoverapptoken,
                     "sound": notification.pushoversounds,
                     "priority": notification.pushoverpriority,
                     "title": notification.pushovertitle,
                     "retry": "30",
                     "expire": "3600",
-                    "html": 1
-                    }
+                    "html": 1,
+                }
                 await axios.post(pushoverlink, data)
                 return okMsg;
             } catch (error) {
@@ -291,24 +302,23 @@ class Notification {
     static async apprise(notification, msg) {
         let s = child_process.spawnSync("apprise", [ "-vv", "-b", msg, notification.appriseURL])
 
-
-        let output = (s.stdout) ? s.stdout.toString() : 'ERROR: maybe apprise not found';
+        let output = (s.stdout) ? s.stdout.toString() : "ERROR: maybe apprise not found";
 
         if (output) {
 
             if (! output.includes("ERROR")) {
                 return "Sent Successfully";
-            } else {
-                throw new Error(output)
             }
+            throw new Error(output)
+
         } else {
             return ""
         }
     }
 
     static checkApprise() {
-        let commandExistsSync = require('command-exists').sync;
-        let exists = commandExistsSync('apprise');
+        let commandExistsSync = require("command-exists").sync;
+        let exists = commandExistsSync("apprise");
         return exists;
     }
 
diff --git a/server/password-hash.js b/server/password-hash.js
index 39bc0c20..52e26b95 100644
--- a/server/password-hash.js
+++ b/server/password-hash.js
@@ -1,5 +1,5 @@
-const passwordHashOld = require('password-hash');
-const bcrypt = require('bcrypt');
+const passwordHashOld = require("password-hash");
+const bcrypt = require("bcrypt");
 const saltRounds = 10;
 
 exports.generate = function (password) {
@@ -9,9 +9,9 @@ exports.generate = function (password) {
 exports.verify = function (password, hash) {
     if (isSHA1(hash)) {
         return passwordHashOld.verify(password, hash)
-    } else {
-        return bcrypt.compareSync(password, hash);
     }
+
+    return bcrypt.compareSync(password, hash);
 }
 
 function isSHA1(hash) {
diff --git a/server/ping-lite.js b/server/ping-lite.js
index e290d887..337bc0d3 100644
--- a/server/ping-lite.js
+++ b/server/ping-lite.js
@@ -1,9 +1,9 @@
 // https://github.com/ben-bradley/ping-lite/blob/master/ping-lite.js
 // Fixed on Windows
 
-var spawn = require('child_process').spawn,
-    events = require('events'),
-    fs = require('fs'),
+let spawn = require("child_process").spawn,
+    events = require("events"),
+    fs = require("fs"),
     WIN = /^win/.test(process.platform),
     LIN = /^linux/.test(process.platform),
     MAC = /^darwin/.test(process.platform);
@@ -11,8 +11,9 @@ var spawn = require('child_process').spawn,
 module.exports = Ping;
 
 function Ping(host, options) {
-    if (!host)
-        throw new Error('You must specify a host to ping!');
+    if (!host) {
+        throw new Error("You must specify a host to ping!");
+    }
 
     this._host = host;
     this._options = options = (options || {});
@@ -20,26 +21,24 @@ function Ping(host, options) {
     events.EventEmitter.call(this);
 
     if (WIN) {
-        this._bin = 'c:/windows/system32/ping.exe';
-        this._args = (options.args) ? options.args : [ '-n', '1', '-w', '5000', host ];
+        this._bin = "c:/windows/system32/ping.exe";
+        this._args = (options.args) ? options.args : [ "-n", "1", "-w", "5000", host ];
         this._regmatch = /[><=]([0-9.]+?)ms/;
-    }
-    else if (LIN) {
-        this._bin = '/bin/ping';
-        this._args = (options.args) ? options.args : [ '-n', '-w', '2', '-c', '1', host ];
+    } else if (LIN) {
+        this._bin = "/bin/ping";
+        this._args = (options.args) ? options.args : [ "-n", "-w", "2", "-c", "1", host ];
         this._regmatch = /=([0-9.]+?) ms/; // need to verify this
-    }
-    else if (MAC) {
-        this._bin = '/sbin/ping';
-        this._args = (options.args) ? options.args : [ '-n', '-t', '2', '-c', '1', host ];
+    } else if (MAC) {
+        this._bin = "/sbin/ping";
+        this._args = (options.args) ? options.args : [ "-n", "-t", "2", "-c", "1", host ];
         this._regmatch = /=([0-9.]+?) ms/;
-    }
-    else {
-        throw new Error('Could not detect your ping binary.');
+    } else {
+        throw new Error("Could not detect your ping binary.");
     }
 
-    if (!fs.existsSync(this._bin))
-        throw new Error('Could not detect '+this._bin+' on your system');
+    if (!fs.existsSync(this._bin)) {
+        throw new Error("Could not detect " + this._bin + " on your system");
+    }
 
     this._i = 0;
 
@@ -51,48 +50,56 @@ Ping.prototype.__proto__ = events.EventEmitter.prototype;
 // SEND A PING
 // ===========
 Ping.prototype.send = function(callback) {
-    var self = this;
+    let self = this;
     callback = callback || function(err, ms) {
-        if (err) return self.emit('error', err);
-        else     return self.emit('result', ms);
+        if (err) {
+            return self.emit("error", err);
+        }
+        return self.emit("result", ms);
     };
 
-    var _ended, _exited, _errored;
+    let _ended, _exited, _errored;
 
     this._ping = spawn(this._bin, this._args); // spawn the binary
 
-    this._ping.on('error', function(err) { // handle binary errors
+    this._ping.on("error", function(err) { // handle binary errors
         _errored = true;
         callback(err);
     });
 
-    this._ping.stdout.on('data', function(data) { // log stdout
-        this._stdout = (this._stdout || '') + data;
+    this._ping.stdout.on("data", function(data) { // log stdout
+        this._stdout = (this._stdout || "") + data;
     });
 
-    this._ping.stdout.on('end', function() {
+    this._ping.stdout.on("end", function() {
         _ended = true;
-        if (_exited && !_errored) onEnd.call(self._ping);
+        if (_exited && !_errored) {
+            onEnd.call(self._ping);
+        }
     });
 
-    this._ping.stderr.on('data', function(data) { // log stderr
-        this._stderr = (this._stderr || '') + data;
+    this._ping.stderr.on("data", function(data) { // log stderr
+        this._stderr = (this._stderr || "") + data;
     });
 
-    this._ping.on('exit', function(code) { // handle complete
+    this._ping.on("exit", function(code) { // handle complete
         _exited = true;
-        if (_ended && !_errored) onEnd.call(self._ping);
+        if (_ended && !_errored) {
+            onEnd.call(self._ping);
+        }
     });
 
     function onEnd() {
-        var stdout = this.stdout._stdout,
+        let stdout = this.stdout._stdout,
             stderr = this.stderr._stderr,
             ms;
 
-        if (stderr)
+        if (stderr) {
             return callback(new Error(stderr));
-        else if (!stdout)
-            return callback(new Error('No stdout detected'));
+        }
+        if (!stdout) {
+            return callback(new Error("No stdout detected"));
+        }
 
         ms = stdout.match(self._regmatch); // parse out the ##ms response
         ms = (ms && ms[1]) ? Number(ms[1]) : ms;
@@ -104,7 +111,7 @@ Ping.prototype.send = function(callback) {
 // CALL Ping#send(callback) ON A TIMER
 // ===================================
 Ping.prototype.start = function(callback) {
-    var self = this;
+    let self = this;
     this._i = setInterval(function() {
         self.send(callback);
     }, (self._options.interval || 5000));
diff --git a/server/server.js b/server/server.js
index 2014d927..5b76b796 100644
--- a/server/server.js
+++ b/server/server.js
@@ -1,23 +1,23 @@
 console.log("Welcome to Uptime Kuma ")
 console.log("Importing libraries")
-const express = require('express');
-const http = require('http');
+const express = require("express");
+const http = require("http");
 const { Server } = require("socket.io");
 const dayjs = require("dayjs");
-const {R} = require("redbean-node");
-const jwt = require('jsonwebtoken');
+const { R } = require("redbean-node");
+const jwt = require("jsonwebtoken");
 const Monitor = require("./model/monitor");
 const fs = require("fs");
-const {getSettings} = require("./util-server");
-const {Notification} = require("./notification")
-const gracefulShutdown = require('http-graceful-shutdown');
+const { getSettings } = require("./util-server");
+const { Notification } = require("./notification")
+const gracefulShutdown = require("http-graceful-shutdown");
 const Database = require("./database");
-const {sleep} = require("./util");
-const args = require('args-parser')(process.argv);
-const prometheusAPIMetrics = require('prometheus-api-metrics');
+const { sleep } = require("./util");
+const args = require("args-parser")(process.argv);
+const prometheusAPIMetrics = require("prometheus-api-metrics");
 const { basicAuth } = require("./auth");
-const {login} = require("./auth");
-const version = require('../package.json').version;
+const { login } = require("./auth");
+const version = require("../package.json").version;
 const hostname = args.host || "0.0.0.0"
 const port = args.port || 3001
 
@@ -63,12 +63,12 @@ let needSetup = false;
 
     // Normal Router here
 
-    app.use('/', express.static("dist"));
+    app.use("/", express.static("dist"));
 
     // Basic Auth Router here
 
     // For testing
-    basicAuthRouter.get('/test-auth', (req, res) => {
+    basicAuthRouter.get("/test-auth", (req, res) => {
         res.end("OK")
     });
 
@@ -77,12 +77,12 @@ let needSetup = false;
     basicAuthRouter.use(prometheusAPIMetrics())
 
     // Universal Route Handler, must be at the end
-    app.get('*', function(request, response, next) {
-        response.sendFile(process.cwd() + '/dist/index.html');
+    app.get("*", function(request, response, next) {
+        response.sendFile(process.cwd() + "/dist/index.html");
     });
 
     console.log("Adding socket handler")
-    io.on('connection', async (socket) => {
+    io.on("connection", async (socket) => {
 
         socket.emit("info", {
             version,
@@ -95,7 +95,7 @@ let needSetup = false;
             socket.emit("setup")
         }
 
-        socket.on('disconnect', () => {
+        socket.on("disconnect", () => {
             totalClient--;
         });
 
@@ -109,7 +109,7 @@ let needSetup = false;
                 console.log("Username from JWT: " + decoded.username)
 
                 let user = await R.findOne("user", " username = ? AND active = 1 ", [
-                    decoded.username
+                    decoded.username,
                 ])
 
                 if (user) {
@@ -121,13 +121,13 @@ let needSetup = false;
                 } else {
                     callback({
                         ok: false,
-                        msg: "The user is inactive or deleted."
+                        msg: "The user is inactive or deleted.",
                     })
                 }
             } catch (error) {
                 callback({
                     ok: false,
-                    msg: "Invalid token."
+                    msg: "Invalid token.",
                 })
             }
 
@@ -144,13 +144,13 @@ let needSetup = false;
                 callback({
                     ok: true,
                     token: jwt.sign({
-                        username: data.username
-                    }, jwtSecret)
+                        username: data.username,
+                    }, jwtSecret),
                 })
             } else {
                 callback({
                     ok: false,
-                    msg: "Incorrect username or password."
+                    msg: "Incorrect username or password.",
                 })
             }
 
@@ -181,13 +181,13 @@ let needSetup = false;
 
                 callback({
                     ok: true,
-                    msg: "Added Successfully."
+                    msg: "Added Successfully.",
                 });
 
             } catch (e) {
                 callback({
                     ok: false,
-                    msg: e.message
+                    msg: e.message,
                 });
             }
         });
@@ -214,13 +214,13 @@ let needSetup = false;
                 callback({
                     ok: true,
                     msg: "Added Successfully.",
-                    monitorID: bean.id
+                    monitorID: bean.id,
                 });
 
             } catch (e) {
                 callback({
                     ok: false,
-                    msg: e.message
+                    msg: e.message,
                 });
             }
         });
@@ -257,14 +257,14 @@ let needSetup = false;
                 callback({
                     ok: true,
                     msg: "Saved.",
-                    monitorID: bean.id
+                    monitorID: bean.id,
                 });
 
             } catch (e) {
                 console.error(e)
                 callback({
                     ok: false,
-                    msg: e.message
+                    msg: e.message,
                 });
             }
         });
@@ -288,7 +288,7 @@ let needSetup = false;
             } catch (e) {
                 callback({
                     ok: false,
-                    msg: e.message
+                    msg: e.message,
                 });
             }
         });
@@ -302,13 +302,13 @@ let needSetup = false;
 
                 callback({
                     ok: true,
-                    msg: "Resumed Successfully."
+                    msg: "Resumed Successfully.",
                 });
 
             } catch (e) {
                 callback({
                     ok: false,
-                    msg: e.message
+                    msg: e.message,
                 });
             }
         });
@@ -321,14 +321,13 @@ let needSetup = false;
 
                 callback({
                     ok: true,
-                    msg: "Paused Successfully."
+                    msg: "Paused Successfully.",
                 });
 
-
             } catch (e) {
                 callback({
                     ok: false,
-                    msg: e.message
+                    msg: e.message,
                 });
             }
         });
@@ -346,12 +345,12 @@ let needSetup = false;
 
                 await R.exec("DELETE FROM monitor WHERE id = ? AND user_id = ? ", [
                     monitorID,
-                    socket.userID
+                    socket.userID,
                 ]);
 
                 callback({
                     ok: true,
-                    msg: "Deleted Successfully."
+                    msg: "Deleted Successfully.",
                 });
 
                 await sendMonitorList(socket);
@@ -359,7 +358,7 @@ let needSetup = false;
             } catch (e) {
                 callback({
                     ok: false,
-                    msg: e.message
+                    msg: e.message,
                 });
             }
         });
@@ -373,19 +372,19 @@ let needSetup = false;
                 }
 
                 let user = await R.findOne("user", " id = ? AND active = 1 ", [
-                    socket.userID
+                    socket.userID,
                 ])
 
                 if (user && passwordHash.verify(password.currentPassword, user.password)) {
 
                     await R.exec("UPDATE `user` SET password = ? WHERE id = ? ", [
                         passwordHash.generate(password.newPassword),
-                        socket.userID
+                        socket.userID,
                     ]);
 
                     callback({
                         ok: true,
-                        msg: "Password has been updated successfully."
+                        msg: "Password has been updated successfully.",
                     })
                 } else {
                     throw new Error("Incorrect current password")
@@ -394,7 +393,7 @@ let needSetup = false;
             } catch (e) {
                 callback({
                     ok: false,
-                    msg: e.message
+                    msg: e.message,
                 });
             }
         });
@@ -403,7 +402,6 @@ let needSetup = false;
             try {
                 checkLogin(socket)
 
-
                 callback({
                     ok: true,
                     data: await getSettings(type),
@@ -412,7 +410,7 @@ let needSetup = false;
             } catch (e) {
                 callback({
                     ok: false,
-                    msg: e.message
+                    msg: e.message,
                 });
             }
         });
@@ -433,7 +431,7 @@ let needSetup = false;
             } catch (e) {
                 callback({
                     ok: false,
-                    msg: e.message
+                    msg: e.message,
                 });
             }
         });
@@ -453,7 +451,7 @@ let needSetup = false;
             } catch (e) {
                 callback({
                     ok: false,
-                    msg: e.message
+                    msg: e.message,
                 });
             }
         });
@@ -466,7 +464,7 @@ let needSetup = false;
 
                 callback({
                     ok: true,
-                    msg
+                    msg,
                 });
 
             } catch (e) {
@@ -474,7 +472,7 @@ let needSetup = false;
 
                 callback({
                     ok: false,
-                    msg: e.message
+                    msg: e.message,
                 });
             }
         });
@@ -499,7 +497,7 @@ let needSetup = false;
 
 async function updateMonitorNotification(monitorID, notificationIDList) {
     R.exec("DELETE FROM monitor_notification WHERE monitor_id = ? ", [
-        monitorID
+        monitorID,
     ])
 
     for (let notificationID in notificationIDList) {
@@ -532,7 +530,7 @@ async function sendMonitorList(socket) {
 async function sendNotificationList(socket) {
     let result = [];
     let list = await R.find("notification", " user_id = ? ", [
-        socket.userID
+        socket.userID,
     ]);
 
     for (let bean of list) {
@@ -562,7 +560,7 @@ async function getMonitorJSONList(userID) {
     let result = {};
 
     let monitorList = await R.find("monitor", " user_id = ? ", [
-        userID
+        userID,
     ])
 
     for (let monitor of monitorList) {
@@ -585,8 +583,8 @@ async function initDatabase() {
     }
 
     console.log("Connecting to Database")
-    R.setup('sqlite', {
-        filename: Database.path
+    R.setup("sqlite", {
+        filename: Database.path,
     });
     console.log("Connected")
 
@@ -598,7 +596,7 @@ async function initDatabase() {
     await R.autoloadModels("./server/model");
 
     let jwtSecretBean = await R.findOne("setting", " `key` = ? ", [
-        "jwtSecret"
+        "jwtSecret",
     ]);
 
     if (! jwtSecretBean) {
@@ -629,11 +627,11 @@ async function startMonitor(userID, monitorID) {
 
     await R.exec("UPDATE monitor SET active = 1 WHERE id = ? AND user_id = ? ", [
         monitorID,
-        userID
+        userID,
     ]);
 
     let monitor = await R.findOne("monitor", " id = ? ", [
-        monitorID
+        monitorID,
     ])
 
     if (monitor.id in monitorList) {
@@ -655,7 +653,7 @@ async function pauseMonitor(userID, monitorID) {
 
     await R.exec("UPDATE monitor SET active = 0 WHERE id = ? AND user_id = ? ", [
         monitorID,
-        userID
+        userID,
     ]);
 
     if (monitorID in monitorList) {
@@ -684,13 +682,13 @@ async function sendHeartbeatList(socket, monitorID) {
         ORDER BY time DESC
         LIMIT 100
     `, [
-        monitorID
+        monitorID,
     ])
 
     let result = [];
 
     for (let bean of list) {
-       result.unshift(bean.toJSON())
+        result.unshift(bean.toJSON())
     }
 
     socket.emit("heartbeatList", monitorID, result)
@@ -703,23 +701,20 @@ async function sendImportantHeartbeatList(socket, monitorID) {
         ORDER BY time DESC
         LIMIT 500
     `, [
-        monitorID
+        monitorID,
     ])
 
     socket.emit("importantHeartbeatList", monitorID, list)
 }
 
-
-
 const startGracefulShutdown = async () => {
-    console.log('Shutdown requested');
-
+    console.log("Shutdown requested");
 
     await (new Promise((resolve) => {
         server.close(async function () {
-            console.log('Stopped Express.');
+            console.log("Stopped Express.");
             process.exit(0)
-            setTimeout(async () =>{
+            setTimeout(async () => {
                 await R.close();
                 console.log("Stopped DB")
 
@@ -729,11 +724,10 @@ const startGracefulShutdown = async () => {
         });
     }));
 
-
 }
 
 async function shutdownFunction(signal) {
-    console.log('Called signal: ' + signal);
+    console.log("Called signal: " + signal);
 
     console.log("Stopping all monitors")
     for (let id in monitorList) {
@@ -745,14 +739,14 @@ async function shutdownFunction(signal) {
 }
 
 function finalFunction() {
-    console.log('Graceful Shutdown')
+    console.log("Graceful Shutdown")
 }
 
 gracefulShutdown(server, {
-    signals: 'SIGINT SIGTERM',
+    signals: "SIGINT SIGTERM",
     timeout: 30000,                   // timeout: 30 secs
     development: false,               // not in dev mode
     forceExit: true,                  // triggers process.exit() at the end of shutdown process
     onShutdown: shutdownFunction,     // shutdown function (async) - e.g. for cleanup DB, ...
-    finally: finalFunction            // finally function (sync) - e.g. for logging
+    finally: finalFunction,            // finally function (sync) - e.g. for logging
 });
diff --git a/server/util-server.js b/server/util-server.js
index f03823d3..43aa5ccf 100644
--- a/server/util-server.js
+++ b/server/util-server.js
@@ -1,6 +1,6 @@
-const tcpp = require('tcp-ping');
+const tcpp = require("tcp-ping");
 const Ping = require("./ping-lite");
-const {R} = require("redbean-node");
+const { R } = require("redbean-node");
 
 exports.tcping = function (hostname, port) {
     return new Promise((resolve, reject) => {
@@ -41,13 +41,13 @@ exports.ping = function (hostname) {
 
 exports.setting = async function (key) {
     return await R.getCell("SELECT `value` FROM setting WHERE `key` = ? ", [
-        key
+        key,
     ])
 }
 
 exports.setSetting = async function (key, value) {
     let bean = await R.findOne("setting", " `key` = ? ", [
-        key
+        key,
     ])
     if (! bean) {
         bean = R.dispense("setting")
@@ -59,7 +59,7 @@ exports.setSetting = async function (key, value) {
 
 exports.getSettings = async function (type) {
     let list = await R.getAll("SELECT * FROM setting WHERE `type` = ? ", [
-        type
+        type,
     ])
 
     let result = {};
@@ -71,7 +71,6 @@ exports.getSettings = async function (type) {
     return result;
 }
 
-
 // ssl-checker by @dyaa
 // param: res - response object from axios
 // return an object containing the certificate information
@@ -97,7 +96,9 @@ exports.checkCertificate = function (res) {
     } = res.request.res.socket.getPeerCertificate(false);
 
     if (!valid_from || !valid_to || !subjectaltname) {
-        throw { message: 'No TLS certificate in response' };
+        throw {
+            message: "No TLS certificate in response",
+        };
     }
 
     const valid = res.request.res.socket.authorized || false;
@@ -118,4 +119,4 @@ exports.checkCertificate = function (res) {
         issuer,
         fingerprint,
     };
-}
\ No newline at end of file
+}
diff --git a/server/util.js b/server/util.js
index 081561bf..6e90dc42 100644
--- a/server/util.js
+++ b/server/util.js
@@ -23,4 +23,3 @@ exports.debug = (msg) => {
         console.log(msg)
     }
 }
-
diff --git a/src/App.vue b/src/App.vue
index 1f05560e..974757a6 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -3,9 +3,7 @@
 </template>
 
 <script>
-export default {
-
-}
+export default {}
 </script>
 
 <style lang="scss">
diff --git a/src/components/Confirm.vue b/src/components/Confirm.vue
index 063ece25..ecf165a0 100644
--- a/src/components/Confirm.vue
+++ b/src/components/Confirm.vue
@@ -1,17 +1,23 @@
 <template>
-    <div class="modal fade" tabindex="-1" ref="modal">
+    <div ref="modal" class="modal fade" tabindex="-1">
         <div class="modal-dialog">
             <div class="modal-content">
                 <div class="modal-header">
-                    <h5 class="modal-title" id="exampleModalLabel">Confirm</h5>
-                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
+                    <h5 id="exampleModalLabel" class="modal-title">
+                        Confirm
+                    </h5>
+                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" />
                 </div>
                 <div class="modal-body">
-                    <slot></slot>
+                    <slot />
                 </div>
                 <div class="modal-footer">
-                    <button type="button" class="btn" :class="btnStyle" @click="yes" data-bs-dismiss="modal">Yes</button>
-                    <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">No</button>
+                    <button type="button" class="btn" :class="btnStyle" data-bs-dismiss="modal" @click="yes">
+                        Yes
+                    </button>
+                    <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
+                        No
+                    </button>
                 </div>
             </div>
         </div>
@@ -19,17 +25,17 @@
 </template>
 
 <script>
-import { Modal } from 'bootstrap'
+import { Modal } from "bootstrap"
 
 export default {
     props: {
         btnStyle: {
             type: String,
-            default: "btn-primary"
-        }
+            default: "btn-primary",
+        },
     },
     data: () => ({
-        modal: null
+        modal: null,
     }),
     mounted() {
         this.modal = new Modal(this.$refs.modal)
@@ -39,9 +45,9 @@ export default {
             this.modal.show()
         },
         yes() {
-            this.$emit('yes');
-        }
-    }
+            this.$emit("yes");
+        },
+    },
 }
 </script>
 
diff --git a/src/components/CountUp.vue b/src/components/CountUp.vue
index 33904b6a..1d2a4c55 100644
--- a/src/components/CountUp.vue
+++ b/src/components/CountUp.vue
@@ -5,7 +5,7 @@
 
 <script>
 
-import {sleep} from '../util-frontend'
+import { sleep } from "../util-frontend"
 
 export default {
 
@@ -18,11 +18,7 @@ export default {
         unit: {
             String,
             default: "ms",
-        }
-    },
-
-    mounted() {
-        this.output = this.value;
+        },
     },
 
     data() {
@@ -32,14 +28,10 @@ export default {
         }
     },
 
-    methods: {
-
-    },
-
     computed: {
         isNum() {
-            return typeof this.value === 'number'
-        }
+            return typeof this.value === "number"
+        },
     },
 
     watch: {
@@ -61,6 +53,12 @@ export default {
         },
     },
 
+    mounted() {
+        this.output = this.value;
+    },
+
+    methods: {},
+
 }
 </script>
 
diff --git a/src/components/Datetime.vue b/src/components/Datetime.vue
index 3e551659..365e9fca 100644
--- a/src/components/Datetime.vue
+++ b/src/components/Datetime.vue
@@ -5,8 +5,8 @@
 <script>
 import dayjs from "dayjs";
 import relativeTime from "dayjs/plugin/relativeTime"
-import utc from 'dayjs/plugin/utc'
-import timezone from 'dayjs/plugin/timezone' // dependent on utc plugin
+import utc from "dayjs/plugin/utc"
+import timezone from "dayjs/plugin/timezone" // dependent on utc plugin
 dayjs.extend(utc)
 dayjs.extend(timezone)
 dayjs.extend(relativeTime)
@@ -28,11 +28,11 @@ export default {
                     format = "YYYY-MM-DD";
                 }
                 return dayjs.utc(this.value).tz(this.$root.timezone).format(format);
-            } else {
-                return "";
             }
+
+            return "";
         },
-    }
+    },
 }
 </script>
 
diff --git a/src/components/HeartbeatBar.vue b/src/components/HeartbeatBar.vue
index 03cdceca..7ee94317 100644
--- a/src/components/HeartbeatBar.vue
+++ b/src/components/HeartbeatBar.vue
@@ -1,28 +1,27 @@
 <template>
-    <div class="wrap" :style="wrapStyle" ref="wrap">
+    <div ref="wrap" class="wrap" :style="wrapStyle">
         <div class="hp-bar-big" :style="barStyle">
             <div
+                v-for="(beat, index) in shortBeatList"
+                :key="index"
                 class="beat"
                 :class="{ 'empty' : (beat === 0), 'down' : (beat.status === 0), 'pending' : (beat.status === 2) }"
                 :style="beatStyle"
-                v-for="(beat, index) in shortBeatList"
-                :key="index"
-                :title="beat.msg">
-            </div>
+                :title="beat.msg"
+            />
         </div>
     </div>
 </template>
 
 <script>
 
-
 export default {
     props: {
         size: {
             type: String,
-            default: "big"
+            default: "big",
         },
-        monitorId: Number
+        monitorId: Number,
     },
     data() {
         return {
@@ -34,26 +33,6 @@ export default {
             maxBeat: -1,
         }
     },
-    unmounted() {
-        window.removeEventListener("resize", this.resize);
-    },
-    mounted() {
-        if (this.size === "small") {
-            this.beatWidth = 5.6;
-            this.beatMargin = 2.4;
-            this.beatHeight = 16
-        }
-
-        window.addEventListener("resize", this.resize);
-        this.resize();
-    },
-    methods: {
-        resize() {
-            if (this.$refs.wrap) {
-                this.maxBeat = Math.floor(this.$refs.wrap.clientWidth / (this.beatWidth + this.beatMargin * 2))
-            }
-        }
-    },
     computed: {
 
         beatList() {
@@ -80,8 +59,6 @@ export default {
                 start = 0;
             }
 
-
-
             return placeholders.concat(this.beatList.slice(start))
         },
 
@@ -98,7 +75,7 @@ export default {
 
             return {
                 padding: `${topBottom}px ${leftRight}px`,
-                width: width
+                width: width,
             }
         },
 
@@ -111,11 +88,11 @@ export default {
                     transform: `translateX(${width}px)`,
                 }
 
-            } else {
-                return {
-                    transform: `translateX(0)`,
-                }
             }
+            return {
+                transform: "translateX(0)",
+            }
+
         },
 
         beatStyle() {
@@ -125,7 +102,7 @@ export default {
                 margin: this.beatMargin + "px",
                 "--hover-scale": this.hoverScale,
             }
-        }
+        },
 
     },
     watch: {
@@ -138,8 +115,28 @@ export default {
                 }, 300)
             },
             deep: true,
+        },
+    },
+    unmounted() {
+        window.removeEventListener("resize", this.resize);
+    },
+    mounted() {
+        if (this.size === "small") {
+            this.beatWidth = 5.6;
+            this.beatMargin = 2.4;
+            this.beatHeight = 16
         }
-    }
+
+        window.addEventListener("resize", this.resize);
+        this.resize();
+    },
+    methods: {
+        resize() {
+            if (this.$refs.wrap) {
+                this.maxBeat = Math.floor(this.$refs.wrap.clientWidth / (this.beatWidth + this.beatMargin * 2))
+            }
+        },
+    },
 }
 </script>
 
diff --git a/src/components/Login.vue b/src/components/Login.vue
index 017261cc..4b08de06 100644
--- a/src/components/Login.vue
+++ b/src/components/Login.vue
@@ -2,31 +2,32 @@
     <div class="form-container">
         <div class="form">
             <form @submit.prevent="submit">
-
-                <h1 class="h3 mb-3 fw-normal"></h1>
+                <h1 class="h3 mb-3 fw-normal" />
 
                 <div class="form-floating">
-                    <input type="text" class="form-control" id="floatingInput" placeholder="Username" v-model="username">
+                    <input id="floatingInput" v-model="username" type="text" class="form-control" placeholder="Username">
                     <label for="floatingInput">Username</label>
                 </div>
 
                 <div class="form-floating mt-3">
-                    <input type="password" class="form-control" id="floatingPassword" placeholder="Password" v-model="password">
+                    <input id="floatingPassword" v-model="password" type="password" class="form-control" placeholder="Password">
                     <label for="floatingPassword">Password</label>
                 </div>
 
                 <div class="form-check mb-3 mt-3 d-flex justify-content-center pe-4">
                     <div class="form-check">
-                        <input type="checkbox" value="remember-me" class="form-check-input" id="remember" v-model="$root.remember">
+                        <input id="remember" v-model="$root.remember" type="checkbox" value="remember-me" class="form-check-input">
 
                         <label class="form-check-label" for="remember">
                             Remember me
                         </label>
                     </div>
                 </div>
-                <button class="w-100 btn btn-primary" type="submit" :disabled="processing">Login</button>
+                <button class="w-100 btn btn-primary" type="submit" :disabled="processing">
+                    Login
+                </button>
 
-                <div class="alert alert-danger mt-3" role="alert" v-if="res && !res.ok">
+                <div v-if="res && !res.ok" class="alert alert-danger mt-3" role="alert">
                     {{ res.msg }}
                 </div>
             </form>
@@ -52,8 +53,8 @@ export default {
                 this.processing = false;
                 this.res = res;
             })
-        }
-    }
+        },
+    },
 }
 </script>
 
diff --git a/src/components/NotificationDialog.vue b/src/components/NotificationDialog.vue
index afbfc0d4..3adbe4af 100644
--- a/src/components/NotificationDialog.vue
+++ b/src/components/NotificationDialog.vue
@@ -1,48 +1,70 @@
 <template>
     <form @submit.prevent="submit">
-
-        <div class="modal fade" tabindex="-1" ref="modal" data-bs-backdrop="static">
+        <div ref="modal" class="modal fade" tabindex="-1" data-bs-backdrop="static">
             <div class="modal-dialog">
                 <div class="modal-content">
                     <div class="modal-header">
-                        <h5 class="modal-title" id="exampleModalLabel">Setup Notification</h5>
-                        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
+                        <h5 id="exampleModalLabel" class="modal-title">
+                            Setup Notification
+                        </h5>
+                        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" />
                     </div>
                     <div class="modal-body">
-
                         <div class="mb-3">
                             <label for="type" class="form-label">Notification Type</label>
-                            <select class="form-select"  id="type" v-model="notification.type">
-                                <option value="telegram">Telegram</option>
-                                <option value="webhook">Webhook</option>
-                                <option value="smtp">Email (SMTP)</option>
-                                <option value="discord">Discord</option>
-                                <option value="signal">Signal</option>
-                                <option value="gotify">Gotify</option>
-                                <option value="slack">Slack</option>
-                                <option value="pushover">Pushover</option>
-                                <option value="apprise">Apprise (Support 50+ Notification services)</option>
+                            <select id="type" v-model="notification.type" class="form-select">
+                                <option value="telegram">
+                                    Telegram
+                                </option>
+                                <option value="webhook">
+                                    Webhook
+                                </option>
+                                <option value="smtp">
+                                    Email (SMTP)
+                                </option>
+                                <option value="discord">
+                                    Discord
+                                </option>
+                                <option value="signal">
+                                    Signal
+                                </option>
+                                <option value="gotify">
+                                    Gotify
+                                </option>
+                                <option value="slack">
+                                    Slack
+                                </option>
+                                <option value="pushover">
+                                    Pushover
+                                </option>
+                                <option value="apprise">
+                                    Apprise (Support 50+ Notification services)
+                                </option>
                             </select>
                         </div>
 
                         <div class="mb-3">
                             <label for="name" class="form-label">Friendly Name</label>
-                            <input type="text" class="form-control" id="name" required v-model="notification.name">
+                            <input id="name" v-model="notification.name" type="text" class="form-control" required>
                         </div>
 
                         <template v-if="notification.type === 'telegram'">
                             <div class="mb-3">
                                 <label for="telegram-bot-token" class="form-label">Bot Token</label>
-                                <input type="text" class="form-control" id="telegram-bot-token" required v-model="notification.telegramBotToken">
-                                <div class="form-text">You can get a token from <a href="https://t.me/BotFather" target="_blank">https://t.me/BotFather</a>.</div>
+                                <input id="telegram-bot-token" v-model="notification.telegramBotToken" type="text" class="form-control" required>
+                                <div class="form-text">
+                                    You can get a token from <a href="https://t.me/BotFather" target="_blank">https://t.me/BotFather</a>.
+                                </div>
                             </div>
 
                             <div class="mb-3">
                                 <label for="telegram-chat-id" class="form-label">Chat ID</label>
 
                                 <div class="input-group mb-3">
-                                    <input type="text" class="form-control" id="telegram-chat-id" required v-model="notification.telegramChatID">
-                                    <button class="btn btn-outline-secondary" type="button" @click="autoGetTelegramChatID" v-if="notification.telegramBotToken">Auto Get</button>
+                                    <input id="telegram-chat-id" v-model="notification.telegramChatID" type="text" class="form-control" required>
+                                    <button v-if="notification.telegramBotToken" class="btn btn-outline-secondary" type="button" @click="autoGetTelegramChatID">
+                                        Auto Get
+                                    </button>
                                 </div>
 
                                 <div class="form-text">
@@ -53,7 +75,6 @@
                                     </p>
 
                                     <p style="margin-top: 8px;">
-
                                         <template v-if="notification.telegramBotToken">
                                             <a :href="telegramGetUpdatesURL" target="_blank" style="word-break: break-word;">{{ telegramGetUpdatesURL }}</a>
                                         </template>
@@ -69,15 +90,18 @@
                         <template v-if="notification.type === 'webhook'">
                             <div class="mb-3">
                                 <label for="webhook-url" class="form-label">Post URL</label>
-                                <input type="url" pattern="https?://.+" class="form-control" id="webhook-url" required v-model="notification.webhookURL">
-
+                                <input id="webhook-url" v-model="notification.webhookURL" type="url" pattern="https?://.+" class="form-control" required>
                             </div>
 
                             <div class="mb-3">
                                 <label for="webhook-content-type" class="form-label">Content Type</label>
-                                <select class="form-select" id="webhook-content-type" v-model="notification.webhookContentType" required>
-                                    <option value="json">application/json</option>
-                                    <option value="form-data">multipart/form-data</option>
+                                <select id="webhook-content-type" v-model="notification.webhookContentType" class="form-select" required>
+                                    <option value="json">
+                                        application/json
+                                    </option>
+                                    <option value="form-data">
+                                        multipart/form-data
+                                    </option>
                                 </select>
 
                                 <div class="form-text">
@@ -90,70 +114,71 @@
                         <template v-if="notification.type === 'smtp'">
                             <div class="mb-3">
                                 <label for="hostname" class="form-label">Hostname</label>
-                                <input type="text" class="form-control" id="hostname" required v-model="notification.smtpHost">
+                                <input id="hostname" v-model="notification.smtpHost" type="text" class="form-control" required>
                             </div>
 
                             <div class="mb-3">
                                 <label for="port" class="form-label">Port</label>
-                                <input type="number" class="form-control" id="port" v-model="notification.smtpPort" required min="0" max="65535" step="1">
+                                <input id="port" v-model="notification.smtpPort" type="number" class="form-control" required min="0" max="65535" step="1">
                             </div>
 
                             <div class="mb-3">
                                 <div class="form-check">
-                                    <input class="form-check-input" type="checkbox" value="" id="secure" v-model="notification.smtpSecure">
+                                    <input id="secure" v-model="notification.smtpSecure" class="form-check-input" type="checkbox" value="">
                                     <label class="form-check-label" for="secure">
                                         Secure
                                     </label>
                                 </div>
-                                <div class="form-text">Generally, true for 465, false for other ports.</div>
+                                <div class="form-text">
+                                    Generally, true for 465, false for other ports.
+                                </div>
                             </div>
 
                             <div class="mb-3">
                                 <label for="username" class="form-label">Username</label>
-                                <input type="text" class="form-control" id="username" v-model="notification.smtpUsername" autocomplete="false">
+                                <input id="username" v-model="notification.smtpUsername" type="text" class="form-control" autocomplete="false">
                             </div>
 
                             <div class="mb-3">
                                 <label for="password" class="form-label">Password</label>
-                                <input type="password" class="form-control" id="password" v-model="notification.smtpPassword" autocomplete="false">
+                                <input id="password" v-model="notification.smtpPassword" type="password" class="form-control" autocomplete="false">
                             </div>
 
                             <div class="mb-3">
                                 <label for="from-email" class="form-label">From Email</label>
-                                <input type="email" class="form-control" id="from-email" required v-model="notification.smtpFrom" autocomplete="false">
+                                <input id="from-email" v-model="notification.smtpFrom" type="email" class="form-control" required autocomplete="false">
                             </div>
 
                             <div class="mb-3">
                                 <label for="to-email" class="form-label">To Email</label>
-                                <input type="email" class="form-control" id="to-email" required v-model="notification.smtpTo" autocomplete="false">
+                                <input id="to-email" v-model="notification.smtpTo" type="email" class="form-control" required autocomplete="false">
                             </div>
-
                         </template>
 
                         <template v-if="notification.type === 'discord'">
                             <div class="mb-3">
                                 <label for="discord-webhook-url" class="form-label">Discord Webhook URL</label>
-                                <input type="text" class="form-control" id="discord-webhook-url" required v-model="notification.discordWebhookUrl" autocomplete="false">
-                                <div class="form-text">You can get this by going to Server Settings -> Integrations -> Create Webhook</div>
+                                <input id="discord-webhook-url" v-model="notification.discordWebhookUrl" type="text" class="form-control" required autocomplete="false">
+                                <div class="form-text">
+                                    You can get this by going to Server Settings -> Integrations -> Create Webhook
+                                </div>
                             </div>
                         </template>
 
                         <template v-if="notification.type === 'signal'">
                             <div class="mb-3">
                                 <label for="signal-url" class="form-label">Post URL</label>
-                                <input type="url" pattern="https?://.+" class="form-control" id="signal-url" required v-model="notification.signalURL">
-
+                                <input id="signal-url" v-model="notification.signalURL" type="url" pattern="https?://.+" class="form-control" required>
                             </div>
 
                             <div class="mb-3">
                                 <label for="signal-number" class="form-label">Number</label>
-                                <input type="text" class="form-control" id="signal-number" required v-model="notification.signalNumber">
-
+                                <input id="signal-number" v-model="notification.signalNumber" type="text" class="form-control" required>
                             </div>
 
                             <div class="mb-3">
                                 <label for="signal-recipients" class="form-label">Recipients</label>
-                                <input type="text" class="form-control" id="signal-recipients" required v-model="notification.signalRecipients">
+                                <input id="signal-recipients" v-model="notification.signalRecipients" type="text" class="form-control" required>
 
                                 <div class="form-text">
                                     You need to have a signal client with REST API.
@@ -174,37 +199,37 @@
                         </template>
 
                         <template v-if="notification.type === 'gotify'">
-                                <div class="mb-3">
-                                    <label for="gotify-application-token" class="form-label">Application Token</label>
-                                    <input type="text" class="form-control" id="gotify-application-token" required v-model="notification.gotifyapplicationToken">
-                                </div>
-                                <div class="mb-3">
-                                    <label for="gotify-server-url" class="form-label">Server URL</label>
-                                    <div class="input-group mb-3">
-                                        <input type="text" class="form-control" id="gotify-server-url" required v-model="notification.gotifyserverurl">
-                                    </div>
+                            <div class="mb-3">
+                                <label for="gotify-application-token" class="form-label">Application Token</label>
+                                <input id="gotify-application-token" v-model="notification.gotifyapplicationToken" type="text" class="form-control" required>
+                            </div>
+                            <div class="mb-3">
+                                <label for="gotify-server-url" class="form-label">Server URL</label>
+                                <div class="input-group mb-3">
+                                    <input id="gotify-server-url" v-model="notification.gotifyserverurl" type="text" class="form-control" required>
                                 </div>
+                            </div>
 
-                                <div class="mb-3">
-                                    <label for="gotify-priority" class="form-label">Priority</label>
-                                    <input type="number" class="form-control" id="gotify-priority" v-model="notification.gotifyPriority" required min="0" max="10" step="1">
-                                </div>
-                            </template>
+                            <div class="mb-3">
+                                <label for="gotify-priority" class="form-label">Priority</label>
+                                <input id="gotify-priority" v-model="notification.gotifyPriority" type="number" class="form-control" required min="0" max="10" step="1">
+                            </div>
+                        </template>
 
                         <template v-if="notification.type === 'slack'">
                             <div class="mb-3">
                                 <label for="slack-webhook-url" class="form-label">Webhook URL<span style="color:red;"><sup>*</sup></span></label>
-                                <input type="text" class="form-control" id="slack-webhook-url" required v-model="notification.slackwebhookURL">
+                                <input id="slack-webhook-url" v-model="notification.slackwebhookURL" type="text" class="form-control" required>
                                 <label for="slack-username" class="form-label">Username</label>
-                                <input type="text" class="form-control" id="slack-username" v-model="notification.slackusername">
+                                <input id="slack-username" v-model="notification.slackusername" type="text" class="form-control">
                                 <label for="slack-iconemo" class="form-label">Icon Emoji</label>
-                                <input type="text" class="form-control" id="slack-iconemo" v-model="notification.slackiconemo">
+                                <input id="slack-iconemo" v-model="notification.slackiconemo" type="text" class="form-control">
                                 <label for="slack-channel" class="form-label">Channel Name</label>
-                                <input type="text" class="form-control" id="slack-channel-name" v-model="notification.slackchannel">
+                                <input id="slack-channel-name" v-model="notification.slackchannel" type="text" class="form-control">
                                 <label for="slack-button-url" class="form-label">Uptime Kuma URL</label>
-                                <input type="text" class="form-control" id="slack-button" v-model="notification.slackbutton">
+                                <input id="slack-button" v-model="notification.slackbutton" type="text" class="form-control">
                                 <div class="form-text">
-                                <span style="color:red;"><sup>*</sup></span>Required
+                                    <span style="color:red;"><sup>*</sup></span>Required
                                     <p style="margin-top: 8px;">
                                         More info about webhooks on: <a href="https://api.slack.com/messaging/webhooks" target="_blank">https://api.slack.com/messaging/webhooks</a>
                                     </p>
@@ -224,15 +249,15 @@
                         <template v-if="notification.type === 'pushover'">
                             <div class="mb-3">
                                 <label for="pushover-user" class="form-label">User Key<span style="color:red;"><sup>*</sup></span></label>
-                                <input type="text" class="form-control" id="pushover-user" required v-model="notification.pushoveruserkey">
+                                <input id="pushover-user" v-model="notification.pushoveruserkey" type="text" class="form-control" required>
                                 <label for="pushover-app-token" class="form-label">Application Token<span style="color:red;"><sup>*</sup></span></label>
-                                <input type="text" class="form-control" id="pushover-app-token" required v-model="notification.pushoverapptoken">
+                                <input id="pushover-app-token" v-model="notification.pushoverapptoken" type="text" class="form-control" required>
                                 <label for="pushover-device" class="form-label">Device</label>
-                                <input type="text" class="form-control" id="pushover-device" v-model="notification.pushoverdevice">
+                                <input id="pushover-device" v-model="notification.pushoverdevice" type="text" class="form-control">
                                 <label for="pushover-device" class="form-label">Message Title</label>
-                                <input type="text" class="form-control" id="pushover-title" v-model="notification.pushovertitle">
+                                <input id="pushover-title" v-model="notification.pushovertitle" type="text" class="form-control">
                                 <label for="pushover-priority" class="form-label">Priority</label>
-                                <select class="form-select"  id="pushover-priority" v-model="notification.pushoverpriority">
+                                <select id="pushover-priority" v-model="notification.pushoverpriority" class="form-select">
                                     <option>-2</option>
                                     <option>-1</option>
                                     <option>0</option>
@@ -240,7 +265,7 @@
                                     <option>2</option>
                                 </select>
                                 <label for="pushover-sound" class="form-label">Notification Sound</label>
-                                <select class="form-select"  id="pushover-sound" v-model="notification.pushoversounds">
+                                <select id="pushover-sound" v-model="notification.pushoversounds" class="form-select">
                                     <option>pushover</option>
                                     <option>bike</option>
                                     <option>bugle</option>
@@ -265,16 +290,16 @@
                                     <option>none</option>
                                 </select>
                                 <div class="form-text">
-                                <span style="color:red;"><sup>*</sup></span>Required
-                                <p style="margin-top: 8px;">
+                                    <span style="color:red;"><sup>*</sup></span>Required
+                                    <p style="margin-top: 8px;">
                                         More info on: <a href="https://pushover.net/api" target="_blank">https://pushover.net/api</a>
-                                </p>
-                                 <p style="margin-top: 8px;">
+                                    </p>
+                                    <p style="margin-top: 8px;">
                                         Emergency priority (2) has default 30 second timeout between retries and will expire after 1 hour.
-                                </p>
-                                 <p style="margin-top: 8px;">
+                                    </p>
+                                    <p style="margin-top: 8px;">
                                         If you want to send notifications to different devices, fill out Device field.
-                                </p>
+                                    </p>
                                 </div>
                             </div>
                         </template>
@@ -282,7 +307,7 @@
                         <template v-if="notification.type === 'apprise'">
                             <div class="mb-3">
                                 <label for="apprise-url" class="form-label">Apprise URL</label>
-                                <input type="text" class="form-control" id="apprise-url" required v-model="notification.appriseURL">
+                                <input id="apprise-url" v-model="notification.appriseURL" type="text" class="form-control" required>
                                 <div class="form-text">
                                     <p>Example: twilio://AccountSid:AuthToken@FromPhoneNo</p>
                                     <p>
@@ -293,40 +318,46 @@
                             <div class="mb-3">
                                 <p>
                                     Status:
-                                    <span class="text-primary" v-if="appriseInstalled">Apprise is installed</span>
-                                    <span class="text-danger" v-else>Apprise is not installed. <a href="https://github.com/caronc/apprise">Read more</a></span>
+                                    <span v-if="appriseInstalled" class="text-primary">Apprise is installed</span>
+                                    <span v-else class="text-danger">Apprise is not installed. <a href="https://github.com/caronc/apprise">Read more</a></span>
                                 </p>
                             </div>
                         </template>
-
                     </div>
                     <div class="modal-footer">
-                        <button type="button" class="btn btn-danger" @click="deleteConfirm" :disabled="processing" v-if="id">Delete</button>
-                        <button type="button" class="btn btn-warning" @click="test" :disabled="processing">Test</button>
-                        <button type="submit" class="btn btn-primary" :disabled="processing">Save</button>
+                        <button v-if="id" type="button" class="btn btn-danger" :disabled="processing" @click="deleteConfirm">
+                            Delete
+                        </button>
+                        <button type="button" class="btn btn-warning" :disabled="processing" @click="test">
+                            Test
+                        </button>
+                        <button type="submit" class="btn btn-primary" :disabled="processing">
+                            Save
+                        </button>
                     </div>
                 </div>
             </div>
         </div>
-
     </form>
 
-    <Confirm ref="confirmDelete" @yes="deleteNotification" btn-style="btn-danger">Are you sure want to delete this notification for all monitors?</Confirm>
+    <Confirm ref="confirmDelete" btn-style="btn-danger" @yes="deleteNotification">
+        Are you sure want to delete this notification for all monitors?
+    </Confirm>
 </template>
 
 <script>
-import { Modal } from 'bootstrap'
-import { ucfirst } from '../util-frontend'
+import { Modal } from "bootstrap"
+import { ucfirst } from "../util-frontend"
 import axios from "axios";
-import { useToast } from 'vue-toastification'
+import { useToast } from "vue-toastification"
 import Confirm from "./Confirm.vue";
 const toast = useToast()
 
 export default {
-    components: {Confirm},
-    props: {
-
+    components: {
+        Confirm,
     },
+    props: {},
     data() {
         return {
             model: null,
@@ -335,11 +366,37 @@ export default {
             notification: {
                 name: "",
                 type: null,
-                gotifyPriority: 8
+                gotifyPriority: 8,
             },
             appriseInstalled: false,
         }
     },
+    computed: {
+        telegramGetUpdatesURL() {
+            let token = "<YOUR BOT TOKEN HERE>"
+
+            if (this.notification.telegramBotToken) {
+                token = this.notification.telegramBotToken;
+            }
+
+            return `https://api.telegram.org/bot${token}/getUpdates`;
+        },
+    },
+    watch: {
+        "notification.type"(to, from) {
+            let oldName;
+
+            if (from) {
+                oldName = `My ${ucfirst(from)} Alert (1)`;
+            } else {
+                oldName = "";
+            }
+
+            if (! this.notification.name || this.notification.name === oldName) {
+                this.notification.name = `My ${ucfirst(to)} Alert (1)`
+            }
+        },
+    },
     mounted() {
         this.modal = new Modal(this.$refs.modal)
 
@@ -437,32 +494,6 @@ export default {
         },
 
     },
-    computed: {
-        telegramGetUpdatesURL() {
-            let token = "<YOUR BOT TOKEN HERE>"
-
-            if (this.notification.telegramBotToken) {
-                token = this.notification.telegramBotToken;
-            }
-
-            return `https://api.telegram.org/bot${token}/getUpdates`;
-        },
-    },
-    watch: {
-        "notification.type"(to, from) {
-            let oldName;
-
-            if (from) {
-                oldName =  `My ${ucfirst(from)} Alert (1)`;
-            } else {
-                oldName = "";
-            }
-
-            if (! this.notification.name || this.notification.name === oldName) {
-                this.notification.name = `My ${ucfirst(to)} Alert (1)`
-            }
-        }
-    }
 }
 </script>
 
diff --git a/src/components/Status.vue b/src/components/Status.vue
index 1eaf17f2..c0549821 100644
--- a/src/components/Status.vue
+++ b/src/components/Status.vue
@@ -5,34 +5,34 @@
 <script>
 export default {
     props: {
-        status: Number
+        status: Number,
     },
 
     computed: {
         color() {
             if (this.status === 0) {
                 return "danger"
-            } else if (this.status === 1) {
+            } if (this.status === 1) {
                 return "primary"
-            } else if (this.status === 2) {
+            } if (this.status === 2) {
                 return "warning"
-            } else {
-                return "secondary"
             }
+            return "secondary"
+
         },
 
         text() {
             if (this.status === 0) {
                 return "Down"
-            } else if (this.status === 1) {
+            } if (this.status === 1) {
                 return "Up"
-            } else if (this.status === 2) {
+            } if (this.status === 2) {
                 return "Pending"
-            } else {
-                return "Unknown"
             }
+            return "Unknown"
+
         },
-    }
+    },
 }
 </script>
 
diff --git a/src/components/Uptime.vue b/src/components/Uptime.vue
index 322b35f7..e9c6f583 100644
--- a/src/components/Uptime.vue
+++ b/src/components/Uptime.vue
@@ -5,7 +5,7 @@
 <script>
 export default {
     props: {
-        monitor : Object,
+        monitor: Object,
         type: String,
         pill: {
             Boolean,
@@ -20,41 +20,41 @@ export default {
 
             if (this.$root.uptimeList[key] !== undefined) {
                 return Math.round(this.$root.uptimeList[key] * 10000) / 100 + "%";
-            } else {
-                return "N/A"
             }
+
+            return "N/A"
         },
 
         color() {
             if (this.lastHeartBeat.status === 0) {
                 return "danger"
-            } else if (this.lastHeartBeat.status === 1) {
+            } if (this.lastHeartBeat.status === 1) {
                 return "primary"
-            } else if (this.lastHeartBeat.status === 2) {
+            } if (this.lastHeartBeat.status === 2) {
                 return "warning"
-            } else {
-                return "secondary"
             }
+
+            return "secondary"
         },
 
         lastHeartBeat() {
             if (this.monitor.id in this.$root.lastHeartbeatList && this.$root.lastHeartbeatList[this.monitor.id]) {
                 return this.$root.lastHeartbeatList[this.monitor.id]
-            } else {
-                return { status: -1 }
+            }
+
+            return {
+                status: -1,
             }
         },
 
         className() {
             if (this.pill) {
                 return `badge rounded-pill bg-${this.color}`;
-            } else {
-                return "";
             }
+
+            return "";
         },
-
     },
-
 }
 </script>
 
diff --git a/src/icon.js b/src/icon.js
index 02c5d818..d8ea36d6 100644
--- a/src/icon.js
+++ b/src/icon.js
@@ -1,12 +1,10 @@
-import { library } from '@fortawesome/fontawesome-svg-core'
+import { library } from "@fortawesome/fontawesome-svg-core"
+import { faCog, faEdit, faList, faPause, faPlay, faPlus, faTachometerAlt, faTrash } from "@fortawesome/free-solid-svg-icons"
 //import { fa } from '@fortawesome/free-regular-svg-icons'
-import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
-import { faCog, faTachometerAlt, faEdit, faPlus, faPause, faPlay, faTrash, faList } from '@fortawesome/free-solid-svg-icons'
+import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome"
 
 // Add Free Font Awesome Icons here
 // https://fontawesome.com/v5.15/icons?d=gallery&p=2&s=solid&m=free
 library.add(faCog, faTachometerAlt, faEdit, faPlus, faPause, faPlay, faTrash, faList)
 
-export {
-    FontAwesomeIcon
-}
+export { FontAwesomeIcon }
diff --git a/src/layouts/EmptyLayout.vue b/src/layouts/EmptyLayout.vue
index 7b720447..6f996587 100644
--- a/src/layouts/EmptyLayout.vue
+++ b/src/layouts/EmptyLayout.vue
@@ -3,9 +3,7 @@
 </template>
 
 <script>
-export default {
-
-}
+export default {}
 </script>
 
 <style scoped>
diff --git a/src/layouts/Layout.vue b/src/layouts/Layout.vue
index bc99854a..546c0ffe 100644
--- a/src/layouts/Layout.vue
+++ b/src/layouts/Layout.vue
@@ -1,28 +1,35 @@
 <template>
-
-    <div class="lost-connection" v-if="! $root.socket.connected && ! $root.socket.firstConnect">
+    <div v-if="! $root.socket.connected && ! $root.socket.firstConnect" class="lost-connection">
         <div class="container-fluid">
             Lost connection to the socket server. Reconnecting...
         </div>
     </div>
 
     <!-- Desktop header -->
-    <header class="d-flex flex-wrap justify-content-center py-3 mb-3 border-bottom" v-if="! $root.isMobile">
+    <header v-if="! $root.isMobile" class="d-flex flex-wrap justify-content-center py-3 mb-3 border-bottom">
         <router-link to="/dashboard" class="d-flex align-items-center mb-3 mb-md-0 me-md-auto text-dark text-decoration-none">
-            <object class="bi me-2 ms-4" width="40" height="40" data="/icon.svg" alt="Logo"></object>
+            <object class="bi me-2 ms-4" width="40" height="40" data="/icon.svg" alt="Logo" />
             <span class="fs-4 title">Uptime Kuma</span>
         </router-link>
 
-        <ul class="nav nav-pills" >
-            <li class="nav-item"><router-link to="/dashboard" class="nav-link"><font-awesome-icon icon="tachometer-alt" /> Dashboard</router-link></li>
-            <li class="nav-item"><router-link to="/settings" class="nav-link"><font-awesome-icon icon="cog" /> Settings</router-link></li>
+        <ul class="nav nav-pills">
+            <li class="nav-item">
+                <router-link to="/dashboard" class="nav-link">
+                    <font-awesome-icon icon="tachometer-alt" /> Dashboard
+                </router-link>
+            </li>
+            <li class="nav-item">
+                <router-link to="/settings" class="nav-link">
+                    <font-awesome-icon icon="cog" /> Settings
+                </router-link>
+            </li>
         </ul>
     </header>
 
     <!-- Mobile header -->
-    <header class="d-flex flex-wrap justify-content-center mt-3 mb-3" v-else>
+    <header v-else class="d-flex flex-wrap justify-content-center mt-3 mb-3">
         <router-link to="/dashboard" class="d-flex align-items-center  text-dark text-decoration-none">
-            <object class="bi" width="40" height="40" data="/icon.svg"></object>
+            <object class="bi" width="40" height="40" data="/icon.svg" />
             <span class="fs-4 title ms-2">Uptime Kuma</span>
         </router-link>
     </header>
@@ -42,9 +49,8 @@
     </footer>
 
     <!-- Mobile Only -->
-    <div style="width: 100%;height: 60px;" v-if="$root.isMobile"></div>
-    <nav class="bottom-nav" v-if="$root.isMobile">
-
+    <div v-if="$root.isMobile" style="width: 100%;height: 60px;" />
+    <nav v-if="$root.isMobile" class="bottom-nav">
         <router-link to="/dashboard" class="nav-link" @click="$root.cancelActiveList">
             <div><font-awesome-icon icon="tachometer-alt" /></div>
             Dashboard
@@ -64,7 +70,6 @@
             <div><font-awesome-icon icon="cog" /></div>
             Settings
         </router-link>
-
     </nav>
 </template>
 
@@ -73,23 +78,19 @@ import Login from "../components/Login.vue";
 
 export default {
     components: {
-        Login
+        Login,
     },
     data() {
-        return {
-
-        }
-    },
-    computed: {
-
-    },
-    mounted() {
-        this.init();
+        return {}
     },
+    computed: {},
     watch: {
         $route (to, from) {
             this.init();
-        }
+        },
+    },
+    mounted() {
+        this.init();
     },
     methods: {
         init() {
@@ -98,7 +99,7 @@ export default {
             }
         },
 
-    }
+    },
 }
 </script>
 
diff --git a/src/main.js b/src/main.js
index 59672f8d..e76db1ed 100644
--- a/src/main.js
+++ b/src/main.js
@@ -1,59 +1,58 @@
-import {createApp, h} from "vue";
-import {createRouter, createWebHistory} from 'vue-router'
-
-import App from './App.vue'
-import Layout from './layouts/Layout.vue'
-import EmptyLayout from './layouts/EmptyLayout.vue'
-import Settings from "./pages/Settings.vue";
+import "bootstrap";
+import { createApp, h } from "vue";
+import { createRouter, createWebHistory } from "vue-router";
+import Toast from "vue-toastification";
+import "vue-toastification/dist/index.css";
+import App from "./App.vue";
+import "./assets/app.scss";
+import { FontAwesomeIcon } from "./icon.js";
+import EmptyLayout from "./layouts/EmptyLayout.vue";
+import Layout from "./layouts/Layout.vue";
+import socket from "./mixins/socket";
 import Dashboard from "./pages/Dashboard.vue";
 import DashboardHome from "./pages/DashboardHome.vue";
 import Details from "./pages/Details.vue";
-import socket from "./mixins/socket"
-import "./assets/app.scss"
 import EditMonitor from "./pages/EditMonitor.vue";
-import Toast from "vue-toastification";
-import "vue-toastification/dist/index.css";
-import "bootstrap"
+import Settings from "./pages/Settings.vue";
 import Setup from "./pages/Setup.vue";
-import {FontAwesomeIcon} from "./icon.js"
 
 const routes = [
     {
-        path: '/',
+        path: "/",
         component: Layout,
         children: [
             {
                 name: "root",
-                path: '',
+                path: "",
                 component: Dashboard,
                 children: [
                     {
                         name: "DashboardHome",
-                        path: '/dashboard',
+                        path: "/dashboard",
                         component: DashboardHome,
                         children: [
                             {
-                                path: '/dashboard/:id',
+                                path: "/dashboard/:id",
                                 component: EmptyLayout,
                                 children: [
                                     {
-                                        path: '',
+                                        path: "",
                                         component: Details,
                                     },
                                     {
-                                        path: '/edit/:id',
+                                        path: "/edit/:id",
                                         component: EditMonitor,
                                     },
-                                ]
+                                ],
                             },
                             {
-                                path: '/add',
+                                path: "/add",
                                 component: EditMonitor,
                             },
-                        ]
+                        ],
                     },
                     {
-                        path: '/settings',
+                        path: "/settings",
                         component: Settings,
                     },
                 ],
@@ -63,13 +62,13 @@ const routes = [
 
     },
     {
-        path: '/setup',
+        path: "/setup",
         component: Setup,
     },
 ]
 
 const router = createRouter({
-    linkActiveClass: 'active',
+    linkActiveClass: "active",
     history: createWebHistory(),
     routes,
 })
@@ -78,18 +77,18 @@ const app = createApp({
     mixins: [
         socket,
     ],
-    render: ()=>h(App)
+    render: () => h(App),
 })
 
 app.use(router)
 
 const options = {
-    position: "bottom-right"
+    position: "bottom-right",
 };
 
 app.use(Toast, options);
 
-app.component('font-awesome-icon', FontAwesomeIcon)
+app.component("FontAwesomeIcon", FontAwesomeIcon)
 
-app.mount('#app')
+app.mount("#app")
 
diff --git a/src/mixins/socket.js b/src/mixins/socket.js
index f36a770e..85cb4e2c 100644
--- a/src/mixins/socket.js
+++ b/src/mixins/socket.js
@@ -1,6 +1,6 @@
-import {io} from "socket.io-client";
-import { useToast } from 'vue-toastification'
 import dayjs from "dayjs";
+import { io } from "socket.io-client";
+import { useToast } from "vue-toastification";
 const toast = useToast()
 
 let socket;
@@ -33,7 +33,7 @@ export default {
     },
 
     created() {
-        window.addEventListener('resize', this.onResize);
+        window.addEventListener("resize", this.onResize);
 
         let wsHost;
         const env = process.env.NODE_ENV || "production";
@@ -44,18 +44,18 @@ export default {
         }
 
         socket = io(wsHost, {
-            transports: ['websocket']
+            transports: ["websocket"],
         });
 
         socket.on("connect_error", (err) => {
             console.error(`Failed to connect to the backend. Socket.io connect_error: ${err.message}`);
         });
 
-        socket.on('info', (info) => {
+        socket.on("info", (info) => {
             this.info = info;
         });
 
-        socket.on('setup', (monitorID, data) => {
+        socket.on("setup", (monitorID, data) => {
             this.$router.push("/setup")
         });
 
@@ -73,11 +73,11 @@ export default {
             this.monitorList = data;
         });
 
-        socket.on('notificationList', (data) => {
+        socket.on("notificationList", (data) => {
             this.notificationList = data;
         });
 
-        socket.on('heartbeat', (data) => {
+        socket.on("heartbeat", (data) => {
             if (! (data.monitorID in this.heartbeatList)) {
                 this.heartbeatList[data.monitorID] = [];
             }
@@ -100,7 +100,6 @@ export default {
                     toast(`[${this.monitorList[data.monitorID].name}] ${data.msg}`);
                 }
 
-
                 if (! (data.monitorID in this.importantHeartbeatList)) {
                     this.importantHeartbeatList[data.monitorID] = [];
                 }
@@ -109,7 +108,7 @@ export default {
             }
         });
 
-        socket.on('heartbeatList', (monitorID, data) => {
+        socket.on("heartbeatList", (monitorID, data) => {
             if (! (monitorID in this.heartbeatList)) {
                 this.heartbeatList[monitorID] = data;
             } else {
@@ -117,19 +116,19 @@ export default {
             }
         });
 
-        socket.on('avgPing', (monitorID, data) => {
+        socket.on("avgPing", (monitorID, data) => {
             this.avgPingList[monitorID] = data
         });
 
-        socket.on('uptime', (monitorID, type, data) => {
+        socket.on("uptime", (monitorID, type, data) => {
             this.uptimeList[`${monitorID}_${type}`] = data
         });
 
-        socket.on('certInfo', (monitorID, data) => {
+        socket.on("certInfo", (monitorID, data) => {
             this.certInfoList[monitorID] = JSON.parse(data)
         });
 
-        socket.on('importantHeartbeatList', (monitorID, data) => {
+        socket.on("importantHeartbeatList", (monitorID, data) => {
             if (! (monitorID in this.importantHeartbeatList)) {
                 this.importantHeartbeatList[monitorID] = data;
             } else {
@@ -137,12 +136,12 @@ export default {
             }
         });
 
-        socket.on('disconnect', () => {
+        socket.on("disconnect", () => {
             console.log("disconnect")
             this.socket.connected = false;
         });
 
-        socket.on('connect', () => {
+        socket.on("connect", () => {
             console.log("connect")
             this.socket.connectCount++;
             this.socket.connected = true;
@@ -201,7 +200,7 @@ export default {
                     this.loggedIn = true;
 
                     // Trigger Chrome Save Password
-                    history.pushState({}, '')
+                    history.pushState({}, "")
                 }
 
                 callback(res)
@@ -254,9 +253,8 @@ export default {
 
             if (this.userTimezone === "auto") {
                 return dayjs.tz.guess()
-            } else {
-                return this.userTimezone
             }
+            return this.userTimezone
 
         },
 
@@ -276,7 +274,7 @@ export default {
 
             let unknown = {
                 text: "Unknown",
-                color: "secondary"
+                color: "secondary",
             }
 
             for (let monitorID in this.lastHeartbeatList) {
@@ -287,17 +285,17 @@ export default {
                 } else if (lastHeartBeat.status === 1) {
                     result[monitorID] = {
                         text: "Up",
-                        color: "primary"
+                        color: "primary",
                     };
                 } else if (lastHeartBeat.status === 0) {
                     result[monitorID] = {
                         text: "Down",
-                        color: "danger"
+                        color: "danger",
                     };
                 } else if (lastHeartBeat.status === 2) {
                     result[monitorID] = {
                         text: "Pending",
-                        color: "warning"
+                        color: "warning",
                     };
                 } else {
                     result[monitorID] = unknown;
@@ -305,23 +303,23 @@ export default {
             }
 
             return result;
-        }
+        },
     },
 
     watch: {
 
         // Reload the SPA if the server version is changed.
         "info.version"(to, from) {
-              if (from && from !== to) {
-                  window.location.reload()
-              }
+            if (from && from !== to) {
+                window.location.reload()
+            }
         },
 
         remember() {
             localStorage.remember = (this.remember) ? "1" : "0"
-        }
+        },
 
-    }
+    },
 
 }
 
diff --git a/src/pages/Dashboard.vue b/src/pages/Dashboard.vue
index d24d9fc0..7df7ec7d 100644
--- a/src/pages/Dashboard.vue
+++ b/src/pages/Dashboard.vue
@@ -1,36 +1,33 @@
 <template>
-
     <div class="container-fluid">
         <div class="row">
             <div class="col-12 col-md-5 col-xl-4">
                 <div v-if="! $root.isMobile">
-                    <router-link to="/add" class="btn btn-primary"><font-awesome-icon icon="plus" /> Add New Monitor</router-link>
+                    <router-link to="/add" class="btn btn-primary">
+                        <font-awesome-icon icon="plus" /> Add New Monitor
+                    </router-link>
                 </div>
 
-                <div class="shadow-box list mb-4" v-if="showList">
-
-                    <div class="text-center mt-3" v-if="Object.keys($root.monitorList).length === 0">
-                        No Monitors, please <router-link to="/add">add one</router-link>.
+                <div v-if="showList" class="shadow-box list mb-4">
+                    <div v-if="Object.keys($root.monitorList).length === 0" class="text-center mt-3">
+                        No Monitors, please <router-link to="/add">
+                            add one
+                        </router-link>.
                     </div>
 
-                    <router-link :to="monitorURL(item.id)" class="item" :class="{ 'disabled': ! item.active }" v-for="(item, index) in sortedMonitorList" @click="$root.cancelActiveList" :key="index">
-
+                    <router-link v-for="(item, index) in sortedMonitorList" :key="index" :to="monitorURL(item.id)" class="item" :class="{ 'disabled': ! item.active }" @click="$root.cancelActiveList">
                         <div class="row">
-                        	<div class="col-6 col-md-8 small-padding">
-
+                            <div class="col-6 col-md-8 small-padding">
                                 <div class="info">
                                     <Uptime :monitor="item" type="24" :pill="true" />
                                     {{ item.name }}
                                 </div>
-
                             </div>
-                        	<div class="col-6 col-md-4">
+                            <div class="col-6 col-md-4">
                                 <HeartbeatBar size="small" :monitor-id="item.id" />
                             </div>
                         </div>
-
                     </router-link>
-
                 </div>
             </div>
             <div class="col-12 col-md-7 col-xl-8">
@@ -38,7 +35,6 @@
             </div>
         </div>
     </div>
-
 </template>
 
 <script>
@@ -49,12 +45,10 @@ import Uptime from "../components/Uptime.vue";
 export default {
     components: {
         Uptime,
-        HeartbeatBar
+        HeartbeatBar,
     },
     data() {
-        return {
-
-        }
+        return {}
     },
     computed: {
         sortedMonitorList() {
@@ -94,8 +88,8 @@ export default {
     methods: {
         monitorURL(id) {
             return "/dashboard/" + id;
-        }
-    }
+        },
+    },
 }
 </script>
 
diff --git a/src/pages/DashboardHome.vue b/src/pages/DashboardHome.vue
index 1fa784ff..657a3a49 100644
--- a/src/pages/DashboardHome.vue
+++ b/src/pages/DashboardHome.vue
@@ -1,15 +1,16 @@
 <template>
-
     <div v-if="$route.name === 'DashboardHome'">
-        <h1 class="mb-3">Quick Stats</h1>
+        <h1 class="mb-3">
+            Quick Stats
+        </h1>
 
         <div class="shadow-box big-padding text-center">
             <div class="row">
-            	<div class="col">
+                <div class="col">
                     <h3>Up</h3>
                     <span class="num">{{ stats.up }}</span>
                 </div>
-            	<div class="col">
+                <div class="col">
                     <h3>Down</h3>
                     <span class="num text-danger">{{ stats.down }}</span>
                 </div>
@@ -22,16 +23,16 @@
                     <span class="num text-secondary">{{ stats.pause }}</span>
                 </div>
             </div>
-            <div class="row" v-if="false">
+            <div v-if="false" class="row">
                 <div class="col-3">
                     <h3>Uptime</h3>
                     <p>(24-hour)</p>
-                    <span class="num"></span>
+                    <span class="num" />
                 </div>
                 <div class="col-3">
                     <h3>Uptime</h3>
                     <p>(30-day)</p>
-                    <span class="num"></span>
+                    <span class="num" />
                 </div>
             </div>
         </div>
@@ -39,32 +40,35 @@
         <div class="shadow-box" style="margin-top: 25px;">
             <table class="table table-borderless table-hover">
                 <thead>
-                <tr>
-                    <th>Name</th>
-                    <th>Status</th>
-                    <th>DateTime</th>
-                    <th>Message</th>
-                </tr>
+                    <tr>
+                        <th>Name</th>
+                        <th>Status</th>
+                        <th>DateTime</th>
+                        <th>Message</th>
+                    </tr>
                 </thead>
                 <tbody>
-                <tr v-for="(beat, index) in displayedRecords" :key="index">
-                    <td>{{ beat.name }}</td>
-                    <td><Status :status="beat.status" /></td>
-                    <td><Datetime :value="beat.time" /></td>
-                    <td>{{ beat.msg }}</td>
-                </tr>
+                    <tr v-for="(beat, index) in displayedRecords" :key="index">
+                        <td>{{ beat.name }}</td>
+                        <td><Status :status="beat.status" /></td>
+                        <td><Datetime :value="beat.time" /></td>
+                        <td>{{ beat.msg }}</td>
+                    </tr>
 
-                <tr v-if="importantHeartBeatList.length === 0">
-                    <td colspan="4">No important events</td>
-                </tr>
+                    <tr v-if="importantHeartBeatList.length === 0">
+                        <td colspan="4">
+                            No important events
+                        </td>
+                    </tr>
                 </tbody>
             </table>
 
             <div class="d-flex justify-content-center kuma_pagination">
                 <pagination
                     v-model="page"
-                    :records=importantHeartBeatList.length
-                    :per-page="perPage" />
+                    :records="importantHeartBeatList.length"
+                    :per-page="perPage"
+                />
             </div>
         </div>
     </div>
@@ -111,7 +115,7 @@ export default {
                     } else if (beat.status === 0) {
                         result.down++;
                     } else if (beat.status === 2) {
-                        result.up++;                
+                        result.up++;
                     } else {
                         result.unknown++;
                     }
@@ -127,7 +131,7 @@ export default {
             let result = [];
 
             for (let monitorID in this.$root.importantHeartbeatList) {
-                let list =  this.$root.importantHeartbeatList[monitorID]
+                let list = this.$root.importantHeartbeatList[monitorID]
                 result = result.concat(list);
             }
 
@@ -142,11 +146,11 @@ export default {
             result.sort((a, b) => {
                 if (a.time > b.time) {
                     return -1;
-                } else if (a.time < b.time) {
+                } if (a.time < b.time) {
                     return 1;
-                } else {
-                    return 0;
                 }
+
+                return 0;
             });
 
             this.heartBeatList = result;
@@ -159,7 +163,7 @@ export default {
             const endIndex = startIndex + this.perPage;
             return this.heartBeatList.slice(startIndex, endIndex);
         },
-    }
+    },
 }
 </script>
 
diff --git a/src/pages/Details.vue b/src/pages/Details.vue
index b1f39613..a83e238f 100644
--- a/src/pages/Details.vue
+++ b/src/pages/Details.vue
@@ -1,20 +1,28 @@
 <template>
     <h1> {{ monitor.name }}</h1>
     <p class="url">
-        <a :href="monitor.url" target="_blank" v-if="monitor.type === 'http' || monitor.type === 'keyword' ">{{ monitor.url }}</a>
+        <a v-if="monitor.type === 'http' || monitor.type === 'keyword' " :href="monitor.url" target="_blank">{{ monitor.url }}</a>
         <span v-if="monitor.type === 'port'">TCP Ping {{ monitor.hostname }}:{{ monitor.port }}</span>
         <span v-if="monitor.type === 'ping'">Ping: {{ monitor.hostname }}</span>
         <span v-if="monitor.type === 'keyword'">
-            <br />
+            <br>
             <span>Keyword:</span> <span style="color: black">{{ monitor.keyword }}</span>
         </span>
     </p>
 
     <div class="functions">
-        <button class="btn btn-light" @click="pauseDialog" v-if="monitor.active"><font-awesome-icon icon="pause" /> Pause</button>
-        <button class="btn btn-primary" @click="resumeMonitor" v-if="! monitor.active"><font-awesome-icon icon="pause" /> Resume</button>
-        <router-link :to=" '/edit/' + monitor.id " class="btn btn-secondary"><font-awesome-icon icon="edit" /> Edit</router-link>
-        <button class="btn btn-danger" @click="deleteDialog"><font-awesome-icon icon="trash" /> Delete</button>
+        <button v-if="monitor.active" class="btn btn-light" @click="pauseDialog">
+            <font-awesome-icon icon="pause" /> Pause
+        </button>
+        <button v-if="! monitor.active" class="btn btn-primary" @click="resumeMonitor">
+            <font-awesome-icon icon="pause" /> Resume
+        </button>
+        <router-link :to=" '/edit/' + monitor.id " class="btn btn-secondary">
+            <font-awesome-icon icon="edit" /> Edit
+        </router-link>
+        <button class="btn btn-danger" @click="deleteDialog">
+            <font-awesome-icon icon="trash" /> Delete
+        </button>
     </div>
 
     <div class="shadow-box">
@@ -52,40 +60,50 @@
                 <span class="num"><Uptime :monitor="monitor" type="720" /></span>
             </div>
 
-            <div class="col" v-if="certInfo">
+            <div v-if="certInfo" class="col">
                 <h4>CertExp.</h4>
                 <p>(<Datetime :value="certInfo.validTo" date-only />)</p>
-                <span class="num" >
-                    <a href="#"  @click.prevent="toggleCertInfoBox = !toggleCertInfoBox">{{certInfo.daysRemaining}} days</a>
+                <span class="num">
+                    <a href="#" @click.prevent="toggleCertInfoBox = !toggleCertInfoBox">{{ certInfo.daysRemaining }} days</a>
                 </span>
             </div>
         </div>
     </div>
 
-    <div class="shadow-box big-padding text-center" v-if="showCertInfoBox">
+    <div v-if="showCertInfoBox" class="shadow-box big-padding text-center">
         <div class="row">
             <div class="col">
                 <h4>Certificate Info</h4>
                 <table class="text-start">
                     <tbody>
                         <tr class="my-3">
-                            <td class="px-3">Valid: </td>
+                            <td class="px-3">
+                                Valid:
+                            </td>
                             <td>{{ certInfo.valid }}</td>
                         </tr>
                         <tr class="my-3">
-                            <td class="px-3">Valid To: </td>
+                            <td class="px-3">
+                                Valid To:
+                            </td>
                             <td><Datetime :value="certInfo.validTo" /></td>
                         </tr>
                         <tr class="my-3">
-                            <td class="px-3">Days Remaining: </td>
+                            <td class="px-3">
+                                Days Remaining:
+                            </td>
                             <td>{{ certInfo.daysRemaining }}</td>
                         </tr>
                         <tr class="my-3">
-                            <td class="px-3">Issuer: </td>
+                            <td class="px-3">
+                                Issuer:
+                            </td>
                             <td>{{ certInfo.issuer }}</td>
                         </tr>
                         <tr class="my-3">
-                            <td class="px-3">Fingerprint: </td>
+                            <td class="px-3">
+                                Fingerprint:
+                            </td>
                             <td>{{ certInfo.fingerprint }}</td>
                         </tr>
                     </tbody>
@@ -111,7 +129,9 @@
                 </tr>
 
                 <tr v-if="importantHeartBeatList.length === 0">
-                    <td colspan="3">No important events</td>
+                    <td colspan="3">
+                        No important events
+                    </td>
                 </tr>
             </tbody>
         </table>
@@ -119,8 +139,9 @@
         <div class="d-flex justify-content-center kuma_pagination">
             <pagination
                 v-model="page"
-                :records=importantHeartBeatList.length
-                :per-page="perPage" />
+                :records="importantHeartBeatList.length"
+                :per-page="perPage"
+            />
         </div>
     </div>
 
@@ -128,13 +149,13 @@
         Are you sure want to pause?
     </Confirm>
 
-    <Confirm ref="confirmDelete" btnStyle="btn-danger" @yes="deleteMonitor">
+    <Confirm ref="confirmDelete" btn-style="btn-danger" @yes="deleteMonitor">
         Are you sure want to delete this monitor?
     </Confirm>
 </template>
 
 <script>
-import { useToast } from 'vue-toastification'
+import { useToast } from "vue-toastification"
 const toast = useToast()
 import Confirm from "../components/Confirm.vue";
 import HeartbeatBar from "../components/HeartbeatBar.vue";
@@ -153,9 +174,6 @@ export default {
         Confirm,
         Status,
         Pagination,
-    },
-    mounted() {
-
     },
     data() {
         return {
@@ -170,9 +188,9 @@ export default {
         pingTitle() {
             if (this.monitor.type === "http") {
                 return "Response"
-            } else {
-                return "Ping"
             }
+
+            return "Ping"
         },
 
         monitor() {
@@ -183,50 +201,52 @@ export default {
         lastHeartBeat() {
             if (this.monitor.id in this.$root.lastHeartbeatList && this.$root.lastHeartbeatList[this.monitor.id]) {
                 return this.$root.lastHeartbeatList[this.monitor.id]
-            } else {
-                return { status: -1 }
+            }
+
+            return {
+                status: -1,
             }
         },
 
         ping() {
             if (this.lastHeartBeat.ping || this.lastHeartBeat.ping === 0) {
                 return this.lastHeartBeat.ping;
-            } else {
-                return "N/A"
             }
+
+            return "N/A"
         },
 
         avgPing() {
             if (this.$root.avgPingList[this.monitor.id] || this.$root.avgPingList[this.monitor.id] === 0) {
                 return this.$root.avgPingList[this.monitor.id];
-            } else {
-                return "N/A"
             }
+
+            return "N/A"
         },
 
         importantHeartBeatList() {
             if (this.$root.importantHeartbeatList[this.monitor.id]) {
                 this.heartBeatList = this.$root.importantHeartbeatList[this.monitor.id];
                 return this.$root.importantHeartbeatList[this.monitor.id]
-            } else {
-                return [];
             }
+
+            return [];
         },
 
         status() {
             if (this.$root.statusList[this.monitor.id]) {
                 return this.$root.statusList[this.monitor.id]
-            } else {
-                return { }
             }
+
+            return { }
         },
 
         certInfo() {
             if (this.$root.certInfoList[this.monitor.id]) {
                 return this.$root.certInfoList[this.monitor.id]
-            } else {
-                return null
             }
+
+            return null
         },
 
         showCertInfoBox() {
@@ -238,6 +258,9 @@ export default {
             const endIndex = startIndex + this.perPage;
             return this.heartBeatList.slice(startIndex, endIndex);
         },
+    },
+    mounted() {
+
     },
     methods: {
         testNotification() {
@@ -274,9 +297,9 @@ export default {
                     toast.error(res.msg);
                 }
             })
-        }
+        },
 
-    }
+    },
 }
 </script>
 
diff --git a/src/pages/EditMonitor.vue b/src/pages/EditMonitor.vue
index 75d7d4b9..b79c6cb1 100644
--- a/src/pages/EditMonitor.vue
+++ b/src/pages/EditMonitor.vue
@@ -1,85 +1,102 @@
 <template>
-    <h1 class="mb-3">{{ pageName }}</h1>
+    <h1 class="mb-3">
+        {{ pageName }}
+    </h1>
     <form @submit.prevent="submit">
-
-    <div class="shadow-box">
-        <div class="row">
-            <div class="col-md-6">
-                <h2>General</h2>
+        <div class="shadow-box">
+            <div class="row">
+                <div class="col-md-6">
+                    <h2>General</h2>
 
                     <div class="mb-3">
                         <label for="type" class="form-label">Monitor Type</label>
-                        <select class="form-select" aria-label="Default select example" id="type" v-model="monitor.type">
-                            <option value="http">HTTP(s)</option>
-                            <option value="port">TCP Port</option>
-                            <option value="ping">Ping</option>
-                            <option value="keyword">HTTP(s) - Keyword</option>
+                        <select id="type" v-model="monitor.type" class="form-select" aria-label="Default select example">
+                            <option value="http">
+                                HTTP(s)
+                            </option>
+                            <option value="port">
+                                TCP Port
+                            </option>
+                            <option value="ping">
+                                Ping
+                            </option>
+                            <option value="keyword">
+                                HTTP(s) - Keyword
+                            </option>
                         </select>
                     </div>
 
                     <div class="mb-3">
                         <label for="name" class="form-label">Friendly Name</label>
-                        <input type="text" class="form-control" id="name" v-model="monitor.name" required>
+                        <input id="name" v-model="monitor.name" type="text" class="form-control" required>
                     </div>
 
-                    <div class="mb-3" v-if="monitor.type === 'http' || monitor.type === 'keyword' ">
+                    <div v-if="monitor.type === 'http' || monitor.type === 'keyword' " class="mb-3">
                         <label for="url" class="form-label">URL</label>
-                        <input type="url" class="form-control" id="url" v-model="monitor.url" pattern="https?://.+" required>
+                        <input id="url" v-model="monitor.url" type="url" class="form-control" pattern="https?://.+" required>
                     </div>
 
-                    <div class="mb-3" v-if="monitor.type === 'keyword' ">
+                    <div v-if="monitor.type === 'keyword' " class="mb-3">
                         <label for="keyword" class="form-label">Keyword</label>
-                        <input type="text" class="form-control" id="keyword" v-model="monitor.keyword" required>
-                        <div class="form-text">Search keyword in plain html or JSON response and it is case-sensitive</div>
+                        <input id="keyword" v-model="monitor.keyword" type="text" class="form-control" required>
+                        <div class="form-text">
+                            Search keyword in plain html or JSON response and it is case-sensitive
+                        </div>
                     </div>
 
-                    <div class="mb-3" v-if="monitor.type === 'port' || monitor.type === 'ping' ">
+                    <div v-if="monitor.type === 'port' || monitor.type === 'ping' " class="mb-3">
                         <label for="hostname" class="form-label">Hostname</label>
-                        <input type="text" class="form-control" id="hostname" v-model="monitor.hostname" required>
+                        <input id="hostname" v-model="monitor.hostname" type="text" class="form-control" required>
                     </div>
 
-                    <div class="mb-3" v-if="monitor.type === 'port' ">
+                    <div v-if="monitor.type === 'port' " class="mb-3">
                         <label for="port" class="form-label">Port</label>
-                        <input type="number" class="form-control" id="port" v-model="monitor.port" required min="0" max="65535" step="1">
+                        <input id="port" v-model="monitor.port" type="number" class="form-control" required min="0" max="65535" step="1">
                     </div>
 
                     <div class="mb-3">
                         <label for="interval" class="form-label">Heartbeat Interval (Every {{ monitor.interval }} seconds)</label>
-                        <input type="number" class="form-control" id="interval" v-model="monitor.interval" required min="20" step="1">
+                        <input id="interval" v-model="monitor.interval" type="number" class="form-control" required min="20" step="1">
                     </div>
 
                     <div class="mb-3">
                         <label for="maxRetries" class="form-label">Retries</label>
-                        <input type="number" class="form-control" id="maxRetries" v-model="monitor.maxretries" required min="0" step="1">
-                        <div class="form-text">Maximum retries before the service is marked as down and a notification is sent</div>
+                        <input id="maxRetries" v-model="monitor.maxretries" type="number" class="form-control" required min="0" step="1">
+                        <div class="form-text">
+                            Maximum retries before the service is marked as down and a notification is sent
+                        </div>
                     </div>
 
                     <div>
-                        <button class="btn btn-primary" type="submit" :disabled="processing">Save</button>
+                        <button class="btn btn-primary" type="submit" :disabled="processing">
+                            Save
+                        </button>
                     </div>
-
-            </div>
-
-            <div class="col-md-6">
-
-                <div class="mt-3" v-if="$root.isMobile"></div>
-
-                <h2>Notifications</h2>
-                <p v-if="$root.notificationList.length === 0">Not available, please setup.</p>
-
-                <div class="form-check form-switch mb-3" :key="notification.id" v-for="notification in $root.notificationList">
-                    <input class="form-check-input" type="checkbox" :id=" 'notification' + notification.id" v-model="monitor.notificationIDList[notification.id]">
-
-                    <label class="form-check-label" :for=" 'notification' + notification.id">
-                        {{ notification.name }}
-                        <a href="#" @click="$refs.notificationDialog.show(notification.id)">Edit</a>
-                    </label>
                 </div>
 
-                <button class="btn btn-primary me-2" @click="$refs.notificationDialog.show()" type="button">Setup Notification</button>
+                <div class="col-md-6">
+                    <div v-if="$root.isMobile" class="mt-3" />
+
+                    <h2>Notifications</h2>
+                    <p v-if="$root.notificationList.length === 0">
+                        Not available, please setup.
+                    </p>
+
+                    <div v-for="notification in $root.notificationList" :key="notification.id" class="form-check form-switch mb-3">
+                        <input :id=" 'notification' + notification.id" v-model="monitor.notificationIDList[notification.id]" class="form-check-input" type="checkbox">
+
+                        <label class="form-check-label" :for=" 'notification' + notification.id">
+                            {{ notification.name }}
+                            <a href="#" @click="$refs.notificationDialog.show(notification.id)">Edit</a>
+                        </label>
+                    </div>
+
+                    <button class="btn btn-primary me-2" type="button" @click="$refs.notificationDialog.show()">
+                        Setup Notification
+                    </button>
+                </div>
             </div>
         </div>
-    </div>
     </form>
 
     <NotificationDialog ref="notificationDialog" />
@@ -87,15 +104,12 @@
 
 <script>
 import NotificationDialog from "../components/NotificationDialog.vue";
-import { useToast } from 'vue-toastification'
+import { useToast } from "vue-toastification"
 const toast = useToast()
 
 export default {
     components: {
-        NotificationDialog
-    },
-    mounted() {
-        this.init();
+        NotificationDialog,
     },
     data() {
         return {
@@ -114,7 +128,15 @@ export default {
         },
         isEdit() {
             return this.$route.path.startsWith("/edit");
-        }
+        },
+    },
+    watch: {
+        "$route.fullPath" () {
+            this.init();
+        },
+    },
+    mounted() {
+        this.init();
     },
     methods: {
         init() {
@@ -161,12 +183,7 @@ export default {
                     this.$root.toastRes(res)
                 })
             }
-        }
-    },
-    watch: {
-        '$route.fullPath' () {
-            this.init();
-        }
+        },
     },
 }
 </script>
diff --git a/src/pages/Settings.vue b/src/pages/Settings.vue
index f4bf156a..d1d3599b 100644
--- a/src/pages/Settings.vue
+++ b/src/pages/Settings.vue
@@ -1,22 +1,29 @@
 <template>
-    <h1 class="mb-3">Settings</h1>
+    <h1 class="mb-3">
+        Settings
+    </h1>
 
     <div class="shadow-box">
         <div class="row">
-
             <div class="col-md-6">
                 <h2>General</h2>
                 <form class="mb-3" @submit.prevent="saveGeneral">
                     <div class="mb-3">
                         <label for="timezone" class="form-label">Timezone</label>
-                        <select class="form-select" id="timezone" v-model="$root.userTimezone">
-                            <option value="auto">Auto: {{ guessTimezone }}</option>
-                            <option v-for="(timezone, index) in timezoneList" :value="timezone.value" :key="index">{{ timezone.name }}</option>
+                        <select id="timezone" v-model="$root.userTimezone" class="form-select">
+                            <option value="auto">
+                                Auto: {{ guessTimezone }}
+                            </option>
+                            <option v-for="(timezone, index) in timezoneList" :key="index" :value="timezone.value">
+                                {{ timezone.name }}
+                            </option>
                         </select>
                     </div>
 
                     <div>
-                        <button class="btn btn-primary" type="submit">Save</button>
+                        <button class="btn btn-primary" type="submit">
+                            Save
+                        </button>
                     </div>
                 </form>
 
@@ -24,51 +31,58 @@
                 <form class="mb-3" @submit.prevent="savePassword">
                     <div class="mb-3">
                         <label for="current-password" class="form-label">Current Password</label>
-                        <input type="password" class="form-control" id="current-password" required v-model="password.currentPassword">
+                        <input id="current-password" v-model="password.currentPassword" type="password" class="form-control" required>
                     </div>
 
                     <div class="mb-3">
                         <label for="new-password" class="form-label">New Password</label>
-                        <input type="password" class="form-control" id="new-password" required v-model="password.newPassword">
+                        <input id="new-password" v-model="password.newPassword" type="password" class="form-control" required>
                     </div>
 
                     <div class="mb-3">
                         <label for="repeat-new-password" class="form-label">Repeat New Password</label>
-                        <input type="password" class="form-control" :class="{ 'is-invalid' : invalidPassword }" id="repeat-new-password" required v-model="password.repeatNewPassword">
+                        <input id="repeat-new-password" v-model="password.repeatNewPassword" type="password" class="form-control" :class="{ 'is-invalid' : invalidPassword }" required>
                         <div class="invalid-feedback">
                             The repeat password does not match.
                         </div>
                     </div>
 
                     <div>
-                        <button class="btn btn-primary" type="submit">Update Password</button>
+                        <button class="btn btn-primary" type="submit">
+                            Update Password
+                        </button>
                     </div>
                 </form>
 
                 <div>
-                    <button class="btn btn-danger" @click="$root.logout">Logout</button>
+                    <button class="btn btn-danger" @click="$root.logout">
+                        Logout
+                    </button>
                 </div>
             </div>
 
             <div class="col-md-6">
-
-                <div class="mt-3" v-if="$root.isMobile"></div>
+                <div v-if="$root.isMobile" class="mt-3" />
 
                 <h2>Notifications</h2>
-                <p v-if="$root.notificationList.length === 0">Not available, please setup.</p>
-                <p v-else>Please assign a notification to monitor(s) to get it to work.</p>
+                <p v-if="$root.notificationList.length === 0">
+                    Not available, please setup.
+                </p>
+                <p v-else>
+                    Please assign a notification to monitor(s) to get it to work.
+                </p>
 
                 <ul class="list-group mb-3" style="border-radius: 1rem;">
-                    <li class="list-group-item" v-for="(notification, index) in $root.notificationList" :key="index">
-                        {{ notification.name }}<br />
+                    <li v-for="(notification, index) in $root.notificationList" :key="index" class="list-group-item">
+                        {{ notification.name }}<br>
                         <a href="#" @click="$refs.notificationDialog.show(notification.id)">Edit</a>
                     </li>
                 </ul>
 
-                <button class="btn btn-primary me-2" @click="$refs.notificationDialog.show()" type="button">Setup Notification</button>
+                <button class="btn btn-primary me-2" type="button" @click="$refs.notificationDialog.show()">
+                    Setup Notification
+                </button>
             </div>
-
-
         </div>
     </div>
 
@@ -77,18 +91,18 @@
 
 <script>
 import dayjs from "dayjs";
-import utc from 'dayjs/plugin/utc'
-import timezone from 'dayjs/plugin/timezone'
+import utc from "dayjs/plugin/utc"
+import timezone from "dayjs/plugin/timezone"
 import NotificationDialog from "../components/NotificationDialog.vue";
 dayjs.extend(utc)
 dayjs.extend(timezone)
-import {timezoneList} from "../util-frontend";
-import { useToast } from 'vue-toastification'
+import { timezoneList } from "../util-frontend";
+import { useToast } from "vue-toastification"
 const toast = useToast()
 
 export default {
     components: {
-        NotificationDialog
+        NotificationDialog,
     },
     data() {
         return {
@@ -100,9 +114,14 @@ export default {
                 currentPassword: "",
                 newPassword: "",
                 repeatNewPassword: "",
-            }
+            },
         }
     },
+    watch: {
+        "password.repeatNewPassword"() {
+            this.invalidPassword = false;
+        },
+    },
 
     mounted() {
 
@@ -130,11 +149,6 @@ export default {
             }
         },
     },
-    watch: {
-        "password.repeatNewPassword"() {
-            this.invalidPassword = false;
-        }
-    }
 }
 </script>
 
diff --git a/src/pages/Setup.vue b/src/pages/Setup.vue
index fa68945d..85a8147c 100644
--- a/src/pages/Setup.vue
+++ b/src/pages/Setup.vue
@@ -2,38 +2,42 @@
     <div class="form-container">
         <div class="form">
             <form @submit.prevent="submit">
-
                 <div>
-                    <object width="64" height="64" data="/icon.svg"></object>
-                    <div style="font-size: 28px; font-weight: bold; margin-top: 5px;">Uptime Kuma</div>
+                    <object width="64" height="64" data="/icon.svg" />
+                    <div style="font-size: 28px; font-weight: bold; margin-top: 5px;">
+                        Uptime Kuma
+                    </div>
                 </div>
 
-                <p class="mt-3">Create your admin account</p>
+                <p class="mt-3">
+                    Create your admin account
+                </p>
 
                 <div class="form-floating">
-                    <input type="text" class="form-control" id="floatingInput" placeholder="Username" v-model="username" required>
+                    <input id="floatingInput" v-model="username" type="text" class="form-control" placeholder="Username" required>
                     <label for="floatingInput">Username</label>
                 </div>
 
                 <div class="form-floating mt-3">
-                    <input type="password" class="form-control" id="floatingPassword" placeholder="Password" v-model="password" required>
+                    <input id="floatingPassword" v-model="password" type="password" class="form-control" placeholder="Password" required>
                     <label for="floatingPassword">Password</label>
                 </div>
 
                 <div class="form-floating mt-3">
-                    <input type="password" class="form-control" id="repeat" placeholder="Repeat Password" v-model="repeatPassword" required>
+                    <input id="repeat" v-model="repeatPassword" type="password" class="form-control" placeholder="Repeat Password" required>
                     <label for="repeat">Repeat Password</label>
                 </div>
 
-                <button class="w-100 btn btn-primary mt-3" type="submit" :disabled="processing">Create</button>
-
+                <button class="w-100 btn btn-primary mt-3" type="submit" :disabled="processing">
+                    Create
+                </button>
             </form>
         </div>
     </div>
 </template>
 
 <script>
-import { useToast } from 'vue-toastification'
+import { useToast } from "vue-toastification"
 const toast = useToast()
 
 export default {
@@ -70,8 +74,8 @@ export default {
                     this.$router.push("/")
                 }
             })
-        }
-    }
+        },
+    },
 }
 </script>
 
diff --git a/src/util-frontend.js b/src/util-frontend.js
index 3cfab2df..d80d4385 100644
--- a/src/util-frontend.js
+++ b/src/util-frontend.js
@@ -1,6 +1,6 @@
 import dayjs from "dayjs";
-import utc from 'dayjs/plugin/utc'
-import timezone from 'dayjs/plugin/timezone'
+import timezone from "dayjs/plugin/timezone";
+import utc from "dayjs/plugin/utc";
 
 dayjs.extend(utc)
 dayjs.extend(timezone)
@@ -18,11 +18,12 @@ export function ucfirst(str) {
     return firstLetter.toUpperCase() + str.substr(1);
 }
 
-
 function getTimezoneOffset(timeZone) {
     const now = new Date();
-    const tzString = now.toLocaleString('en-US', { timeZone });
-    const localString = now.toLocaleString('en-US');
+    const tzString = now.toLocaleString("en-US", {
+        timeZone,
+    });
+    const localString = now.toLocaleString("en-US");
     const diff = (Date.parse(localString) - Date.parse(tzString)) / 3600000;
     const offset = diff + now.getTimezoneOffset() / 60;
     return -offset;
@@ -31,355 +32,354 @@ function getTimezoneOffset(timeZone) {
 // From: https://stackoverflow.com/questions/38399465/how-to-get-list-of-all-timezones-in-javascript
 // TODO: Move to separate file
 const aryIannaTimeZones = [
-    'Europe/Andorra',
-    'Asia/Dubai',
-    'Asia/Kabul',
-    'Europe/Tirane',
-    'Asia/Yerevan',
-    'Antarctica/Casey',
-    'Antarctica/Davis',
-    'Antarctica/Mawson',
-    'Antarctica/Palmer',
-    'Antarctica/Rothera',
-    'Antarctica/Syowa',
-    'Antarctica/Troll',
-    'Antarctica/Vostok',
-    'America/Argentina/Buenos_Aires',
-    'America/Argentina/Cordoba',
-    'America/Argentina/Salta',
-    'America/Argentina/Jujuy',
-    'America/Argentina/Tucuman',
-    'America/Argentina/Catamarca',
-    'America/Argentina/La_Rioja',
-    'America/Argentina/San_Juan',
-    'America/Argentina/Mendoza',
-    'America/Argentina/San_Luis',
-    'America/Argentina/Rio_Gallegos',
-    'America/Argentina/Ushuaia',
-    'Pacific/Pago_Pago',
-    'Europe/Vienna',
-    'Australia/Lord_Howe',
-    'Antarctica/Macquarie',
-    'Australia/Hobart',
-    'Australia/Currie',
-    'Australia/Melbourne',
-    'Australia/Sydney',
-    'Australia/Broken_Hill',
-    'Australia/Brisbane',
-    'Australia/Lindeman',
-    'Australia/Adelaide',
-    'Australia/Darwin',
-    'Australia/Perth',
-    'Australia/Eucla',
-    'Asia/Baku',
-    'America/Barbados',
-    'Asia/Dhaka',
-    'Europe/Brussels',
-    'Europe/Sofia',
-    'Atlantic/Bermuda',
-    'Asia/Brunei',
-    'America/La_Paz',
-    'America/Noronha',
-    'America/Belem',
-    'America/Fortaleza',
-    'America/Recife',
-    'America/Araguaina',
-    'America/Maceio',
-    'America/Bahia',
-    'America/Sao_Paulo',
-    'America/Campo_Grande',
-    'America/Cuiaba',
-    'America/Santarem',
-    'America/Porto_Velho',
-    'America/Boa_Vista',
-    'America/Manaus',
-    'America/Eirunepe',
-    'America/Rio_Branco',
-    'America/Nassau',
-    'Asia/Thimphu',
-    'Europe/Minsk',
-    'America/Belize',
-    'America/St_Johns',
-    'America/Halifax',
-    'America/Glace_Bay',
-    'America/Moncton',
-    'America/Goose_Bay',
-    'America/Blanc-Sablon',
-    'America/Toronto',
-    'America/Nipigon',
-    'America/Thunder_Bay',
-    'America/Iqaluit',
-    'America/Pangnirtung',
-    'America/Atikokan',
-    'America/Winnipeg',
-    'America/Rainy_River',
-    'America/Resolute',
-    'America/Rankin_Inlet',
-    'America/Regina',
-    'America/Swift_Current',
-    'America/Edmonton',
-    'America/Cambridge_Bay',
-    'America/Yellowknife',
-    'America/Inuvik',
-    'America/Creston',
-    'America/Dawson_Creek',
-    'America/Fort_Nelson',
-    'America/Vancouver',
-    'America/Whitehorse',
-    'America/Dawson',
-    'Indian/Cocos',
-    'Europe/Zurich',
-    'Africa/Abidjan',
-    'Pacific/Rarotonga',
-    'America/Santiago',
-    'America/Punta_Arenas',
-    'Pacific/Easter',
-    'Asia/Shanghai',
-    'Asia/Urumqi',
-    'America/Bogota',
-    'America/Costa_Rica',
-    'America/Havana',
-    'Atlantic/Cape_Verde',
-    'America/Curacao',
-    'Indian/Christmas',
-    'Asia/Nicosia',
-    'Asia/Famagusta',
-    'Europe/Prague',
-    'Europe/Berlin',
-    'Europe/Copenhagen',
-    'America/Santo_Domingo',
-    'Africa/Algiers',
-    'America/Guayaquil',
-    'Pacific/Galapagos',
-    'Europe/Tallinn',
-    'Africa/Cairo',
-    'Africa/El_Aaiun',
-    'Europe/Madrid',
-    'Africa/Ceuta',
-    'Atlantic/Canary',
-    'Europe/Helsinki',
-    'Pacific/Fiji',
-    'Atlantic/Stanley',
-    'Pacific/Chuuk',
-    'Pacific/Pohnpei',
-    'Pacific/Kosrae',
-    'Atlantic/Faroe',
-    'Europe/Paris',
-    'Europe/London',
-    'Asia/Tbilisi',
-    'America/Cayenne',
-    'Africa/Accra',
-    'Europe/Gibraltar',
-    'America/Godthab',
-    'America/Danmarkshavn',
-    'America/Scoresbysund',
-    'America/Thule',
-    'Europe/Athens',
-    'Atlantic/South_Georgia',
-    'America/Guatemala',
-    'Pacific/Guam',
-    'Africa/Bissau',
-    'America/Guyana',
-    'Asia/Hong_Kong',
-    'America/Tegucigalpa',
-    'America/Port-au-Prince',
-    'Europe/Budapest',
-    'Asia/Jakarta',
-    'Asia/Pontianak',
-    'Asia/Makassar',
-    'Asia/Jayapura',
-    'Europe/Dublin',
-    'Asia/Jerusalem',
-    'Asia/Kolkata',
-    'Indian/Chagos',
-    'Asia/Baghdad',
-    'Asia/Tehran',
-    'Atlantic/Reykjavik',
-    'Europe/Rome',
-    'America/Jamaica',
-    'Asia/Amman',
-    'Asia/Tokyo',
-    'Africa/Nairobi',
-    'Asia/Bishkek',
-    'Pacific/Tarawa',
-    'Pacific/Enderbury',
-    'Pacific/Kiritimati',
-    'Asia/Pyongyang',
-    'Asia/Seoul',
-    'Asia/Almaty',
-    'Asia/Qyzylorda',
-    'Asia/Aqtobe',
-    'Asia/Aqtau',
-    'Asia/Atyrau',
-    'Asia/Oral',
-    'Asia/Beirut',
-    'Asia/Colombo',
-    'Africa/Monrovia',
-    'Europe/Vilnius',
-    'Europe/Luxembourg',
-    'Europe/Riga',
-    'Africa/Tripoli',
-    'Africa/Casablanca',
-    'Europe/Monaco',
-    'Europe/Chisinau',
-    'Pacific/Majuro',
-    'Pacific/Kwajalein',
-    'Asia/Yangon',
-    'Asia/Ulaanbaatar',
-    'Asia/Hovd',
-    'Asia/Choibalsan',
-    'Asia/Macau',
-    'America/Martinique',
-    'Europe/Malta',
-    'Indian/Mauritius',
-    'Indian/Maldives',
-    'America/Mexico_City',
-    'America/Cancun',
-    'America/Merida',
-    'America/Monterrey',
-    'America/Matamoros',
-    'America/Mazatlan',
-    'America/Chihuahua',
-    'America/Ojinaga',
-    'America/Hermosillo',
-    'America/Tijuana',
-    'America/Bahia_Banderas',
-    'Asia/Kuala_Lumpur',
-    'Asia/Kuching',
-    'Africa/Maputo',
-    'Africa/Windhoek',
-    'Pacific/Noumea',
-    'Pacific/Norfolk',
-    'Africa/Lagos',
-    'America/Managua',
-    'Europe/Amsterdam',
-    'Europe/Oslo',
-    'Asia/Kathmandu',
-    'Pacific/Nauru',
-    'Pacific/Niue',
-    'Pacific/Auckland',
-    'Pacific/Chatham',
-    'America/Panama',
-    'America/Lima',
-    'Pacific/Tahiti',
-    'Pacific/Marquesas',
-    'Pacific/Gambier',
-    'Pacific/Port_Moresby',
-    'Pacific/Bougainville',
-    'Asia/Manila',
-    'Asia/Karachi',
-    'Europe/Warsaw',
-    'America/Miquelon',
-    'Pacific/Pitcairn',
-    'America/Puerto_Rico',
-    'Asia/Gaza',
-    'Asia/Hebron',
-    'Europe/Lisbon',
-    'Atlantic/Madeira',
-    'Atlantic/Azores',
-    'Pacific/Palau',
-    'America/Asuncion',
-    'Asia/Qatar',
-    'Indian/Reunion',
-    'Europe/Bucharest',
-    'Europe/Belgrade',
-    'Europe/Kaliningrad',
-    'Europe/Moscow',
-    'Europe/Simferopol',
-    'Europe/Kirov',
-    'Europe/Astrakhan',
-    'Europe/Volgograd',
-    'Europe/Saratov',
-    'Europe/Ulyanovsk',
-    'Europe/Samara',
-    'Asia/Yekaterinburg',
-    'Asia/Omsk',
-    'Asia/Novosibirsk',
-    'Asia/Barnaul',
-    'Asia/Tomsk',
-    'Asia/Novokuznetsk',
-    'Asia/Krasnoyarsk',
-    'Asia/Irkutsk',
-    'Asia/Chita',
-    'Asia/Yakutsk',
-    'Asia/Khandyga',
-    'Asia/Vladivostok',
-    'Asia/Ust-Nera',
-    'Asia/Magadan',
-    'Asia/Sakhalin',
-    'Asia/Srednekolymsk',
-    'Asia/Kamchatka',
-    'Asia/Anadyr',
-    'Asia/Riyadh',
-    'Pacific/Guadalcanal',
-    'Indian/Mahe',
-    'Africa/Khartoum',
-    'Europe/Stockholm',
-    'Asia/Singapore',
-    'America/Paramaribo',
-    'Africa/Juba',
-    'Africa/Sao_Tome',
-    'America/El_Salvador',
-    'Asia/Damascus',
-    'America/Grand_Turk',
-    'Africa/Ndjamena',
-    'Indian/Kerguelen',
-    'Asia/Bangkok',
-    'Asia/Dushanbe',
-    'Pacific/Fakaofo',
-    'Asia/Dili',
-    'Asia/Ashgabat',
-    'Africa/Tunis',
-    'Pacific/Tongatapu',
-    'Europe/Istanbul',
-    'America/Port_of_Spain',
-    'Pacific/Funafuti',
-    'Asia/Taipei',
-    'Europe/Kiev',
-    'Europe/Uzhgorod',
-    'Europe/Zaporozhye',
-    'Pacific/Wake',
-    'America/New_York',
-    'America/Detroit',
-    'America/Kentucky/Louisville',
-    'America/Kentucky/Monticello',
-    'America/Indiana/Indianapolis',
-    'America/Indiana/Vincennes',
-    'America/Indiana/Winamac',
-    'America/Indiana/Marengo',
-    'America/Indiana/Petersburg',
-    'America/Indiana/Vevay',
-    'America/Chicago',
-    'America/Indiana/Tell_City',
-    'America/Indiana/Knox',
-    'America/Menominee',
-    'America/North_Dakota/Center',
-    'America/North_Dakota/New_Salem',
-    'America/North_Dakota/Beulah',
-    'America/Denver',
-    'America/Boise',
-    'America/Phoenix',
-    'America/Los_Angeles',
-    'America/Anchorage',
-    'America/Juneau',
-    'America/Sitka',
-    'America/Metlakatla',
-    'America/Yakutat',
-    'America/Nome',
-    'America/Adak',
-    'Pacific/Honolulu',
-    'America/Montevideo',
-    'Asia/Samarkand',
-    'Asia/Tashkent',
-    'America/Caracas',
-    'Asia/Ho_Chi_Minh',
-    'Pacific/Efate',
-    'Pacific/Wallis',
-    'Pacific/Apia',
-    'Africa/Johannesburg',
+    "Europe/Andorra",
+    "Asia/Dubai",
+    "Asia/Kabul",
+    "Europe/Tirane",
+    "Asia/Yerevan",
+    "Antarctica/Casey",
+    "Antarctica/Davis",
+    "Antarctica/Mawson",
+    "Antarctica/Palmer",
+    "Antarctica/Rothera",
+    "Antarctica/Syowa",
+    "Antarctica/Troll",
+    "Antarctica/Vostok",
+    "America/Argentina/Buenos_Aires",
+    "America/Argentina/Cordoba",
+    "America/Argentina/Salta",
+    "America/Argentina/Jujuy",
+    "America/Argentina/Tucuman",
+    "America/Argentina/Catamarca",
+    "America/Argentina/La_Rioja",
+    "America/Argentina/San_Juan",
+    "America/Argentina/Mendoza",
+    "America/Argentina/San_Luis",
+    "America/Argentina/Rio_Gallegos",
+    "America/Argentina/Ushuaia",
+    "Pacific/Pago_Pago",
+    "Europe/Vienna",
+    "Australia/Lord_Howe",
+    "Antarctica/Macquarie",
+    "Australia/Hobart",
+    "Australia/Currie",
+    "Australia/Melbourne",
+    "Australia/Sydney",
+    "Australia/Broken_Hill",
+    "Australia/Brisbane",
+    "Australia/Lindeman",
+    "Australia/Adelaide",
+    "Australia/Darwin",
+    "Australia/Perth",
+    "Australia/Eucla",
+    "Asia/Baku",
+    "America/Barbados",
+    "Asia/Dhaka",
+    "Europe/Brussels",
+    "Europe/Sofia",
+    "Atlantic/Bermuda",
+    "Asia/Brunei",
+    "America/La_Paz",
+    "America/Noronha",
+    "America/Belem",
+    "America/Fortaleza",
+    "America/Recife",
+    "America/Araguaina",
+    "America/Maceio",
+    "America/Bahia",
+    "America/Sao_Paulo",
+    "America/Campo_Grande",
+    "America/Cuiaba",
+    "America/Santarem",
+    "America/Porto_Velho",
+    "America/Boa_Vista",
+    "America/Manaus",
+    "America/Eirunepe",
+    "America/Rio_Branco",
+    "America/Nassau",
+    "Asia/Thimphu",
+    "Europe/Minsk",
+    "America/Belize",
+    "America/St_Johns",
+    "America/Halifax",
+    "America/Glace_Bay",
+    "America/Moncton",
+    "America/Goose_Bay",
+    "America/Blanc-Sablon",
+    "America/Toronto",
+    "America/Nipigon",
+    "America/Thunder_Bay",
+    "America/Iqaluit",
+    "America/Pangnirtung",
+    "America/Atikokan",
+    "America/Winnipeg",
+    "America/Rainy_River",
+    "America/Resolute",
+    "America/Rankin_Inlet",
+    "America/Regina",
+    "America/Swift_Current",
+    "America/Edmonton",
+    "America/Cambridge_Bay",
+    "America/Yellowknife",
+    "America/Inuvik",
+    "America/Creston",
+    "America/Dawson_Creek",
+    "America/Fort_Nelson",
+    "America/Vancouver",
+    "America/Whitehorse",
+    "America/Dawson",
+    "Indian/Cocos",
+    "Europe/Zurich",
+    "Africa/Abidjan",
+    "Pacific/Rarotonga",
+    "America/Santiago",
+    "America/Punta_Arenas",
+    "Pacific/Easter",
+    "Asia/Shanghai",
+    "Asia/Urumqi",
+    "America/Bogota",
+    "America/Costa_Rica",
+    "America/Havana",
+    "Atlantic/Cape_Verde",
+    "America/Curacao",
+    "Indian/Christmas",
+    "Asia/Nicosia",
+    "Asia/Famagusta",
+    "Europe/Prague",
+    "Europe/Berlin",
+    "Europe/Copenhagen",
+    "America/Santo_Domingo",
+    "Africa/Algiers",
+    "America/Guayaquil",
+    "Pacific/Galapagos",
+    "Europe/Tallinn",
+    "Africa/Cairo",
+    "Africa/El_Aaiun",
+    "Europe/Madrid",
+    "Africa/Ceuta",
+    "Atlantic/Canary",
+    "Europe/Helsinki",
+    "Pacific/Fiji",
+    "Atlantic/Stanley",
+    "Pacific/Chuuk",
+    "Pacific/Pohnpei",
+    "Pacific/Kosrae",
+    "Atlantic/Faroe",
+    "Europe/Paris",
+    "Europe/London",
+    "Asia/Tbilisi",
+    "America/Cayenne",
+    "Africa/Accra",
+    "Europe/Gibraltar",
+    "America/Godthab",
+    "America/Danmarkshavn",
+    "America/Scoresbysund",
+    "America/Thule",
+    "Europe/Athens",
+    "Atlantic/South_Georgia",
+    "America/Guatemala",
+    "Pacific/Guam",
+    "Africa/Bissau",
+    "America/Guyana",
+    "Asia/Hong_Kong",
+    "America/Tegucigalpa",
+    "America/Port-au-Prince",
+    "Europe/Budapest",
+    "Asia/Jakarta",
+    "Asia/Pontianak",
+    "Asia/Makassar",
+    "Asia/Jayapura",
+    "Europe/Dublin",
+    "Asia/Jerusalem",
+    "Asia/Kolkata",
+    "Indian/Chagos",
+    "Asia/Baghdad",
+    "Asia/Tehran",
+    "Atlantic/Reykjavik",
+    "Europe/Rome",
+    "America/Jamaica",
+    "Asia/Amman",
+    "Asia/Tokyo",
+    "Africa/Nairobi",
+    "Asia/Bishkek",
+    "Pacific/Tarawa",
+    "Pacific/Enderbury",
+    "Pacific/Kiritimati",
+    "Asia/Pyongyang",
+    "Asia/Seoul",
+    "Asia/Almaty",
+    "Asia/Qyzylorda",
+    "Asia/Aqtobe",
+    "Asia/Aqtau",
+    "Asia/Atyrau",
+    "Asia/Oral",
+    "Asia/Beirut",
+    "Asia/Colombo",
+    "Africa/Monrovia",
+    "Europe/Vilnius",
+    "Europe/Luxembourg",
+    "Europe/Riga",
+    "Africa/Tripoli",
+    "Africa/Casablanca",
+    "Europe/Monaco",
+    "Europe/Chisinau",
+    "Pacific/Majuro",
+    "Pacific/Kwajalein",
+    "Asia/Yangon",
+    "Asia/Ulaanbaatar",
+    "Asia/Hovd",
+    "Asia/Choibalsan",
+    "Asia/Macau",
+    "America/Martinique",
+    "Europe/Malta",
+    "Indian/Mauritius",
+    "Indian/Maldives",
+    "America/Mexico_City",
+    "America/Cancun",
+    "America/Merida",
+    "America/Monterrey",
+    "America/Matamoros",
+    "America/Mazatlan",
+    "America/Chihuahua",
+    "America/Ojinaga",
+    "America/Hermosillo",
+    "America/Tijuana",
+    "America/Bahia_Banderas",
+    "Asia/Kuala_Lumpur",
+    "Asia/Kuching",
+    "Africa/Maputo",
+    "Africa/Windhoek",
+    "Pacific/Noumea",
+    "Pacific/Norfolk",
+    "Africa/Lagos",
+    "America/Managua",
+    "Europe/Amsterdam",
+    "Europe/Oslo",
+    "Asia/Kathmandu",
+    "Pacific/Nauru",
+    "Pacific/Niue",
+    "Pacific/Auckland",
+    "Pacific/Chatham",
+    "America/Panama",
+    "America/Lima",
+    "Pacific/Tahiti",
+    "Pacific/Marquesas",
+    "Pacific/Gambier",
+    "Pacific/Port_Moresby",
+    "Pacific/Bougainville",
+    "Asia/Manila",
+    "Asia/Karachi",
+    "Europe/Warsaw",
+    "America/Miquelon",
+    "Pacific/Pitcairn",
+    "America/Puerto_Rico",
+    "Asia/Gaza",
+    "Asia/Hebron",
+    "Europe/Lisbon",
+    "Atlantic/Madeira",
+    "Atlantic/Azores",
+    "Pacific/Palau",
+    "America/Asuncion",
+    "Asia/Qatar",
+    "Indian/Reunion",
+    "Europe/Bucharest",
+    "Europe/Belgrade",
+    "Europe/Kaliningrad",
+    "Europe/Moscow",
+    "Europe/Simferopol",
+    "Europe/Kirov",
+    "Europe/Astrakhan",
+    "Europe/Volgograd",
+    "Europe/Saratov",
+    "Europe/Ulyanovsk",
+    "Europe/Samara",
+    "Asia/Yekaterinburg",
+    "Asia/Omsk",
+    "Asia/Novosibirsk",
+    "Asia/Barnaul",
+    "Asia/Tomsk",
+    "Asia/Novokuznetsk",
+    "Asia/Krasnoyarsk",
+    "Asia/Irkutsk",
+    "Asia/Chita",
+    "Asia/Yakutsk",
+    "Asia/Khandyga",
+    "Asia/Vladivostok",
+    "Asia/Ust-Nera",
+    "Asia/Magadan",
+    "Asia/Sakhalin",
+    "Asia/Srednekolymsk",
+    "Asia/Kamchatka",
+    "Asia/Anadyr",
+    "Asia/Riyadh",
+    "Pacific/Guadalcanal",
+    "Indian/Mahe",
+    "Africa/Khartoum",
+    "Europe/Stockholm",
+    "Asia/Singapore",
+    "America/Paramaribo",
+    "Africa/Juba",
+    "Africa/Sao_Tome",
+    "America/El_Salvador",
+    "Asia/Damascus",
+    "America/Grand_Turk",
+    "Africa/Ndjamena",
+    "Indian/Kerguelen",
+    "Asia/Bangkok",
+    "Asia/Dushanbe",
+    "Pacific/Fakaofo",
+    "Asia/Dili",
+    "Asia/Ashgabat",
+    "Africa/Tunis",
+    "Pacific/Tongatapu",
+    "Europe/Istanbul",
+    "America/Port_of_Spain",
+    "Pacific/Funafuti",
+    "Asia/Taipei",
+    "Europe/Kiev",
+    "Europe/Uzhgorod",
+    "Europe/Zaporozhye",
+    "Pacific/Wake",
+    "America/New_York",
+    "America/Detroit",
+    "America/Kentucky/Louisville",
+    "America/Kentucky/Monticello",
+    "America/Indiana/Indianapolis",
+    "America/Indiana/Vincennes",
+    "America/Indiana/Winamac",
+    "America/Indiana/Marengo",
+    "America/Indiana/Petersburg",
+    "America/Indiana/Vevay",
+    "America/Chicago",
+    "America/Indiana/Tell_City",
+    "America/Indiana/Knox",
+    "America/Menominee",
+    "America/North_Dakota/Center",
+    "America/North_Dakota/New_Salem",
+    "America/North_Dakota/Beulah",
+    "America/Denver",
+    "America/Boise",
+    "America/Phoenix",
+    "America/Los_Angeles",
+    "America/Anchorage",
+    "America/Juneau",
+    "America/Sitka",
+    "America/Metlakatla",
+    "America/Yakutat",
+    "America/Nome",
+    "America/Adak",
+    "Pacific/Honolulu",
+    "America/Montevideo",
+    "Asia/Samarkand",
+    "Asia/Tashkent",
+    "America/Caracas",
+    "Asia/Ho_Chi_Minh",
+    "Pacific/Efate",
+    "Pacific/Wallis",
+    "Pacific/Apia",
+    "Africa/Johannesburg",
 ];
 
-
 export function timezoneList() {
 
     let result = [];
@@ -404,12 +404,14 @@ export function timezoneList() {
     result.sort((a, b) => {
         if (a.time > b.time) {
             return 1;
-        } else if (b.time > a.time) {
-            return -1;
-        } else {
-            return 0;
         }
+
+        if (b.time > a.time) {
+            return -1;
+        }
+
+        return 0;
     })
 
     return result;
-};
+}

From 4c8fdd07d998a7af7764e6d61886854e61cf5b6c Mon Sep 17 00:00:00 2001
From: Adam Stachowicz <adam.stachowicz@fingo.info>
Date: Tue, 27 Jul 2021 19:53:59 +0200
Subject: [PATCH 3/6] Manual fixes

---
 server/model/heartbeat.js             | 1 +
 server/model/monitor.js               | 3 ++-
 src/App.vue                           | 4 ----
 src/components/Confirm.vue            | 4 ----
 src/components/CountUp.vue            | 8 ++------
 src/components/Datetime.vue           | 4 ----
 src/components/HeartbeatBar.vue       | 2 +-
 src/components/NotificationDialog.vue | 4 ----
 src/components/Status.vue             | 4 ++--
 src/components/Uptime.vue             | 6 +-----
 src/layouts/EmptyLayout.vue           | 4 ----
 src/main.js                           | 1 -
 src/mixins/socket.js                  | 3 +--
 src/pages/DashboardHome.vue           | 4 +++-
 src/pages/Details.vue                 | 4 ++--
 15 files changed, 15 insertions(+), 41 deletions(-)

diff --git a/server/model/heartbeat.js b/server/model/heartbeat.js
index 0e492ada..54679414 100644
--- a/server/model/heartbeat.js
+++ b/server/model/heartbeat.js
@@ -9,6 +9,7 @@ const { BeanModel } = require("redbean-node/dist/bean-model");
  * status:
  *      0 = DOWN
  *      1 = UP
+ *      2 = PENDING
  */
 class Heartbeat extends BeanModel {
 
diff --git a/server/model/monitor.js b/server/model/monitor.js
index 27f3f9ba..b725f43c 100644
--- a/server/model/monitor.js
+++ b/server/model/monitor.js
@@ -22,6 +22,7 @@ const customAgent = new https.Agent({
  * status:
  *      0 = DOWN
  *      1 = UP
+ *      2 = PENDING
  */
 class Monitor extends BeanModel {
     async toJSON() {
@@ -197,7 +198,7 @@ class Monitor extends BeanModel {
             if (bean.status === UP) {
                 console.info(`Monitor #${this.id} '${this.name}': Successful Response: ${bean.ping} ms | Interval: ${this.interval} seconds | Type: ${this.type}`)
             } else if (bean.status === PENDING) {
-                console.warn(`Monitor #${this.id} '${this.name}': Pending: ${bean.msg} | Type: ${this.type}`)
+                console.warn(`Monitor #${this.id} '${this.name}': Pending: ${bean.msg} | Max retries: ${this.maxretries} | Type: ${this.type}`)
             } else {
                 console.warn(`Monitor #${this.id} '${this.name}': Failing: ${bean.msg} | Type: ${this.type}`)
             }
diff --git a/src/App.vue b/src/App.vue
index 974757a6..a16d4208 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -5,7 +5,3 @@
 <script>
 export default {}
 </script>
-
-<style lang="scss">
-
-</style>
diff --git a/src/components/Confirm.vue b/src/components/Confirm.vue
index ecf165a0..36d3781a 100644
--- a/src/components/Confirm.vue
+++ b/src/components/Confirm.vue
@@ -50,7 +50,3 @@ export default {
     },
 }
 </script>
-
-<style scoped>
-
-</style>
diff --git a/src/components/CountUp.vue b/src/components/CountUp.vue
index 1d2a4c55..c63aea14 100644
--- a/src/components/CountUp.vue
+++ b/src/components/CountUp.vue
@@ -12,11 +12,11 @@ export default {
     props: {
         value: [String, Number],
         time: {
-            Number,
+            type: Number,
             default: 0.3,
         },
         unit: {
-            String,
+            type: String,
             default: "ms",
         },
     },
@@ -61,7 +61,3 @@ export default {
 
 }
 </script>
-
-<style scoped>
-
-</style>
diff --git a/src/components/Datetime.vue b/src/components/Datetime.vue
index 365e9fca..84093afb 100644
--- a/src/components/Datetime.vue
+++ b/src/components/Datetime.vue
@@ -35,7 +35,3 @@ export default {
     },
 }
 </script>
-
-<style scoped>
-
-</style>
diff --git a/src/components/HeartbeatBar.vue b/src/components/HeartbeatBar.vue
index 7ee94317..bfcb9085 100644
--- a/src/components/HeartbeatBar.vue
+++ b/src/components/HeartbeatBar.vue
@@ -69,7 +69,7 @@ export default {
             let width
             if (this.maxBeat > 0) {
                 width = (this.beatWidth + this.beatMargin * 2) * this.maxBeat + (leftRight * 2) + "px"
-            } {
+            } else {
                 width = "100%"
             }
 
diff --git a/src/components/NotificationDialog.vue b/src/components/NotificationDialog.vue
index 3adbe4af..83a0d180 100644
--- a/src/components/NotificationDialog.vue
+++ b/src/components/NotificationDialog.vue
@@ -496,7 +496,3 @@ export default {
     },
 }
 </script>
-
-<style scoped>
-
-</style>
diff --git a/src/components/Status.vue b/src/components/Status.vue
index c0549821..a8f2ea59 100644
--- a/src/components/Status.vue
+++ b/src/components/Status.vue
@@ -17,8 +17,8 @@ export default {
             } if (this.status === 2) {
                 return "warning"
             }
-            return "secondary"
 
+            return "secondary"
         },
 
         text() {
@@ -29,8 +29,8 @@ export default {
             } if (this.status === 2) {
                 return "Pending"
             }
-            return "Unknown"
 
+            return "Unknown"
         },
     },
 }
diff --git a/src/components/Uptime.vue b/src/components/Uptime.vue
index e9c6f583..411ff95d 100644
--- a/src/components/Uptime.vue
+++ b/src/components/Uptime.vue
@@ -8,7 +8,7 @@ export default {
         monitor: Object,
         type: String,
         pill: {
-            Boolean,
+            type: Boolean,
             default: false,
         },
     },
@@ -57,7 +57,3 @@ export default {
     },
 }
 </script>
-
-<style scoped>
-
-</style>
diff --git a/src/layouts/EmptyLayout.vue b/src/layouts/EmptyLayout.vue
index 6f996587..a16d4208 100644
--- a/src/layouts/EmptyLayout.vue
+++ b/src/layouts/EmptyLayout.vue
@@ -5,7 +5,3 @@
 <script>
 export default {}
 </script>
-
-<style scoped>
-
-</style>
diff --git a/src/main.js b/src/main.js
index e76db1ed..6eb296dc 100644
--- a/src/main.js
+++ b/src/main.js
@@ -91,4 +91,3 @@ app.use(Toast, options);
 app.component("FontAwesomeIcon", FontAwesomeIcon)
 
 app.mount("#app")
-
diff --git a/src/mixins/socket.js b/src/mixins/socket.js
index 85cb4e2c..585b929e 100644
--- a/src/mixins/socket.js
+++ b/src/mixins/socket.js
@@ -254,8 +254,8 @@ export default {
             if (this.userTimezone === "auto") {
                 return dayjs.tz.guess()
             }
-            return this.userTimezone
 
+            return this.userTimezone
         },
 
         lastHeartbeatList() {
@@ -322,4 +322,3 @@ export default {
     },
 
 }
-
diff --git a/src/pages/DashboardHome.vue b/src/pages/DashboardHome.vue
index 657a3a49..1fd4f602 100644
--- a/src/pages/DashboardHome.vue
+++ b/src/pages/DashboardHome.vue
@@ -146,7 +146,9 @@ export default {
             result.sort((a, b) => {
                 if (a.time > b.time) {
                     return -1;
-                } if (a.time < b.time) {
+                }
+
+                if (a.time < b.time) {
                     return 1;
                 }
 
diff --git a/src/pages/Details.vue b/src/pages/Details.vue
index a83e238f..20ce046d 100644
--- a/src/pages/Details.vue
+++ b/src/pages/Details.vue
@@ -45,7 +45,7 @@
                 <span class="num"><CountUp :value="ping" /></span>
             </div>
             <div class="col">
-                <h4>Avg.{{ pingTitle }}</h4>
+                <h4>Avg. {{ pingTitle }}</h4>
                 <p>(24-hour)</p>
                 <span class="num"><CountUp :value="avgPing" /></span>
             </div>
@@ -61,7 +61,7 @@
             </div>
 
             <div v-if="certInfo" class="col">
-                <h4>CertExp.</h4>
+                <h4>Cert Exp.</h4>
                 <p>(<Datetime :value="certInfo.validTo" date-only />)</p>
                 <span class="num">
                     <a href="#" @click.prevent="toggleCertInfoBox = !toggleCertInfoBox">{{ certInfo.daysRemaining }} days</a>

From d97091af5173a93e6a3e231eb23f8e446dc4198b Mon Sep 17 00:00:00 2001
From: Adam Stachowicz <adam.stachowicz@fingo.info>
Date: Tue, 27 Jul 2021 20:02:20 +0200
Subject: [PATCH 4/6] Missing this

---
 server/notification.js | 2 +-
 server/ping-lite.js    | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/server/notification.js b/server/notification.js
index f4cd08af..f25ca80a 100644
--- a/server/notification.js
+++ b/server/notification.js
@@ -309,8 +309,8 @@ class Notification {
             if (! output.includes("ERROR")) {
                 return "Sent Successfully";
             }
-            throw new Error(output)
 
+            throw new Error(output)
         } else {
             return ""
         }
diff --git a/server/ping-lite.js b/server/ping-lite.js
index 337bc0d3..0b9a7401 100644
--- a/server/ping-lite.js
+++ b/server/ping-lite.js
@@ -97,6 +97,7 @@ Ping.prototype.send = function(callback) {
         if (stderr) {
             return callback(new Error(stderr));
         }
+
         if (!stdout) {
             return callback(new Error("No stdout detected"));
         }

From be1fc0c2b66ccd5db5de5ca65e4acd76aae9e362 Mon Sep 17 00:00:00 2001
From: Adam Stachowicz <adam.stachowicz@fingo.info>
Date: Tue, 27 Jul 2021 20:03:53 +0200
Subject: [PATCH 5/6] Missing this part 2

---
 src/components/Status.vue | 16 ++++++++++++----
 src/components/Uptime.vue |  8 ++++++--
 2 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/src/components/Status.vue b/src/components/Status.vue
index a8f2ea59..ff430558 100644
--- a/src/components/Status.vue
+++ b/src/components/Status.vue
@@ -12,9 +12,13 @@ export default {
         color() {
             if (this.status === 0) {
                 return "danger"
-            } if (this.status === 1) {
+            }
+
+            if (this.status === 1) {
                 return "primary"
-            } if (this.status === 2) {
+            }
+
+            if (this.status === 2) {
                 return "warning"
             }
 
@@ -24,9 +28,13 @@ export default {
         text() {
             if (this.status === 0) {
                 return "Down"
-            } if (this.status === 1) {
+            }
+
+            if (this.status === 1) {
                 return "Up"
-            } if (this.status === 2) {
+            }
+
+            if (this.status === 2) {
                 return "Pending"
             }
 
diff --git a/src/components/Uptime.vue b/src/components/Uptime.vue
index 411ff95d..39349623 100644
--- a/src/components/Uptime.vue
+++ b/src/components/Uptime.vue
@@ -28,9 +28,13 @@ export default {
         color() {
             if (this.lastHeartBeat.status === 0) {
                 return "danger"
-            } if (this.lastHeartBeat.status === 1) {
+            }
+
+            if (this.lastHeartBeat.status === 1) {
                 return "primary"
-            } if (this.lastHeartBeat.status === 2) {
+            }
+
+            if (this.lastHeartBeat.status === 2) {
                 return "warning"
             }
 

From d54bc866b4c0d5b452468610757c794a0d7f0155 Mon Sep 17 00:00:00 2001
From: Adam Stachowicz <adam.stachowicz@fingo.info>
Date: Tue, 27 Jul 2021 22:23:46 +0200
Subject: [PATCH 6/6] Fix block-no-empty error from Stylelint

---
 src/layouts/Layout.vue | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/src/layouts/Layout.vue b/src/layouts/Layout.vue
index 546c0ffe..8e725500 100644
--- a/src/layouts/Layout.vue
+++ b/src/layouts/Layout.vue
@@ -155,10 +155,6 @@ export default {
     color: white;
 }
 
-main {
-
-}
-
 footer {
     color: #AAA;
     font-size: 13px;