Add info block for teachers

Also refactor CirclePage

Resolves VBV-310
This commit is contained in:
Ramon Wenger 2023-04-27 11:55:45 +02:00
parent 96334b4eb6
commit 0bae4a8cb2
3 changed files with 132 additions and 110 deletions

View File

@ -16,6 +16,10 @@
"modalNameInformation": "Max. 70 Zeichen", "modalNameInformation": "Max. 70 Zeichen",
"selectFile": "Bitte wähle eine Datei aus", "selectFile": "Bitte wähle eine Datei aus",
"title": "Unterlagen", "title": "Unterlagen",
"trainerDescription": "Finde auf Teams zusätzliche Inhalte für deinen Unterricht.",
"trainerLinkSrc": "https://teams.microsoft.com",
"trainerLinkText": "Inhalte auf Teams anschauen",
"trainerTitle": "Begleitung für Trainer",
"uploadErrorMessage": "Beim Hochladen ist ein Fehler aufgetreten. Bitte versuche es erneut.", "uploadErrorMessage": "Beim Hochladen ist ein Fehler aufgetreten. Bitte versuche es erneut.",
"userDescription": "Hier findest du die Unterlagen, die dir die Fachexpertin zur Verfügung gestellt hat." "userDescription": "Hier findest du die Unterlagen, die dir die Fachexpertin zur Verfügung gestellt hat."
}, },

View File

