magazin new categories
This commit is contained in:
parent
d2923187d5
commit
bbe1f7382e
@ -140,14 +140,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const navigationLinks = [
|
const navigationLinks = [
|
||||||
{
|
{ routeKey: 'webagency', label: 'menu.webagency' },
|
||||||
routeKey: '',
|
{ routeKey: 'magazin', label: 'menu.menuMagazin' },
|
||||||
label: 'menu.webagency',
|
|
||||||
subNav: [
|
|
||||||
{ routeKey: 'webagency', label: 'menu.menuAbout' },
|
|
||||||
{ routeKey: 'magazin', label: 'menu.menuMagazin' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
routeKey: '',
|
routeKey: '',
|
||||||
label: 'menu.services',
|
label: 'menu.services',
|
||||||
|
|||||||
@ -1,436 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div
|
|
||||||
class="navigationBox"
|
|
||||||
:class="[
|
|
||||||
isMenuOpen ? 'menu-active' : '',
|
|
||||||
screenWidth < 1350 ? 'mobile' : 'desk'
|
|
||||||
]"
|
|
||||||
role="navigation"
|
|
||||||
aria-label="Hauptnavigation"
|
|
||||||
tabindex="0"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="closer"
|
|
||||||
role="button"
|
|
||||||
tabindex="0"
|
|
||||||
aria-label="Navigation schließen"
|
|
||||||
@click="toggleMenu"
|
|
||||||
@keydown.enter="toggleMenu"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<nav
|
|
||||||
v-if="isMenuOpen || screenWidth > 1350"
|
|
||||||
:aria-expanded="screenWidth < 1350 ? 'true' : undefined"
|
|
||||||
@mouseleave="screenWidth >= 1350 && hideSubNav()"
|
|
||||||
>
|
|
||||||
|
|
||||||
<!-- <div class="mobilNavLogo">
|
|
||||||
<NuxtImg
|
|
||||||
v-if="screenWidth < 1350"
|
|
||||||
provider="strapi"
|
|
||||||
src="/uploads/DML_Logo_mint_negative_2024_9257db5430.svg"
|
|
||||||
alt="digimedialoop Logo"
|
|
||||||
width="120"
|
|
||||||
/>
|
|
||||||
</div> -->
|
|
||||||
|
|
||||||
<span
|
|
||||||
v-for="link in navigationLinks"
|
|
||||||
:key="link.routeKey"
|
|
||||||
class="main-nav-item"
|
|
||||||
@mouseenter="screenWidth >= 1350 && showSubNav(link.routeKey)"
|
|
||||||
@mouseleave="screenWidth >= 1350 && hideSubNav(link.routeKey)"
|
|
||||||
>
|
|
||||||
<NuxtLinkLocale
|
|
||||||
:to="link.routeKey"
|
|
||||||
class="main-nav-link"
|
|
||||||
:aria-haspopup="link.subNav && link.subNav.length > 0 ? 'true' : undefined"
|
|
||||||
:aria-expanded="isSubNavOpen === link.routeKey ? 'true' : 'false'"
|
|
||||||
@click="handleMobileClose"
|
|
||||||
>
|
|
||||||
{{ $t(link.label) }}
|
|
||||||
</NuxtLinkLocale>
|
|
||||||
|
|
||||||
<!-- PFEIL FÜR MOBILE UND TOGGLE -->
|
|
||||||
<button
|
|
||||||
v-if="link.subNav && link.subNav.length > 0 && screenWidth < 1350"
|
|
||||||
class="submenu-toggle"
|
|
||||||
@click.prevent="toggleMobileSubNav(link.routeKey)"
|
|
||||||
:aria-expanded="isMobileSubNavOpen === link.routeKey ? 'true' : 'false'"
|
|
||||||
aria-label="Untermenü öffnen/schließen"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
:class="{ 'open': isMobileSubNavOpen === link.routeKey }"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
width="12"
|
|
||||||
height="8"
|
|
||||||
viewBox="0 0 12 8"
|
|
||||||
fill="none"
|
|
||||||
>
|
|
||||||
<path d="M1 1L6 6L11 1" stroke="currentColor" stroke-width="2"/>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<!-- SUBNAVIGATION -->
|
|
||||||
<ul
|
|
||||||
v-if="link.subNav && link.subNav.length > 0"
|
|
||||||
v-show="(screenWidth >= 1350 && isSubNavOpen === link.routeKey) || (screenWidth < 1350 && isMobileSubNavOpen === link.routeKey)"
|
|
||||||
class="sub-nav"
|
|
||||||
>
|
|
||||||
<li v-for="subLink in link.subNav" :key="subLink.routeKey" class="sub-nav-item">
|
|
||||||
<NuxtLinkLocale
|
|
||||||
:to="subLink.routeKey"
|
|
||||||
class="sub-nav-link"
|
|
||||||
@click="handleMobileClose"
|
|
||||||
>
|
|
||||||
{{ $t(subLink.label) }}
|
|
||||||
</NuxtLinkLocale>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
|
|
||||||
<a
|
|
||||||
class="menu_link" href="#"
|
|
||||||
role="button"
|
|
||||||
aria-label="Kontaktformular öffnen"
|
|
||||||
@click="toggleContactBubble"
|
|
||||||
>
|
|
||||||
{{ $t('contact') }}
|
|
||||||
</a>
|
|
||||||
<SettingsPanel v-if="screenWidth < 1350" />
|
|
||||||
</nav>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref, computed } from 'vue'
|
|
||||||
import { useMainStore } from '@/stores/main'
|
|
||||||
const mainStore = useMainStore()
|
|
||||||
|
|
||||||
const screenWidth = computed(() => mainStore.screenWidth)
|
|
||||||
const scrollPosition = computed(() => mainStore.scrollPosition)
|
|
||||||
|
|
||||||
const isSubNavOpen = ref(null) // speichert, welches Submenü auf Desktop offen ist
|
|
||||||
const isMobileSubNavOpen = ref(null) // Trackt, welches Submenü auf Mobile offen ist
|
|
||||||
|
|
||||||
function toggleMobileSubNav(routeKey) {
|
|
||||||
if (screenWidth.value < 1350) {
|
|
||||||
isMobileSubNavOpen.value = isMobileSubNavOpen.value === routeKey ? null : routeKey
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Funktionen zum Öffnen und Schließen der Subnavigation auf Desktop
|
|
||||||
function showSubNav(routeKey) {
|
|
||||||
isSubNavOpen.value = routeKey
|
|
||||||
}
|
|
||||||
function hideSubNav(routeKey) {
|
|
||||||
if (isSubNavOpen.value === routeKey) {
|
|
||||||
isSubNavOpen.value = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const isMenuOpen = computed(() => mainStore.menuOpen)
|
|
||||||
const toggleMenu = () => mainStore.toggleMenu()
|
|
||||||
|
|
||||||
const toggleContactBubble = () => mainStore.toggleContactBubble()
|
|
||||||
|
|
||||||
const handleMobileClose = () => {
|
|
||||||
if (screenWidth.value < 1350 && isMenuOpen.value) {
|
|
||||||
toggleMenu()
|
|
||||||
} else {
|
|
||||||
hideSubNav()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const navigationLinks = [
|
|
||||||
{
|
|
||||||
routeKey: 'webagency',
|
|
||||||
label: 'webagency'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
routeKey: '',
|
|
||||||
label: 'services',
|
|
||||||
subNav: [
|
|
||||||
{ routeKey: 'services-cms', label: 'menuCms' },
|
|
||||||
{ routeKey: 'services-seo', label: 'menuSEO' },
|
|
||||||
{ routeKey: 'services-accessibility', label: 'menuAccessibility' },
|
|
||||||
{ routeKey: 'services-ai', label: 'menuAi' },
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
routeKey: '',
|
|
||||||
label: 'sectors',
|
|
||||||
subNav: [
|
|
||||||
{ routeKey: 'sectors-schools', label: 'menuSchools' },
|
|
||||||
{ routeKey: 'sectors-film', label: 'menuFilm' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{ routeKey: 'references', label: 'references' }
|
|
||||||
]
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="sass">
|
|
||||||
.navigationBox
|
|
||||||
position: relative
|
|
||||||
display: flex
|
|
||||||
align-items: center
|
|
||||||
justify-content: flex-end
|
|
||||||
width: 80%
|
|
||||||
transition: .8s
|
|
||||||
margin-top: 1.2rem // -1rem
|
|
||||||
|
|
||||||
nav
|
|
||||||
display: block
|
|
||||||
z-index: 102
|
|
||||||
//background: linear-gradient(to right, rgba($lightgrey, 0.8), rgba(white, 0.9), rgba(white, 0.9))
|
|
||||||
background: white
|
|
||||||
border: 1px solid adjust-color($beige, $lightness: 5%)
|
|
||||||
padding: 1rem 2rem
|
|
||||||
text-align: center
|
|
||||||
border-radius: 1rem
|
|
||||||
margin: 4.8rem 1rem 0 1rem
|
|
||||||
transition: .8s
|
|
||||||
|
|
||||||
a
|
|
||||||
margin: 0 1.2rem
|
|
||||||
text-decoration: none
|
|
||||||
color: $darkgrey
|
|
||||||
text-transform: uppercase
|
|
||||||
font-family: 'Comfortaa-Bold'
|
|
||||||
font-size: 1.1rem
|
|
||||||
letter-spacing: .05rem
|
|
||||||
transition: .6s
|
|
||||||
display: inline-block
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
transform: scale(1.15)
|
|
||||||
background-image: radial-gradient(rgba(white, .5), rgba(white, .1))
|
|
||||||
box-shadow: 0 0 10px 10px rgba(white, 0.2)
|
|
||||||
border-radius: 10px
|
|
||||||
|
|
||||||
&.desk
|
|
||||||
.sub-nav
|
|
||||||
display: block
|
|
||||||
position: absolute
|
|
||||||
top: 3rem
|
|
||||||
right: 5%
|
|
||||||
background-color: rgba(white, .95)
|
|
||||||
padding: 2rem 2rem 1rem 2rem
|
|
||||||
text-align: left
|
|
||||||
cursor: pointer
|
|
||||||
border-bottom-left-radius: 1rem
|
|
||||||
border-bottom-right-radius: 1rem
|
|
||||||
list-style: none
|
|
||||||
|
|
||||||
.sub-nav-item
|
|
||||||
padding: 0 0 1.5rem 0
|
|
||||||
|
|
||||||
.sub-nav-link
|
|
||||||
position: relative
|
|
||||||
margin-left: 1.2rem
|
|
||||||
|
|
||||||
&::before
|
|
||||||
content: ''
|
|
||||||
width: .5rem
|
|
||||||
height: .4rem
|
|
||||||
background-color: rgba($primaryColor, .9)
|
|
||||||
border-radius: $loopShape
|
|
||||||
position: absolute
|
|
||||||
top: .4rem
|
|
||||||
left: -1.3rem
|
|
||||||
border-radius: 20px
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
transform: scale(1.025)
|
|
||||||
|
|
||||||
&.mobile
|
|
||||||
top: 0
|
|
||||||
|
|
||||||
&.navigationBox
|
|
||||||
display: block
|
|
||||||
position: relative
|
|
||||||
background-color: $darkgrey
|
|
||||||
width: 4rem
|
|
||||||
height: 4rem
|
|
||||||
z-index: 8
|
|
||||||
border-radius: 50%
|
|
||||||
margin-right: 5vw
|
|
||||||
margin-top: 2rem
|
|
||||||
|
|
||||||
.closer
|
|
||||||
position: relative
|
|
||||||
width: 100%
|
|
||||||
height: 4rem
|
|
||||||
|
|
||||||
&::after, &::before
|
|
||||||
position: absolute
|
|
||||||
content: ''
|
|
||||||
width: 2rem
|
|
||||||
z-index: 12
|
|
||||||
height: 5px
|
|
||||||
border-radius: 4px
|
|
||||||
background-color: white
|
|
||||||
right: 75%
|
|
||||||
transform: translateX(100%)
|
|
||||||
transition: .8s
|
|
||||||
|
|
||||||
&::before
|
|
||||||
top: 35%
|
|
||||||
|
|
||||||
&::after
|
|
||||||
top: 55%
|
|
||||||
|
|
||||||
nav
|
|
||||||
display: none
|
|
||||||
background-image: none
|
|
||||||
background: transparent
|
|
||||||
border: none
|
|
||||||
padding-top: 0rem !important
|
|
||||||
|
|
||||||
.submenu-toggle
|
|
||||||
background: none
|
|
||||||
border: none
|
|
||||||
padding: 0 0 0 0.5rem
|
|
||||||
margin-top: -1rem
|
|
||||||
cursor: pointer
|
|
||||||
display: inline-flex
|
|
||||||
align-items: center
|
|
||||||
color: white
|
|
||||||
transition: transform 0.3s ease
|
|
||||||
|
|
||||||
svg
|
|
||||||
transition: transform 0.3s ease
|
|
||||||
|
|
||||||
&.open svg,
|
|
||||||
svg.open
|
|
||||||
transform: rotate(180deg) // Pfeil zeigt nach oben, wenn offen
|
|
||||||
|
|
||||||
.sub-nav
|
|
||||||
overflow: hidden
|
|
||||||
max-height: 0
|
|
||||||
opacity: 0
|
|
||||||
transition: max-height 0.4s ease, opacity 0.4s ease
|
|
||||||
|
|
||||||
&.open
|
|
||||||
max-height: 500px
|
|
||||||
opacity: 1
|
|
||||||
|
|
||||||
.sub-nav
|
|
||||||
list-style: none
|
|
||||||
padding-left: 1.8rem
|
|
||||||
margin: 0
|
|
||||||
|
|
||||||
.sub-nav-item
|
|
||||||
padding-left: 1rem
|
|
||||||
margin-bottom: 0.2rem
|
|
||||||
|
|
||||||
.sub-nav-link
|
|
||||||
color: white
|
|
||||||
font-size: 1rem !important
|
|
||||||
line-height: 1.5rem
|
|
||||||
padding: 0.5rem 1.5rem
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
|
|
||||||
&::before
|
|
||||||
content: ''
|
|
||||||
width: .5rem
|
|
||||||
height: .4rem
|
|
||||||
background-color: rgba($primaryColor, .9)
|
|
||||||
border-radius: $loopShape
|
|
||||||
position: absolute
|
|
||||||
top: 1rem
|
|
||||||
left: 0
|
|
||||||
border-radius: 20px
|
|
||||||
|
|
||||||
.menu_link
|
|
||||||
margin-left: 1.5rem
|
|
||||||
transition: .8s
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
transform: scale(1.06)
|
|
||||||
background-image: radial-gradient(rgba($primaryColor, .1), transparent, transparent)
|
|
||||||
box-shadow: 0 0 0 0 transparent
|
|
||||||
border-radius: 20px
|
|
||||||
|
|
||||||
a, .menu_link
|
|
||||||
display: block
|
|
||||||
color: white
|
|
||||||
text-align: left
|
|
||||||
margin-bottom: .2rem
|
|
||||||
padding: 1rem 2.8rem .5rem 1.2rem
|
|
||||||
position: relative
|
|
||||||
font-size: 1.25rem !important
|
|
||||||
width: auto
|
|
||||||
max-width: 18rem
|
|
||||||
text-transform: uppercase
|
|
||||||
font-family: 'Mainfont-Bold'
|
|
||||||
|
|
||||||
&::before
|
|
||||||
content: ''
|
|
||||||
width: .8rem
|
|
||||||
height: .6rem
|
|
||||||
background-color: rgba($primaryColor, .9)
|
|
||||||
border-radius: $loopShape
|
|
||||||
position: absolute
|
|
||||||
top: 1.5rem
|
|
||||||
left: -.5rem
|
|
||||||
border-radius: 20px
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
transform: scale(1.06)
|
|
||||||
background-image: radial-gradient(rgba($primaryColor, .1), transparent, transparent)
|
|
||||||
box-shadow: 0 0 0 0 transparent
|
|
||||||
border-radius: 20px
|
|
||||||
|
|
||||||
&.menu-active
|
|
||||||
width: 100vw
|
|
||||||
height: 98vh
|
|
||||||
border-radius: 5px
|
|
||||||
margin: 0
|
|
||||||
background-color: rgba($darkgrey, .97)
|
|
||||||
|
|
||||||
.closer
|
|
||||||
&::before, &::after
|
|
||||||
top: 2rem
|
|
||||||
right: 2rem
|
|
||||||
|
|
||||||
&::before
|
|
||||||
transform: rotate(45deg)
|
|
||||||
|
|
||||||
&::after
|
|
||||||
transform: rotate(-45deg)
|
|
||||||
|
|
||||||
nav
|
|
||||||
display: block
|
|
||||||
padding: 10vh 0
|
|
||||||
margin: 0 5vw
|
|
||||||
|
|
||||||
.navigationBox
|
|
||||||
margin-top: .5rem
|
|
||||||
|
|
||||||
nav
|
|
||||||
display: flex
|
|
||||||
margin: 2.5rem 0 0 0
|
|
||||||
padding: 1rem .5rem
|
|
||||||
border-top-right-radius: 0
|
|
||||||
border-top-left-radius: 0
|
|
||||||
border-bottom-left-radius: 50px
|
|
||||||
border-bottom-right-radius: 0
|
|
||||||
background: transparent
|
|
||||||
border: 1px solid transparent
|
|
||||||
|
|
||||||
a
|
|
||||||
font-size: 1rem
|
|
||||||
font-weight: bold
|
|
||||||
margin: 0 .8rem
|
|
||||||
|
|
||||||
&.desk
|
|
||||||
.sub-nav
|
|
||||||
top: 1.5rem
|
|
||||||
right: 2%
|
|
||||||
background-color: transparent
|
|
||||||
background-image: linear-gradient(to bottom, transparent 0%, white 15%)
|
|
||||||
|
|
||||||
</style>
|
|
||||||
@ -120,7 +120,7 @@ export const i18nPages = {
|
|||||||
tr: '/kosullar'
|
tr: '/kosullar'
|
||||||
},
|
},
|
||||||
magazin: {
|
magazin: {
|
||||||
de: '/wissenswertes',
|
de: '/magazin',
|
||||||
en: '/magazine',
|
en: '/magazine',
|
||||||
fr: '/magazine',
|
fr: '/magazine',
|
||||||
it: '/magazine',
|
it: '/magazine',
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
"menu": {
|
"menu": {
|
||||||
"webagency": "Webagentur",
|
"webagency": "Webagentur",
|
||||||
"menuAbout": "Über uns",
|
"menuAbout": "Über uns",
|
||||||
"menuMagazin": "Wissenswertes",
|
"menuMagazin": "Magazin",
|
||||||
"services": "Leistungen",
|
"services": "Leistungen",
|
||||||
"sectors": "Branchen",
|
"sectors": "Branchen",
|
||||||
"menuCms": "Headless Content-Management-System (CMS)",
|
"menuCms": "Headless Content-Management-System (CMS)",
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="article" class="article">
|
<div v-if="article" class="article">
|
||||||
<SideBarNaviSlider link="/wissenswertes">
|
<SideBarNaviSlider link="/magazin">
|
||||||
{{ $t('pages.article.artikelUebersicht') }}
|
{{ $t('pages.article.artikelUebersicht') }}
|
||||||
</SideBarNaviSlider>
|
</SideBarNaviSlider>
|
||||||
|
|
||||||
|
|||||||
@ -2,25 +2,46 @@
|
|||||||
<div class="knowledgeBox topSpace">
|
<div class="knowledgeBox topSpace">
|
||||||
<section class="teaserBox">
|
<section class="teaserBox">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1>Wissenswertes für digitale Entscheider</h1>
|
<h1>Digital Insights Magazin</h1>
|
||||||
<h2>Webdesign und Webentwicklung, SEO, Performance & AI</h2>
|
<h2>Wissenswertes rund um moderne Weblösungen</h2>
|
||||||
<p>In unserem Fachmagazin erfahren Sie, wie moderne Webseiten aufgebaut sein müssen,
|
<p>Hier finden Sie praxisnahe Beiträge zu Technik, Strategie und Gestaltung im Web. Wir bieten wertvolle Impulse und aktuelles Wissen,
|
||||||
um technisch, inhaltlich und strategisch zu überzeugen.
|
damit Sie gut informiert sind und fundierte Entscheidungen für Ihre Webprojekte treffen können.
|
||||||
Themen wie <b>KI-gestütztes SEO (AI-SEO)</b>, <b>nachhaltige Webentwicklung</b>, <b>Barrierefreiheit</b>,
|
</p>
|
||||||
<b>Ladezeit-Optimierung</b>, <b>User Experience</b> und <b>Headless CMS</b> zeigen, worauf es heute im Webdesign wirklich ankommt.</p>
|
<div class="selectionZone">
|
||||||
<p>Entdecken Sie <b>praxisnahe Insights und zukunftsorientierte Lösungen</b> für mehr Sichtbarkeit, Effizienz und Erfolg im digitalen Raum.</p>
|
<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>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="articleBox container">
|
<section class="articleBox container">
|
||||||
<div class="grid">
|
<transition-group
|
||||||
|
name="article"
|
||||||
|
tag="div"
|
||||||
|
class="grid"
|
||||||
|
appear
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
v-for="article in articles"
|
v-for="article in filteredArticles"
|
||||||
:key="article.id"
|
:key="article.id"
|
||||||
class="article"
|
class="article"
|
||||||
>
|
>
|
||||||
|
<NuxtLinkLocale
|
||||||
<NuxtLinkLocale :to="localePath({ name: 'article-link', params: { link: article.slug } })" class="article-link">
|
:to="localePath({ name: 'article-link', params: { link: article.slug } })"
|
||||||
|
class="article-link"
|
||||||
|
>
|
||||||
<div class="image-wrapper">
|
<div class="image-wrapper">
|
||||||
<NuxtImg
|
<NuxtImg
|
||||||
v-if="article.image?.url"
|
v-if="article.image?.url"
|
||||||
@ -32,29 +53,26 @@
|
|||||||
/>
|
/>
|
||||||
<div class="overlay">
|
<div class="overlay">
|
||||||
<h2>{{ article.header }}</h2>
|
<h2>{{ article.header }}</h2>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<button class="btn mintBtn">{{ $t('pages.magazin.readmore') }}</button>
|
<button class="btn mintBtn">{{ $t('pages.magazin.readmore') }}</button>
|
||||||
</div>
|
</div>
|
||||||
</NuxtLinkLocale>
|
</NuxtLinkLocale>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</transition-group>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { watch } from 'vue'
|
|
||||||
import { useMainStore } from '@/stores/main'
|
import { useMainStore } from '@/stores/main'
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
import { useLocalePath } from '#i18n'
|
import { useLocalePath } from '#i18n'
|
||||||
const localePath = useLocalePath()
|
const localePath = useLocalePath()
|
||||||
|
|
||||||
const mainStore = useMainStore()
|
const mainStore = useMainStore()
|
||||||
const { articles } = storeToRefs(mainStore)
|
const { articles, categories } = storeToRefs(mainStore)
|
||||||
|
|
||||||
const truncateText = (text: string, length = 200) =>
|
const truncateText = (text: string, length = 200) =>
|
||||||
text?.length > length ? text.substring(0, length) + '…' : text
|
text?.length > length ? text.substring(0, length) + '…' : text
|
||||||
@ -63,6 +81,29 @@ const currentDomain = typeof window !== 'undefined'
|
|||||||
? window.location.origin
|
? window.location.origin
|
||||||
: 'https://www.digimedialoop.de'
|
: '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
|
// SEO: JSON-LD für Artikelübersicht
|
||||||
watch(articles, (newVal) => {
|
watch(articles, (newVal) => {
|
||||||
@ -90,19 +131,52 @@ watch(articles, (newVal) => {
|
|||||||
|
|
||||||
|
|
||||||
<style lang="sass">
|
<style lang="sass">
|
||||||
.articleBox
|
.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
|
display: flex
|
||||||
justify-content: center
|
justify-content: center
|
||||||
width: 100%
|
width: (9)0%
|
||||||
|
|
||||||
|
|
||||||
.grid
|
.grid
|
||||||
display: grid
|
display: grid
|
||||||
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr))
|
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr))
|
||||||
gap: 2rem
|
gap: 2.5rem
|
||||||
justify-content: start
|
justify-content: start
|
||||||
width: 100%
|
width: 100%
|
||||||
max-width: 100%
|
max-width: 100%
|
||||||
margin: 0 auto
|
margin: 0 auto
|
||||||
|
transition: all 0.3s ease-in-out // weichere Umordnung der Items
|
||||||
|
|
||||||
.article
|
.article
|
||||||
width: 100%
|
width: 100%
|
||||||
@ -110,15 +184,27 @@ watch(articles, (newVal) => {
|
|||||||
border: 1px solid $beige
|
border: 1px solid $beige
|
||||||
background: linear-gradient(to bottom right, white, $lightgrey)
|
background: linear-gradient(to bottom right, white, $lightgrey)
|
||||||
border-radius: 1rem
|
border-radius: 1rem
|
||||||
transition: .5s
|
|
||||||
position: relative
|
position: relative
|
||||||
display: flex
|
display: flex
|
||||||
flex-direction: column
|
flex-direction: column
|
||||||
align-items: flex-start
|
align-items: flex-start
|
||||||
overflow: hidden
|
overflow: hidden
|
||||||
|
cursor: pointer
|
||||||
|
transition: transform 0.3s ease, opacity 0.3s ease
|
||||||
|
|
||||||
&:hover
|
&:hover
|
||||||
transform: scale(1.05)
|
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
|
.article-link
|
||||||
position: relative
|
position: relative
|
||||||
display: block
|
display: block
|
||||||
@ -128,7 +214,7 @@ watch(articles, (newVal) => {
|
|||||||
.image-wrapper
|
.image-wrapper
|
||||||
position: relative
|
position: relative
|
||||||
width: 100%
|
width: 100%
|
||||||
height: 280px
|
height: 220px
|
||||||
border: 1px solid $lightgrey
|
border: 1px solid $lightgrey
|
||||||
|
|
||||||
.article-image
|
.article-image
|
||||||
@ -143,10 +229,10 @@ watch(articles, (newVal) => {
|
|||||||
position: absolute
|
position: absolute
|
||||||
bottom: .6rem
|
bottom: .6rem
|
||||||
right: 0rem
|
right: 0rem
|
||||||
border: 1px solid darken($primaryColor, 30%)
|
border: 1px solid $darkgrey
|
||||||
font-size: 1rem
|
font-size: 1rem
|
||||||
box-shadow: 1px 1px 4px 2px rgba(black, .2)
|
box-shadow: 1px 1px 4px 2px rgba(black, .2)
|
||||||
background-color: darken($primaryColor, 15%)
|
background-color: lighten($darkgrey, 10%)
|
||||||
letter-spacing: .05rem
|
letter-spacing: .05rem
|
||||||
|
|
||||||
|
|
||||||
@ -156,8 +242,8 @@ watch(articles, (newVal) => {
|
|||||||
left: 0
|
left: 0
|
||||||
width: 80%
|
width: 80%
|
||||||
height: auto
|
height: auto
|
||||||
min-height: 60%
|
min-height: 80%
|
||||||
background-image: linear-gradient(to bottom right, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0.96) )
|
background-image: linear-gradient(to bottom right, rgba(darken(white, 0), 1), rgba(darken($beige, 0), 0.9) )
|
||||||
margin: 0 20% 7rem 0
|
margin: 0 20% 7rem 0
|
||||||
display: flex
|
display: flex
|
||||||
flex-direction: column
|
flex-direction: column
|
||||||
@ -165,7 +251,8 @@ watch(articles, (newVal) => {
|
|||||||
justify-content: flex-start
|
justify-content: flex-start
|
||||||
padding: 1rem
|
padding: 1rem
|
||||||
border-top-left-radius: 1rem
|
border-top-left-radius: 1rem
|
||||||
border-bottom-right-radius: 1rem
|
border-bottom-right-radius: 50%
|
||||||
|
//border: 1px solid darken($beige, 10%)
|
||||||
//border-radius: .5rem
|
//border-radius: .5rem
|
||||||
text-align: left
|
text-align: left
|
||||||
transition: .3s
|
transition: .3s
|
||||||
@ -173,11 +260,13 @@ watch(articles, (newVal) => {
|
|||||||
|
|
||||||
|
|
||||||
h2
|
h2
|
||||||
color: black
|
color: $darkgrey
|
||||||
font-size: 1.1rem
|
font-size: 1rem
|
||||||
line-height: 140%
|
line-height: 140%
|
||||||
font-family: 'Mainfont-Bold'
|
font-family: 'Mainfont-Bold'
|
||||||
margin: .2rem 1rem
|
margin: .2rem 1rem
|
||||||
|
//text-transform: uppercase
|
||||||
|
hyphens: auto
|
||||||
|
|
||||||
.mintBtn
|
.mintBtn
|
||||||
background-color: $primaryColor
|
background-color: $primaryColor
|
||||||
|
|||||||
@ -144,7 +144,7 @@ const mainStore = useMainStore();
|
|||||||
const { projects, companyinfo } = storeToRefs(mainStore)
|
const { projects, companyinfo } = storeToRefs(mainStore)
|
||||||
|
|
||||||
const navigateToArticle = () => {
|
const navigateToArticle = () => {
|
||||||
router.push('/wissenswertes/artikel/design-und-inhalt-sauber-getrennt-warum-headless-webdesign-die-beste-wahl-fuer-moderne-unternehmen-ist');
|
router.push('/artikel/design-und-inhalt-sauber-getrennt-warum-headless-webdesign-die-beste-wahl-fuer-moderne-unternehmen-ist');
|
||||||
};
|
};
|
||||||
|
|
||||||
const projectItems = computed(() => {
|
const projectItems = computed(() => {
|
||||||
|
|||||||
@ -93,6 +93,10 @@ interface NewsArticle {
|
|||||||
name: string
|
name: string
|
||||||
// optional: weitere Felder aus dem Team-Modell
|
// optional: weitere Felder aus dem Team-Modell
|
||||||
} | null
|
} | null
|
||||||
|
categories?: {
|
||||||
|
id: number
|
||||||
|
name: string
|
||||||
|
}[]
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ContactData {
|
interface ContactData {
|
||||||
@ -118,6 +122,7 @@ export const useMainStore = defineStore('main', {
|
|||||||
customers: [] as Customer[],
|
customers: [] as Customer[],
|
||||||
projects: [] as CustomerProject[],
|
projects: [] as CustomerProject[],
|
||||||
articles: [] as NewsArticle[],
|
articles: [] as NewsArticle[],
|
||||||
|
categories: [] as { id: number; name: string }[],
|
||||||
dataFetched: false,
|
dataFetched: false,
|
||||||
loading: false,
|
loading: false,
|
||||||
error: null as { message: string; stack?: string } | null,
|
error: null as { message: string; stack?: string } | null,
|
||||||
@ -211,7 +216,7 @@ export const useMainStore = defineStore('main', {
|
|||||||
const { public: cfg } = useRuntimeConfig()
|
const { public: cfg } = useRuntimeConfig()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const [companyRes, pagesRes, customersRes, projectsRes, articlesRes] = await Promise.all([
|
const [companyRes, pagesRes, customersRes, projectsRes, articlesRes, categoriesRes] = await Promise.all([
|
||||||
$fetch(`${cfg.cmsBaseUrl}/api/companyinfo?populate=*`, {
|
$fetch(`${cfg.cmsBaseUrl}/api/companyinfo?populate=*`, {
|
||||||
headers: { Authorization: `Bearer ${cfg.cmsToken}` },
|
headers: { Authorization: `Bearer ${cfg.cmsToken}` },
|
||||||
}),
|
}),
|
||||||
@ -224,7 +229,10 @@ export const useMainStore = defineStore('main', {
|
|||||||
$fetch(`${cfg.cmsBaseUrl}/api/references?populate=projectImages,Technologien,customer&sort=launchDate:desc`, {
|
$fetch(`${cfg.cmsBaseUrl}/api/references?populate=projectImages,Technologien,customer&sort=launchDate:desc`, {
|
||||||
headers: { Authorization: `Bearer ${cfg.cmsToken}` },
|
headers: { Authorization: `Bearer ${cfg.cmsToken}` },
|
||||||
}),
|
}),
|
||||||
$fetch(`${cfg.cmsBaseUrl}/api/newsarticels?populate=image,SEO,author&locale=all&sort=createdAt:desc`, {
|
$fetch(`${cfg.cmsBaseUrl}/api/newsarticels?populate=image,SEO,categories,author&locale=all&sort=createdAt:desc`, {
|
||||||
|
headers: { Authorization: `Bearer ${cfg.cmsToken}` },
|
||||||
|
}),
|
||||||
|
$fetch(`${cfg.cmsBaseUrl}/api/magazin-cats?populate=*&locale=all`, {
|
||||||
headers: { Authorization: `Bearer ${cfg.cmsToken}` },
|
headers: { Authorization: `Bearer ${cfg.cmsToken}` },
|
||||||
}),
|
}),
|
||||||
])
|
])
|
||||||
@ -348,9 +356,18 @@ export const useMainStore = defineStore('main', {
|
|||||||
name: a.author.data.attributes.name,
|
name: a.author.data.attributes.name,
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
|
categories: a.categories?.data?.map((c: any) => ({
|
||||||
|
id: c.id,
|
||||||
|
name: c.attributes.category,
|
||||||
|
})) ?? [],
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
this.categories = categoriesRes.data.map((item: any) => ({
|
||||||
|
id: item.id,
|
||||||
|
name: item.attributes.category,
|
||||||
|
}))
|
||||||
|
|
||||||
this.dataFetched = true
|
this.dataFetched = true
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
const e = err as Error
|
const e = err as Error
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user