Implementing Exercise system in database with API and frontend visualization

This commit is contained in:
2024-10-07 13:15:16 +02:00
parent 4a62c7a96b
commit f81e9be320
20 changed files with 413 additions and 99 deletions

View File

@@ -27,7 +27,6 @@ function itemPropsGenre(genre: GenreModel) {
<card-view
variant="tonal"
:title="$t('filtering')"
subtitle="123"
icon="mdi-cog"
>
<v-row class="d-flex justify-center" >

View File

@@ -1,49 +1,35 @@
<script setup lang="ts">
import { getAllExerciseGroups } from '@/data/api/exerciseApi';
import scoreCard from './scoreCard.vue';
import { ref } from 'vue';
import { ExerciseGroupModel } from '@/data/models/exercises/exerciseGroupModel';
import { useFeedbackStore } from '@/data/stores/feedbackStore';
const exerciseGroups = ref<Array<ExerciseGroupModel>>([])
const feedbackStore = useFeedbackStore()
feedbackStore.fetchDataFromServerInProgress = true
getAllExerciseGroups()
.then(result => {
exerciseGroups.value = result.data
feedbackStore.fetchDataFromServerInProgress = false
})
</script>
<template>
<v-container max-width="1000">
<v-row>
<v-row v-if="feedbackStore.fetchDataFromServerInProgress" v-for="i in 3">
<v-col>
<score-card
:title="$t('scoreBoard.exerciseGroup0')"
:progress="2"
:total-steps="2"
:step-names="['Registrieren', 'Bestellung ausführen']"
/>
<score-card :loading="true"
/>
</v-col>
</v-row>
<v-row>
<v-row v-for="exerciseGroup in exerciseGroups">
<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="['', '', '']"
:exercise-group="exerciseGroup"
/>
</v-col>
</v-row>

View File

@@ -1,46 +1,83 @@
<script setup lang="ts">
import cardView from '@/components/basics/cardView.vue';
import { ExerciseGroupModel } from '@/data/models/exercises/exerciseGroupModel';
const props = defineProps({
exerciseGroup: String,
progress: Number,
totalSteps: Number,
stepNames: Array<String>
defineProps({
exerciseGroup: ExerciseGroupModel,
loading: Boolean
})
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" >
<card-view v-if="loading" :loading="loading" >
<v-timeline
direction="horizontal"
side="end"
side="start"
class="pb-3"
>
<v-timeline-item
v-for="step in totalSteps"
:dot-color="getDotColor(step)"
:icon="getIcon(step)"
v-for="i in 3"
dot-color="grey"
icon="mdi-pencil"
>
{{ stepNames[step - 1] }}
<v-skeleton-loader
type="list-item"
:loading="loading"
width="200"
/>
<template #opposite>
<v-skeleton-loader
type="sentences"
:loading="loading"
width="200"
/>
</template>
</v-timeline-item>
</v-timeline>
</card-view>
<card-view
v-else
:title="$t('exerciseGroup') + ' ' + exerciseGroup.groupNr + ': ' + exerciseGroup.nameDe"
:loading="loading"
>
<v-timeline
direction="horizontal"
side="start"
class="pb-3"
>
<v-timeline-item
v-for="exercise in exerciseGroup.exercises"
:dot-color="exercise.solved ? 'green' : 'grey'"
:icon="exercise.solved ? 'mdi-check' : 'mdi-pencil'"
>
<v-skeleton-loader
type="text"
:loading="loading"
>
<div class="text-h6">
{{ $t('exercise') }} {{ exercise.exerciseNr }}
</div>
</v-skeleton-loader>
<template #opposite>
{{ $t('scoreBoard.exercise', [step]) }}
<v-skeleton-loader
type="text"
:loading="loading"
>
<div class="text-center">
<div class="text-h6">
{{ exercise.nameDe }}
</div>
<div>
{{ exercise.descriptionDe }}
</div>
</div>
</v-skeleton-loader>
</template>
</v-timeline-item>