Add info block for teachers
Also refactor CirclePage Resolves VBV-310
This commit is contained in:
parent
96334b4eb6
commit
0bae4a8cb2
|
|
@ -16,6 +16,10 @@
|
|||
"modalNameInformation": "Max. 70 Zeichen",
|
||||
"selectFile": "Bitte wähle eine Datei aus",
|
||||
"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.",
|
||||
"userDescription": "Hier findest du die Unterlagen, die dir die Fachexpertin zur Verfügung gestellt hat."
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,31 +1,29 @@
|
|||
<script setup lang="ts">
|
||||
import ItModal from "@/components/ui/ItModal.vue";
|
||||
import * as log from "loglevel";
|
||||
import { computed, onMounted, ref, watch } from "vue";
|
||||
import log from "loglevel";
|
||||
import { computed, onMounted } from "vue";
|
||||
import CircleDiagram from "./CircleDiagram.vue";
|
||||
import CircleOverview from "./CircleOverview.vue";
|
||||
import DocumentUploadForm from "./DocumentUploadForm.vue";
|
||||
import DocumentBlock from "./DocumentBlock.vue";
|
||||
import LearningSequence from "./LearningSequence.vue";
|
||||
|
||||
import { uploadCircleDocument } from "@/services/files";
|
||||
import { useAppStore } from "@/stores/app";
|
||||
import { useCircleStore } from "@/stores/circle";
|
||||
import { useCourseSessionsStore } from "@/stores/courseSessions";
|
||||
import type { CourseSessionUser, DocumentUploadData } from "@/types";
|
||||
import type { CourseSessionUser } from "@/types";
|
||||
import { humanizeDuration } from "@/utils/humanizeDuration";
|
||||
import sumBy from "lodash/sumBy";
|
||||
import { useRoute } from "vue-router";
|
||||
|
||||
const route = useRoute();
|
||||
const courseSessionsStore = useCourseSessionsStore();
|
||||
|
||||
interface Props {
|
||||
export interface Props {
|
||||
courseSlug: string;
|
||||
circleSlug: string;
|
||||
profileUser?: CourseSessionUser;
|
||||
readonly?: boolean;
|
||||
}
|
||||
|
||||
const route = useRoute();
|
||||
const courseSessionsStore = useCourseSessionsStore();
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
readonly: false,
|
||||
profileUser: undefined,
|
||||
|
|
@ -33,10 +31,6 @@ const props = withDefaults(defineProps<Props>(), {
|
|||
|
||||
log.debug("CirclePage created", props.readonly, props.profileUser);
|
||||
|
||||
const showUploadModal = ref(false);
|
||||
const showUploadErrorMessage = ref(false);
|
||||
const isUploading = ref(false);
|
||||
|
||||
const appStore = useAppStore();
|
||||
appStore.showMainNavigationBar = true;
|
||||
|
||||
|
|
@ -51,15 +45,6 @@ const duration = computed(() => {
|
|||
return "";
|
||||
});
|
||||
|
||||
const dropdownLearningSequences = computed(() =>
|
||||
circleStore.circle?.learningSequences.map((sequence) => ({
|
||||
id: sequence.id,
|
||||
name: sequence.title,
|
||||
}))
|
||||
);
|
||||
|
||||
watch(showUploadModal, (_v) => (showUploadErrorMessage.value = false));
|
||||
|
||||
onMounted(async () => {
|
||||
log.debug(
|
||||
"CirclePage mounted",
|
||||
|
|
@ -107,28 +92,6 @@ onMounted(async () => {
|
|||
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>
|
||||
|
||||
<template>
|
||||
|
|
@ -213,60 +176,7 @@ async function uploadDocument(data: DocumentUploadData) {
|
|||
{{ $t("circlePage.learnMore") }}
|
||||
</button>
|
||||
</div>
|
||||
<div v-if="!props.readonly" class="mt-8 block border p-6">
|
||||
<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>
|
||||
|
||||
<DocumentBlock v-if="!readonly" />
|
||||
<div v-if="!props.readonly" class="expert mt-8 border p-6">
|
||||
<h3 class="text-blue-dark">{{ $t("circlePage.gotQuestions") }}</h3>
|
||||
<div class="mt-4 leading-relaxed">
|
||||
|
|
@ -312,17 +222,6 @@ async function uploadDocument(data: DocumentUploadData) {
|
|||
</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>
|
||||
</Transition>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
Loading…
Reference in New Issue