diff --git a/FullstackProsjekt/src/frontend/package-lock.json b/FullstackProsjekt/src/frontend/package-lock.json index c7a1d0ee9d3cfc751b67c7e62cdf25cfab1365ae..5d4be7ff5a5d9630e2f8ddf0b7cf92c9dc408be9 100644 --- a/FullstackProsjekt/src/frontend/package-lock.json +++ b/FullstackProsjekt/src/frontend/package-lock.json @@ -8,6 +8,11 @@ "name": "frontend", "version": "0.0.0", "dependencies": { + "@fortawesome/fontawesome-svg-core": "^6.5.1", + "@fortawesome/free-brands-svg-icons": "^6.5.1", + "@fortawesome/free-regular-svg-icons": "^6.5.1", + "@fortawesome/free-solid-svg-icons": "^6.5.1", + "@fortawesome/vue-fontawesome": "^3.0.6", "pinia": "^2.1.7", "vue": "^3.4.21", "vue-router": "^4.3.0" @@ -1150,6 +1155,72 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@fortawesome/fontawesome-common-types": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.5.1.tgz", + "integrity": "sha512-GkWzv+L6d2bI5f/Vk6ikJ9xtl7dfXtoRu3YGE6nq0p/FFqA1ebMOAWg3XgRyb0I6LYyYkiAo+3/KrwuBp8xG7A==", + "hasInstallScript": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/fontawesome-svg-core": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.5.1.tgz", + "integrity": "sha512-MfRCYlQPXoLlpem+egxjfkEuP9UQswTrlCOsknus/NcMoblTH2g0jPrapbcIb04KGA7E2GZxbAccGZfWoYgsrQ==", + "hasInstallScript": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.5.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/free-brands-svg-icons": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.5.1.tgz", + "integrity": "sha512-093l7DAkx0aEtBq66Sf19MgoZewv1zeY9/4C7vSKPO4qMwEsW/2VYTUTpBtLwfb9T2R73tXaRDPmE4UqLCYHfg==", + "hasInstallScript": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.5.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/free-regular-svg-icons": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.5.1.tgz", + "integrity": "sha512-m6ShXn+wvqEU69wSP84coxLbNl7sGVZb+Ca+XZq6k30SzuP3X4TfPqtycgUh9ASwlNh5OfQCd8pDIWxl+O+LlQ==", + "hasInstallScript": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.5.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/free-solid-svg-icons": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.5.1.tgz", + "integrity": "sha512-S1PPfU3mIJa59biTtXJz1oI0+KAXW6bkAb31XKhxdxtuXDiUIFsih4JR1v5BbxY7hVHsD1RKq+jRkVRaf773NQ==", + "hasInstallScript": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.5.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/vue-fontawesome": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@fortawesome/vue-fontawesome/-/vue-fontawesome-3.0.6.tgz", + "integrity": "sha512-akrL7lTroyNpPkoHtvK2UpsMzJr6jXdHaQ0YdcwqDsB8jdwlpNHZYijpOUd9KJsARr+VB3WXY4EyObepqJ4ytQ==", + "peerDependencies": { + "@fortawesome/fontawesome-svg-core": "~1 || ~6", + "vue": ">= 3.0.0 < 4" + } + }, "node_modules/@hapi/hoek": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", diff --git a/FullstackProsjekt/src/frontend/package.json b/FullstackProsjekt/src/frontend/package.json index 1842120d7976716e51dbd99130a03d6aee188ead..a16f36e1fd41c8710951ea5114f1b76ac96bb3a7 100644 --- a/FullstackProsjekt/src/frontend/package.json +++ b/FullstackProsjekt/src/frontend/package.json @@ -14,6 +14,11 @@ "format": "prettier --write src/" }, "dependencies": { + "@fortawesome/fontawesome-svg-core": "^6.5.1", + "@fortawesome/free-brands-svg-icons": "^6.5.1", + "@fortawesome/free-regular-svg-icons": "^6.5.1", + "@fortawesome/free-solid-svg-icons": "^6.5.1", + "@fortawesome/vue-fontawesome": "^3.0.6", "pinia": "^2.1.7", "vue": "^3.4.21", "vue-router": "^4.3.0" diff --git a/FullstackProsjekt/src/frontend/public/favicon.ico b/FullstackProsjekt/src/frontend/public/favicon.ico index 9db9f913dd2bf4ad0c6541878280a743d23394eb..586d86a67e5cac04950d9ccc38f645d395cc4d9d 100644 Binary files a/FullstackProsjekt/src/frontend/public/favicon.ico and b/FullstackProsjekt/src/frontend/public/favicon.ico differ diff --git a/FullstackProsjekt/src/frontend/src/App.vue b/FullstackProsjekt/src/frontend/src/App.vue index 71478656e1792351dd5f2fcfa6cb8bbc2513c5fe..25bbd9a9bf6562e6bdb84c7ea954b1cd1e0ef95c 100644 --- a/FullstackProsjekt/src/frontend/src/App.vue +++ b/FullstackProsjekt/src/frontend/src/App.vue @@ -1,9 +1,19 @@ +<script> +import { RouterLink, RouterView } from 'vue-router' +import Sidebar from "@/components/sidebar/Sidebar.vue" +import { sidebarWidth} from "@/components/sidebar/state.js"; +export default { + components:{Sidebar}, + setup(){ + return {sidebarWidth} + } + }; +</script> <template> - <RouterView /> + <Sidebar/> + <div style="{'margin-left': sidebarWidth}"> + <RouterView /> + </div> </template> -<script setup> -import { RouterLink, RouterView } from 'vue-router' -</script> - diff --git a/FullstackProsjekt/src/frontend/src/assets/logo.svg b/FullstackProsjekt/src/frontend/src/assets/logo.svg deleted file mode 100644 index 7565660356e5b3723c9c33d508b830c9cfbea29f..0000000000000000000000000000000000000000 --- a/FullstackProsjekt/src/frontend/src/assets/logo.svg +++ /dev/null @@ -1 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 261.76 226.69"><path d="M161.096.001l-30.225 52.351L100.647.001H-.005l130.877 226.688L261.749.001z" fill="#41b883"/><path d="M161.096.001l-30.225 52.351L100.647.001H52.346l78.526 136.01L209.398.001z" fill="#34495e"/></svg> diff --git a/FullstackProsjekt/src/frontend/src/assets/main.css b/FullstackProsjekt/src/frontend/src/assets/main.css index 8b137891791fe96927ad78e64b0aad7bded08bdc..0d449044eb0385b0e2cdbd2d1b8dd663120c93cc 100644 --- a/FullstackProsjekt/src/frontend/src/assets/main.css +++ b/FullstackProsjekt/src/frontend/src/assets/main.css @@ -1 +1,4 @@ - +body { + font-family: Arial, sans-serif; + margin: 0 0 0 27px; +} diff --git a/FullstackProsjekt/src/frontend/src/components/TheWelcome.vue b/FullstackProsjekt/src/frontend/src/components/TheWelcome.vue index 3c6644c32f98b8a6be1571a9f1eb3363ab2a6312..cb4a58c37221f9b3377882f64519aecc50ef681b 100644 --- a/FullstackProsjekt/src/frontend/src/components/TheWelcome.vue +++ b/FullstackProsjekt/src/frontend/src/components/TheWelcome.vue @@ -1,7 +1,18 @@ +<script> +export default { + data(){ + return{ + } + }, +} +</script> + + <template> <body> <section class ="header"> <div class="text-box"> + <img id="logo" src="../components/icons/brain.png"/> <h1 class="heading">BrainStormer</h1> <p> An easy way to learn and share quizzes. <br> Make your own quiz now! </p> <a href="" class="hero-btn">CREATE QUIZ</a> @@ -31,26 +42,24 @@ </body> </template> + + + <style scoped> -body { - background-color: #f0f0f0; - font-family: Arial, sans-serif; - margin: 0; - padding: 0; - text-align: center; -} /*---Top----*/ -.header { +.header{ min-height: 100vh; width: 100%; background-image: linear-gradient(rgba(4,9,30,0.7), rgba(4,9,30,0.7)),url(photos/lightning.gif); background-position: center; background-size: cover; position: relative; - color: white; } - +#logo{ + height: 150px; + padding: 10px; +} /*Front page*/ .text-box{ @@ -67,7 +76,7 @@ body { } .text-box p{ margin: 10px 0 40px; - font-size: 14px; + font-size: 18px; color: #fff; } @@ -88,17 +97,6 @@ body { transition: 1s; } - -@media (max-width: 700px){ - .text-box h1{ - font-size: 36px; - } - .row{ - flex-direction: column; - - } -} - /*Info with three levels*/ .info{ width: 80%; @@ -124,7 +122,7 @@ p{ } .course-col{ flex-basis: 31%; - background: #D9C590; + background: #E5E5E5; border-radius: 10px; margin-bottom: 5%; padding: 20px; @@ -139,5 +137,15 @@ h3{ .course-col:hover{ box-shadow: 0 0 20px 0px rgba(0,0,0,0.3); } + +@media (max-width: 700px){ + .text-box h1{ + font-size: 42px; + transition: 1s; + } + .row{ + flex-direction: column; + } +} + </style> -``` \ No newline at end of file diff --git a/FullstackProsjekt/src/frontend/src/components/icons/brain.png b/FullstackProsjekt/src/frontend/src/components/icons/brain.png index 9db9f913dd2bf4ad0c6541878280a743d23394eb..586d86a67e5cac04950d9ccc38f645d395cc4d9d 100644 Binary files a/FullstackProsjekt/src/frontend/src/components/icons/brain.png and b/FullstackProsjekt/src/frontend/src/components/icons/brain.png differ diff --git a/FullstackProsjekt/src/frontend/src/components/icons/cross.png b/FullstackProsjekt/src/frontend/src/components/icons/cross.png new file mode 100644 index 0000000000000000000000000000000000000000..91b567924d441b6f93bd0e0e9558c070a9d9374e Binary files /dev/null and b/FullstackProsjekt/src/frontend/src/components/icons/cross.png differ diff --git a/FullstackProsjekt/src/frontend/src/components/icons/menu-burger.png b/FullstackProsjekt/src/frontend/src/components/icons/menu-burger.png new file mode 100644 index 0000000000000000000000000000000000000000..71dc200e10a3163158a379775c85eceac567c5d0 Binary files /dev/null and b/FullstackProsjekt/src/frontend/src/components/icons/menu-burger.png differ diff --git a/FullstackProsjekt/src/frontend/src/components/sidebar/Sidebar.vue b/FullstackProsjekt/src/frontend/src/components/sidebar/Sidebar.vue new file mode 100644 index 0000000000000000000000000000000000000000..7523558fb146924b5e848da2009c5db7d5c931e0 --- /dev/null +++ b/FullstackProsjekt/src/frontend/src/components/sidebar/Sidebar.vue @@ -0,0 +1,87 @@ +<script> +import {collapsed, toggleSideBar, sidebarWidth} from "@/components/sidebar/state.js"; +import SidebarLink from "@/components/sidebar/SidebarLink.vue"; + +export default { + components: {SidebarLink}, + props: {}, + setup() { + return{ collapsed,toggleSideBar,sidebarWidth } + } +} +</script> + +<template> + <div class="sidebar" :style="{width: sidebarWidth}"> + <h1> + <span v-if="collapsed"> + <div> B </div> + <div> S </div> + </span> + <span v-else> + Brain Stormer + </span> + </h1> + + <SidebarLink to="/" icon="fas fa-home">Home</SidebarLink> + <SidebarLink to="/dashboard" icon="fas fa-columns">Dashboard</SidebarLink> + <SidebarLink to="/about" icon="fas fa-chart-bar">About</SidebarLink> + <SidebarLink to="/feedback" icon="fas fa-users">Feedback</SidebarLink> + <SidebarLink to="/login" icon="fas fa-image">Login</SidebarLink> + + <span class="collapse-icon" :class="{'rotate-180': collapsed}" @click="toggleSideBar"> + <button class="iconButton"> <img id="icon" src="../icons/menu-burger.png"/> + </button> + </span> + </div> +</template> + + + +<style> +:root{ + --sidebar-bd-color: #242F40; + --sidebar-item-hover: #CCA43B; + --sidebar-item-active: #CCA43B; +} +</style> +<style scoped> +.sidebar{ + color: white; + background-color: var(--sidebar-bd-color); + + float: left; + position: fixed; + z-index: 1; + top: 0; + left: 0; + bottom: 0; + padding: 0.5rem; + + transition: 0.3s ease; + + display: flex; + flex-direction: column; +} + +.collapse-icon{ + position: absolute; + bottom: 0; + padding: 4px; + + color: white; + transition: 0.2s linear; +} +#icon{ + height: 18px; +} +.iconButton{ + background-color: transparent; + border-color: transparent; +} + +.rotate-180{ + transform: rotate(180deg); + transition: 0.2s linear; +} +</style> \ No newline at end of file diff --git a/FullstackProsjekt/src/frontend/src/components/sidebar/SidebarLink.vue b/FullstackProsjekt/src/frontend/src/components/sidebar/SidebarLink.vue new file mode 100644 index 0000000000000000000000000000000000000000..69bb7ad1c07a91eba669c3c5b95f387154ab86cd --- /dev/null +++ b/FullstackProsjekt/src/frontend/src/components/sidebar/SidebarLink.vue @@ -0,0 +1,72 @@ +<script> +import { computed } from 'vue' +import { useRoute } from 'vue-router' +import { collapsed } from './state' + +export default { + props: { + to: { type: String, required: true }, + icon: { type: String, required: true } + }, + setup(props) { + const route = useRoute() + const isActive = computed(() => route.path === props.to) + return { isActive, collapsed } + } +} +</script> + +<template> + <router-link :to="to" class="link" :class="{ active: isActive }"> + <i class="icon" :class="icon" /> + <transition name="fade"> + <span v-if="!collapsed"> + <slot /> + </span> + </transition> + </router-link> +</template> + +<style scoped> +.fade-enter-active, +.fade-leave-active { + transition: opacity 0.1s; +} + +.fade-enter, +.fade-leave-to { + opacity: 0; +} + +.link { + display: flex; + align-items: center; + + cursor: pointer; + position: relative; + font-weight: 400; + user-select: none; + + margin: 0.1em 0; + padding: 0.4em; + border-radius: 0.25em; + height: 1.5em; + + color: white; + text-decoration: none; +} + +.link:hover { + background-color: var(--sidebar-item-hover); +} + +.link.active { + background-color: var(--sidebar-item-active); +} + +.link .icon { + flex-shrink: 0; + width: 25px; + margin-right: 10px; +} +</style> \ No newline at end of file diff --git a/FullstackProsjekt/src/frontend/src/components/sidebar/state.js b/FullstackProsjekt/src/frontend/src/components/sidebar/state.js new file mode 100644 index 0000000000000000000000000000000000000000..938cc0721c6aafe379de704a9a5b7400461442b3 --- /dev/null +++ b/FullstackProsjekt/src/frontend/src/components/sidebar/state.js @@ -0,0 +1,12 @@ + +import {ref, computed} from 'vue' + +export const collapsed = ref(true) +export const toggleSideBar = () => (collapsed.value = !collapsed.value) + +export const SIDEBAR_WIDTH = 180 +export const SIDEBAR_WIDTH_COLLAPSED = 38 +export const sidebarWidth = computed( + () => `${collapsed.value ? SIDEBAR_WIDTH_COLLAPSED : SIDEBAR_WIDTH}px` +) + diff --git a/FullstackProsjekt/src/frontend/src/main.js b/FullstackProsjekt/src/frontend/src/main.js index 5dcad83c30800a564e96bad81c93d6be2ffaceaa..fdbbd02dd1783e84597521557ceafdd8cea4708f 100644 --- a/FullstackProsjekt/src/frontend/src/main.js +++ b/FullstackProsjekt/src/frontend/src/main.js @@ -6,8 +6,26 @@ import { createPinia } from 'pinia' import App from './App.vue' import router from './router' +import '@fortawesome/fontawesome-svg-core' +import '@fortawesome/vue-fontawesome' +import '@fortawesome/free-solid-svg-icons' + + +/* import the fontawesome core */ +//import { library } from '@fortawesome/fontawesome-svg-core' + +/* import font awesome icon component */ +//import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome' + +//import {faUser} from '@fortawesome/free-solid-svg-icons' + +/* add icons to the library */ +//library.add(faUser) + + const app = createApp(App) +//app.component('font-awesome-icon', FontAwesomeIcon) app.use(createPinia()) app.use(router) diff --git a/FullstackProsjekt/src/frontend/src/router/index.js b/FullstackProsjekt/src/frontend/src/router/index.js index b45755cb7f9353fa8f67fd89dd4f5a5052541842..8e5fec7623ee412f1780bfe57fe74e8cc1ff8c28 100644 --- a/FullstackProsjekt/src/frontend/src/router/index.js +++ b/FullstackProsjekt/src/frontend/src/router/index.js @@ -9,17 +9,31 @@ const router = createRouter({ name: 'home', component: HomeView }, - /* + { + path: '/dashboard', + name: 'dashboard', + component: () => import('../views/DashboardView.vue') + }, { path: '/about', name: 'about', - // route level code-splitting - // this generates a separate chunk (About.[hash].js) for this route - // which is lazy-loaded when the route is visited. component: () => import('../views/AboutView.vue') - } - - */ + }, + { + path: '/feedback', + name: 'feedback', + component: () => import('../views/FeedbackView.vue') + }, + { + path: '/login', + name: 'login', + component: () => import('../views/LoginView.vue') + }, + { + path: '/signup', + name: 'signup', + component: () => import('../views/SignupView.vue') + }, ] }) diff --git a/FullstackProsjekt/src/frontend/src/views/AboutView.vue b/FullstackProsjekt/src/frontend/src/views/AboutView.vue new file mode 100644 index 0000000000000000000000000000000000000000..b1574d2dbb242800d7bca30c551e5740f50ec7b7 --- /dev/null +++ b/FullstackProsjekt/src/frontend/src/views/AboutView.vue @@ -0,0 +1,8 @@ +<script setup> +</script> + +<template> + <body> + <h1> This is about page</h1> + </body> +</template> \ No newline at end of file diff --git a/FullstackProsjekt/src/frontend/src/views/DashboardView.vue b/FullstackProsjekt/src/frontend/src/views/DashboardView.vue new file mode 100644 index 0000000000000000000000000000000000000000..78359cdb02bc6046d1c106104bb926d9b5ee1161 --- /dev/null +++ b/FullstackProsjekt/src/frontend/src/views/DashboardView.vue @@ -0,0 +1,8 @@ +<script > +</script> + +<template> + <body> + <h1> This is the dashboard</h1> + </body> +</template> \ No newline at end of file diff --git a/FullstackProsjekt/src/frontend/src/views/FeedbackView.vue b/FullstackProsjekt/src/frontend/src/views/FeedbackView.vue new file mode 100644 index 0000000000000000000000000000000000000000..e6998e00b05f8fa620d66a0a9c37d96518c6ba0b --- /dev/null +++ b/FullstackProsjekt/src/frontend/src/views/FeedbackView.vue @@ -0,0 +1,9 @@ +<script > +</script> + + +<template> + <body> + <p> This is the feedback page. </p> + </body> +</template> diff --git a/FullstackProsjekt/src/frontend/src/views/LoginView.vue b/FullstackProsjekt/src/frontend/src/views/LoginView.vue new file mode 100644 index 0000000000000000000000000000000000000000..e8dba18ea10fd7dd215336098aff23423b4dae39 --- /dev/null +++ b/FullstackProsjekt/src/frontend/src/views/LoginView.vue @@ -0,0 +1,90 @@ +<script> +export default { + data() { + return { + email: this.email, + password: this.password, + login: this.login + }; + } +} +</script> + + +<template> + <form @submit.prevent="handleSubmit"> + <div class="login"> + <h1 id="login">Login</h1> + <div class="loginBox"> + <label>Email</label> + <input type="email" required v-model="email" ref="emailInput"/> <br> + <label>Password</label> + <input type="password" required v-model="password" ref="passwordInput"/> <br> + <router-link to="/signup">Signup</router-link> + </div> + </div> + <div class="submit-section"> + <input id="submit" type="submit"/> + </div> + </form> + </template> + + + <style> + .login { + text-align: center; + padding: 20px; + border-radius: 15px; + align-items: center; + border-style: solid; + margin: 20px; + } + + .loginBox { + padding: 30px; + } + + label { + display: inline-block; + margin-right: 10px; + font-weight: bold; + } + + input { + padding: 5px; + border-radius: 5px; + border: none; + min-width: 250px; + background-color: #E5E5E5; + margin: 10px; + } + + input::placeholder, textarea::placeholder { + color: #242F40; + } + + + .submit-section { + display: flex; + justify-content: center; + align-items: center; + } + + #submit { + min-width: 150px; + min-height: 60px; + font-size: 24px; + border-radius: 6px; + background-color: #242F40; + color: white; + border: none; + cursor: pointer; + margin-top: 20px; + } + + #submit:hover:enabled { + background-color: rgba(23, 55, 44, 0.9); + transition: 0.5s; + } + + </style> diff --git a/FullstackProsjekt/src/frontend/src/views/SignupView.vue b/FullstackProsjekt/src/frontend/src/views/SignupView.vue new file mode 100644 index 0000000000000000000000000000000000000000..ebed0afe7372c93d953d9bc294eaf32b4a2cc83e --- /dev/null +++ b/FullstackProsjekt/src/frontend/src/views/SignupView.vue @@ -0,0 +1,84 @@ + +<script> +</script> + + + +<template> + <form @submit.prevent="handleSubmit"> + <div class="signup"> + <h1 id="signup">Signup</h1> + <div class="signupBox"> + <label>First Name</label> + <input type="text" required v-model="fName" ref="fNameInput"/> <br> + <label>Last Name</label> + <input type="text" required v-model="lName" ref="lNameInput"/> <br> + <label> Email </label> + <input type="email" required v-model="email" ref="emailInput"/> <br> + <label>Password</label> + <input type="password" required v-model="password" ref="passwordInput"/> <br> + </div> + </div> + <div class="submit-section"> + <input id="submit" type="submit"/> + </div> + </form> +</template> + +<style> +.signup { + text-align: center; + padding: 20px; + border-radius: 15px; + align-items: center; + border-style: solid; + margin: 20px; +} + +.signupBox { + padding: 30px; +} + +label { + display: inline-block; + font-weight: bold; +} + +input { + padding: 5px; + border-radius: 5px; + border: none; + min-width: 250px; + background-color: #E5E5E5; + margin: 10px; +} + +input::placeholder, textarea::placeholder { + color: #242F40; +} + + +.submit-section { + display: flex; + justify-content: center; + align-items: center; +} + +#submit { + min-width: 150px; + min-height: 60px; + font-size: 24px; + border-radius: 6px; + background-color: #242F40; + color: white; + border: none; + cursor: pointer; + margin-top: 20px; +} + +#submit:hover:enabled { + background-color: rgba(23, 55, 44, 0.9); + transition: 0.5s; +} + +</style>