228 lines
6.3 KiB
Vue
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>
|
|
|