- one more time rework slider
- rework design system - fill trainer page
This commit is contained in:
@@ -3,8 +3,12 @@ import BaseLayout from '@/layouts/BaseLayout.astro'
|
||||
import { getCollection } from 'astro:content'
|
||||
import { optimizeSliderImages, optimizeSliderThumbs } from '@/libs/image'
|
||||
import Section from '@/components/Section.astro'
|
||||
import { SwiperWithThumbs } from '@/components/swiper/SwiperWithThumbs'
|
||||
import { MediaSwiperWithThumbs } from '@/components/swiper/MediaSwiperWithThumbs'
|
||||
import Header from '@/components/header/Header.astro'
|
||||
import './styles.css'
|
||||
import { SocialMediaIcon } from '@/components/SocialMediaIcon'
|
||||
import { useTranslations } from '@/i18n/utils'
|
||||
import {slide, ViewTransitions} from 'astro:transitions'
|
||||
|
||||
export const getStaticPaths = async () => {
|
||||
const coaches = await getCollection('coaches')
|
||||
@@ -13,6 +17,7 @@ export const getStaticPaths = async () => {
|
||||
|
||||
const { data, render } = Astro.props
|
||||
const { gallery, cover } = data
|
||||
const t = useTranslations(Astro.currentLocale)
|
||||
const { Content } = await render()
|
||||
const galleryWithCover = gallery ? [cover, ...gallery] : undefined
|
||||
const [thumbs, optimizedGallery] = galleryWithCover
|
||||
@@ -31,18 +36,37 @@ const [thumbs, optimizedGallery] = galleryWithCover
|
||||
<Header />
|
||||
{
|
||||
optimizedGallery && (
|
||||
<Section>
|
||||
<SwiperWithThumbs
|
||||
swiperClassName="h-[540px]"
|
||||
client:load
|
||||
images={optimizedGallery}
|
||||
thumbs={thumbs}
|
||||
/>
|
||||
<Section className="mt-[var(--header-height)] md:mt-0">
|
||||
<div class="grid w-full grid-cols-1 place-items-start gap-8 lg:grid-cols-2">
|
||||
<MediaSwiperWithThumbs
|
||||
client:load
|
||||
images={optimizedGallery}
|
||||
thumbs={thumbs}
|
||||
className="sm:max-w-[400px] lg:max-w-none"
|
||||
imageClassName="aspect-3/4 w-[400px] lg:w-auto object-top mx-auto h-auto"
|
||||
/>
|
||||
<div class="flex flex-1 flex-col gap-8">
|
||||
<h1 class="text-nowrap font-bold">{data.name}</h1>
|
||||
{data.description && <span>{data.description}</span>}
|
||||
<Content />
|
||||
{data.socialMediaLinks && (
|
||||
<div class="coach-card">
|
||||
<h2 class="coach-card-title">{t('coaches.socialMedias.title', data.name)}</h2>
|
||||
<div class="flex gap-4">
|
||||
{data.socialMediaLinks.map(({ icon, ...link }) => (
|
||||
<a {...link}>
|
||||
<SocialMediaIcon
|
||||
type={icon}
|
||||
className="fill-text hover:fill-text-light transition-all duration-300"
|
||||
/>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</Section>
|
||||
)
|
||||
}
|
||||
|
||||
<Section>
|
||||
<Content />
|
||||
</Section>
|
||||
</BaseLayout>
|
||||
|
||||
29
src/pages/coaches/styles.css
Normal file
29
src/pages/coaches/styles.css
Normal file
@@ -0,0 +1,29 @@
|
||||
.coach-grid {
|
||||
@apply grid grid-cols-1 gap-8;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.coach-grid {
|
||||
@apply grid-cols-[repeat(auto-fit,minmax(400px,1fr))];
|
||||
}
|
||||
}
|
||||
|
||||
.coach-card {
|
||||
@apply flex flex-col;
|
||||
}
|
||||
|
||||
.coach-card-title {
|
||||
@apply mb-6 font-bold;
|
||||
}
|
||||
|
||||
.coach-card-emoji {
|
||||
@apply mx-2 text-2xl;
|
||||
}
|
||||
|
||||
.coach-card-list {
|
||||
@apply flex flex-col gap-4;
|
||||
}
|
||||
|
||||
.coach-card-list > li {
|
||||
@apply flex items-center rounded-2xl bg-card px-3 py-2;
|
||||
}
|
||||
@@ -2,31 +2,23 @@
|
||||
import { useTranslations } from '@/i18n/utils'
|
||||
import BaseLayout from '../layouts/BaseLayout.astro'
|
||||
import Section from '@/components/Section.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'
|
||||
import { getEntry } from 'astro:content'
|
||||
import CoachCard from '@/components/CoachCard.astro'
|
||||
import ServiceCard from '@/components/ServiceCard.astro'
|
||||
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 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, coaches] = await Promise.all([getEntry('pages', 'main'), getCollection('coaches')])
|
||||
const { slider, services, hero, marquee, reviews, footer } = page?.data || {}
|
||||
@@ -57,7 +49,7 @@ const t = useTranslations(lang)
|
||||
---
|
||||
|
||||
<BaseLayout title={t('home.title')}>
|
||||
<Header lang={lang} navItems={navItems} />
|
||||
<Header lang={lang} />
|
||||
|
||||
{hero && <Hero {...hero} />}
|
||||
|
||||
@@ -72,11 +64,7 @@ const t = useTranslations(lang)
|
||||
{
|
||||
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) => (
|
||||
<CoachCard {...coach} lang={lang} />
|
||||
))}
|
||||
</div>
|
||||
<Coaches client:load coaches={coaches} lang={lang} />
|
||||
</Section>
|
||||
)
|
||||
}
|
||||
@@ -89,14 +77,7 @@ const t = useTranslations(lang)
|
||||
description={t('slider.subtitle')}
|
||||
className="bg-bg-light"
|
||||
>
|
||||
<div class="-ml-4 flex w-[calc(100%+(1rem*2))] md:ml-0 md:w-full">
|
||||
<SwiperWithNav
|
||||
className="h-[540px]"
|
||||
slideClass="object-cover sm:object-contain"
|
||||
client:visible
|
||||
images={optimizedSlider}
|
||||
/>
|
||||
</div>
|
||||
<GymGallery client:visible images={optimizedSlider} />
|
||||
</Section>
|
||||
)
|
||||
}
|
||||
@@ -104,11 +85,7 @@ const t = useTranslations(lang)
|
||||
{
|
||||
services && (
|
||||
<Section id="services" title={t('services.title')}>
|
||||
<div class="grid place-items-center gap-4 md:grid-cols-2 md:gap-8 lg:grid-cols-3">
|
||||
{services.map((service) => (
|
||||
<ServiceCard {...service} />
|
||||
))}
|
||||
</div>
|
||||
<Services client:visible services={services} />
|
||||
</Section>
|
||||
)
|
||||
}
|
||||
@@ -116,9 +93,7 @@ const t = useTranslations(lang)
|
||||
{
|
||||
optimizedReviews && (
|
||||
<Section id="reviews" title={t('reviews.title')}>
|
||||
<div class="-mx-4 flex w-[calc(100%+2rem)] md:-mx-16 md:w-[calc(100%+8rem)] lg:-mx-24 lg:w-[calc(100%+12rem)]">
|
||||
<Reviews client:visible reviews={optimizedReviews} lang={lang} />
|
||||
</div>
|
||||
<Reviews client:visible reviews={optimizedReviews} lang={lang} />
|
||||
</Section>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user