- one more time rework slider

- rework design system
- fill trainer page
This commit is contained in:
Salam-vsem
2025-05-16 15:08:36 +03:00
parent 2c1ebe5dae
commit 24899dc686
46 changed files with 576 additions and 274 deletions

View File

@@ -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>

View 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;
}

View File

@@ -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>
)
}