Refactor LearningContent routing
This commit is contained in:
parent
dc5adb6214
commit
6b0cf9effd
|
|
@ -1,23 +1,28 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import * as log from 'loglevel'
|
import * as log from 'loglevel'
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
|
import type { LearningContent } from '@/types'
|
||||||
import { useCircleStore } from '@/stores/circle'
|
import { useCircleStore } from '@/stores/circle'
|
||||||
|
|
||||||
log.debug('LearningContent.vue setup')
|
log.debug('LearningContent.vue setup')
|
||||||
|
|
||||||
const circleStore = useCircleStore()
|
const circleStore = useCircleStore()
|
||||||
|
|
||||||
const learningContent = computed(() => circleStore.currentLearningContent)
|
const props = defineProps<{
|
||||||
|
learningContent: LearningContent
|
||||||
|
}>()
|
||||||
|
|
||||||
const block = computed(() => {
|
const block = computed(() => {
|
||||||
if (learningContent.value) {
|
if (props.learningContent?.contents?.length) {
|
||||||
return learningContent.value.contents[0]
|
return props.learningContent.contents[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return undefined
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div v-if="block">
|
||||||
<nav class="px-4 lg:px-8 py-4 flex justify-between items-center border-b border-gray-500">
|
<nav class="px-4 lg:px-8 py-4 flex justify-between items-center border-b border-gray-500">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
|
@ -35,7 +40,7 @@ const block = computed(() => {
|
||||||
type="button"
|
type="button"
|
||||||
class="btn-blue"
|
class="btn-blue"
|
||||||
data-cy="complete-and-continue"
|
data-cy="complete-and-continue"
|
||||||
@click="circleStore.continueFromLearningContent()"
|
@click="circleStore.continueFromLearningContent(this.learningContent)"
|
||||||
>
|
>
|
||||||
Abschliessen und weiter
|
Abschliessen und weiter
|
||||||
</button>
|
</button>
|
||||||
|
|
|
||||||
|
|
@ -1,42 +1,39 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import * as log from 'loglevel';
|
import * as log from 'loglevel'
|
||||||
import {computed, reactive} from 'vue';
|
import { computed, reactive } from 'vue'
|
||||||
import {useCircleStore} from '@/stores/circle';
|
import { useCircleStore } from '@/stores/circle'
|
||||||
|
import { LearningUnit } from '@/types'
|
||||||
|
|
||||||
log.debug('LearningContent.vue setup');
|
log.debug('LearningContent.vue setup')
|
||||||
|
|
||||||
const circleStore = useCircleStore();
|
const circleStore = useCircleStore()
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
questionIndex: 0,
|
questionIndex: 0,
|
||||||
});
|
})
|
||||||
|
|
||||||
const questions = computed(() => circleStore.currentSelfEvaluation!.children);
|
const props = defineProps<{
|
||||||
const currentQuestion = computed(() => questions.value[state.questionIndex]);
|
learningUnit: LearningUnit
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const questions = computed(() => props.learningUnit?.children)
|
||||||
|
const currentQuestion = computed(() => questions.value[state.questionIndex])
|
||||||
|
|
||||||
function handleContinue() {
|
function handleContinue() {
|
||||||
log.debug('handleContinue');
|
log.debug('handleContinue')
|
||||||
if (state.questionIndex + 1 < questions.value.length) {
|
if (state.questionIndex + 1 < questions.value.length) {
|
||||||
log.debug('increment questionIndex', state.questionIndex);
|
log.debug('increment questionIndex', state.questionIndex)
|
||||||
state.questionIndex += 1;
|
state.questionIndex += 1
|
||||||
} else {
|
} else {
|
||||||
log.debug('continue to next learning content');
|
log.debug('continue to next learning content')
|
||||||
circleStore.continueFromSelfEvaluation();
|
circleStore.continueFromSelfEvaluation()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div v-if="learningUnit">
|
||||||
<nav
|
<nav class="px-4 lg:px-8 py-4 flex justify-between items-center border-b border-gray-500">
|
||||||
class="
|
|
||||||
px-4 lg:px-8
|
|
||||||
py-4
|
|
||||||
flex justify-between items-center
|
|
||||||
border-b border-gray-500
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="btn-text inline-flex items-center px-3 py-2 font-normal"
|
class="btn-text inline-flex items-center px-3 py-2 font-normal"
|
||||||
|
|
@ -46,24 +43,17 @@ function handleContinue() {
|
||||||
<span class="hidden lg:inline">zurück zum Circle</span>
|
<span class="hidden lg:inline">zurück zum Circle</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<h1 class="text-xl hidden lg:block">{{ circleStore.currentSelfEvaluation.title }}</h1>
|
<h1 class="text-xl hidden lg:block">{{ learningUnit.title }}</h1>
|
||||||
|
|
||||||
<button
|
<button type="button" class="btn-blue" @click="handleContinue()">Weiter</button>
|
||||||
type="button"
|
|
||||||
class="btn-blue"
|
|
||||||
@click="handleContinue()"
|
|
||||||
>
|
|
||||||
Weiter
|
|
||||||
</button>
|
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
|
||||||
<div class="mx-auto max-w-6xl px-4 lg:px-8 py-4">
|
<div class="mx-auto max-w-6xl px-4 lg:px-8 py-4">
|
||||||
|
|
||||||
<div class="mt-2 lg:mt-8 text-gray-700">Schritt {{ state.questionIndex + 1 }} von {{ questions.length }}</div>
|
<div class="mt-2 lg:mt-8 text-gray-700">Schritt {{ state.questionIndex + 1 }} von {{ questions.length }}</div>
|
||||||
|
|
||||||
<p class="text-xl mt-4">
|
<p class="text-xl mt-4">
|
||||||
Überprüfe, ob du in der Lernheinheit <span class="font-bold">"{{ circleStore.currentSelfEvaluation.title }}"</span> alles verstanden hast.<br>
|
Überprüfe, ob du in der Lernheinheit
|
||||||
|
<span class="font-bold">"{{ learningUnit.title }}"</span> alles verstanden hast.<br />
|
||||||
Lies die folgende Aussage und bewerte sie:
|
Lies die folgende Aussage und bewerte sie:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
@ -81,9 +71,7 @@ function handleContinue() {
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<it-icon-smiley-happy class="w-16 h-16 mr-4"></it-icon-smiley-happy>
|
<it-icon-smiley-happy class="w-16 h-16 mr-4"></it-icon-smiley-happy>
|
||||||
<span class="font-bold text-xl">
|
<span class="font-bold text-xl"> Ja, ich kann das. </span>
|
||||||
Ja, ich kann das.
|
|
||||||
</span>
|
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
@click="circleStore.markCompletion(currentQuestion, false)"
|
@click="circleStore.markCompletion(currentQuestion, false)"
|
||||||
|
|
@ -95,20 +83,14 @@ function handleContinue() {
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<it-icon-smiley-thinking class="w-16 h-16 mr-4"></it-icon-smiley-thinking>
|
<it-icon-smiley-thinking class="w-16 h-16 mr-4"></it-icon-smiley-thinking>
|
||||||
<span class="font-bold text-xl">
|
<span class="font-bold text-xl"> Das muss ich nochmals anschauen. </span>
|
||||||
Das muss ich nochmals anschauen.
|
|
||||||
</span>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-6 lg:mt-12">Schau dein Fortschritt in deinem Kompetenzprofil: Kompetenzprofil öffnen</div>
|
<div class="mt-6 lg:mt-12">Schau dein Fortschritt in deinem Kompetenzprofil: Kompetenzprofil öffnen</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped></style>
|
||||||
</style>
|
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,6 @@ import { useLearningPathStore } from '@/stores/learningPath'
|
||||||
|
|
||||||
export type CircleStoreState = {
|
export type CircleStoreState = {
|
||||||
circle: Circle | undefined
|
circle: Circle | undefined
|
||||||
currentLearningContent: LearningContent | undefined
|
|
||||||
currentSelfEvaluation: LearningUnit | undefined
|
|
||||||
page: 'INDEX' | 'OVERVIEW' | 'LEARNING_CONTENT' | 'SELF_EVALUATION'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useCircleStore = defineStore({
|
export const useCircleStore = defineStore({
|
||||||
|
|
@ -19,9 +16,6 @@ export const useCircleStore = defineStore({
|
||||||
state: () => {
|
state: () => {
|
||||||
return {
|
return {
|
||||||
circle: undefined,
|
circle: undefined,
|
||||||
currentLearningContent: undefined,
|
|
||||||
currentSelfEvaluation: undefined,
|
|
||||||
page: 'INDEX',
|
|
||||||
} as CircleStoreState;
|
} as CircleStoreState;
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
|
|
@ -45,32 +39,27 @@ export const useCircleStore = defineStore({
|
||||||
},
|
},
|
||||||
async loadLearningContent(learningPathSlug: string, circleSlug: string, learningContentSlug: string) {
|
async loadLearningContent(learningPathSlug: string, circleSlug: string, learningContentSlug: string) {
|
||||||
const circle = await this.loadCircle(learningPathSlug, circleSlug);
|
const circle = await this.loadCircle(learningPathSlug, circleSlug);
|
||||||
if (circle) {
|
const result = circle.flatLearningContents.find((learningContent) => {
|
||||||
this.currentLearningContent = circle.flatLearningContents.find((learningContent) => {
|
return learningContent.slug.endsWith(learningContentSlug);
|
||||||
return learningContent.slug.endsWith(learningContentSlug);
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.currentLearningContent) {
|
if (!result) {
|
||||||
throw `No learning content found with slug: ${learningContentSlug}`;
|
throw `No learning content found with slug: ${learningContentSlug}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.currentLearningContent;
|
return result
|
||||||
},
|
},
|
||||||
async loadSelfEvaluation(learningPathSlug: string, circleSlug: string, learningUnitSlug: string) {
|
async loadSelfEvaluation(learningPathSlug: string, circleSlug: string, learningUnitSlug: string) {
|
||||||
const circle = await this.loadCircle(learningPathSlug, circleSlug);
|
const circle = await this.loadCircle(learningPathSlug, circleSlug);
|
||||||
if (circle) {
|
const learningUnit = circle.flatLearningUnits.find((child) => {
|
||||||
this.currentSelfEvaluation = circle.flatLearningUnits.find((child) => {
|
return child.slug.endsWith(learningUnitSlug)
|
||||||
return child.slug.endsWith(learningUnitSlug)
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.currentSelfEvaluation) {
|
if (!learningUnit) {
|
||||||
throw `No self evaluation found with slug: ${learningUnitSlug}`;
|
throw `No self evaluation found with slug: ${learningUnitSlug}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.currentLearningContent;
|
return learningUnit
|
||||||
|
|
||||||
},
|
},
|
||||||
async markCompletion(page: LearningContent | LearningUnitQuestion, flag = true) {
|
async markCompletion(page: LearningContent | LearningUnitQuestion, flag = true) {
|
||||||
try {
|
try {
|
||||||
|
|
@ -88,7 +77,6 @@ export const useCircleStore = defineStore({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
openLearningContent(learningContent: LearningContent) {
|
openLearningContent(learningContent: LearningContent) {
|
||||||
this.currentLearningContent = learningContent;
|
|
||||||
const shortSlug = learningContent.slug.replace(`${this.circle?.slug}-lc-`, '');
|
const shortSlug = learningContent.slug.replace(`${this.circle?.slug}-lc-`, '');
|
||||||
this.router.push({
|
this.router.push({
|
||||||
path: `${this.circle?.getUrl()}/${shortSlug}`,
|
path: `${this.circle?.getUrl()}/${shortSlug}`,
|
||||||
|
|
@ -100,7 +88,6 @@ export const useCircleStore = defineStore({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
openSelfEvaluation(learningUnit: LearningUnit) {
|
openSelfEvaluation(learningUnit: LearningUnit) {
|
||||||
this.currentSelfEvaluation = learningUnit;
|
|
||||||
const shortSlug = learningUnit.slug.replace(`${this.circle?.slug}-lu-`, '');
|
const shortSlug = learningUnit.slug.replace(`${this.circle?.slug}-lu-`, '');
|
||||||
this.router.push({
|
this.router.push({
|
||||||
path: `${this.circle?.getUrl()}/evaluate/${shortSlug}`,
|
path: `${this.circle?.getUrl()}/evaluate/${shortSlug}`,
|
||||||
|
|
@ -122,12 +109,12 @@ export const useCircleStore = defineStore({
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
},
|
},
|
||||||
continueFromLearningContent() {
|
continueFromLearningContent(currentLearningContent: LearningContent) {
|
||||||
if (this.currentLearningContent) {
|
if (currentLearningContent) {
|
||||||
this.markCompletion(this.currentLearningContent, true);
|
this.markCompletion(currentLearningContent, true);
|
||||||
|
|
||||||
const nextLearningContent = this.currentLearningContent.nextLearningContent;
|
const nextLearningContent = currentLearningContent.nextLearningContent;
|
||||||
const currentParent = this.currentLearningContent.parentLearningUnit;
|
const currentParent = currentLearningContent.parentLearningUnit;
|
||||||
const nextParent = nextLearningContent?.parentLearningUnit;
|
const nextParent = nextLearningContent?.parentLearningUnit;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
|
@ -138,12 +125,12 @@ export const useCircleStore = defineStore({
|
||||||
// go to self evaluation
|
// go to self evaluation
|
||||||
// this.openSelfEvaluation(currentParent);
|
// this.openSelfEvaluation(currentParent);
|
||||||
this.closeLearningContent();
|
this.closeLearningContent();
|
||||||
} else if (this.currentLearningContent.nextLearningContent) {
|
} else if (currentLearningContent.nextLearningContent) {
|
||||||
if (
|
if (
|
||||||
this.currentLearningContent.parentLearningSequence &&
|
currentLearningContent.parentLearningSequence &&
|
||||||
this.currentLearningContent.parentLearningSequence.id === nextLearningContent?.parentLearningSequence?.id
|
currentLearningContent.parentLearningSequence.id === nextLearningContent?.parentLearningSequence?.id
|
||||||
) {
|
) {
|
||||||
this.openLearningContent(this.currentLearningContent.nextLearningContent);
|
this.openLearningContent(currentLearningContent.nextLearningContent);
|
||||||
} else {
|
} else {
|
||||||
this.closeLearningContent();
|
this.closeLearningContent();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import * as log from 'loglevel'
|
import * as log from 'loglevel'
|
||||||
import LearningContent from '@/components/circle/LearningContent.vue'
|
import { onMounted, reactive, watch } from 'vue'
|
||||||
|
|
||||||
import { onMounted } from 'vue'
|
|
||||||
import { useCircleStore } from '@/stores/circle'
|
import { useCircleStore } from '@/stores/circle'
|
||||||
import { useAppStore } from '@/stores/app'
|
import { useAppStore } from '@/stores/app'
|
||||||
|
import LearningContent from '@/components/circle/LearningContent.vue'
|
||||||
|
import { LearningContent as LearningContentType } from '@/types'
|
||||||
|
|
||||||
log.debug('LearningContentView created')
|
log.debug('LearningContentView created')
|
||||||
|
|
||||||
|
|
@ -14,27 +14,46 @@ const props = defineProps<{
|
||||||
contentSlug: string
|
contentSlug: string
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
|
const state: { learningContent?: LearningContentType } = reactive({})
|
||||||
|
|
||||||
const appStore = useAppStore()
|
const appStore = useAppStore()
|
||||||
appStore.showMainNavigationBar = false
|
appStore.showMainNavigationBar = false
|
||||||
|
|
||||||
const circleStore = useCircleStore()
|
const circleStore = useCircleStore()
|
||||||
|
|
||||||
onMounted(async () => {
|
const loadLearningContent = async () => {
|
||||||
log.debug('LearningContentView mounted', props.learningPathSlug, props.circleSlug, props.contentSlug)
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await circleStore.loadLearningContent(props.learningPathSlug, props.circleSlug, props.contentSlug)
|
state.learningContent = await circleStore.loadLearningContent(
|
||||||
|
props.learningPathSlug,
|
||||||
|
props.circleSlug,
|
||||||
|
props.contentSlug
|
||||||
|
)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(error)
|
log.error(error)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.contentSlug,
|
||||||
|
async () => {
|
||||||
|
log.debug(
|
||||||
|
'LearningContentView props.contentSlug changed',
|
||||||
|
props.learningPathSlug,
|
||||||
|
props.circleSlug,
|
||||||
|
props.contentSlug
|
||||||
|
)
|
||||||
|
await loadLearningContent()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
log.debug('LearningContentView mounted', props.learningPathSlug, props.circleSlug, props.contentSlug)
|
||||||
|
await loadLearningContent()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<LearningContent
|
<LearningContent v-if="state.learningContent" :learning-content="state.learningContent" />
|
||||||
v-if="circleStore.currentLearningContent"
|
|
||||||
:key="circleStore.currentLearningContent.translation_key"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="postcss" scoped></style>
|
<style lang="postcss" scoped></style>
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,10 @@ import * as log from 'loglevel'
|
||||||
|
|
||||||
import SelfEvaluation from '@/components/circle/SelfEvaluation.vue'
|
import SelfEvaluation from '@/components/circle/SelfEvaluation.vue'
|
||||||
|
|
||||||
import { onMounted } from 'vue'
|
import { onMounted, reactive } from 'vue'
|
||||||
import { useCircleStore } from '@/stores/circle'
|
|
||||||
import { useAppStore } from '@/stores/app'
|
import { useAppStore } from '@/stores/app'
|
||||||
|
import { useCircleStore } from '@/stores/circle'
|
||||||
|
import type { LearningUnit } from '@/types'
|
||||||
|
|
||||||
log.debug('LearningUnitSelfEvaluationView created')
|
log.debug('LearningUnitSelfEvaluationView created')
|
||||||
|
|
||||||
|
|
@ -20,11 +21,17 @@ appStore.showMainNavigationBar = false
|
||||||
|
|
||||||
const circleStore = useCircleStore()
|
const circleStore = useCircleStore()
|
||||||
|
|
||||||
|
const state: { learningUnit?: LearningUnit } = reactive({})
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
log.debug('LearningUnitSelfEvaluationView mounted', props.learningPathSlug, props.circleSlug, props.learningUnitSlug)
|
log.debug('LearningUnitSelfEvaluationView mounted', props.learningPathSlug, props.circleSlug, props.learningUnitSlug)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await circleStore.loadSelfEvaluation(props.learningPathSlug, props.circleSlug, props.learningUnitSlug)
|
state.learningUnit = await circleStore.loadSelfEvaluation(
|
||||||
|
props.learningPathSlug,
|
||||||
|
props.circleSlug,
|
||||||
|
props.learningUnitSlug
|
||||||
|
)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error(error)
|
log.error(error)
|
||||||
}
|
}
|
||||||
|
|
@ -32,7 +39,7 @@ onMounted(async () => {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<SelfEvaluation v-if="circleStore.currentSelfEvaluation" :key="circleStore.currentSelfEvaluation.translation_key" />
|
<SelfEvaluation v-if="state.learningUnit" :learning-unit="state.learningUnit" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="postcss" scoped></style>
|
<style lang="postcss" scoped></style>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue