Add Score board page to visualize progress of exercises
This commit is contained in:
@@ -59,6 +59,7 @@ const navRail = defineModel("navRail", { type: Boolean })
|
||||
<div v-else></div>
|
||||
</v-list-subheader>
|
||||
<v-list-item :title="$t('menu.helpInstructions')" prepend-icon="mdi-chat-question" to="/help" link />
|
||||
<v-list-item :title="$t('menu.scoreBoard')" prepend-icon="mdi-podium-gold" to="/scoreBoard" link />
|
||||
<v-list-item :title="$t('menu.preferences')" prepend-icon="mdi-cog" to="/preferences" link />
|
||||
</v-list>
|
||||
</template>
|
||||
11
software/src/data/stores/scoreStore.ts
Normal file
11
software/src/data/stores/scoreStore.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { useLocalStorage } from "@vueuse/core";
|
||||
import { defineStore } from "pinia";
|
||||
|
||||
const useScoreStore = defineStore("scoreStore", {
|
||||
state: () => ({
|
||||
progressGroup0: useLocalStorage("hackmycart/scoreStore/progressGroup0", 0),
|
||||
progressGroup1: useLocalStorage("hackmycart/scoreStore/progressGroup1", 0),
|
||||
progressGroup2: useLocalStorage("hackmycart/scoreStore/progressGroup2", 0),
|
||||
progressGroup3: useLocalStorage("hackmycart/scoreStore/progressGroup3", 0),
|
||||
})
|
||||
})
|
||||
@@ -9,7 +9,8 @@
|
||||
"systemAndHelp": "System & Hilfe",
|
||||
"helpInstructions": "Hilfestellung",
|
||||
"preferences": "Einstellungen",
|
||||
"logout": "Ausloggen"
|
||||
"logout": "Ausloggen",
|
||||
"scoreBoard": "Score Board"
|
||||
},
|
||||
"preferences": {
|
||||
"pageSetup": "Seiteneinstellungen",
|
||||
@@ -102,5 +103,12 @@
|
||||
"title": "Datenbank zurücksetzen?",
|
||||
"description": "Soll die Datenbank des Servers wirklich zurückgesetzt werden? Dies kann nicht rückgänig gemacht werden!"
|
||||
}
|
||||
},
|
||||
"scoreBoard": {
|
||||
"exerciseGroup0": "Aufgabengruppe 0: Den Shop kennenlernen",
|
||||
"exerciseGroup1": "Aufgabengruppe 1: SQL Injections",
|
||||
"exerciseGroup2": "Aufgabengruppe 2: Broken Access Control",
|
||||
"exerciseGroup3": "Aufgabengruppe 3: Cross-Site Scripting (XSS)",
|
||||
"exercise": "Aufgabe {0}"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
"systemAndHelp": "System & Help",
|
||||
"helpInstructions": "Help instructions",
|
||||
"preferences": "Preferences",
|
||||
"logout": "Logout"
|
||||
"logout": "Logout",
|
||||
"scoreBoard": "Score Board"
|
||||
},
|
||||
"preferences": {
|
||||
"pageSetup": "Page setup",
|
||||
@@ -102,5 +103,12 @@
|
||||
"title": "Reset database?",
|
||||
"description": "Do you really want to reset the server database? This can't be undone!"
|
||||
}
|
||||
},
|
||||
"scoreBoard": {
|
||||
"exerciseGroup0": "Exercise Group 0: Getting Started",
|
||||
"exerciseGroup1": "Exercise Group 1: SQL Injections",
|
||||
"exerciseGroup2": "Exercise Group 2: Broken Access Control",
|
||||
"exerciseGroup3": "Exercise Group 3: Cross-Site Scripting (XSS)",
|
||||
"exercise": "Exercise {0}"
|
||||
}
|
||||
}
|
||||
|
||||
51
software/src/pages/scoreBoardPage/index.vue
Normal file
51
software/src/pages/scoreBoardPage/index.vue
Normal file
@@ -0,0 +1,51 @@
|
||||
<script setup lang="ts">
|
||||
import scoreCard from './scoreCard.vue';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-container max-width="1000">
|
||||
<v-row>
|
||||
<v-col>
|
||||
<score-card
|
||||
:title="$t('scoreBoard.exerciseGroup0')"
|
||||
:progress="2"
|
||||
:total-steps="2"
|
||||
:step-names="['Registrieren', 'Bestellung ausführen']"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<score-card
|
||||
:title="$t('scoreBoard.exerciseGroup1')"
|
||||
:progress="1"
|
||||
:total-steps="4"
|
||||
:step-names="['', '']"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<score-card
|
||||
:title="$t('scoreBoard.exerciseGroup2')"
|
||||
:progress="1"
|
||||
:total-steps="4"
|
||||
:step-names="['', '']"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<score-card
|
||||
:title="$t('scoreBoard.exerciseGroup3')"
|
||||
:progress="0"
|
||||
:total-steps="3"
|
||||
:step-names="['', '', '']"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</template>
|
||||
49
software/src/pages/scoreBoardPage/scoreCard.vue
Normal file
49
software/src/pages/scoreBoardPage/scoreCard.vue
Normal file
@@ -0,0 +1,49 @@
|
||||
<script setup lang="ts">
|
||||
import cardView from '@/components/cardView.vue';
|
||||
|
||||
const props = defineProps({
|
||||
exerciseGroup: String,
|
||||
progress: Number,
|
||||
totalSteps: Number,
|
||||
stepNames: Array<String>
|
||||
})
|
||||
|
||||
function getDotColor(step: number) {
|
||||
if (props.progress >= step) {
|
||||
return "green"
|
||||
} else {
|
||||
return "grey"
|
||||
}
|
||||
}
|
||||
|
||||
function getIcon(step: number) {
|
||||
if (props.progress >= step) {
|
||||
return "mdi-check"
|
||||
} else {
|
||||
return "mdi-pencil"
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<card-view :title="exerciseGroup" >
|
||||
<v-timeline
|
||||
direction="horizontal"
|
||||
side="end"
|
||||
class="pb-3"
|
||||
>
|
||||
<v-timeline-item
|
||||
v-for="step in totalSteps"
|
||||
:dot-color="getDotColor(step)"
|
||||
:icon="getIcon(step)"
|
||||
>
|
||||
{{ stepNames[step - 1] }}
|
||||
|
||||
<template #opposite>
|
||||
{{ $t('scoreBoard.exercise', [step]) }}
|
||||
</template>
|
||||
|
||||
</v-timeline-item>
|
||||
</v-timeline>
|
||||
</card-view>
|
||||
</template>
|
||||
@@ -5,6 +5,7 @@ import ProductsPage from "@/pages/productsPage/index.vue";
|
||||
import LoginPage from "@/pages/loginPage/index.vue"
|
||||
import BasketPage from "@/pages/basketPage/index.vue"
|
||||
import HelpPage from "@/pages/helpPage/index.vue"
|
||||
import ScoreBoardPage from "@/pages/scoreBoardPage/index.vue"
|
||||
|
||||
const routes = [
|
||||
{ path: '/', component: ProductsPage },
|
||||
@@ -13,6 +14,7 @@ const routes = [
|
||||
{ path: '/preferences', component: PreferencesPage },
|
||||
{ path: '/login', component: LoginPage },
|
||||
{ path: '/basket', component: BasketPage },
|
||||
{ path: '/scoreboard', component: ScoreBoardPage },
|
||||
{ path: '/help', component: HelpPage }
|
||||
]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user