reworked slider + added coaches page
This commit is contained in:
@@ -2,8 +2,8 @@
|
||||
import { useTranslations } from '@/i18n/utils'
|
||||
import BaseLayout from '../layouts/BaseLayout.astro'
|
||||
import Section from '@/components/Section.astro'
|
||||
import { Swiper } from '@/components/swiper'
|
||||
import Header from '@/components/header/Header.astro'
|
||||
import { SwiperWithNav } from '@/components/swiper'
|
||||
import Header, { type HeaderProps } from '@/components/header/Header.astro'
|
||||
import Footer from '@/components/Footer.astro'
|
||||
|
||||
import type { CollectionEntry } from 'astro:content'
|
||||
@@ -14,28 +14,24 @@ 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 { TW_SCREENS, TW_WIDTHS } from '@/constants/images'
|
||||
import { imageResultToImageAttributes } from '@/libs/image'
|
||||
import { imageResultToImageAttributes, optimizeSliderImages } from '@/libs/image'
|
||||
import { getCollection } from 'astro:content'
|
||||
|
||||
type Props = CollectionEntry<'pages'>['data']
|
||||
|
||||
const navItems: HeaderProps['navItems'] = [
|
||||
{ key: 'nav.coaches', href: '#coaches' },
|
||||
{ key: 'nav.slider', href: '#image-slider' },
|
||||
{ key: 'nav.services', href: '#services' },
|
||||
{ key: 'nav.reviews', href: '#reviews' },
|
||||
{ key: 'nav.contact', href: '#contacts' },
|
||||
]
|
||||
|
||||
const { lang } = Astro.params
|
||||
const page = await getEntry('pages', 'main')
|
||||
const { slider, coaches, services, hero, marquee, reviews, footer } = page?.data || {}
|
||||
const [page, coaches] = await Promise.all([getEntry('pages', 'main'), getCollection('coaches')])
|
||||
const { slider, services, hero, marquee, reviews, footer } = page?.data || {}
|
||||
const optimizedSlider = slider
|
||||
? await Promise.all(
|
||||
slider.map((slide) =>
|
||||
getImage({
|
||||
src: slide.image,
|
||||
alt: slide.imageAlt,
|
||||
widths: [TW_SCREENS.SM, TW_SCREENS.LG],
|
||||
sizes: `(max-width: ${TW_WIDTHS.LG}px) ${TW_SCREENS.SM}px, ${TW_SCREENS.LG}px`,
|
||||
quality: 80,
|
||||
format: 'webp',
|
||||
loading: 'eager',
|
||||
}).then(imageResultToImageAttributes)
|
||||
)
|
||||
)
|
||||
? await optimizeSliderImages(slider.map(({ image, imageAlt }) => ({ src: image, alt: imageAlt })))
|
||||
: undefined
|
||||
|
||||
const optimizedReviews = reviews
|
||||
@@ -61,7 +57,7 @@ const t = useTranslations(lang)
|
||||
---
|
||||
|
||||
<BaseLayout title={t('home.title')}>
|
||||
<Header lang={lang} />
|
||||
<Header lang={lang} navItems={navItems} />
|
||||
|
||||
{hero && <Hero {...hero} />}
|
||||
|
||||
@@ -74,7 +70,7 @@ const t = useTranslations(lang)
|
||||
}
|
||||
|
||||
{
|
||||
coaches && (
|
||||
coaches.length > 0 && (
|
||||
<Section id="coaches" title={t('coaches.title')} description={t('coaches.subtitle')}>
|
||||
<div class="grid place-items-center gap-4 sm:grid-cols-2 md:gap-8 lg:grid-cols-3">
|
||||
{coaches.map((coach) => (
|
||||
@@ -94,7 +90,12 @@ const t = useTranslations(lang)
|
||||
className="bg-bg-light"
|
||||
>
|
||||
<div class="-ml-4 flex w-[calc(100%+(1rem*2))] md:ml-0 md:w-full">
|
||||
<Swiper className="h-[540px]" client:visible images={optimizedSlider} />
|
||||
<SwiperWithNav
|
||||
className="h-[540px]"
|
||||
slideClass="object-cover sm:object-contain"
|
||||
client:visible
|
||||
images={optimizedSlider}
|
||||
/>
|
||||
</div>
|
||||
</Section>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user