280 lines
7.6 KiB
Vue
280 lines
7.6 KiB
Vue
<template>
|
|
<div class="knowledgeBox topSpace">
|
|
<section class="teaserBox">
|
|
<div class="container">
|
|
<h1>Digital Insights Magazin</h1>
|
|
<h2>Wissenswertes rund um moderne Weblösungen</h2>
|
|
<p>Hier finden Sie praxisnahe Beiträge zu Technik, Strategie und Gestaltung im Web. Wir bieten wertvolle Impulse und aktuelles Wissen,
|
|
damit Sie gut informiert sind und fundierte Entscheidungen für Ihre Webprojekte treffen können.
|
|
</p>
|
|
<div class="selectionZone">
|
|
<button
|
|
:class="{ active: isAllSelected }"
|
|
@click="selectAll"
|
|
>
|
|
Alle
|
|
</button>
|
|
<button
|
|
v-for="category in categories"
|
|
:key="category.id"
|
|
:class="{ active: selectedCategories.has(category.id) }"
|
|
@click="toggleCategory(category.id)"
|
|
>
|
|
{{ category.name }}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="articleBox container">
|
|
<transition-group
|
|
name="article"
|
|
tag="div"
|
|
class="grid"
|
|
appear
|
|
>
|
|
<div
|
|
v-for="article in filteredArticles"
|
|
:key="article.id"
|
|
class="article"
|
|
>
|
|
<NuxtLinkLocale
|
|
:to="localePath({ name: 'article-link', params: { link: article.slug } })"
|
|
class="article-link"
|
|
>
|
|
<div class="image-wrapper">
|
|
<NuxtImg
|
|
v-if="article.image?.url"
|
|
:src="article.image.url"
|
|
provider="strapi"
|
|
:alt="article.image.alternativeText"
|
|
format="webp"
|
|
class="article-image"
|
|
/>
|
|
<div class="overlay">
|
|
<h2>{{ article.header }}</h2>
|
|
</div>
|
|
<button class="btn mintBtn">{{ $t('pages.magazin.readmore') }}</button>
|
|
</div>
|
|
</NuxtLinkLocale>
|
|
</div>
|
|
</transition-group>
|
|
</section>
|
|
|
|
</div>
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
import { useMainStore } from '@/stores/main'
|
|
import { storeToRefs } from 'pinia'
|
|
import { useLocalePath } from '#i18n'
|
|
const localePath = useLocalePath()
|
|
|
|
const mainStore = useMainStore()
|
|
const { articles, categories } = storeToRefs(mainStore)
|
|
|
|
const truncateText = (text: string, length = 200) =>
|
|
text?.length > length ? text.substring(0, length) + '…' : text
|
|
|
|
const currentDomain = typeof window !== 'undefined'
|
|
? window.location.origin
|
|
: 'https://www.digimedialoop.de'
|
|
|
|
const selectedCategories = ref<Set<number>>(new Set())
|
|
|
|
const isAllSelected = computed(() => selectedCategories.value.size === 0)
|
|
|
|
function toggleCategory(categoryId: number) {
|
|
if (selectedCategories.value.has(categoryId)) {
|
|
selectedCategories.value.delete(categoryId)
|
|
} else {
|
|
selectedCategories.value.add(categoryId)
|
|
}
|
|
}
|
|
|
|
function selectAll() {
|
|
selectedCategories.value.clear()
|
|
}
|
|
|
|
const filteredArticles = computed(() => {
|
|
if (isAllSelected.value) return articles.value
|
|
return articles.value.filter(article => {
|
|
if (!article.categories || article.categories.length === 0) return false
|
|
return article.categories.some(cat => selectedCategories.value.has(cat.id))
|
|
})
|
|
})
|
|
|
|
// SEO: JSON-LD für Artikelübersicht
|
|
watch(articles, (newVal) => {
|
|
if (newVal?.length) {
|
|
useHead({
|
|
script: [
|
|
{
|
|
type: 'application/ld+json',
|
|
children: JSON.stringify({
|
|
"@context": "https://schema.org",
|
|
"@type": "ItemList",
|
|
itemListElement: newVal.map((article, index) => ({
|
|
"@type": "ListItem",
|
|
position: index + 1,
|
|
url: `${currentDomain}/wissenswertes/artikel/${article.slug}`,
|
|
name: article.header,
|
|
}))
|
|
})
|
|
}
|
|
]
|
|
})
|
|
}
|
|
}, { immediate: true })
|
|
</script>
|
|
|
|
|
|
<style lang="sass">
|
|
.knowledgeBox
|
|
h1
|
|
margin: 2rem 0 0 0
|
|
h2
|
|
margin: 0 0 0 0
|
|
.selectionZone
|
|
border: 1px solid $lightgrey
|
|
border-radius: 1rem
|
|
padding: 1rem 1.5rem 0 1.5rem
|
|
background-color: lighten($beige, 5%)
|
|
margin: 0 0 4rem 0
|
|
button
|
|
all: unset
|
|
background-color: white
|
|
padding: .5rem 1.5rem
|
|
border-radius: .8rem
|
|
margin: 0 1rem 1rem 0
|
|
box-shadow: 1px 1px 1px 0 rgba(black, .3)
|
|
border: 1px solid darken($lightgrey, 8%)
|
|
transition: .5s
|
|
cursor: pointer
|
|
|
|
&:hover
|
|
transform: scale(1.05)
|
|
|
|
&.active
|
|
font-family: 'Mainfont-Bold'
|
|
box-shadow: 0 0 2px 0 rgba(black, .3)
|
|
background-color: darken($lightgrey, 10%)
|
|
border: 1px solid darken($lightgrey, 25%)
|
|
|
|
.articleBox
|
|
display: flex
|
|
justify-content: center
|
|
width: (9)0%
|
|
|
|
|
|
.grid
|
|
display: grid
|
|
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr))
|
|
gap: 2.5rem
|
|
justify-content: start
|
|
width: 100%
|
|
max-width: 100%
|
|
margin: 0 auto
|
|
transition: all 0.3s ease-in-out // weichere Umordnung der Items
|
|
|
|
.article
|
|
width: 100%
|
|
max-width: 500px
|
|
border: 1px solid $beige
|
|
background: linear-gradient(to bottom right, white, $lightgrey)
|
|
border-radius: 1rem
|
|
position: relative
|
|
display: flex
|
|
flex-direction: column
|
|
align-items: flex-start
|
|
overflow: hidden
|
|
cursor: pointer
|
|
transition: transform 0.3s ease, opacity 0.3s ease
|
|
|
|
&:hover
|
|
transform: scale(1.05)
|
|
|
|
.article-enter-from,
|
|
.article-leave-to
|
|
opacity: 0
|
|
transform: scale(0.85)
|
|
|
|
.article-enter-active,
|
|
.article-leave-active
|
|
transition: all 0.3s ease
|
|
|
|
|
|
.article-link
|
|
position: relative
|
|
display: block
|
|
color: white
|
|
text-decoration: none
|
|
|
|
.image-wrapper
|
|
position: relative
|
|
width: 100%
|
|
height: 220px
|
|
border: 1px solid $lightgrey
|
|
|
|
.article-image
|
|
width: 100%
|
|
height: 500px
|
|
object-fit: cover
|
|
border-top-left-radius: 1rem
|
|
border-top-right-radius: 1rem
|
|
opacity: .6
|
|
|
|
button
|
|
position: absolute
|
|
bottom: .6rem
|
|
right: 0rem
|
|
border: 1px solid $darkgrey
|
|
font-size: 1rem
|
|
box-shadow: 1px 1px 4px 2px rgba(black, .2)
|
|
background-color: lighten($darkgrey, 10%)
|
|
letter-spacing: .05rem
|
|
|
|
|
|
.overlay
|
|
position: absolute
|
|
top: 0
|
|
left: 0
|
|
width: 80%
|
|
height: auto
|
|
min-height: 80%
|
|
background-image: linear-gradient(to bottom right, rgba(darken(white, 0), 1), rgba(darken($beige, 0), 0.9) )
|
|
margin: 0 20% 7rem 0
|
|
display: flex
|
|
flex-direction: column
|
|
align-items: center
|
|
justify-content: flex-start
|
|
padding: 1rem
|
|
border-top-left-radius: 1rem
|
|
border-bottom-right-radius: 50%
|
|
//border: 1px solid darken($beige, 10%)
|
|
//border-radius: .5rem
|
|
text-align: left
|
|
transition: .3s
|
|
box-shadow: 2px 2px 5px 3px rgba(black, .2)
|
|
|
|
|
|
h2
|
|
color: $darkgrey
|
|
font-size: 1rem
|
|
line-height: 140%
|
|
font-family: 'Mainfont-Bold'
|
|
margin: .2rem 1rem
|
|
//text-transform: uppercase
|
|
hyphens: auto
|
|
|
|
.mintBtn
|
|
background-color: $primaryColor
|
|
color: white
|
|
font-size: 0.9rem
|
|
font-family: 'Mainfont-Bold'
|
|
border: none
|
|
padding: 0.4rem 1rem
|
|
border-radius: 0.3rem
|
|
cursor: pointer
|
|
</style> |