143 lines
4.0 KiB
Vue
143 lines
4.0 KiB
Vue
|
<script setup lang="ts">
|
||
|
const { data: page } = await useAsyncData('index', () => queryContent('/').findOne())
|
||
|
if (!page.value) {
|
||
|
throw createError({ statusCode: 404, statusMessage: 'Page not found', fatal: true })
|
||
|
}
|
||
|
|
||
|
useSeoMeta({
|
||
|
titleTemplate: '',
|
||
|
title: page.value.title,
|
||
|
ogTitle: page.value.title,
|
||
|
description: page.value.description,
|
||
|
ogDescription: page.value.description
|
||
|
})
|
||
|
|
||
|
|
||
|
const items = [
|
||
|
'https://picsum.photos/1920/1080?random=1',
|
||
|
'https://picsum.photos/1920/1080?random=2',
|
||
|
'https://picsum.photos/1920/1080?random=3',
|
||
|
'https://picsum.photos/1920/1080?random=4',
|
||
|
'https://picsum.photos/1920/1080?random=5',
|
||
|
'https://picsum.photos/1920/1080?random=6'
|
||
|
]
|
||
|
|
||
|
const carouselRef = ref()
|
||
|
|
||
|
onMounted(() => {
|
||
|
setInterval(() => {
|
||
|
if (!carouselRef.value) return
|
||
|
|
||
|
if (carouselRef.value.page === carouselRef.value.pages) {
|
||
|
return carouselRef.value.select(0)
|
||
|
}
|
||
|
|
||
|
carouselRef.value.next()
|
||
|
}, 10000)
|
||
|
})
|
||
|
</script>
|
||
|
|
||
|
<template>
|
||
|
<div v-if="page">
|
||
|
<!-- <Galaxy /> -->
|
||
|
<Transition name="bounce">
|
||
|
<ULandingHero :title="page.hero.title" :description="page.hero.description" :links="page.hero.links">
|
||
|
<!-- <div
|
||
|
class="absolute inset-0 landing-grid z-[-1] [mask-image:radial-gradient(100%_100%_at_top_right,white,transparent)]"
|
||
|
/> -->
|
||
|
|
||
|
<template #headline>
|
||
|
<UBadge v-if="page.hero.headline" variant="subtle" size="lg" class="relative rounded-full font-semibold">
|
||
|
<NuxtLink :to="page.hero.headline.to" target="_blank" class="focus:outline-none" tabindex="-1">
|
||
|
<span class="absolute inset-0" aria-hidden="true" />
|
||
|
</NuxtLink>
|
||
|
|
||
|
{{ page.hero.headline.label }}
|
||
|
|
||
|
<UIcon
|
||
|
v-if="page.hero.headline.icon" :name="page.hero.headline.icon"
|
||
|
class="ml-1 w-4 h-4 pointer-events-none"
|
||
|
/>
|
||
|
</UBadge>
|
||
|
</template>
|
||
|
</ULandingHero>
|
||
|
</Transition>
|
||
|
|
||
|
<!-- <ULandingSection class="!pt-0">
|
||
|
<UCarousel
|
||
|
ref="carouselRef" v-slot="{ item }" :items="items" :ui="{ item: 'basis-full' }"
|
||
|
class="rounded-lg overflow-hidden" indicators
|
||
|
>
|
||
|
<img :src="item" class="w-full" draggable="false">
|
||
|
</UCarousel>
|
||
|
</ULandingSection> -->
|
||
|
|
||
|
<ULandingSection
|
||
|
v-for="(section, index) in page.sections" :key="index" :title="section.title"
|
||
|
:description="section.description" :align="section.align" :features="section.features"
|
||
|
>
|
||
|
<Placeholder />
|
||
|
</ULandingSection>
|
||
|
|
||
|
<ULandingSection :title="page.features.title" :description="page.features.description">
|
||
|
<UPageGrid>
|
||
|
<ULandingCard v-for="(item, index) in page.features.items" :key="index" v-bind="item" />
|
||
|
</UPageGrid>
|
||
|
</ULandingSection>
|
||
|
|
||
|
<ULandingSection
|
||
|
:headline="page.testimonials.headline" :title="page.testimonials.title"
|
||
|
:description="page.testimonials.description"
|
||
|
>
|
||
|
<UPageColumns class="xl:columns-4">
|
||
|
<div v-for="(testimonial, index) in page.testimonials.items" :key="index" class="break-inside-avoid">
|
||
|
<ULandingTestimonial v-bind="testimonial" class="bg-gray-100/50 dark:bg-gray-800/50" />
|
||
|
</div>
|
||
|
</UPageColumns>
|
||
|
</ULandingSection>
|
||
|
|
||
|
<ULandingSection>
|
||
|
<ULandingCTA v-bind="page.cta" class="bg-gray-100/50 dark:bg-gray-800/50" />
|
||
|
</ULandingSection>
|
||
|
</div>
|
||
|
</template>
|
||
|
|
||
|
<style scoped>
|
||
|
.landing-grid {
|
||
|
background-size: 100px 100px;
|
||
|
background-image:
|
||
|
linear-gradient(to right, rgb(var(--color-gray-200)) 1px, transparent 1px),
|
||
|
linear-gradient(to bottom, rgb(var(--color-gray-200)) 1px, transparent 1px);
|
||
|
}
|
||
|
|
||
|
.dark {
|
||
|
.landing-grid {
|
||
|
background-image:
|
||
|
linear-gradient(to right, rgb(var(--color-gray-800)) 1px, transparent 1px),
|
||
|
linear-gradient(to bottom, rgb(var(--color-gray-800)) 1px, transparent 1px);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
.bounce-enter-active {
|
||
|
animation: bounce-in 0.5s;
|
||
|
}
|
||
|
|
||
|
.bounce-leave-active {
|
||
|
animation: bounce-in 0.5s reverse;
|
||
|
}
|
||
|
|
||
|
@keyframes bounce-in {
|
||
|
0% {
|
||
|
transform: scale(0);
|
||
|
}
|
||
|
|
||
|
50% {
|
||
|
transform: scale(1.25);
|
||
|
}
|
||
|
|
||
|
100% {
|
||
|
transform: scale(1);
|
||
|
}
|
||
|
}
|
||
|
</style>
|