Show circle in frontend with new data

This commit is contained in:
Daniel Egger 2022-06-03 18:18:41 +02:00
parent 20d10da944
commit d559921038
7 changed files with 113 additions and 12 deletions

View File

@ -1,15 +1,43 @@
<script setup>
<script setup lang="ts">
import IconCheckboxUnchecked from '@/components/icons/IconCheckboxUnchecked.vue';
import IconSmileyNeutral from '@/components/icons/IconSmileyNeutral.vue';
defineProps(['learningSequence'])
</script>
<template>
<div class="mb-8 learning-sequence">
<h3 class="mb-2 text-xl">{{ learningSequence.title }}</h3>
<div class="flex items-center gap-4 mb-2">
<component :is="learningSequence.icon" />
<h3 class="text-xl">
{{ learningSequence.title }}
</h3>
<div>{{ learningSequence.minutes }} Minuten</div>
</div>
<div class="bg-white px-4 border border-gray-500 border-l-4 border-l-sky-500">
<div
v-for="learningPackage in learningSequence.learningPackages"
class="py-3"
>
<div class="pb-3 flex gap-4" v-if="learningPackage.title">
<div class="font-bold">{{ learningPackage.title }}</div>
<div>{{ learningPackage.minutes }} Minuten</div>
</div>
<div
v-for="learningUnit in learningPackage.learningUnits"
class="flex items-center gap-4 pb-3"
>
<IconSmileyNeutral v-if="learningUnit.contents[0].type === 'self_evaluation'"/>
<IconCheckboxUnchecked v-else/>
<div>{{ learningUnit.title }}</div>
</div>
<hr class="-mx-4 text-gray-500">
<div class="bg-white p-4 border border-slate-300 border-l-4 border-l-blue-500">
<div v-for="learningUnit in learningSequence.learningUnits">
{{ learningUnit.title }}
</div>
</div>
</div>

View File

@ -0,0 +1,7 @@
<template>
<svg width="30" height="30" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="1" y="1" width="28" height="28" rx="1" stroke="#00224D" stroke-width="2"/>
<path d="M12.1529 18.7528L8.30897 14.9088L7 16.2086L12.1529 21.3615L23.2147 10.2998L21.9149 9L12.1529 18.7528Z"
fill="#00224D"/>
</svg>
</template>

View File

@ -0,0 +1,5 @@
<template>
<svg width="30" height="30" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="1" y="1" width="28" height="28" rx="1" stroke="#B1C1CA" stroke-width="2"/>
</svg>
</template>

View File

@ -5,6 +5,14 @@ import {setupI18n} from './i18n'
import App from './App.vue'
import router from './router'
import IconLsApply from '@/components/icons/IconLsApply.vue';
import IconLsWatch from '@/components/icons/IconLsWatch.vue';
import IconLsTest from '@/components/icons/IconLsTest.vue';
import IconLsPractice from '@/components/icons/IconLsPractice.vue';
import IconLsNetwork from '@/components/icons/IconLsNetwork.vue';
import IconLsStart from '@/components/icons/IconLsStart.vue';
import IconLsEnd from '@/components/icons/IconLsEnd.vue';
import '@/assets/styles/index.scss'
const i18n = setupI18n()
@ -18,3 +26,12 @@ app.use(router)
app.use(i18n)
app.mount('#app')
// register icons globally
app.component('IconLsApply', IconLsApply)
app.component('IconLsWatch', IconLsWatch)
app.component('IconLsTest', IconLsTest)
app.component('IconLsPractice', IconLsPractice)
app.component('IconLsNetwork', IconLsNetwork)
app.component('IconLsStart', IconLsStart)
app.component('IconLsEnd', IconLsEnd)

View File

@ -28,7 +28,7 @@ const router = createRouter({
},
{
path: '/circle/:circleSlug',
component: () => import('../views/Circle.vue'),
component: () => import('../views/CircleView.vue'),
props: true
},
{

View File

@ -16,7 +16,7 @@ export default {
}
},
mounted() {
log.debug('CircleAnalyseExampleView mounted', this.circleSlug);
log.debug('CircleView mounted', this.circleSlug);
axios({
method: 'get',
url: `/learnpath/api/circle/${this.circleSlug}/`,
@ -24,17 +24,47 @@ export default {
log.debug(response.data);
this.circleData = response.data;
let learningSequence = { learningUnits: [] };
// aggregate wagtail data into LearningSequence > LearningPackages > LearningUnit hierarchy
let learningSequence = null;
let learningPackageIndex = 0;
this.circleData.children.forEach((child) => {
if (child.type === 'learnpath.LearningSequence') {
if (learningSequence.learningUnits.length) {
if (learningSequence) {
this.learningSequences.push(learningSequence);
}
learningSequence = Object.assign(child, { learningUnits: [] });
learningSequence = Object.assign(child, { learningPackages: [] });
learningPackageIndex = 0;
} else {
learningSequence.learningUnits.push(child);
if (learningSequence.learningPackages.length === 0) {
learningSequence.learningPackages.push({
title: child.package,
learningUnits: [],
})
}
if (learningSequence.learningPackages[learningPackageIndex].title !== child.package) {
learningPackageIndex += 1;
learningSequence.learningPackages.push({
title: child.package,
learningUnits: [],
})
}
learningSequence.learningPackages[learningPackageIndex].learningUnits.push(child);
}
});
this.learningSequences.push(learningSequence);
// sum minutes
this.learningSequences.forEach((learningSequence) => {
learningSequence.minutes = 0;
learningSequence.learningPackages.forEach((learningPackage) => {
learningPackage.minutes = 0;
learningPackage.learningUnits.forEach((learningUnit) => {
learningPackage.minutes += learningUnit.minutes;
});
learningSequence.minutes += learningPackage.minutes;
});
});
log.debug(this.learningSequences);
});
}
@ -74,7 +104,7 @@ export default {
</div>
</div>
<div class="flex-auto bg-gray-100 px-4 py-8">
<div class="flex-auto bg-gray-100 px-4 py-8 lg:px-24">
<div v-for="learningSequence in learningSequences">
<LearningSequence :learning-sequence="learningSequence"></LearningSequence>
</div>

View File

@ -19,6 +19,8 @@ import IconArrowRight from '@/components/icons/IconArrowRight.vue';
import IconClose from '@/components/icons/IconClose.vue';
import IconCheck from '@/components/icons/IconCheck.vue';
import IconInfo from '@/components/icons/IconInfo.vue';
import IconCheckboxChecked from '@/components/icons/IconCheckboxChecked.vue';
import IconCheckboxUnchecked from '@/components/icons/IconCheckboxUnchecked.vue';
const colors = ['blue', 'sky', 'orange', 'green', 'red', 'gray',];
const colorValues = [100, 300, 500, 700, 900,];
@ -79,6 +81,18 @@ function colorBgClass(color: string, value: number) {
IconInfo
<IconInfo/>
</div>
<div>
IconCheckboxChecked
<IconCheckboxChecked/>
</div>
<div>
IconCheckboxUnchecked
<IconCheckboxUnchecked/>
</div>
</div>
<div class="mt-8 mb-8 flex gap-4">