skillbox/client/src/pages/activity.vue

262 lines
7.1 KiB
Vue

<template>
<div class="activity">
<h1 class="activity__heading">Meine Aktivitäten</h1>
<loading-message v-if="loading">Aktivitäten werden geladen</loading-message>
<template v-else>
<div class="activity__categories">
<a
class="activity__category default-link"
data-cy="activity-category"
:class="{ 'activity__category--active': selectedCategory === HIGHLIGHTS }"
@click="selectedCategory = HIGHLIGHTS"
>Markierungen</a
>
<a
class="activity__category default-link"
data-cy="activity-category"
:class="{ 'activity__category--active': selectedCategory === BOOKMARKS }"
@click="selectedCategory = BOOKMARKS"
>Lesezeichen</a
>
<a
class="activity__category default-link"
data-cy="activity-category"
:class="{ 'activity__category--active': selectedCategory === ASSIGNMENTS }"
@click="selectedCategory = ASSIGNMENTS"
>Ergebnisse</a
>
<a
class="activity__category default-link"
data-cy="activity-category"
:class="{ 'activity__category--active': selectedCategory === SURVEYS }"
@click="selectedCategory = SURVEYS"
>Übungen</a
>
</div>
<div class="activity__activities">
<instrument-activity-list
property="highlights"
:instruments="instruments"
v-if="selectedCategory === HIGHLIGHTS"
v-slot="{ item }"
>
<mark
class="highlight"
:class="[`highlight--${item?.color}`]"
>{{ item?.text }}</mark
>
<div v-if="item.note">Notiz: {{ item.note.text }}</div>
</instrument-activity-list>
<activity-list
:topics="highlightTopics"
property="myHighlights"
v-if="selectedCategory === HIGHLIGHTS"
v-slot="{ item }"
>
<mark
class="highlight"
:class="[`highlight--${item?.color}`]"
>{{ item?.text }}</mark
>
<div v-if="item.note">Notiz: {{ item.note.text }}</div>
</activity-list>
<instrument-activity-list
property="bookmarks"
:instruments="instruments"
v-if="selectedCategory === BOOKMARKS"
v-slot="{ item }"
>
<activity-bookmark :item="item" />
</instrument-activity-list>
<activity-list
:topics="bookmarkTopics"
property="myBookmarks"
v-if="selectedCategory === BOOKMARKS"
v-slot="{ item }"
>
<activity-bookmark :item="item" />
</activity-list>
<activity-list
:topics="submissionsTopics"
property="mySubmissions"
v-if="selectedCategory === ASSIGNMENTS"
v-slot="{ item }"
>
Submission: {{ item.text }}
</activity-list>
<activity-list
:topics="answersTopics"
property="myAnswers"
v-if="selectedCategory === SURVEYS"
v-slot="{ item }"
>
Übung: {{ item.survey.title }}
</activity-list>
</div>
</template>
</div>
</template>
<script setup lang="ts">
import { graphql } from '@/__generated__';
import { useQuery } from '@vue/apollo-composable';
import { ref, computed } from 'vue';
import ActivityList from '@/components/profile/ActivityList.vue';
import InstrumentActivityList from '@/components/profile/InstrumentActivityList.vue';
import LoadingMessage from '@/components/ui/LoadingMessage.vue';
import ActivityBookmark from '@/components/ActivityBookmark.vue';
import { TopicNode } from '@/__generated__/graphql';
const HIGHLIGHTS = 'highlights';
const BOOKMARKS = 'bookmarks';
const ASSIGNMENTS = 'assignments';
const SURVEYS = 'surveys';
const selectedCategory = ref(HIGHLIGHTS);
// todo: use fragments to simplify cache updates
const { result, loading } = useQuery(
graphql(`
query MyActivitiesQuery {
myActivities {
instruments {
id
slug
title
path
highlights {
...HighlightParts
}
bookmarks {
... on InstrumentBookmarkNode {
path
content
}
}
}
topics {
id
title
modules {
id
slug
title
metaTitle
myHighlights {
...HighlightParts
}
myBookmarks {
... on ChapterBookmarkNode {
chapter {
path
}
path
content
note {
id
text
}
}
... on ContentBlockBookmarkNode {
id
uuid
path
content
contentBlock {
id
path
}
note {
id
text
}
}
... on ModuleBookmarkNode {
path
content
note {
id
text
}
}
}
mySubmissions {
id
text
assignment {
id
title
path
module {
slug
}
}
}
myAnswers {
id
survey {
path
id
title
}
}
}
}
}
}
`)
);
const topics = computed(() => result.value?.myActivities?.topics || []);
const instruments = computed(() => result.value?.myActivities?.instruments || []);
const highlightTopics = computed(() => {
return topics.value.filter((topic: TopicNode) => topic.modules?.some((module) => module?.myHighlights?.length));
});
const bookmarkTopics = computed(() => {
return topics.value.filter((topic: TopicNode) => topic.modules?.some((module) => module?.myBookmarks?.length));
});
const submissionsTopics = computed(() => {
return topics.value.filter((topic: TopicNode) => topic.modules?.some((module) => module?.mySubmissions?.length));
});
const answersTopics = computed(() => {
return topics.value.filter((topic: TopicNode) => topic.modules?.some((module) => module?.myAnswers?.length));
});
</script>
<style lang="postcss">
.activity {
&__activities {
padding-top: var(--section-spacing);
}
&__heading {
margin-bottom: var(--section-spacing);
}
&__categories {
display: flex;
flex-direction: row;
border-bottom: 1px solid var(--color-silver);
padding-bottom: var(--medium-spacing);
}
&__category {
color: inherit;
flex-grow: 1;
&--active {
color: var(--color-brand);
}
}
&__module {
border-bottom: 1px solid var(--color-silver);
margin-bottom: var(--section-spacing);
}
&__entry {
padding: var(--medium-spacing) 0;
border-top: 1px solid var(--color-silver);
}
}
</style>