website/pages/index.vue

143 lines
4.0 KiB
Vue
Raw Permalink Normal View History

2024-05-25 15:20:10 +08:00
<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>