@ -1,31 +1,29 @@
<script setup lang="ts"> <script setup lang="ts">
import ItModal from "@/components/ui/ItModal.vue"; import log from "loglevel";
import * as log from "loglevel"; import { computed, onMounted } from "vue";
import { computed, onMounted, ref, watch } from "vue";
import CircleDiagram from "./CircleDiagram.vue"; import CircleDiagram from "./CircleDiagram.vue";
import CircleOverview from "./CircleOverview.vue"; import CircleOverview from "./CircleOverview.vue";
import DocumentUploadForm from "./DocumentUploadForm.vue"; import DocumentBlock from "./DocumentBlock.vue";
import LearningSequence from "./LearningSequence.vue"; import LearningSequence from "./LearningSequence.vue";
import { uploadCircleDocument } from "@/services/files";
import { useAppStore } from "@/stores/app"; import { useAppStore } from "@/stores/app";
import { useCircleStore } from "@/stores/circle"; import { useCircleStore } from "@/stores/circle";
import { useCourseSessionsStore } from "@/stores/courseSessions"; import { useCourseSessionsStore } from "@/stores/courseSessions";
import type { CourseSessionUser, DocumentUploadData } from "@/types"; import type { CourseSessionUser } from "@/types";
import { humanizeDuration } from "@/utils/humanizeDuration"; import { humanizeDuration } from "@/utils/humanizeDuration";
import sumBy from "lodash/sumBy"; import sumBy from "lodash/sumBy";
import { useRoute } from "vue-router"; import { useRoute } from "vue-router";
const route = useRoute(); export interface Props {
const courseSessionsStore = useCourseSessionsStore();
interface Props {
courseSlug: string; courseSlug: string;
circleSlug: string; circleSlug: string;
profileUser?: CourseSessionUser; profileUser?: CourseSessionUser;
readonly?: boolean; readonly?: boolean;
} }
const route = useRoute();
const courseSessionsStore = useCourseSessionsStore();
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
readonly: false, readonly: false,
profileUser: undefined, profileUser: undefined,
@ -33,10 +31,6 @@ const props = withDefaults(defineProps<Props>(), {
log.debug("CirclePage created", props.readonly, props.profileUser); log.debug("CirclePage created", props.readonly, props.profileUser);
const showUploadModal = ref(false);
const showUploadErrorMessage = ref(false);
const isUploading = ref(false);
const appStore = useAppStore(); const appStore = useAppStore();
appStore.showMainNavigationBar = true; appStore.showMainNavigationBar = true;
@ -51,15 +45,6 @@ const duration = computed(() => {
return ""; return "";
}); });
const dropdownLearningSequences = computed(() =>
circleStore.circle?.learningSequences.map((sequence) => ({
id: sequence.id,
name: sequence.title,
}))
);
watch(showUploadModal, (_v) => (showUploadErrorMessage.value = false));
onMounted(async () => { onMounted(async () => {
log.debug( log.debug(
"CirclePage mounted", "CirclePage mounted",
@ -107,28 +92,6 @@ onMounted(async () => {
log.error(error); log.error(error);
} }
}); });
async function uploadDocument(data: DocumentUploadData) {
isUploading.value = true;
showUploadErrorMessage.value = false;
try {
if (!courseSessionsStore.currentCourseSession) {
throw new Error("No course session found");
}
const newDocument = await uploadCircleDocument(
data,
courseSessionsStore.currentCourseSession.id
);
const courseSessionStore = useCourseSessionsStore();
courseSessionStore.addDocument(newDocument);
showUploadModal.value = false;
isUploading.value = false;
} catch (error) {
log.error(error);
showUploadErrorMessage.value = true;
isUploading.value = false;
}
}
</script> </script>
<template> <template>
@ -213,60 +176,7 @@ async function uploadDocument(data: DocumentUploadData) {
{{ $t("circlePage.learnMore") }} {{ $t("circlePage.learnMore") }}
</button> </button>
</div> </div>
<div v-if="!props.readonly" class="mt-8 block border p-6"> <DocumentBlock v-if="!readonly" />
<h3 class="text-blue-dark">
{{ $t("circlePage.documents.title") }}
</h3>
<div v-if="!courseSessionsStore.canUploadCircleDocuments">
<div class="mt-4 leading-relaxed">
{{ $t("circlePage.documents.userDescription") }}
</div>
</div>
<ol
v-if="
courseSessionsStore &&
courseSessionsStore.circleDocuments &&
courseSessionsStore.circleDocuments.length > 0
"
>
<li
v-for="learningSequence of courseSessionsStore.circleDocuments"
:key="learningSequence.id"
>
<h4 class="text-bold mt-4">{{ learningSequence.title }}</h4>
<ul>
<li
v-for="document of learningSequence.documents"
:key="document.url"
>
<a :href="document.url" download>
<span>{{ document.name }}</span>
</a>
<button
v-if="courseSessionsStore.canUploadCircleDocuments"
type="button"
class="relative top-[1px] ml-2 inline-block h-3 w-3 cursor-pointer leading-6"
@click="courseSessionsStore.removeDocument(document.id)"
>
<it-icon-close class="h-3 w-3"></it-icon-close>
</button>
</li>
</ul>
</li>
</ol>
<div v-if="courseSessionsStore.canUploadCircleDocuments">
<div class="mt-4 leading-relaxed">
{{ $t("circlePage.documents.expertDescription") }}
</div>
<button
class="btn-primary mt-4 text-xl"
@click="showUploadModal = true"
>
{{ $t("circlePage.documents.action") }}
</button>
</div>
</div>
<div v-if="!props.readonly" class="expert mt-8 border p-6"> <div v-if="!props.readonly" class="expert mt-8 border p-6">
<h3 class="text-blue-dark">{{ $t("circlePage.gotQuestions") }}</h3> <h3 class="text-blue-dark">{{ $t("circlePage.gotQuestions") }}</h3>
<div class="mt-4 leading-relaxed"> <div class="mt-4 leading-relaxed">
@ -312,17 +222,6 @@ async function uploadDocument(data: DocumentUploadData) {
</div> </div>
</div> </div>
</div> </div>
<ItModal v-model="showUploadModal">
<template #title>{{ $t("circlePage.documents.action") }}</template>
<template #body>
<DocumentUploadForm
:learning-sequences="dropdownLearningSequences"
:show-upload-error-message="showUploadErrorMessage"
:is-uploading="isUploading"
@form-submit="uploadDocument"
/>
</template>
</ItModal>
</div> </div>
</Transition> </Transition>
</div> </div>

View File

@ -0,0 +1,119 @@
<template>
<div class="mt-8 block border p-6">
<!-- documents block -->
<h3 class="text-blue-dark">
{{ $t("circlePage.documents.title") }}
</h3>
<div v-if="!courseSessionsStore.canUploadCircleDocuments">
<div class="mt-4 leading-relaxed">
{{ $t("circlePage.documents.userDescription") }}
</div>
</div>
<ol
v-if="
courseSessionsStore &&
courseSessionsStore.circleDocuments &&
courseSessionsStore.circleDocuments.length > 0
"
>
<li
v-for="learningSequence of courseSessionsStore.circleDocuments"
:key="learningSequence.id"
>
<h4 class="text-bold mt-4">{{ learningSequence.title }}</h4>
<ul>
<li v-for="document of learningSequence.documents" :key="document.url">
<a :href="document.url" download>
<span>{{ document.name }}</span>
</a>
<button
v-if="courseSessionsStore.canUploadCircleDocuments"
type="button"
class="relative top-[1px] ml-2 inline-block h-3 w-3 cursor-pointer leading-6"
@click="courseSessionsStore.removeDocument(document.id)"
>
<it-icon-close class="h-3 w-3"></it-icon-close>
</button>
</li>
</ul>
</li>
</ol>
<div v-if="courseSessionsStore.canUploadCircleDocuments">
<div class="mt-4 leading-relaxed">
{{ $t("circlePage.documents.expertDescription") }}
</div>
<button class="btn-primary mt-4 text-xl" @click="showUploadModal = true">
{{ $t("circlePage.documents.action") }}
</button>
</div>
</div>
<ItModal v-model="showUploadModal">
<template #title>{{ $t("circlePage.documents.action") }}</template>
<template #body>
<DocumentUploadForm
:learning-sequences="dropdownLearningSequences"
:show-upload-error-message="showUploadErrorMessage"
:is-uploading="isUploading"
@form-submit="uploadDocument"
/>
</template>
</ItModal>
<div
v-if="courseSessionsStore.canUploadCircleDocuments"
class="mt-8 flex flex-col gap-y-4 border p-6"
>
<h3 class="text-blue-dark">
{{ $t("circlePage.documents.trainerTitle") }}
</h3>
<div class="leading-relaxed">
{{ $t("circlePage.documents.trainerDescription") }}
</div>
<a target="_blank" class="link" :href="$t('circlePage.documents.trainerLinkSrc')">
{{ $t("circlePage.documents.trainerLinkText") }}
</a>
</div>
</template>
<script setup lang="ts">
import ItModal from "@/components/ui/ItModal.vue";
import { uploadCircleDocument } from "@/services/files";
import { useCircleStore } from "@/stores/circle";
import { useCourseSessionsStore } from "@/stores/courseSessions";
import type { DocumentUploadData } from "@/types";
import log from "loglevel";
import { computed, ref, watch } from "vue";
import DocumentUploadForm from "./DocumentUploadForm.vue";
const courseSessionsStore = useCourseSessionsStore();
const circleStore = useCircleStore();
const showUploadModal = ref(false);
const showUploadErrorMessage = ref(false);
const isUploading = ref(false);
const dropdownLearningSequences = computed(() =>
circleStore.circle?.learningSequences.map((sequence) => ({
id: sequence.id,
name: sequence.title,
}))
);
watch(showUploadModal, () => (showUploadErrorMessage.value = false));
async function uploadDocument(data: DocumentUploadData) {
isUploading.value = true;
showUploadErrorMessage.value = false;
try {
if (!courseSessionsStore.currentCourseSession) {
throw new Error("No course session found");
}
const newDocument = await uploadCircleDocument(
data,
courseSessionsStore.currentCourseSession.id
);
const courseSessionStore = useCourseSessionsStore();
courseSessionStore.addDocument(newDocument);
showUploadModal.value = false;
isUploading.value = false;
} catch (error) {
log.error(error);
showUploadErrorMessage.value = true;
isUploading.value = false;
}
}
</script>