diff --git a/FullstackProsjekt/src/frontend/src/assets/main.css b/FullstackProsjekt/src/frontend/src/assets/main.css index c89d2a32baba2e9122c8a713cdd51f85376c4205..3c8595702f56ae724043ca764c3b862db72ee509 100644 --- a/FullstackProsjekt/src/frontend/src/assets/main.css +++ b/FullstackProsjekt/src/frontend/src/assets/main.css @@ -8,7 +8,7 @@ input { padding: 5px; border-radius: 5px; border: none; - background-color: #E5E5E5; + background-color: #dedede; margin-bottom: 10px; font-family: monospace; } @@ -25,8 +25,6 @@ select{ font-family: monospace; } - - .space{ margin: 90px; } @@ -51,10 +49,7 @@ select{ .course-col:hover{ box-shadow: 0 0 20px 0px rgba(0,0,0,0.3); } -.go-back-section{ - padding-top: 5vh; - padding-left: 5vh; -} + /* ERROR HANDLE */ diff --git a/FullstackProsjekt/src/frontend/src/components/TheWelcome.vue b/FullstackProsjekt/src/frontend/src/components/TheWelcome.vue index 9b3049bff693381e4263264d5c20c345b1ee4889..7d60374e0cc49269accf6c5078c6b1efe453bfd3 100644 --- a/FullstackProsjekt/src/frontend/src/components/TheWelcome.vue +++ b/FullstackProsjekt/src/frontend/src/components/TheWelcome.vue @@ -16,35 +16,35 @@ export default { <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> + <p> Get ready to challenge your knowledge and have fun! <br> Experience a new way of learning </p> <router-link to="/dashboard" class="hero-btn">LOOK AT QUIZZES</router-link> </div> </section> <!----- Info -----> <section class="info"> - <h1>How does it work</h1> - <p>Set a difficulty to your quizzes ..... [Add more text here]</p> + <h1>Ace your classes with our new learning platform</h1> + <p>Explore our various difficulties and challenge yourself</p> <div class="row"> <div class="course-col"> <h3>Easy</h3> - <p>The simplest of quizzes </p> + <p>Suitable for beginners or those with basic knowledge on the topic.</p> </div> <div class="course-col"> <h3>Medium</h3> - <p>A more challenging quiz for those who want a challenge </p> + <p>Suitable for intermediate users with some experience on the topic.</p> </div> <div class="course-col"> <h3>Hard</h3> - <p>Quizzes that challenge the mind to new limits... </p> + <p>Suitable for advanced users or experts on the topic. </p> </div> </div> </section> <div class="space"> </div> <section class="cta"> - <h1> Enroll For Our Various Online Quizzes </h1> + <h1> Include and engage every student </h1> <router-link to="/about" class="hero-btn"> About us</router-link> </section> @@ -67,15 +67,15 @@ export default { .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-image: linear-gradient(rgba(4,9,30,0.7), rgba(4,9,30,0.7)),url(photos/mountain-backdrop.png); background-position: center; background-size: cover; position: relative; } #logo{ - height: 150px; - width: 150px; - padding: 10px; + height: 170px; + width: 170px; + padding: 5vh; } .text-box{ @@ -88,11 +88,11 @@ export default { text-align: center; } .text-box h1{ - font-size: 62px; + font-size: 60px; } .text-box p{ margin: 10px 0 40px; - font-size: 18px; + font-size: 20px; color: #fff; } @@ -143,7 +143,7 @@ h3{ .cta{ margin: 100px auto; width: 80%; - background-image: linear-gradient(rgba(4,9,30,0.7), rgba(4,9,30,0.7)),url(photos/background.png); + background-image: linear-gradient(rgba(4,9,30,0.7), rgba(4,9,30,0.7)),url(photos/office-backdrop.png); background-position: center; background-size: cover; border-radius: 10px; diff --git a/FullstackProsjekt/src/frontend/src/components/photos/background.png b/FullstackProsjekt/src/frontend/src/components/photos/background.png deleted file mode 100644 index e968b4bd6100bf6b3261beee0053e82708d0f964..0000000000000000000000000000000000000000 Binary files a/FullstackProsjekt/src/frontend/src/components/photos/background.png and /dev/null differ diff --git a/FullstackProsjekt/src/frontend/src/components/photos/mountain-backdrop.png b/FullstackProsjekt/src/frontend/src/components/photos/mountain-backdrop.png new file mode 100644 index 0000000000000000000000000000000000000000..5945b761b707f0823c9492adc11afe65727ad3ec Binary files /dev/null and b/FullstackProsjekt/src/frontend/src/components/photos/mountain-backdrop.png differ diff --git a/FullstackProsjekt/src/frontend/src/components/photos/office-backdrop.png b/FullstackProsjekt/src/frontend/src/components/photos/office-backdrop.png new file mode 100644 index 0000000000000000000000000000000000000000..c6dcad7739294e331b83e9e41bfe95046bd5a9f5 Binary files /dev/null and b/FullstackProsjekt/src/frontend/src/components/photos/office-backdrop.png differ diff --git a/FullstackProsjekt/src/frontend/src/components/photos/wheel-backdrop.png b/FullstackProsjekt/src/frontend/src/components/photos/wheel-backdrop.png new file mode 100644 index 0000000000000000000000000000000000000000..fe40f6ee980cef102f41bae1d7491e80731af859 Binary files /dev/null and b/FullstackProsjekt/src/frontend/src/components/photos/wheel-backdrop.png differ diff --git a/FullstackProsjekt/src/frontend/src/components/shared/create-quiz/CreateQuizView.vue b/FullstackProsjekt/src/frontend/src/components/shared/create-quiz/CreateQuizView.vue index e6512e2c9c8f1ea37d9cfe60cc7a294f2eb69278..882c1a08aa1f018c8919592adbd10e98e720b329 100644 --- a/FullstackProsjekt/src/frontend/src/components/shared/create-quiz/CreateQuizView.vue +++ b/FullstackProsjekt/src/frontend/src/components/shared/create-quiz/CreateQuizView.vue @@ -103,6 +103,11 @@ export default { padding: 0 20px; } +.go-back-section{ + padding-top: 5vh; + padding-left: 5vh; +} + input, select { width: 100%; diff --git a/FullstackProsjekt/src/frontend/src/components/shared/sidebar/Sidebar.vue b/FullstackProsjekt/src/frontend/src/components/shared/sidebar/Sidebar.vue index d0014adffe8bd3f2db9a8b89d0b5926273770e25..800b932851f1500c6e78c1760f0e4703904dced1 100644 --- a/FullstackProsjekt/src/frontend/src/components/shared/sidebar/Sidebar.vue +++ b/FullstackProsjekt/src/frontend/src/components/shared/sidebar/Sidebar.vue @@ -2,11 +2,14 @@ import { collapsed, toggleSideBar, sidebarWidth } from "@/components/shared/sidebar/state.js"; import SidebarLink from "@/components/shared/sidebar/SidebarLink.vue"; import Svg from "@/assets/Svg.vue"; +import {ref} from "vue"; export default { components: {Svg, SidebarLink}, props: {}, setup() { + const isLoggedIn = ref(false); + const handleClickOutside = (event) => { const sidebar = document.querySelector('.sidebar'); if (sidebar && !sidebar.contains(event.target)) { @@ -20,7 +23,7 @@ export default { document.removeEventListener('click', handleClickOutside); }; - return { collapsed, toggleSideBar, sidebarWidth, beforeUnmount }; + return { collapsed, toggleSideBar, sidebarWidth, beforeUnmount, isLoggedIn }; } } </script> @@ -34,7 +37,7 @@ export default { <SidebarLink to="/about" icon="about-us-icon">About</SidebarLink> <SidebarLink to="/feedback" icon="feedback-icon">Feedback</SidebarLink> <SidebarLink to="/login" icon="login-icon">Login</SidebarLink> - <SidebarLink to="/profile" icon="profile-icon">Profile</SidebarLink> + <SidebarLink v-if="isLoggedIn" to="/profile" icon="profile-icon">Profile</SidebarLink> <span class="collapse-icon" :class="{'rotate-180': collapsed}" @click="toggleSideBar"> <Svg name="double-arrow" class="sidebar-c-icon"/> diff --git a/FullstackProsjekt/src/frontend/src/views/AboutView.vue b/FullstackProsjekt/src/frontend/src/views/AboutView.vue index 909d494df9e140d992e835bf0e304dedcffedf29..f02a87d9268545d5a0429d0843ce2ac2b9d7c41c 100644 --- a/FullstackProsjekt/src/frontend/src/views/AboutView.vue +++ b/FullstackProsjekt/src/frontend/src/views/AboutView.vue @@ -4,30 +4,29 @@ <h1>About</h1> <p>Welcome to our quiz web application! We provide a comprehensive and user-friendly platform for creating, managing, and taking quizzes for educational, training, or entertainment purposes.</p> <div class="space"> </div> - <h2>Our Features</h2> + </div> + + <div> <div class="columns"> + <h2>Our Features</h2> + <div class="column"> <ul> - <li>Quiz Creation: Create quizzes with various question types, difficulty levels, and multimedia elements.</li> - <li>Tagging and Categorization: Organize your questions with difficulty level and categories.</li> - <li>Search and Filter: Quickly find relevant questions based on categories and difficulty levels.</li> - <li>Question Management: Add, edit, delete, and organize questions within quizzes.</li> - </ul> - </div> - <div class="column"> - <ul> - <li>Quiz Templates: Use pre-designed or customizable templates for easy quiz creation.</li> - <li>Import and Export: Import questions from external sources and export quizzes in various formats.</li> - <li>Scoring and Feedback: Automatically score quizzes and provide immediate feedback.</li> - <li>Progress Tracking: Track your progress, view past quiz attempts, and monitor performance statistics.</li> - <li>Feedback and Support: Provide feedback, report issues, and access customer support.</li> + <li><strong>Quiz Creation:</strong> Create quizzes with various question types, difficulty levels, and multimedia elements.</li> + <li><strong>Tagging and Categorization:</strong> Organize your questions with difficulty level and categories.</li> + <li><strong>Search and Filter:</strong> Quickly find relevant questions based on categories and difficulty levels.</li> + <li><strong>Question Management:</strong> Add, edit, delete, and organize questions within quizzes.</li> + <li><strong>Quiz Templates:</strong> Use pre-designed or customizable templates for easy quiz creation.</li> + <li><strong>Import and Export:</strong> Import questions from external sources and export quizzes in various formats.</li> + <li><strong>Scoring and Feedback:</strong> Automatically score quizzes and provide immediate feedback.</li> + <li><strong>Progress Tracking:</strong> Track your progress, view past quiz attempts, and monitor performance statistics.</li> + <li><strong>Feedback and Support:</strong> Provide feedback, report issues, and access customer support.</li> </ul> </div> </div> </div> - <h1 class ="our-team" style="text-align:center">Our Team</h1> <div class="row"> <div class="column"> @@ -38,7 +37,6 @@ <p class="title">Developer</p> <p>2 year Bachelor in Computer Science at NTNU Trondheim </p> <p>torbjorn@ntnu.no</p> - <p><button class="button">Contact</button></p> </div> </div> </div> @@ -51,7 +49,6 @@ <p class="title">Developer</p> <p>2 year Bachelor in Computer Science at NTNU Trondheim</p> <p>heine@ntnu.no</p> - <p><button class="button">Contact</button></p> </div> </div> </div> @@ -65,7 +62,6 @@ <p class="title">Developer</p> <p>2 year Bachelor in Computer Science at NTNU Trondheim</p> <p>kristiane@ntnu.no</p> - <p><button class="button">Contact</button></p> </div> </div> </div> @@ -78,7 +74,6 @@ <p class="title">Developer</p> <p>2 year Bachelor in Computer Science at NTNU Trondheim</p> <p>madelesj@ntnu.no</p> - <p><button class="button">Contact</button></p> </div> </div> </div> @@ -94,9 +89,19 @@ export default { </script> <style> +.about-section { + background-image: linear-gradient(rgba(4,9,30,0.7), rgba(4,9,30,0.7)),url("@/components/photos/wheel-backdrop.png"); + padding: 20px; +} + .columns { display: flex; justify-content: space-between; + margin: 10vh; +} + +.column ul li { + margin-bottom: 20px; } .column { @@ -116,14 +121,17 @@ li{ .card { box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2); - margin: 8px; + margin: 8px auto; /* Center the cards horizontally */ + padding: 10px; + max-width: 400px; /* Adjust the maximum width of the card */ } + .about-section { padding: 10vh 10vh 10vh 10vh; text-align: center; - background-color: #858A93; - color: #242F40; + color: #ffffff; + } .our-team{ color: #242F40; @@ -138,22 +146,6 @@ li{ color: grey; } -.button { - border: none; - outline: 0; - display: inline-block; - padding: 8px; - color: white; - background-color: #363636; - text-align: center; - cursor: pointer; - width: 100%; - font-family: monospace; -} - -.button:hover { - background-color: #555; -} #logo{ width: 100%; @@ -163,6 +155,7 @@ li{ .column { width: 100%; display: block; + max-width: 100%; } } </style> diff --git a/FullstackProsjekt/src/frontend/src/views/DashboardView.vue b/FullstackProsjekt/src/frontend/src/views/DashboardView.vue index 82e4701518389e7a65c80c33bbb59ea567dc8014..92525973e89ecb64169049a67146333576f18400 100644 --- a/FullstackProsjekt/src/frontend/src/views/DashboardView.vue +++ b/FullstackProsjekt/src/frontend/src/views/DashboardView.vue @@ -1,88 +1,71 @@ -<script > - import { apiClient } from "@/api.js"; - import router from "@/router/index.js"; - import Svg from "@/assets/Svg.vue"; - import { categoryEnums } from "@/data/categories.js"; - - export default { - components: { Svg }, - props: { - quizId: { - type: Number, - required: true, -}, -}, - data() { - return { - quizList: [] - }; -}, - mounted() { - this.getQuiz(); -}, - methods: { - async getQuiz() { - try { - const response = await apiClient.get('/quiz/'); - this.quizList = response.data; - - console.log(this.quizList[0]) - } catch (error) { - // TODO: Proper error handling - console.error('Error retrieving quiz:', error); - } -}, - getIcon(category) { - // Check if the category exists in the enum - if (categoryEnums.includes(category)) { - // Retrieve the icon name from the mapping - return categoryIcons[category] || categoryIcons.Default; -} else { - // If category not found, return the default icon - return categoryIcons.Default; -} -}, - playQuiz(id) { - console.log(id) - router.push({ name: 'playQuiz', params: { quizId: id } }); -}, -}, -}; -</script> - - <template> - <body class="dashboard"> - <div class="top-bar"> + <div class="dashboard"> + <div class="top-bar"> + <router-link to="/" ><Svg name="go-back-icon"/></router-link> - <div class="search-container"> - <input class="searchBox" placeholder="Search for category..."> - </div> <br> - <div class="create-container"> - <router-link to="/overviewQuiz" class="create-btn">YOUR QUIZES</router-link> + <div class="search-container"> + <input class="searchBox" v-model="searchTerm" placeholder="Search for category..."> + </div> + <div class="create-container"> + <router-link to="/overviewQuiz" class="add-Btn">YOUR QUIZZES</router-link> + </div> </div> - - </div> <div class="row"> - <div class="quiz-list"> - <div class="quiz-col" v-for="quiz in quizList" :key="quiz.id"> - <div class="quiz-header"> - <h3>{{ quiz.title }}</h3> - </div> - <div class="quiz-body"> - <p>Difficulty level: {{ quiz.difficulty }}</p> - <p>Category: {{ quiz.category }}</p> - </div> - <div class="quiz-footer"> - <button @click="playQuiz(quiz.id)" class="play-btn">Play</button> - </div> - </div> - </div> + <div class="quiz-list"> + <div class="quiz-col" v-for="quiz in filteredQuizList" :key="quiz.id"> + <div class="quiz-header"> + <h3>{{ quiz.title }}</h3> + </div> + <div class="quiz-body"> + <p>Difficulty level: {{ quiz.difficulty }}</p> + <p>Category: {{ quiz.category }}</p> + </div> + <div class="quiz-footer"> + <button @click="playQuiz(quiz.id)" class="play-btn">Play</button> + </div> + </div> + </div> </div> - - </body> + </div> </template> +<script> +import { apiClient } from "@/api.js"; +import router from "@/router/index.js"; +import Svg from "@/assets/Svg.vue"; + +export default { + components: {Svg}, + data() { + return { + quizList: [], + searchTerm: '' + }; + }, + mounted() { + this.getQuiz(); + }, + methods: { + async getQuiz() { + try { + const response = await apiClient.get('/quiz/'); + this.quizList = response.data; + } catch (error) { + console.error('Error retrieving quiz:', error); + } + }, + playQuiz(id) { + router.push({ name: 'playQuiz', params: { quizId: id } }); + } + }, + computed: { + filteredQuizList() { + return this.quizList.filter(quiz => quiz.category.toLowerCase().includes(this.searchTerm.toLowerCase())); + } + } +}; +</script> + <style> .dashboard{ @@ -92,47 +75,32 @@ display: flex; justify-content: space-between; align-items: center; - margin-bottom: 20px; + margin-bottom: 10vh; + margin-top: 2vh; } .search-container { - flex-grow: 1; /* Grow to take available space */ - margin-right: 10px; /* Adjust margin between search box and button */ + flex-grow: 1; } .create-container { - flex-shrink: 0; /* Do not shrink */ + flex-shrink: 0; } -.searchBox{ + +.searchBox { width: 250px; padding: 10px; - margin: 0 auto; /* Center horizontally */ + margin: 0 auto; display: block; text-align: center; } -.quiz-col{ +.quiz-col { flex-basis: 31%; background: #d7d7d7; border-radius: 10px; margin-bottom: 5%; padding: 20px; box-sizing: border-box; - transition: 0.5s;} - -.create-btn{ - text-decoration: none; - color: #E5E5E5; - padding: 12px 34px; - font-size: 16px; - cursor: pointer; - margin-bottom: 60px; - background-color: #242F40; -} -.create-btn:hover{ - border: 1px solid #CCA43B; - color: #242F40; - background: #CCA43B; - transition: 1s; + transition: 0.5s; } - </style> \ No newline at end of file diff --git a/FullstackProsjekt/src/frontend/src/views/OverviewQuizView.vue b/FullstackProsjekt/src/frontend/src/views/OverviewQuizView.vue index 187c0f606e90d09875309bf9f6f35cd238a2302f..e37cc64b4cce932e62451baeb6908077c7365643 100644 --- a/FullstackProsjekt/src/frontend/src/views/OverviewQuizView.vue +++ b/FullstackProsjekt/src/frontend/src/views/OverviewQuizView.vue @@ -3,13 +3,11 @@ <div class="overViewQuestion-page"> <div class="headerDiv"> - <div> - <router-link to="/dashboard"> <- </router-link> - <h1>Your quizzes</h1> - <p>Select a quiz for your creation to either play, edit or delete</p> - </div> - <router-link to="/createQuiz" class="add-Btn">New quiz</router-link> - </div> + <router-link to="/" ><Svg name="go-back-icon"/></router-link> + <h1>Your quizzes</h1> + <router-link to="/create-quiz" class="add-Btn">Create new quiz</router-link> + </div> + <p>Play, edit or delete a quiz saved from your profile</p> <div class="row"> <div class="quiz-div"> @@ -25,9 +23,11 @@ import QuizCard from "@/components/shared/create-quiz/QuizCard.vue"; import {getIdByToken} from "@/tokenController.js"; import {apiClient} from "@/api.js"; +import Svg from "@/assets/Svg.vue"; export default { components: { + Svg, QuizCard, }, data() { @@ -38,22 +38,21 @@ export default { }; }, mounted() { - this.populateQuizzes(); // Call populateQuizzes directly + this.populateQuizzes(); }, methods: { async populateQuizzes() { try { - await this.setUserId(); // Wait for setUserId to complete before fetching quizzes + await this.setUserId(); const response = await apiClient.get('/quiz/creator/' + this.userId); this.quizList = response.data; this.quizNo = this.quizList.length; } catch (error) { - // Handle errors this.errorMsg = 'Error retrieving quizzes'; } }, async setUserId() { - this.userId = await getIdByToken(); // Wait for getIdByToken() to resolve before assigning to this.userId + this.userId = await getIdByToken(); } } } @@ -63,6 +62,14 @@ export default { .overViewQuestion-page{ padding: 40px; } +.headerDiv{ + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 10vh; + margin-top: 2vh; +} + .quiz-div { display: flex; @@ -77,6 +84,4 @@ export default { width: 100%; justify-content: space-between; } - - </style> \ No newline at end of file