Refactor LearningContent component
This commit is contained in:
parent
aa6054a84e
commit
865e0d80f6
|
|
@ -4,12 +4,16 @@ import { useCircleStore } from "@/stores/circle";
|
|||
import type { LearningContent } from "@/types";
|
||||
import * as log from "loglevel";
|
||||
import { computed } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
|
||||
import DescriptionBlock from "@/components/learningPath/blocks/DescriptionBlock.vue";
|
||||
import DescriptionTextBlock from "@/components/learningPath/blocks/DescriptionTextBlock.vue";
|
||||
import FeedbackBlock from "@/components/learningPath/blocks/FeedbackBlock.vue";
|
||||
import IframeBlock from "@/components/learningPath/blocks/IframeBlock.vue";
|
||||
import PlaceholderBlock from "@/components/learningPath/blocks/PlaceholderBlock.vue";
|
||||
import VideoBlock from "@/components/learningPath/blocks/VideoBlock.vue";
|
||||
|
||||
log.debug("LearningContent.vue setup");
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
const circleStore = useCircleStore();
|
||||
|
||||
const props = defineProps<{
|
||||
|
|
@ -23,71 +27,45 @@ const block = computed(() => {
|
|||
|
||||
return undefined;
|
||||
});
|
||||
|
||||
// can't use the type as component name, as some are reserved HTML components, e.g. video
|
||||
const COMPONENTS: Record<string, InstanceType<typeof VideoBlock>> = {
|
||||
placeholder: PlaceholderBlock,
|
||||
video: VideoBlock,
|
||||
assignment: DescriptionTextBlock,
|
||||
resource: DescriptionTextBlock,
|
||||
exercise: IframeBlock,
|
||||
test: IframeBlock,
|
||||
learningmodule: IframeBlock,
|
||||
feedback: FeedbackBlock,
|
||||
};
|
||||
const DEFAULT_BLOCK = DescriptionBlock;
|
||||
|
||||
const component = computed(() => {
|
||||
if (block.value) {
|
||||
return COMPONENTS[block.value.type] || DEFAULT_BLOCK;
|
||||
}
|
||||
return DEFAULT_BLOCK;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="block">
|
||||
<LearningContentContainer
|
||||
:title="learningContent.title"
|
||||
:next-button-text="$t('learningContent.completeAndContinue')"
|
||||
:exit-text="$t('general.backToCircle')"
|
||||
@exit="circleStore.closeLearningContent(props.learningContent)"
|
||||
@next="circleStore.continueFromLearningContent(props.learningContent)"
|
||||
>
|
||||
<div class="content">
|
||||
<div
|
||||
v-if="
|
||||
block.type === 'exercise' ||
|
||||
block.type === 'test' ||
|
||||
block.type === 'learningmodule'
|
||||
"
|
||||
class="h-screen"
|
||||
>
|
||||
<iframe width="100%" height="100%" scrolling="no" :src="block.value.url" />
|
||||
</div>
|
||||
|
||||
<div v-else class="container-medium">
|
||||
<div v-if="block.type === 'video'">
|
||||
<iframe
|
||||
class="mt-8 w-full aspect-video"
|
||||
:src="block.value.url"
|
||||
:title="learningContent.title"
|
||||
frameborder="0"
|
||||
allow="accelerometer; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowfullscreen
|
||||
></iframe>
|
||||
</div>
|
||||
|
||||
<div v-else-if="block.type === 'media_library'" class="mt-4 lg:mt-12">
|
||||
<h1>{{ learningContent.title }}</h1>
|
||||
|
||||
<p class="text-large my-4 lg:my-8">{{ block.value.description }}</p>
|
||||
<router-link
|
||||
:to="`${block.value.url}?back=${route.path}`"
|
||||
class="button btn-primary"
|
||||
>
|
||||
Mediathek öffnen
|
||||
</router-link>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-else-if="block.type === 'resource' || block.type === 'assignment'"
|
||||
class="mt-4 lg:mt-12"
|
||||
>
|
||||
<p class="text-large my-4">{{ block.value.description }}</p>
|
||||
<div class="resource-text" v-html="block.value.text"></div>
|
||||
</div>
|
||||
|
||||
<div v-else-if="block.type === 'placeholder'" class="mt-4 lg:mt-12">
|
||||
<p class="text-large my-4">{{ block.value.description }}</p>
|
||||
<h1>{{ learningContent.title }}</h1>
|
||||
</div>
|
||||
|
||||
<div v-else class="text-large my-4">{{ block.value.description }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</LearningContentContainer>
|
||||
</div>
|
||||
<LearningContentContainer
|
||||
v-if="block"
|
||||
:title="learningContent.title"
|
||||
:next-button-text="$t('learningContent.completeAndContinue')"
|
||||
:exit-text="$t('general.backToCircle')"
|
||||
@exit="circleStore.closeLearningContent(props.learningContent)"
|
||||
@next="circleStore.continueFromLearningContent(props.learningContent)"
|
||||
>
|
||||
<div class="content">
|
||||
<component
|
||||
:is="component"
|
||||
:value="block.value"
|
||||
:content="learningContent"
|
||||
></component>
|
||||
</div>
|
||||
</LearningContentContainer>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
|||
|
|
@ -3,14 +3,14 @@ import * as log from "loglevel";
|
|||
|
||||
log.debug("LeariningContentContainer.vue setup");
|
||||
|
||||
const props = defineProps<{
|
||||
defineProps<{
|
||||
exitText: string;
|
||||
title: string;
|
||||
nextButtonText: string;
|
||||
showBackButton?: boolean;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits(["back", "next", "exit"]);
|
||||
defineEmits(["back", "next", "exit"]);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
<template>
|
||||
<div class="container-medium">
|
||||
<div class="mt-4 lg:mt-12">
|
||||
<p class="text-large my-4">{{ value.description }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { LearningContent } from "@/types";
|
||||
|
||||
interface Value {
|
||||
description: string;
|
||||
}
|
||||
|
||||
defineProps<{
|
||||
value: Value;
|
||||
content: LearningContent;
|
||||
}>();
|
||||
</script>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<template>
|
||||
<div class="container-medium">
|
||||
<div class="mt-4 lg:mt-12">
|
||||
<p class="text-large my-4">{{ value.description }}</p>
|
||||
<div class="resource-text" v-html="value.text"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { LearningContent } from "@/types";
|
||||
|
||||
interface Value {
|
||||
description: string;
|
||||
text: string;
|
||||
}
|
||||
|
||||
defineProps<{
|
||||
value: Value;
|
||||
content: LearningContent;
|
||||
}>();
|
||||
</script>
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
<template>
|
||||
<div class="container-medium">
|
||||
<div class="mt-4 lg:mt-12">
|
||||
<Feedback :page="content" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import Feedback from "@/components/Feedback.vue";
|
||||
import type { LearningContent } from "@/types";
|
||||
|
||||
interface Value {
|
||||
description: string;
|
||||
}
|
||||
|
||||
defineProps<{
|
||||
value: Value;
|
||||
content: LearningContent;
|
||||
}>();
|
||||
</script>
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
<template>
|
||||
<div
|
||||
class="h-screen"
|
||||
>
|
||||
<iframe width="100%" height="100%" scrolling="no" :src="value.url" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { LearningContent } from "@/types";
|
||||
|
||||
interface Value {
|
||||
url: string;
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
value: Value;
|
||||
content: LearningContent;
|
||||
}>();
|
||||
</script>
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
<template>
|
||||
<div class="container-medium">
|
||||
<div class="mt-4 lg:mt-12">
|
||||
<h1>{{ content.title }}</h1>
|
||||
|
||||
<p class="text-large my-4 lg:my-8">{{ value.description }}</p>
|
||||
<router-link :to="`${value.url}?back=${route.path}`" class="button btn-primary">
|
||||
Mediathek öffnen
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { LearningContent } from "@/types";
|
||||
import { useRoute } from "vue-router";
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
interface Value {
|
||||
description: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
defineProps<{
|
||||
value: Value;
|
||||
content: LearningContent;
|
||||
}>();
|
||||
</script>
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
<template>
|
||||
<div class="container-medium">
|
||||
<div class="mt-4 lg:mt-12">
|
||||
<p class="text-large my-4">{{ value.description }}</p>
|
||||
<h1>{{ content.title }}</h1>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { LearningContent } from "@/types";
|
||||
|
||||
interface Value {
|
||||
description: string;
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
value: Value;
|
||||
content: LearningContent;
|
||||
}>();
|
||||
</script>
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
<template>
|
||||
<div class="container-medium">
|
||||
<iframe
|
||||
class="mt-8 w-full aspect-video"
|
||||
:src="value.url"
|
||||
:title="content.title"
|
||||
frameborder="0"
|
||||
allow="accelerometer; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowfullscreen
|
||||
>
|
||||
</iframe>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { LearningContent } from "@/types";
|
||||
|
||||
interface Value {
|
||||
url: string;
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
value: Value;
|
||||
content: LearningContent;
|
||||
}>();
|
||||
</script>
|
||||
Loading…
Reference in New Issue