feat: make partners-slider
This commit is contained in:
parent
c94140545c
commit
cdc70e9c36
@ -44,6 +44,7 @@
|
||||
"react-hook-form": "^7.56.1",
|
||||
"react-redux": "^9.2.0",
|
||||
"sonner": "^2.0.3",
|
||||
"swiper": "^11.2.6",
|
||||
"tailwind-merge": "^3.2.0",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"tailwindcss-animated": "^2.0.0",
|
||||
|
||||
9
pnpm-lock.yaml
generated
9
pnpm-lock.yaml
generated
@ -110,6 +110,9 @@ importers:
|
||||
sonner:
|
||||
specifier: ^2.0.3
|
||||
version: 2.0.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||
swiper:
|
||||
specifier: ^11.2.6
|
||||
version: 11.2.6
|
||||
tailwind-merge:
|
||||
specifier: ^3.2.0
|
||||
version: 3.2.0
|
||||
@ -2640,6 +2643,10 @@ packages:
|
||||
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
swiper@11.2.6:
|
||||
resolution: {integrity: sha512-8aXpYKtjy3DjcbzZfz+/OX/GhcU5h+looA6PbAzHMZT6ESSycSp9nAjPCenczgJyslV+rUGse64LMGpWE3PX9Q==}
|
||||
engines: {node: '>= 4.7.0'}
|
||||
|
||||
tailwind-merge@3.2.0:
|
||||
resolution: {integrity: sha512-FQT/OVqCD+7edmmJpsgCsY820RTD5AkBryuG5IUqR5YQZSdj5xlH5nLgH7YPths7WsLPSpSBNneJdM8aS8aeFA==}
|
||||
|
||||
@ -5314,6 +5321,8 @@ snapshots:
|
||||
|
||||
supports-preserve-symlinks-flag@1.0.0: {}
|
||||
|
||||
swiper@11.2.6: {}
|
||||
|
||||
tailwind-merge@3.2.0: {}
|
||||
|
||||
tailwindcss-animate@1.0.7(tailwindcss@4.1.4):
|
||||
|
||||
@ -1,14 +1,15 @@
|
||||
'use client';
|
||||
|
||||
import { Handshake } from 'lucide-react';
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { Partners } from '@/app/api-utlities/@types';
|
||||
|
||||
import { useTextController } from '@/shared/language/hooks/use-text-controller';
|
||||
import { Button } from '@/shared/shadcn-ui/button';
|
||||
|
||||
import { PartnersSlider } from './partners-slider';
|
||||
|
||||
interface PartnersSectionProps {
|
||||
partners: Partners;
|
||||
}
|
||||
@ -16,9 +17,19 @@ interface PartnersSectionProps {
|
||||
export const PartnersSection = ({ partners }: PartnersSectionProps) => {
|
||||
const { t } = useTextController();
|
||||
|
||||
const [partnersFirstHalf, partnersSecondHalf] = useMemo(() => {
|
||||
const length = partners.length;
|
||||
const midPoint = Math.floor(length / 2);
|
||||
|
||||
const partnersFirstHalf = partners.slice(0, midPoint);
|
||||
const partnersSecondHalf = partners.slice(midPoint);
|
||||
|
||||
return [partnersFirstHalf, partnersSecondHalf];
|
||||
}, [partners]);
|
||||
|
||||
return (
|
||||
<section id='partners' className='bg-gray-50 px-2 py-8 sm:py-16'>
|
||||
<div className='container mx-auto'>
|
||||
<section id='partners' className='bg-gray-50 py-8 sm:py-16'>
|
||||
<div className='mx-auto'>
|
||||
<div className='mb-12 flex flex-col items-center justify-center text-center'>
|
||||
<div className='mb-4 inline-flex items-center justify-center rounded-full bg-red-100 p-2'>
|
||||
<Handshake className='h-6 w-6 text-red-600' />
|
||||
@ -31,27 +42,17 @@ export const PartnersSection = ({ partners }: PartnersSectionProps) => {
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className='grid grid-cols-2 gap-4 sm:gap-8 md:grid-cols-4'>
|
||||
{partners.map(({ id, name, poster }) => (
|
||||
<div
|
||||
key={id}
|
||||
className='flex h-32 flex-col items-center justify-center gap-0.5 rounded-lg bg-white p-6 shadow-md transition-transform hover:scale-105'
|
||||
data-aos='flip-left'
|
||||
>
|
||||
<Image
|
||||
src={
|
||||
poster ??
|
||||
`/placeholder.svg?height=80&width=160&text=Partner ${id}`
|
||||
}
|
||||
alt={`Partner ${id}`}
|
||||
width={160}
|
||||
height={80}
|
||||
className='max-h-16 w-auto'
|
||||
/>
|
||||
<h4 className='font-extralight'>{name}</h4>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<PartnersSlider
|
||||
partners={partnersFirstHalf}
|
||||
autoplaySpeed={3000}
|
||||
className='mb-12'
|
||||
/>
|
||||
|
||||
<PartnersSlider
|
||||
partners={partnersSecondHalf}
|
||||
autoplaySpeed={4000}
|
||||
direction='rtl'
|
||||
/>
|
||||
|
||||
<div className='mt-12 text-center'>
|
||||
<h3 className='mb-4 text-xl font-bold'>
|
||||
@ -60,11 +61,9 @@ export const PartnersSection = ({ partners }: PartnersSectionProps) => {
|
||||
<p className='mx-auto mb-6 max-w-2xl text-gray-600'>
|
||||
{t('home.partners.becomePartnerText')}
|
||||
</p>
|
||||
<Link href='#'>
|
||||
<Button className='bg-red-600 hover:bg-red-700'>
|
||||
{t('common.buttons.contactUs')}
|
||||
</Button>
|
||||
</Link>
|
||||
<Button className='bg-red-600 hover:bg-red-700'>
|
||||
{t('common.buttons.contactUs')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
75
src/widgets/partners-slider.tsx
Normal file
75
src/widgets/partners-slider.tsx
Normal file
@ -0,0 +1,75 @@
|
||||
'use client';
|
||||
|
||||
import Image from 'next/image';
|
||||
// Import Swiper styles
|
||||
import 'swiper/css';
|
||||
import { Autoplay, FreeMode } from 'swiper/modules';
|
||||
import { Swiper, SwiperSlide } from 'swiper/react';
|
||||
|
||||
import { Partners } from '@/app/api-utlities/@types';
|
||||
|
||||
interface PartnersSliderProps {
|
||||
partners: Partners;
|
||||
autoplaySpeed?: number;
|
||||
className?: string;
|
||||
direction?: 'ltr' | 'rtl';
|
||||
}
|
||||
|
||||
export function PartnersSlider({
|
||||
partners,
|
||||
autoplaySpeed = 3000,
|
||||
className = '',
|
||||
direction = 'ltr',
|
||||
}: PartnersSliderProps) {
|
||||
return (
|
||||
<div className={`w-full ${className}`}>
|
||||
<Swiper
|
||||
modules={[Autoplay, FreeMode]} // Register Swiper modules
|
||||
slidesPerView='auto'
|
||||
spaceBetween={30}
|
||||
loop={true}
|
||||
freeMode={true}
|
||||
speed={autoplaySpeed}
|
||||
grabCursor={true}
|
||||
autoplay={{
|
||||
delay: 1000,
|
||||
disableOnInteraction: false,
|
||||
pauseOnMouseEnter: false,
|
||||
reverseDirection: direction === 'rtl',
|
||||
}}
|
||||
allowTouchMove={true}
|
||||
breakpoints={{
|
||||
320: {
|
||||
slidesPerView: 2,
|
||||
spaceBetween: 5,
|
||||
},
|
||||
640: {
|
||||
slidesPerView: 3,
|
||||
spaceBetween: 20,
|
||||
},
|
||||
768: {
|
||||
slidesPerView: 4,
|
||||
spaceBetween: 30,
|
||||
},
|
||||
1024: {
|
||||
slidesPerView: 5,
|
||||
spaceBetween: 30,
|
||||
},
|
||||
}}
|
||||
>
|
||||
{partners.map((partner) => (
|
||||
<SwiperSlide key={partner.id}>
|
||||
<div className='flex h-32 items-center justify-center px-4'>
|
||||
<Image
|
||||
src={partner.poster || '/placeholder.svg'}
|
||||
alt={partner.name}
|
||||
fill
|
||||
className='w-auto scale-90 object-contain transition-transform hover:scale-105'
|
||||
/>
|
||||
</div>
|
||||
</SwiperSlide>
|
||||
))}
|
||||
</Swiper>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user