162 lines
5.1 KiB
TypeScript
162 lines
5.1 KiB
TypeScript
'use client';
|
||
|
||
import { ChevronLeft, ChevronRight } from 'lucide-react';
|
||
import Image from 'next/image';
|
||
import Link from 'next/link';
|
||
import { useEffect, useState } from 'react';
|
||
|
||
import { Discounts } from '@/app/api-utlities/@types/main';
|
||
|
||
import { Button } from '@/shared/shadcn-ui/button';
|
||
import { Card, CardContent } from '@/shared/shadcn-ui/card';
|
||
|
||
import { useLanguage } from '../language';
|
||
|
||
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',
|
||
},
|
||
];
|
||
|
||
interface PromotionSliderProps {
|
||
discounts: Discounts;
|
||
}
|
||
|
||
export default function PromotionSlider({ discounts }: PromotionSliderProps) {
|
||
const [currentIndex, setCurrentIndex] = useState(0);
|
||
const [visibleItems, setVisibleItems] = useState(3);
|
||
|
||
const { t } = useLanguage();
|
||
|
||
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)}%)`,
|
||
}}
|
||
>
|
||
{discounts.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.name}
|
||
fill
|
||
className='object-cover'
|
||
/>
|
||
</div>
|
||
<CardContent className='p-4'>
|
||
<h3 className='mb-2 text-lg font-bold'>{promo.name}</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.expiresAt
|
||
? `Действует до: ${promo.expiresAt}`
|
||
: null}
|
||
</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>
|
||
{discounts.length > 3 && (
|
||
<>
|
||
<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>
|
||
);
|
||
}
|