2025-06-18 19:33:21 +02:00

228 lines
6.3 KiB
Vue

<template>
<div v-if="article" class="article">
<SideBarNaviSlider link="/wissenswertes">
{{ $t('pages.article.artikelUebersicht') }}
</SideBarNaviSlider>
<NuxtImg
v-if="article.image?.url"
:src="article.image.url"
:alt="article.image.alternativeText || article.header"
class="img_background"
provider="strapi"
role="img"
/>
<div class="paper">
<p class="articleInfo">
<span><b>{{ $t('pages.article.autor') }}</b> {{ author }}</span> <span><b>{{ $t('pages.article.date') }}</b> {{ formattedDate }}</span>
</p>
<h1>{{ article.header }}</h1>
<NuxtImg
v-if="article.image?.url && screenWidth > 800"
:src="article.image.url"
:alt="article.image.alternativeText || article.header"
class="img_article"
provider="strapi"
role="img"
/>
<p class="teaser">{{ article.teaser }}</p>
<div class="content" v-html="htmlContent(article.content)"></div>
<button
class="btn pinkBtn"
role="button"
aria-label="Kontakt aufnehmen"
@click.prevent="toggleContactBubble"
>
{{ $t('pages.article.buttonText') }}
</button>
</div>
</div>
<section v-else class="container topSpace">
<p>{{ $t('pages.article.ladenOderNichtGefunden') }}</p>
</section>
</template>
<script setup>
definePageMeta({
name: 'article-link'
})
import { computed } from 'vue'
import { useRoute } from 'vue-router'
import { useMainStore } from '@/stores/main'
import { storeToRefs } from 'pinia'
import { useHtmlConverter } from '@/composables/useHTMLConverter'
import SideBarNaviSlider from '@/components/SideBarNaviSlider.vue'
import { useI18n } from 'vue-i18n'
const runtimeConfig = useRuntimeConfig();
const route = useRoute()
const slug = route.params.link
console.log(slug)
const mainStore = useMainStore()
const { articles } = storeToRefs(mainStore)
const { t } = useI18n()
const screenWidth = computed(() => mainStore.screenWidth)
// Artikel suchen
const article = computed(() => {
if (!articles.value) return null
return articles.value.find(item => item.slug === slug) ?? null
})
const { convertToHTML } = useHtmlConverter()
const htmlContent = (content) => convertToHTML(content)
const toggleContactBubble = () => mainStore.toggleContactBubble()
// Beispiel Autor und formatierte Datum (kannst du anpassen)
const author = 'Sabrina Hennrich'
const formattedDate = computed(() => {
if (!article.value?.createdAt) return ''
const d = new Date(article.value.createdAt)
return d.toLocaleDateString('de-DE')
})
// ARTIKEL META AND JSON_LD INFOS
watchEffect(() => {
if (!article.value) return
const truncate = (text, maxLength) => {
if (!text) return ''
return text.length <= maxLength ? text : text.slice(0, maxLength - 1).trimEnd() + '…'
}
const rawTitle = article.value.header
const rawDescription = article.value.teaser
const metaTitle = truncate(rawTitle, 60)
const metaDescription = truncate(rawDescription, 160)
const metaImage = `${runtimeConfig.public.cmsBaseUrl}${article.value.image?.url}` || 'https://strapi.digimedialoop.de/uploads/DML_Logo_Info_c4011028f9.png'
const metaKeywords = article.value.SEO?.keywords || ''
const metaType = article.value.SEO?.type || 'article'
const canonical = `${runtimeConfig.public.appUrl}${route.fullPath}`
const jsonLd = {
'@context': 'https://schema.org',
'@type': 'NewsArticle',
headline: rawTitle,
image: [metaImage],
datePublished: article.value.dateCreated,
dateModified: article.value.dateModified,
author: {
'@type': 'Person',
name: author
},
publisher: {
'@type': 'Organization',
name: 'digimedialoop',
logo: {
'@type': 'ImageObject',
url: 'https://strapi.digimedialoop.de/uploads/DML_Logo_Info_c4011028f9.png'
}
},
description: metaDescription
}
useHead({
title: metaTitle,
meta: [
{ name: 'description', content: metaDescription },
{ name: 'keywords', content: metaKeywords },
{ name: 'robots', content: 'index, follow' },
{ property: 'og:title', content: metaTitle },
{ property: 'og:description', content: metaDescription },
{ property: 'og:image', content: metaImage },
{ property: 'og:type', content: metaType },
{ name: 'twitter:title', content: metaTitle },
{ name: 'twitter:description', content: metaDescription },
{ name: 'twitter:image', content: metaImage }
],
link: [
{ rel: 'canonical', href: canonical }
],
script: [
{
type: 'application/ld+json',
children: JSON.stringify(jsonLd)
}
]
})
})
</script>
<style lang="sass">
.article
margin-top: -1rem
.img_background
position: absolute
top: 0
left: 0
width: 80%
height: auto
z-index: 0
border-bottom-right-radius: 50%
.img_article
float: right
margin: -1rem 0 1rem 2rem
border-radius: 1rem
width: 45%
max-width: 400px
.paper
background-color: rgba(white, .98)
width: 88%
margin: 10rem 6% 15vh 6%
position: relative
z-index: 1
border-radius: 1rem
border: 1px solid $lightgrey
padding: 1rem 6% 2rem 6%
box-shadow: 2px 2px 15px 2px rgba(black, .2)
.teaser
font-family: 'Mainfont-Bold'
.articleInfo
font-size: 0.8rem
color: lighten(#333, 20%)
text-align: right
b
color: #e91e63
span
margin-left: 1.5rem
display: inline-block
h1
font-size: clamp(1.6rem, 1.2rem + 2vw, 2.4rem)
font-family: 'Mainfont-Bold'
margin-bottom: 1.5rem
line-height: 140%
max-width: 800px
.content
line-height: 140%
hyphens: auto
h2, h3, h4
margin: 2rem auto .8rem auto
h2
font-size: 1.6rem !important
color: darken($primaryColor, 40%)
h3
font-size: 1.3rem !important
color: darken($primaryColor, 30%)
li
margin-bottom: .5rem
font-size: 1.05rem
.pinkBtn
margin-top: 1.5rem
display: block
</style>