163 lines
5.3 KiB
Vue
163 lines
5.3 KiB
Vue
<script setup lang="ts">
|
|
import LinkCard from "@/components/mediaLibrary/LinkCard.vue";
|
|
import MediaLink from "@/components/mediaLibrary/MediaLink.vue";
|
|
import MLCategoryLayout from "@/pages/mediaLibrary/MLCategoryLayout.vue";
|
|
import { useMediaLibraryStore } from "@/stores/mediaLibrary";
|
|
import * as log from "loglevel";
|
|
import { computed } from "vue";
|
|
|
|
const props = defineProps<{
|
|
mediaCategorySlug: string;
|
|
}>();
|
|
|
|
log.debug("MediaCategoryDetailView created", props.mediaCategorySlug);
|
|
|
|
const mediaStore = useMediaLibraryStore();
|
|
|
|
const mediaCategory = computed(() => {
|
|
return mediaStore.mediaLibraryPage?.children.find((category) =>
|
|
category.slug.endsWith(props.mediaCategorySlug)
|
|
);
|
|
});
|
|
|
|
const maxCardItems = 4;
|
|
const maxListItems = 6;
|
|
|
|
const displayAsCard = (itemType: string): boolean => {
|
|
return itemType === "learn_media" || itemType === "relative_link";
|
|
};
|
|
|
|
const hasMoreItems = (items: object[], maxItems: number): boolean => {
|
|
return items.length > maxItems;
|
|
};
|
|
|
|
const getMaxDisplayItems = (items: object[], maxItems: number) => {
|
|
return items.slice(0, maxItems);
|
|
};
|
|
|
|
const getMaxDisplayItemsForType = (itemType: string, items: object[]) => {
|
|
return displayAsCard(itemType)
|
|
? getMaxDisplayItems(items, maxCardItems)
|
|
: getMaxDisplayItems(items, maxListItems);
|
|
};
|
|
|
|
const hasMoreItemsForType = (itemType: string, items: object[]) => {
|
|
const maxItems = displayAsCard(itemType) ? maxCardItems : maxListItems;
|
|
return hasMoreItems(items, maxItems);
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<Teleport v-if="mediaStore.mediaLibraryPage && mediaCategory" to="body">
|
|
<MLCategoryLayout>
|
|
<template #header>
|
|
<div class="flex justify-between">
|
|
<div class="lg:w-6/12">
|
|
<h3 class="font-normal text-large mb-3">Handlungsfeld</h3>
|
|
<h1 class="mb-4 lg:mb-8">{{ mediaCategory.title }}</h1>
|
|
<p class="text-xl">{{ mediaCategory.introduction_text }}</p>
|
|
</div>
|
|
<div>
|
|
<img
|
|
class="hidden lg:block float-right"
|
|
:src="'/static/icons/demo/category-large.png'"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<template #body>
|
|
<section class="mb-20 mt-8 lg:w-2/3">
|
|
<h2 class="mb-4">{{ mediaCategory.description_title }}</h2>
|
|
<p class="mb-4">{{ mediaCategory.description_text }}</p>
|
|
<ul>
|
|
<li
|
|
v-for="item in mediaCategory.items"
|
|
:key="item"
|
|
class="mb-2 flex items-center"
|
|
>
|
|
<it-icon-check
|
|
class="h-8 w-8 text-sky-500 mr-4 flex-none"
|
|
></it-icon-check>
|
|
{{ item.value }}
|
|
</li>
|
|
</ul>
|
|
</section>
|
|
|
|
<template
|
|
v-for="content_collection in mediaCategory.body"
|
|
:key="content_collection.value.title"
|
|
>
|
|
<section v-if="content_collection.value?.contents?.length" class="mb-20">
|
|
<h2 class="mb-4">{{ content_collection.value.title }}</h2>
|
|
<p class="mb-4 lg:w-2/3">
|
|
{{ content_collection.value.description }}
|
|
</p>
|
|
<ul
|
|
:class="{
|
|
'grid gap-4 grid-cols-1 lg:grid-cols-2': displayAsCard(
|
|
content_collection.value.contents[0].type
|
|
),
|
|
'border-t': !displayAsCard(content_collection.value.contents[0].type),
|
|
'mb-6': hasMoreItemsForType(
|
|
content_collection.value.contents[0].type,
|
|
content_collection.value.contents
|
|
),
|
|
}"
|
|
>
|
|
<li
|
|
v-for="mediaItem in getMaxDisplayItemsForType(
|
|
content_collection.value.contents[0].type,
|
|
content_collection.value.contents
|
|
)"
|
|
:key="mediaItem.id"
|
|
>
|
|
<LinkCard
|
|
v-if="displayAsCard(mediaItem.type)"
|
|
:title="mediaItem.value.title"
|
|
:icon="mediaItem.value.icon_url"
|
|
:description="mediaItem.value.description"
|
|
:url="mediaItem.value.url"
|
|
:link-text="mediaItem.value.link_display_text"
|
|
:open-window="mediaItem.value.open_window"
|
|
/>
|
|
<div v-else class="flex items-center justify-between border-b py-4">
|
|
<h4 class="text-bold">{{ mediaItem.value.title }}</h4>
|
|
<media-link
|
|
:blank="mediaItem.value.open_window"
|
|
:to="mediaItem.value.url"
|
|
class="link"
|
|
>{{ mediaItem.value.link_display_text }}
|
|
</media-link>
|
|
</div>
|
|
</li>
|
|
</ul>
|
|
<router-link
|
|
v-if="
|
|
hasMoreItemsForType(
|
|
content_collection.value.contents[0].type,
|
|
content_collection.value.contents
|
|
)
|
|
"
|
|
:to="`${mediaCategory.frontend_url}/media`"
|
|
class="flex items-center"
|
|
>
|
|
<span>Alle anschauen</span>
|
|
<it-icon-arrow-right></it-icon-arrow-right>
|
|
</router-link>
|
|
</section>
|
|
</template>
|
|
</template>
|
|
</MLCategoryLayout>
|
|
</Teleport>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.it-icon-hf {
|
|
color: blue;
|
|
}
|
|
|
|
.it-icon-hf > * {
|
|
@apply m-auto;
|
|
}
|
|
</style>
|