108 lines
3.1 KiB
Plaintext
108 lines
3.1 KiB
Plaintext
---
|
|
import { useTranslations } from '@/i18n/utils'
|
|
import BaseLayout from '../layouts/BaseLayout.astro'
|
|
import Section from '@/components/Section.astro'
|
|
import Header, { type HeaderProps } from '@/components/header/Header.astro'
|
|
import Footer from '@/components/Footer.astro'
|
|
|
|
import type { CollectionEntry } from 'astro:content'
|
|
import { getEntry } from 'astro:content'
|
|
import Marquee from '@/components/Marquee.astro'
|
|
import { Reviews, type OptimizedReview } from '@/components/Reviews.tsx'
|
|
import Hero from '@/components/Hero.astro'
|
|
import { getImage } from 'astro:assets'
|
|
import { imageResultToImageAttributes, optimizeSliderImages } from '@/libs/image'
|
|
import { getCollection } from 'astro:content'
|
|
import { Services } from '@/components/services/Services'
|
|
import { GymGallery } from '@/components/GymGallery'
|
|
import { Coaches } from '@/components/coaches/Coaches'
|
|
|
|
type Props = CollectionEntry<'pages'>['data']
|
|
|
|
const { lang } = Astro.params
|
|
const [page, coaches] = await Promise.all([
|
|
getEntry('pages', 'main'),
|
|
getCollection('coaches').then((coaches) =>
|
|
coaches.sort((a, b) => (a.data.order ?? -1) - (b.data.order ?? -1))
|
|
),
|
|
])
|
|
const { slider, services, hero, marquee, reviews, footer } = page?.data || {}
|
|
const optimizedSlider = slider
|
|
? await optimizeSliderImages(slider.map(({ image, imageAlt }) => ({ src: image, alt: imageAlt })))
|
|
: undefined
|
|
|
|
const optimizedReviews = reviews
|
|
? await Promise.all(
|
|
reviews.map(async (review): Promise<OptimizedReview> => {
|
|
if (!review.author?.image)
|
|
return { ...review, author: { ...review.author, image: undefined } }
|
|
|
|
const optimizedImage = await getImage({
|
|
src: review.author?.image,
|
|
alt: review.author?.imageAlt,
|
|
width: 64,
|
|
height: 64,
|
|
format: 'webp',
|
|
loading: 'lazy',
|
|
}).then(imageResultToImageAttributes)
|
|
|
|
return { ...review, author: { ...review.author, image: optimizedImage } }
|
|
})
|
|
)
|
|
: undefined
|
|
const t = useTranslations(lang)
|
|
---
|
|
|
|
<BaseLayout title={t('home.title')}>
|
|
<Header lang={lang} />
|
|
|
|
{hero && <Hero {...hero} />}
|
|
|
|
{
|
|
marquee && (
|
|
<section class="h-[var(--marquee-height)] overflow-clip bg-brand">
|
|
<Marquee texts={marquee} />
|
|
</section>
|
|
)
|
|
}
|
|
|
|
{
|
|
coaches.length > 0 && (
|
|
<Section id="coaches" title={t('coaches.title')} description={t('coaches.subtitle')}>
|
|
<Coaches client:load coaches={coaches} lang={lang} />
|
|
</Section>
|
|
)
|
|
}
|
|
|
|
{
|
|
optimizedSlider && (
|
|
<Section
|
|
id="image-slider"
|
|
title={t('slider.title')}
|
|
description={t('slider.subtitle')}
|
|
className="bg-bg-light"
|
|
>
|
|
<GymGallery client:only="react" images={optimizedSlider} />
|
|
</Section>
|
|
)
|
|
}
|
|
|
|
{
|
|
services && (
|
|
<Section id="services" title={t('services.title')}>
|
|
<Services client:visible services={services} />
|
|
</Section>
|
|
)
|
|
}
|
|
|
|
{
|
|
optimizedReviews && (
|
|
<Section id="reviews" title={t('reviews.title')}>
|
|
<Reviews client:only="react" reviews={optimizedReviews} lang={lang} />
|
|
</Section>
|
|
)
|
|
}
|
|
|
|
<Footer lang={lang} {...footer} />
|
|
</BaseLayout>
|