Merge branch 'feature/learning-content-urls' into develop
This commit is contained in:
commit
384999619c
|
|
@ -1,32 +1,29 @@
|
|||
<script setup lang="ts">
|
||||
import * as log from 'loglevel';
|
||||
import {computed} from 'vue';
|
||||
import {useCircleStore} from '@/stores/circle';
|
||||
import * as log from 'loglevel'
|
||||
import { computed } from 'vue'
|
||||
import type { LearningContent } from '@/types'
|
||||
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(() => {
|
||||
if (learningContent.value) {
|
||||
return learningContent.value.contents[0];
|
||||
if (props.learningContent?.contents?.length) {
|
||||
return props.learningContent.contents[0]
|
||||
}
|
||||
})
|
||||
|
||||
return undefined
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<nav
|
||||
class="
|
||||
px-4 lg:px-8
|
||||
py-4
|
||||
flex justify-between items-center
|
||||
border-b border-gray-500
|
||||
"
|
||||
>
|
||||
<div v-if="block">
|
||||
<nav class="px-4 lg:px-8 py-4 flex justify-between items-center border-b border-gray-500">
|
||||
<button
|
||||
type="button"
|
||||
class="btn-text inline-flex items-center px-3 py-2 font-normal"
|
||||
|
|
@ -43,22 +40,16 @@ const block = computed(() => {
|
|||
type="button"
|
||||
class="btn-blue"
|
||||
data-cy="complete-and-continue"
|
||||
@click="circleStore.continueFromLearningContent()"
|
||||
@click="circleStore.continueFromLearningContent(this.learningContent)"
|
||||
>
|
||||
Abschliessen und weiter
|
||||
</button>
|
||||
</nav>
|
||||
|
||||
<div v-if="block.type === 'exercise'" class="h-screen">
|
||||
<iframe
|
||||
width="100%"
|
||||
height="100%"
|
||||
scrolling="no"
|
||||
:src="block.value.url"
|
||||
/>
|
||||
<iframe width="100%" height="100%" scrolling="no" :src="block.value.url" />
|
||||
</div>
|
||||
|
||||
|
||||
<div v-else class="mx-auto max-w-5xl px-4 lg:px-8 py-4">
|
||||
<p>{{ block.value.description }}</p>
|
||||
|
||||
|
|
@ -69,24 +60,19 @@ const block = computed(() => {
|
|||
:title="learningContent.title"
|
||||
frameborder="0"
|
||||
allow="accelerometer; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowfullscreen>
|
||||
allowfullscreen
|
||||
>
|
||||
</iframe>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="block.type === 'podcast'"
|
||||
>
|
||||
<div v-if="block.type === 'podcast'">
|
||||
<iframe width="100%" height="300" scrolling="no" frameborder="no" allow="" :src="block.value.url"></iframe>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
$header-height: 77px;
|
||||
$footer-height: 57px;
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,26 @@ const allFinished = computed(() => {
|
|||
return false
|
||||
})
|
||||
|
||||
const continueTranslationKey = computed(() => {
|
||||
if (props.learningSequence && circleStore.circle) {
|
||||
const childrenReversed = [...circleStore.circle.flatLearningContents].reverse()
|
||||
const lastFinished = childrenReversed.find((learningContent) => {
|
||||
return learningContent.completed
|
||||
})
|
||||
|
||||
if (!lastFinished) {
|
||||
// must be the first
|
||||
return circleStore.circle.flatLearningContents[0].translation_key
|
||||
}
|
||||
|
||||
if (lastFinished && lastFinished.nextLearningContent) {
|
||||
return lastFinished.nextLearningContent.translation_key
|
||||
}
|
||||
}
|
||||
|
||||
return ''
|
||||
})
|
||||
|
||||
const learningSequenceBorderClass = computed(() => {
|
||||
let result = []
|
||||
if (props.learningSequence && circleStore.circle) {
|
||||
|
|
@ -77,6 +97,14 @@ const learningSequenceBorderClass = computed(() => {
|
|||
>{{ learningContent.contents[0].type }}: {{ learningContent.title }}</span
|
||||
>
|
||||
</ItCheckbox>
|
||||
|
||||
<button
|
||||
v-if="learningContent.translation_key === continueTranslationKey"
|
||||
class="btn-blue -my-4"
|
||||
@click.stop="circleStore.openLearningContent(learningContent)"
|
||||
>
|
||||
Weiter gehts
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div v-if="learningUnit.id" class="hover:cursor-pointer" @click="circleStore.openSelfEvaluation(learningUnit)">
|
||||
|
|
|
|||
|
|
@ -1,42 +1,39 @@
|
|||
<script setup lang="ts">
|
||||
import * as log from 'loglevel';
|
||||
import {computed, reactive} from 'vue';
|
||||
import {useCircleStore} from '@/stores/circle';
|
||||
import * as log from 'loglevel'
|
||||
import { computed, reactive } from 'vue'
|
||||
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({
|
||||
questionIndex: 0,
|
||||
});
|
||||
})
|
||||
|
||||
const questions = computed(() => circleStore.currentSelfEvaluation!.children);
|
||||
const currentQuestion = computed(() => questions.value[state.questionIndex]);
|
||||
const props = defineProps<{
|
||||
learningUnit: LearningUnit
|
||||
}>()
|
||||
|
||||
const questions = computed(() => props.learningUnit?.children)
|
||||
const currentQuestion = computed(() => questions.value[state.questionIndex])
|
||||
|
||||
function handleContinue() {
|
||||
log.debug('handleContinue');
|
||||
log.debug('handleContinue')
|
||||
if (state.questionIndex + 1 < questions.value.length) {
|
||||
log.debug('increment questionIndex', state.questionIndex);
|
||||
state.questionIndex += 1;
|
||||
log.debug('increment questionIndex', state.questionIndex)
|
||||
state.questionIndex += 1
|
||||
} else {
|
||||
log.debug('continue to next learning content');
|
||||
circleStore.continueFromSelfEvaluation();
|
||||
log.debug('continue to next learning content')
|
||||
circleStore.continueFromSelfEvaluation()
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<nav
|
||||
class="
|
||||
px-4 lg:px-8
|
||||
py-4
|
||||
flex justify-between items-center
|
||||
border-b border-gray-500
|
||||
"
|
||||
>
|
||||
<div v-if="learningUnit">
|
||||
<nav class="px-4 lg:px-8 py-4 flex justify-between items-center border-b border-gray-500">
|
||||
<button
|
||||
type="button"
|
||||
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>
|
||||
</button>
|
||||
|
||||
<h1 class="text-xl hidden lg:block">{{ circleStore.currentSelfEvaluation.title }}</h1>
|
||||
<h1 class="text-xl hidden lg:block">{{ learningUnit.title }}</h1>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="btn-blue"
|
||||
@click="handleContinue()"
|
||||
>
|
||||
Weiter
|
||||
</button>
|
||||
<button type="button" class="btn-blue" @click="handleContinue()">Weiter</button>
|
||||
</nav>
|
||||
|
||||
|
||||
<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>
|
||||
|
||||
<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:
|
||||
</p>
|
||||
|
||||
|
|
@ -81,9 +71,7 @@ function handleContinue() {
|
|||
}"
|
||||
>
|
||||
<it-icon-smiley-happy class="w-16 h-16 mr-4"></it-icon-smiley-happy>
|
||||
<span class="font-bold text-xl">
|
||||
Ja, ich kann das.
|
||||
</span>
|
||||
<span class="font-bold text-xl"> Ja, ich kann das. </span>
|
||||
</button>
|
||||
<button
|
||||
@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>
|
||||
<span class="font-bold text-xl">
|
||||
Das muss ich nochmals anschauen.
|
||||
</span>
|
||||
<span class="font-bold text-xl"> Das muss ich nochmals anschauen. </span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 lg:mt-12">Schau dein Fortschritt in deinem Kompetenzprofil: Kompetenzprofil öffnen</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
<style scoped></style>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { createApp } from 'vue'
|
||||
import { createApp, markRaw } from 'vue'
|
||||
import { createPinia } from 'pinia'
|
||||
import * as log from 'loglevel'
|
||||
|
||||
|
|
@ -7,6 +7,7 @@ import App from './App.vue'
|
|||
import router from './router'
|
||||
|
||||
import '../tailwind.css'
|
||||
import type { Router } from 'vue-router'
|
||||
|
||||
if (window.location.href.indexOf('localhost') >= 0) {
|
||||
log.setLevel('trace')
|
||||
|
|
@ -21,8 +22,19 @@ const app = createApp(App)
|
|||
// todo: define lang setup
|
||||
// await loadLocaleMessages(i18n, 'de')
|
||||
|
||||
app.use(createPinia())
|
||||
app.use(router)
|
||||
|
||||
declare module 'pinia' {
|
||||
export interface PiniaCustomProperties {
|
||||
router: Router
|
||||
}
|
||||
}
|
||||
const pinia = createPinia();
|
||||
pinia.use(({ store }) => {
|
||||
store.router = markRaw(router)
|
||||
})
|
||||
app.use(pinia)
|
||||
// app.use(i18n)
|
||||
|
||||
|
||||
app.mount('#app')
|
||||
|
|
|
|||
|
|
@ -46,6 +46,16 @@ const router = createRouter({
|
|||
component: () => import('../views/CircleView.vue'),
|
||||
props: true,
|
||||
},
|
||||
{
|
||||
path: '/learn/:learningPathSlug/:circleSlug/evaluate/:learningUnitSlug',
|
||||
component: () => import('../views/LearningUnitSelfEvaluationView.vue'),
|
||||
props: true,
|
||||
},
|
||||
{
|
||||
path: '/learn/:learningPathSlug/:circleSlug/:contentSlug',
|
||||
component: () => import('../views/LearningContentView.vue'),
|
||||
props: true,
|
||||
},
|
||||
{
|
||||
path: '/styleguide',
|
||||
component: () => import('../views/StyleGuideView.vue'),
|
||||
|
|
|
|||
|
|
@ -174,6 +174,16 @@ export class Circle implements LearningWagtailPage {
|
|||
return result;
|
||||
}
|
||||
|
||||
public get flatLearningUnits(): LearningUnit[] {
|
||||
const result: LearningUnit[] = [];
|
||||
this.learningSequences.forEach((learningSequence) => {
|
||||
learningSequence.learningUnits.forEach((learningUnit) => {
|
||||
result.push(learningUnit);
|
||||
});
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
public someFinishedInLearningSequence(translationKey: string): boolean {
|
||||
if (translationKey) {
|
||||
return this.flatChildren.filter((lc) => {
|
||||
|
|
@ -215,4 +225,9 @@ export class Circle implements LearningWagtailPage {
|
|||
this.parentLearningPath.calcNextLearningContent(completionData);
|
||||
}
|
||||
}
|
||||
|
||||
public getUrl(): string {
|
||||
const shortSlug = this.slug.replace(`${this.parentLearningPath?.slug}-circle-`, '')
|
||||
return `/learn/${this.parentLearningPath?.slug}/${shortSlug}`;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,10 +6,28 @@ export type AppState = {
|
|||
showMainNavigationBar: boolean
|
||||
}
|
||||
|
||||
const showMainNavigationBarInitialState = () => {
|
||||
let path = window.location.pathname;
|
||||
|
||||
// remove dangling slash
|
||||
if (path.endsWith('/')) {
|
||||
path = path.slice(0, -1);
|
||||
}
|
||||
|
||||
const numberOfSlashes = (path.match(/\//g) || []).length;
|
||||
|
||||
// it should hide main navigation bar when on learning content page
|
||||
if (path.startsWith('/learn/') && numberOfSlashes >= 4) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
export const useAppStore = defineStore({
|
||||
id: 'app',
|
||||
state: () => ({
|
||||
showMainNavigationBar: true,
|
||||
showMainNavigationBar: showMainNavigationBarInitialState(),
|
||||
userLoaded: false,
|
||||
routingFinished: false,
|
||||
} as AppState),
|
||||
|
|
|
|||
|
|
@ -5,14 +5,10 @@ import { defineStore } from 'pinia'
|
|||
import type { LearningContent, LearningUnit, LearningUnitQuestion } from '@/types'
|
||||
import type { Circle } from '@/services/circle'
|
||||
import { itPost } from '@/fetchHelpers'
|
||||
import { useAppStore } from '@/stores/app'
|
||||
import { useLearningPathStore } from '@/stores/learningPath'
|
||||
|
||||
export type CircleStoreState = {
|
||||
circle: Circle | undefined
|
||||
currentLearningContent: LearningContent | undefined
|
||||
currentSelfEvaluation: LearningUnit | undefined
|
||||
page: 'INDEX' | 'OVERVIEW' | 'LEARNING_CONTENT' | 'SELF_EVALUATION'
|
||||
}
|
||||
|
||||
export const useCircleStore = defineStore({
|
||||
|
|
@ -20,15 +16,12 @@ export const useCircleStore = defineStore({
|
|||
state: () => {
|
||||
return {
|
||||
circle: undefined,
|
||||
currentLearningContent: undefined,
|
||||
currentSelfEvaluation: undefined,
|
||||
page: 'INDEX',
|
||||
} as CircleStoreState;
|
||||
},
|
||||
getters: {
|
||||
},
|
||||
actions: {
|
||||
async loadCircle(learningPathSlug: string, circleSlug: string) {
|
||||
async loadCircle(learningPathSlug: string, circleSlug: string): Promise<Circle> {
|
||||
this.circle = undefined;
|
||||
const learningPathStore = useLearningPathStore();
|
||||
await learningPathStore.loadLearningPath(learningPathSlug);
|
||||
|
|
@ -44,6 +37,30 @@ export const useCircleStore = defineStore({
|
|||
|
||||
return this.circle
|
||||
},
|
||||
async loadLearningContent(learningPathSlug: string, circleSlug: string, learningContentSlug: string) {
|
||||
const circle = await this.loadCircle(learningPathSlug, circleSlug);
|
||||
const result = circle.flatLearningContents.find((learningContent) => {
|
||||
return learningContent.slug.endsWith(learningContentSlug);
|
||||
});
|
||||
|
||||
if (!result) {
|
||||
throw `No learning content found with slug: ${learningContentSlug}`;
|
||||
}
|
||||
|
||||
return result
|
||||
},
|
||||
async loadSelfEvaluation(learningPathSlug: string, circleSlug: string, learningUnitSlug: string) {
|
||||
const circle = await this.loadCircle(learningPathSlug, circleSlug);
|
||||
const learningUnit = circle.flatLearningUnits.find((child) => {
|
||||
return child.slug.endsWith(learningUnitSlug)
|
||||
});
|
||||
|
||||
if (!learningUnit) {
|
||||
throw `No self evaluation found with slug: ${learningUnitSlug}`;
|
||||
}
|
||||
|
||||
return learningUnit
|
||||
},
|
||||
async markCompletion(page: LearningContent | LearningUnitQuestion, flag = true) {
|
||||
try {
|
||||
page.completed = flag;
|
||||
|
|
@ -60,28 +77,26 @@ export const useCircleStore = defineStore({
|
|||
}
|
||||
},
|
||||
openLearningContent(learningContent: LearningContent) {
|
||||
this.currentLearningContent = learningContent;
|
||||
const appStore = useAppStore();
|
||||
appStore.showMainNavigationBar = false;
|
||||
this.page = 'LEARNING_CONTENT';
|
||||
const shortSlug = learningContent.slug.replace(`${this.circle?.slug}-lc-`, '');
|
||||
this.router.push({
|
||||
path: `${this.circle?.getUrl()}/${shortSlug}`,
|
||||
});
|
||||
},
|
||||
closeLearningContent() {
|
||||
this.currentLearningContent = undefined;
|
||||
const appStore = useAppStore();
|
||||
appStore.showMainNavigationBar = true;
|
||||
this.page = 'INDEX';
|
||||
this.router.push({
|
||||
path: `${this.circle?.getUrl()}`
|
||||
});
|
||||
},
|
||||
openSelfEvaluation(learningUnit: LearningUnit) {
|
||||
this.page = 'SELF_EVALUATION';
|
||||
const appStore = useAppStore();
|
||||
appStore.showMainNavigationBar = false;
|
||||
this.currentSelfEvaluation = learningUnit;
|
||||
const shortSlug = learningUnit.slug.replace(`${this.circle?.slug}-lu-`, '');
|
||||
this.router.push({
|
||||
path: `${this.circle?.getUrl()}/evaluate/${shortSlug}`,
|
||||
});
|
||||
},
|
||||
closeSelfEvaluation() {
|
||||
this.currentSelfEvaluation = undefined;
|
||||
const appStore = useAppStore();
|
||||
appStore.showMainNavigationBar = true;
|
||||
this.page = 'INDEX';
|
||||
this.router.push({
|
||||
path: `${this.circle?.getUrl()}`
|
||||
});
|
||||
},
|
||||
calcSelfEvaluationStatus(learningUnit: LearningUnit) {
|
||||
if (learningUnit.children.length > 0) {
|
||||
|
|
@ -94,12 +109,12 @@ export const useCircleStore = defineStore({
|
|||
}
|
||||
return undefined;
|
||||
},
|
||||
continueFromLearningContent() {
|
||||
if (this.currentLearningContent) {
|
||||
this.markCompletion(this.currentLearningContent, true);
|
||||
continueFromLearningContent(currentLearningContent: LearningContent) {
|
||||
if (currentLearningContent) {
|
||||
this.markCompletion(currentLearningContent, true);
|
||||
|
||||
const nextLearningContent = this.currentLearningContent.nextLearningContent;
|
||||
const currentParent = this.currentLearningContent.parentLearningUnit;
|
||||
const nextLearningContent = currentLearningContent.nextLearningContent;
|
||||
const currentParent = currentLearningContent.parentLearningUnit;
|
||||
const nextParent = nextLearningContent?.parentLearningUnit;
|
||||
|
||||
if (
|
||||
|
|
@ -108,13 +123,14 @@ export const useCircleStore = defineStore({
|
|||
currentParent.children.length > 0
|
||||
) {
|
||||
// go to self evaluation
|
||||
this.openSelfEvaluation(currentParent);
|
||||
} else if (this.currentLearningContent.nextLearningContent) {
|
||||
// this.openSelfEvaluation(currentParent);
|
||||
this.closeLearningContent();
|
||||
} else if (currentLearningContent.nextLearningContent) {
|
||||
if (
|
||||
this.currentLearningContent.parentLearningSequence &&
|
||||
this.currentLearningContent.parentLearningSequence.id === nextLearningContent?.parentLearningSequence?.id
|
||||
currentLearningContent.parentLearningSequence &&
|
||||
currentLearningContent.parentLearningSequence.id === nextLearningContent?.parentLearningSequence?.id
|
||||
) {
|
||||
this.openLearningContent(this.currentLearningContent.nextLearningContent);
|
||||
this.openLearningContent(currentLearningContent.nextLearningContent);
|
||||
} else {
|
||||
this.closeLearningContent();
|
||||
}
|
||||
|
|
@ -126,21 +142,22 @@ export const useCircleStore = defineStore({
|
|||
}
|
||||
},
|
||||
continueFromSelfEvaluation() {
|
||||
if (this.currentSelfEvaluation) {
|
||||
const nextContent = this.currentSelfEvaluation.learningContents[this.currentSelfEvaluation.learningContents.length - 1].nextLearningContent;
|
||||
|
||||
if (nextContent) {
|
||||
if (this.currentSelfEvaluation?.parentLearningSequence?.id === nextContent?.parentLearningSequence?.id) {
|
||||
this.openLearningContent(nextContent);
|
||||
} else {
|
||||
this.closeSelfEvaluation();
|
||||
}
|
||||
} else {
|
||||
this.closeSelfEvaluation();
|
||||
}
|
||||
} else {
|
||||
log.error('currentSelfEvaluation is undefined');
|
||||
}
|
||||
this.closeSelfEvaluation()
|
||||
// if (this.currentSelfEvaluation) {
|
||||
// const nextContent = this.currentSelfEvaluation.learningContents[this.currentSelfEvaluation.learningContents.length - 1].nextLearningContent;
|
||||
//
|
||||
// if (nextContent) {
|
||||
// if (this.currentSelfEvaluation?.parentLearningSequence?.id === nextContent?.parentLearningSequence?.id) {
|
||||
// this.openLearningContent(nextContent);
|
||||
// } else {
|
||||
// this.closeSelfEvaluation();
|
||||
// }
|
||||
// } else {
|
||||
// this.closeSelfEvaluation();
|
||||
// }
|
||||
// } else {
|
||||
// log.error('currentSelfEvaluation is undefined');
|
||||
// }
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import LearningContent from '@/components/circle/LearningContent.vue'
|
|||
|
||||
import { onMounted } from 'vue'
|
||||
import { useCircleStore } from '@/stores/circle'
|
||||
import SelfEvaluation from '@/components/circle/SelfEvaluation.vue'
|
||||
import { useAppStore } from '@/stores/app'
|
||||
|
||||
log.debug('CircleView.vue created')
|
||||
|
||||
|
|
@ -16,6 +16,9 @@ const props = defineProps<{
|
|||
circleSlug: string
|
||||
}>()
|
||||
|
||||
const appStore = useAppStore()
|
||||
appStore.showMainNavigationBar = true
|
||||
|
||||
const circleStore = useCircleStore()
|
||||
|
||||
onMounted(async () => {
|
||||
|
|
@ -42,9 +45,6 @@ onMounted(async () => {
|
|||
<div v-if="circleStore.page === 'LEARNING_CONTENT'">
|
||||
<LearningContent :key="circleStore.currentLearningContent.translation_key" />
|
||||
</div>
|
||||
<div v-else-if="circleStore.page === 'SELF_EVALUATION'">
|
||||
<SelfEvaluation :key="circleStore.currentSelfEvaluation.translation_key" />
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="circle-container">
|
||||
<div class="circle">
|
||||
|
|
|
|||
|
|
@ -0,0 +1,59 @@
|
|||
<script setup lang="ts">
|
||||
import * as log from 'loglevel'
|
||||
import { onMounted, reactive, watch } from 'vue'
|
||||
import { useCircleStore } from '@/stores/circle'
|
||||
import { useAppStore } from '@/stores/app'
|
||||
import LearningContent from '@/components/circle/LearningContent.vue'
|
||||
import { LearningContent as LearningContentType } from '@/types'
|
||||
|
||||
log.debug('LearningContentView created')
|
||||
|
||||
const props = defineProps<{
|
||||
learningPathSlug: string
|
||||
circleSlug: string
|
||||
contentSlug: string
|
||||
}>()
|
||||
|
||||
const state: { learningContent?: LearningContentType } = reactive({})
|
||||
|
||||
const appStore = useAppStore()
|
||||
appStore.showMainNavigationBar = false
|
||||
|
||||
const circleStore = useCircleStore()
|
||||
|
||||
const loadLearningContent = async () => {
|
||||
try {
|
||||
state.learningContent = await circleStore.loadLearningContent(
|
||||
props.learningPathSlug,
|
||||
props.circleSlug,
|
||||
props.contentSlug
|
||||
)
|
||||
} catch (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>
|
||||
|
||||
<template>
|
||||
<LearningContent v-if="state.learningContent" :learning-content="state.learningContent" />
|
||||
</template>
|
||||
|
||||
<style lang="postcss" scoped></style>
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
<script setup lang="ts">
|
||||
import * as log from 'loglevel'
|
||||
|
||||
import SelfEvaluation from '@/components/circle/SelfEvaluation.vue'
|
||||
|
||||
import { onMounted, reactive } from 'vue'
|
||||
import { useAppStore } from '@/stores/app'
|
||||
import { useCircleStore } from '@/stores/circle'
|
||||
import type { LearningUnit } from '@/types'
|
||||
|
||||
log.debug('LearningUnitSelfEvaluationView created')
|
||||
|
||||
const props = defineProps<{
|
||||
learningPathSlug: string
|
||||
circleSlug: string
|
||||
learningUnitSlug: string
|
||||
}>()
|
||||
|
||||
const appStore = useAppStore()
|
||||
appStore.showMainNavigationBar = false
|
||||
|
||||
const circleStore = useCircleStore()
|
||||
|
||||
const state: { learningUnit?: LearningUnit } = reactive({})
|
||||
|
||||
onMounted(async () => {
|
||||
log.debug('LearningUnitSelfEvaluationView mounted', props.learningPathSlug, props.circleSlug, props.learningUnitSlug)
|
||||
|
||||
try {
|
||||
state.learningUnit = await circleStore.loadSelfEvaluation(
|
||||
props.learningPathSlug,
|
||||
props.circleSlug,
|
||||
props.learningUnitSlug
|
||||
)
|
||||
} catch (error) {
|
||||
log.error(error)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<SelfEvaluation v-if="state.learningUnit" :learning-unit="state.learningUnit" />
|
||||
</template>
|
||||
|
||||
<style lang="postcss" scoped></style>
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
import {fileURLToPath, URL} from 'url'
|
||||
import { fileURLToPath, URL } from "url";
|
||||
|
||||
import {defineConfig, loadEnv} from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import { defineConfig, loadEnv } from "vite";
|
||||
import vue from "@vitejs/plugin-vue";
|
||||
// import vueI18n from '@intlify/vite-plugin-vue-i18n'
|
||||
import alias from '@rollup/plugin-alias'
|
||||
import alias from "@rollup/plugin-alias";
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig(({ mode }) => {
|
||||
|
|
@ -33,6 +33,10 @@ export default defineConfig(({ mode }) => {
|
|||
// ]
|
||||
}),
|
||||
],
|
||||
server: {
|
||||
port: 5173,
|
||||
hmr: { port: 5173 }
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': fileURLToPath(new URL('./src', import.meta.url)),
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ django-csp==3.7
|
|||
# via -r requirements.in
|
||||
django-debug-toolbar==3.2.4
|
||||
# via -r requirements-dev.in
|
||||
django-extensions==3.1.5
|
||||
django-extensions==3.2.0
|
||||
# via -r requirements-dev.in
|
||||
django-filter==21.1
|
||||
# via wagtail
|
||||
|
|
@ -428,9 +428,9 @@ wagtail-factories==2.0.1
|
|||
# via -r requirements.in
|
||||
wagtail-localize==1.2.1
|
||||
# via -r requirements.in
|
||||
watchdog==2.1.7
|
||||
watchdog==2.1.9
|
||||
# via werkzeug
|
||||
watchgod==0.8.1
|
||||
watchgod==0.8.2
|
||||
# via
|
||||
# -r requirements-dev.in
|
||||
# uvicorn
|
||||
|
|
@ -440,7 +440,7 @@ webencodings==0.5.1
|
|||
# via html5lib
|
||||
websockets==10.2
|
||||
# via uvicorn
|
||||
werkzeug[watchdog]==2.1.0
|
||||
werkzeug[watchdog]==2.2.0
|
||||
# via -r requirements-dev.in
|
||||
wheel==0.37.1
|
||||
# via pip-tools
|
||||
|
|
|
|||
Loading…
Reference in New Issue