188 lines
4.8 KiB
Vue

<template>
<div>
<section class="topSpace">
<div class="container">
<h1>{{ $t('pages.references.hero.h1') }}</h1>
<p v-html="$t('pages.references.hero.p')"></p>
</div>
</section>
<section>
<div class="referenceBox" v-if="projects && projects.length">
<slot>
<NuxtLink
class="reference"
v-for="project in projects"
:key="project.id"
:to="getProjectLink(project.link)"
>
<NuxtImg
provider="strapi"
:src="project.projectImages?.[0]?.url"
:alt="project.projectImages?.[0]?.alternativeText || project.projectTitle"
width="200"
class="project-image"
priority
/>
<div class="infoBox">
<div class="info-content">
<h2>{{ project.projectTitle }}</h2>
</div>
<div class="logo-wrapper">
<NuxtImg
provider="strapi"
:src="getCustomerLogo(project.customer?.id)"
:alt="getCustomerAlt(project.customer?.id)"
height="50"
priority
/>
</div>
</div>
</NuxtLink>
</slot>
</div>
</section>
<CallToActionBox
:headline="$t('pages.references.ctaBox.headline')"
:text="$t('pages.references.ctaBox.text')"
:buttonText="$t('pages.references.ctaBox.button')"
/>
</div>
</template>
<script setup>
import { useMainStore } from '@/stores/main'
import { storeToRefs } from 'pinia'
const runtimeConfig = useRuntimeConfig();
const cmsUrl = runtimeConfig.public.cmsBaseUrl
const mainStore = useMainStore()
const { projects } = storeToRefs(mainStore)
import { useI18nPages } from '@/composables/useI18nPages'
const { getProjectLink } = useI18nPages()
function getCustomerLogo(customerId) {
if (!customerId) return ''
const customer = mainStore.customers?.find(c => c.id === customerId)
return customer?.logo?.url || ''
}
function getCustomerAlt(customerId) {
if (!customerId) return ''
const customer = mainStore.customers?.find(c => c.id === customerId)
return customer?.logo?.alternativeText || 'Kundenlogo'
}
function toggleContactBubble() {
console.log('Kontaktanfrage öffnen')
}
// Erstelle das JSON-LD für alle Projekte
const jsonLdProjects = computed(() => {
if (!projects.value || !Array.isArray(projects.value) || projects.value.length === 0) return null;
const origin = typeof window !== 'undefined' ? window.location.origin : '';
return {
"@context": "https://schema.org",
"@type": "ItemList",
"itemListElement": projects.value.map((project, index) => ({
"@type": "ListItem",
"position": index + 1,
"item": {
"@type": "CreativeWork", // alternativ "WebPage", wenn es sich um Projektseiten handelt
"@id": origin + (project.link ? getProjectLink(project.link) : ''),
"name": project.projectTitle || 'Projekt',
"image": cmsUrl + (project.projectImages?.[0]?.url || ''),
"description": project.projectDescription?.[0]?.children?.[0]?.text || ''
}
}))
}
})
// useHead einbinden, wenn Projekte da sind
watchEffect(() => {
if (jsonLdProjects.value) {
useHead({
script: [
{
type: 'application/ld+json',
children: JSON.stringify(jsonLdProjects.value)
}
]
})
}
})
</script>
<style lang="sass" scoped>
.referenceBox
display: grid
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr))
gap: 4rem
width: 80%
margin: 0 10% 5rem auto
h2
font-size: 1.4rem
.reference
display: flex
flex-direction: column
position: relative
text-decoration: none
color: $darkgrey
background: white
border-radius: 10px
overflow: hidden
transition: transform 0.3s ease, box-shadow 0.3s ease
&:hover
transform: scale(1.02)
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1)
img
width: 90%
height: auto
object-fit: cover
margin: 1rem 5% 0 5%
transition: transform 0.6s ease
&:hover
transform: scale(1.05)
.infoBox
display: flex
align-items: center
justify-content: space-between
padding: 1rem 1.5rem
border-bottom-left-radius: 10px
border-bottom-right-radius: 10px
background: linear-gradient(to bottom right, white 40%, $lightgrey)
min-height: 8rem
.info-content
flex: 2
h2
font-size: 1rem
margin: 0.5rem 0
line-height: 1.2
hyphens: auto
color: $darkgrey
.logo-wrapper
flex: 1
display: flex
justify-content: flex-end
align-items: center
img
max-height: 50px
max-width: 100%
object-fit: contain
</style>