diff --git a/package-lock.json b/package-lock.json index 6b3078a..a42191d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1308,6 +1308,22 @@ "@fortawesome/fontawesome-common-types": "^0.2.32" } }, + "@fortawesome/free-brands-svg-icons": { + "version": "5.15.1", + "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-5.15.1.tgz", + "integrity": "sha512-pkTZIWn7iuliCCgV+huDfZmZb2UjslalXGDA2PcqOVUYJmYL11y6ooFiMJkJvUZu+xgAc1gZgQe+Px12mZF0CA==", + "requires": { + "@fortawesome/fontawesome-common-types": "^0.2.32" + } + }, + "@fortawesome/free-regular-svg-icons": { + "version": "5.15.1", + "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-5.15.1.tgz", + "integrity": "sha512-eD9NWFy89e7SVVtrLedJUxIpCBGhd4x7s7dhesokjyo1Tw62daqN5UcuAGu1NrepLLq1IeAYUVfWwnOjZ/j3HA==", + "requires": { + "@fortawesome/fontawesome-common-types": "^0.2.32" + } + }, "@fortawesome/free-solid-svg-icons": { "version": "5.15.1", "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.1.tgz", @@ -2214,16 +2230,6 @@ "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "optional": true, - "requires": { - "color-convert": "^2.0.1" - } - }, "cacache": { "version": "13.0.1", "resolved": "https://registry.npmjs.org/cacache/-/cacache-13.0.1.tgz", @@ -2250,53 +2256,6 @@ "unique-filename": "^1.1.1" } }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "optional": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "optional": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "optional": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "optional": true - }, - "loader-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", - "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", - "dev": true, - "optional": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -2313,16 +2272,6 @@ "minipass": "^3.1.1" } }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "optional": true, - "requires": { - "has-flag": "^4.0.0" - } - }, "terser-webpack-plugin": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.3.8.tgz", @@ -2339,18 +2288,6 @@ "terser": "^4.6.12", "webpack-sources": "^1.4.3" } - }, - "vue-loader-v16": { - "version": "npm:vue-loader@16.1.1", - "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.1.1.tgz", - "integrity": "sha512-wz/+HFg/3SBayHWAlZXARcnDTl3VOChrfW9YnxvAweiuyKX/7IGx1ad/4yJHmwhgWlOVYMAbTiI7GV8G33PfGQ==", - "dev": true, - "optional": true, - "requires": { - "chalk": "^4.1.0", - "hash-sum": "^2.0.0", - "loader-utils": "^2.0.0" - } } } }, @@ -13114,6 +13051,87 @@ } } }, + "vue-loader-v16": { + "version": "npm:vue-loader@16.1.1", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.1.1.tgz", + "integrity": "sha512-wz/+HFg/3SBayHWAlZXARcnDTl3VOChrfW9YnxvAweiuyKX/7IGx1ad/4yJHmwhgWlOVYMAbTiI7GV8G33PfGQ==", + "dev": true, + "optional": true, + "requires": { + "chalk": "^4.1.0", + "hash-sum": "^2.0.0", + "loader-utils": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "optional": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "optional": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "optional": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "optional": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "optional": true + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "optional": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "optional": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "vue-notification": { "version": "1.3.20", "resolved": "https://registry.npmjs.org/vue-notification/-/vue-notification-1.3.20.tgz", diff --git a/package.json b/package.json index 5c4ca7c..4bbab78 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,8 @@ }, "dependencies": { "@fortawesome/fontawesome-svg-core": "^1.2.32", + "@fortawesome/free-brands-svg-icons": "^5.15.1", + "@fortawesome/free-regular-svg-icons": "^5.15.1", "@fortawesome/free-solid-svg-icons": "^5.15.1", "@fortawesome/vue-fontawesome": "^2.0.0", "bootstrap": "^4.5.3", diff --git a/src/App.vue b/src/App.vue index d742d7b..82d6f6e 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,9 +1,31 @@ + + diff --git a/src/assets/app.sass b/src/assets/app.sass index a8a8181..f147ad7 100644 --- a/src/assets/app.sass +++ b/src/assets/app.sass @@ -5,9 +5,7 @@ @import 'node_modules/bootstrap/scss/bootstrap.scss' @import 'node_modules/bootstrap-vue/src/index.scss' @import url('https://fonts.googleapis.com/css2?family=Titillium+Web:ital,wght@0,200;0,300;0,400;0,600;0,700;0,900;1,200;1,300;1,400;1,600;1,700&display=swap') - - -$primary: #b51683 +@import 'variables' body diff --git a/src/assets/img/sitenav-bg.jpg b/src/assets/img/sitenav-bg.jpg new file mode 100644 index 0000000..ac3655a Binary files /dev/null and b/src/assets/img/sitenav-bg.jpg differ diff --git a/src/assets/variables.sass b/src/assets/variables.sass new file mode 100644 index 0000000..13257ae --- /dev/null +++ b/src/assets/variables.sass @@ -0,0 +1,5 @@ +// colors: +$primary: #b51683 + +//layout +$sitenav-size: 200px \ No newline at end of file diff --git a/src/components/AdministratorTable.vue b/src/components/AdministratorTable.vue new file mode 100644 index 0000000..0b5d9e4 --- /dev/null +++ b/src/components/AdministratorTable.vue @@ -0,0 +1,117 @@ + + + diff --git a/src/components/base/DashboardCard.vue b/src/components/base/DashboardCard.vue new file mode 100644 index 0000000..d7f92aa --- /dev/null +++ b/src/components/base/DashboardCard.vue @@ -0,0 +1,57 @@ + + + + + diff --git a/src/components/base/Sitenav.vue b/src/components/base/Sitenav.vue new file mode 100644 index 0000000..2d81fd9 --- /dev/null +++ b/src/components/base/Sitenav.vue @@ -0,0 +1,81 @@ + + + + + diff --git a/src/components/sitenav/sitenav-link.vue b/src/components/sitenav/sitenav-link.vue new file mode 100644 index 0000000..ec9eb63 --- /dev/null +++ b/src/components/sitenav/sitenav-link.vue @@ -0,0 +1,43 @@ + + + + + diff --git a/src/main.js b/src/main.js index ff40289..9997986 100644 --- a/src/main.js +++ b/src/main.js @@ -8,6 +8,14 @@ import Notifications from 'vue-notification' import firebase from 'firebase/app' import * as fbService from './services/firebase.service' +// Fontawesome +import { library } from '@fortawesome/fontawesome-svg-core' +import { faUserSecret, faChevronLeft, faBorderAll } from '@fortawesome/free-solid-svg-icons' +import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome' + +library.add(faUserSecret, faChevronLeft, faBorderAll) +Vue.component('font-awesome-icon', FontAwesomeIcon) + Vue.use(BootstrapVue) Vue.prototype.$firebase = firebase diff --git a/src/router/index.js b/src/router/index.js index efa5a7d..05b96aa 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -2,6 +2,7 @@ import Vue from 'vue' import VueRouter from 'vue-router' import Home from '../views/Home' import SignIn from '../views/SignIn' +import AdminCredentials from '@/views/AdminCredentials' import ContactReport from '@/views/ContactReport' import { userService } from '@/services/user.service' @@ -24,6 +25,7 @@ const routes = [ path: '/signin', name: 'SignIn', component: SignIn, + meta: { displayNavbar: false }, beforeEnter: (to, from, next) => { if (userService.isLoggedIn()) { next({ name: 'Home' }) @@ -31,6 +33,19 @@ const routes = [ next() } } + }, + { + path: '/administrators', + name: 'AdminCredentials', + component: AdminCredentials, + beforeEnter: async (to, from, next) => { + const currentUser = await userService.currentUser() + if (userService.isLoggedIn() && currentUser.isAdmin === true) { + next() + } else { + next({ name: 'Home' }) + } + } } ] diff --git a/src/services/user.service.js b/src/services/user.service.js index 181af7c..eb2a403 100644 --- a/src/services/user.service.js +++ b/src/services/user.service.js @@ -37,6 +37,21 @@ class UserService { } } + async fetchAllUsers () { + const users = [] + const response = await $db().collection(COLLECTION_NAME).get() + response.forEach(doc => { + users.push({ + id: doc.id, + firstName: doc.data().firstName, + lastName: doc.data().lastName, + initials: doc.data().initials, + isAdmin: doc.data().isAdmin === undefined || doc.data().isAdmin === null ? false : doc.data().isAdmin + }) + }) + return users + } + async fetchUserByInitials (initials) { const users = [] const response = await $db().collection(COLLECTION_NAME).where('initials', '==', initials).get() @@ -56,13 +71,14 @@ class UserService { const userDoc = await $db().collection(COLLECTION_NAME).doc(userId).get() return { id: userDoc.id, + isAdmin: userDoc.data().isAdmin, firstName: userDoc.data().firstName, lastName: userDoc.data().lastName, initials: userDoc.data().initials } } - currentUser () { + async currentUser () { const userId = localStorage.getItem('userId') let result = null @@ -70,10 +86,10 @@ class UserService { if (this.user && this.user.userId === userId) { result = this.user } else { - result = this.fetchUserById(userId) + result = await this.fetchUserById(userId) } } - return Promise.resolve(result) + return result } isLoggedIn () { @@ -110,6 +126,27 @@ class UserService { }) return await roomService.getRoomByID(myRoom) } + + async setAdminStatus (user) { + console.log('🚀 ~ user', user) + const updatedUser = { + firstName: user.firstName, + lastName: user.lastName, + initials: user.initials, + isAdmin: user.isAdmin + } + try { + await $db().collection(COLLECTION_NAME).doc(user.id).update(updatedUser) + } catch (error) { + console.log('Something went wrong with setting isAdmin to value x: ' + error) + this.$notify({ + group: 'network', + title: 'Error', + type: 'error', + text: error.message + }) + } + } } export const userService = new UserService() diff --git a/src/views/AdminCredentials.vue b/src/views/AdminCredentials.vue new file mode 100644 index 0000000..69701b1 --- /dev/null +++ b/src/views/AdminCredentials.vue @@ -0,0 +1,18 @@ + + + + + diff --git a/src/views/Home.vue b/src/views/Home.vue index fb3bcef..4c0f420 100644 --- a/src/views/Home.vue +++ b/src/views/Home.vue @@ -1,3 +1,62 @@ + + +