Update
This commit is contained in:
103
resources/js/modules/upgrade/partials/upgrade-plan-carousel.tsx
Normal file
103
resources/js/modules/upgrade/partials/upgrade-plan-carousel.tsx
Normal file
@@ -0,0 +1,103 @@
|
||||
'use client';
|
||||
|
||||
import { Carousel, CarouselContent, CarouselItem, type CarouselApi } from '@/components/ui/carousel';
|
||||
import { cn } from '@/lib/utils';
|
||||
import Autoplay from 'embla-carousel-autoplay';
|
||||
import { CheckCircle, Handshake, Lock, Zap } from 'lucide-react';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
const upgradePlanData = [
|
||||
{
|
||||
icon: Zap,
|
||||
title: 'Remove watermarks',
|
||||
description: 'Export up to 50 watermark-free videos, perfect for posting to your creator channel (8¢ per video)',
|
||||
},
|
||||
{
|
||||
icon: CheckCircle,
|
||||
title: 'Personal license included',
|
||||
description: 'Full rights to use videos for personal social media, creator and non-commercial projects',
|
||||
},
|
||||
{
|
||||
icon: Lock,
|
||||
title: 'Lock in your pricing',
|
||||
description: 'Subscribe now and keep this price forever - even when we raise prices for new users',
|
||||
},
|
||||
{
|
||||
icon: Handshake,
|
||||
title: 'Support our development',
|
||||
description: 'Help us to improve and grow so you get the best features & experience',
|
||||
},
|
||||
];
|
||||
|
||||
const UpgradePlanCarousel = () => {
|
||||
const [api, setApi] = useState<CarouselApi>();
|
||||
const [current, setCurrent] = useState(0);
|
||||
const [count, setCount] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
if (!api) {
|
||||
return;
|
||||
}
|
||||
|
||||
setCount(api.scrollSnapList().length);
|
||||
setCurrent(api.selectedScrollSnap() + 1);
|
||||
|
||||
api.on('select', () => {
|
||||
setCurrent(api.selectedScrollSnap() + 1);
|
||||
});
|
||||
}, [api]);
|
||||
|
||||
const scrollTo = (index: number) => {
|
||||
api?.scrollTo(index);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="mx-auto w-full max-w-2xl space-y-4">
|
||||
<Carousel
|
||||
plugins={[
|
||||
Autoplay({
|
||||
delay: 5500,
|
||||
}),
|
||||
]}
|
||||
setApi={setApi}
|
||||
className="w-full"
|
||||
>
|
||||
<CarouselContent>
|
||||
{upgradePlanData.map((item, index) => {
|
||||
const IconComponent = item.icon;
|
||||
return (
|
||||
<CarouselItem key={index}>
|
||||
<div className="flex w-full items-center justify-center">
|
||||
<div className="space-y-2 text-center">
|
||||
<div className="mx-auto mb-0 flex h-20 w-20 items-center justify-center rounded-full">
|
||||
<IconComponent className="h-10 w-10" />
|
||||
</div>
|
||||
<h3 className="text-xl font-bold">{item.title}</h3>
|
||||
<p className="max-w-sm text-sm">{item.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
</CarouselItem>
|
||||
);
|
||||
})}
|
||||
</CarouselContent>
|
||||
</Carousel>
|
||||
|
||||
{/* Centered Dot Navigation */}
|
||||
<div className="flex justify-center space-x-2">
|
||||
{Array.from({ length: count }, (_, index) => (
|
||||
<button
|
||||
key={index}
|
||||
onClick={() => scrollTo(index)}
|
||||
className={cn(
|
||||
'h-3 w-3 rounded-full transition-all duration-200 hover:scale-110',
|
||||
current === index + 1 ? 'bg-primary scale-110' : 'bg-muted-foreground/30 hover:bg-muted-foreground/50',
|
||||
)}
|
||||
aria-label={`Go to slide ${index + 1}`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default UpgradePlanCarousel;
|
||||
Reference in New Issue
Block a user