oriyo_next/src/shared/components/promotion-slider.tsx
2025-04-30 17:00:52 +05:00

149 lines
4.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use client';
import { ChevronLeft, ChevronRight } from 'lucide-react';
import Image from 'next/image';
import Link from 'next/link';
import { useEffect, useState } from 'react';
import { useTextController } from '@/shared/language/hooks/use-text-controller';
import { Button } from '@/shared/shadcn-ui/button';
import { Card, CardContent } from '@/shared/shadcn-ui/card';
const promotions = [
{
id: 1,
title: 'Скидка 10% на премиум топливо',
description:
'Получите скидку 10% на премиум топливо при заправке от 30 литров',
image: '/placeholder.svg?height=200&width=400&text=Promotion 1',
validUntil: '31.12.2023',
},
{
id: 2,
title: 'Кофе в подарок',
description: 'Получите бесплатный кофе при заправке от 20 литров',
image: '/placeholder.svg?height=200&width=400&text=Promotion 2',
validUntil: '15.11.2023',
},
{
id: 3,
title: 'Двойные баллы по карте лояльности',
description: 'Получайте в 2 раза больше баллов при заправке в выходные дни',
image: '/placeholder.svg?height=200&width=400&text=Promotion 3',
validUntil: '30.11.2023',
},
{
id: 4,
title: 'Скидка на автомойку',
description: 'Скидка 20% на автомойку при заправке от 40 литров',
image: '/placeholder.svg?height=200&width=400&text=Promotion 4',
validUntil: '31.12.2023',
},
];
export default function PromotionSlider() {
const [currentIndex, setCurrentIndex] = useState(0);
const [visibleItems, setVisibleItems] = useState(3);
const { t } = useTextController();
useEffect(() => {
const handleResize = () => {
if (window.innerWidth < 640) {
setVisibleItems(1);
} else if (window.innerWidth < 1024) {
setVisibleItems(2);
} else {
setVisibleItems(3);
}
};
handleResize();
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
const nextSlide = () => {
setCurrentIndex((prevIndex) =>
prevIndex + visibleItems >= promotions.length ? 0 : prevIndex + 1,
);
};
const prevSlide = () => {
setCurrentIndex((prevIndex) =>
prevIndex === 0
? Math.max(0, promotions.length - visibleItems)
: prevIndex - 1,
);
};
return (
<div className='relative overflow-hidden'>
<div
className='flex transition-transform duration-300 ease-in-out'
style={{
transform: `translateX(-${currentIndex * (100 / visibleItems)}%)`,
}}
>
{promotions.map((promo) => (
<div
key={promo.id}
className='w-full flex-none p-2 sm:w-1/2 lg:w-1/3'
data-aos='zoom-in-right'
data-aos-duration='700'
>
<Card className='h-full overflow-hidden transition-shadow hover:shadow-lg'>
<div className='relative h-48'>
<Image
src={promo.image || '/placeholder.svg'}
alt={promo.title}
fill
className='object-cover'
/>
</div>
<CardContent className='p-4'>
<h3 className='mb-2 text-lg font-bold'>{promo.title}</h3>
<p className='mb-3 text-sm text-gray-600'>
{promo.description}
</p>
<div className='flex items-center justify-between'>
<span className='text-xs text-gray-500'>
Действует до: {promo.validUntil}
</span>
<Link href='#'>
<Button
variant='outline'
size='sm'
className='border-red-600 text-red-600 hover:bg-red-50'
>
{t('common.buttons.readMore')}
</Button>
</Link>
</div>
</CardContent>
</Card>
</div>
))}
</div>
<Button
variant='outline'
size='icon'
className='absolute top-1/2 left-0 z-10 -translate-y-1/2 border-gray-200 bg-white shadow-lg'
onClick={prevSlide}
>
<ChevronLeft className='h-4 w-4' />
<span className='sr-only'>Предыдущий</span>
</Button>
<Button
variant='outline'
size='icon'
className='absolute top-1/2 right-0 z-10 -translate-y-1/2 border-gray-200 bg-white shadow-lg'
onClick={nextSlide}
>
<ChevronRight className='h-4 w-4' />
<span className='sr-only'>Следующий</span>
</Button>
</div>
);
}