188 lines
4.8 KiB
Vue
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')"/>
|
|
</div>
|
|
</section>
|
|
|
|
<section>
|
|
<div v-if="projects && projects.length" class="referenceBox">
|
|
<slot>
|
|
<NuxtLinkLocale
|
|
v-for="project in projects"
|
|
:key="project.id"
|
|
class="reference"
|
|
:to="localePath({ name: 'project-link', params: { link: 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>
|
|
</NuxtLinkLocale>
|
|
</slot>
|
|
</div>
|
|
</section>
|
|
|
|
<CallToActionBox
|
|
:headline="$t('pages.references.ctaBox.headline')"
|
|
:text="$t('pages.references.ctaBox.text')"
|
|
:button-text="$t('pages.references.ctaBox.button')"
|
|
/>
|
|
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { useMainStore } from '@/stores/main'
|
|
import { storeToRefs } from 'pinia'
|
|
import { useLocalePath } from '#i18n'
|
|
const localePath = useLocalePath()
|
|
|
|
const runtimeConfig = useRuntimeConfig();
|
|
const cmsUrl = runtimeConfig.public.cmsBaseUrl
|
|
|
|
const mainStore = useMainStore()
|
|
const { projects } = storeToRefs(mainStore)
|
|
|
|
|
|
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 ? 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">
|
|
.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>
|