81 lines
2.4 KiB
TypeScript
81 lines
2.4 KiB
TypeScript
'use client';
|
|
|
|
import { useState, useEffect } from 'react';
|
|
|
|
interface Slide {
|
|
title: string;
|
|
description: string;
|
|
image: string;
|
|
}
|
|
|
|
interface HeroBannerProps {
|
|
slides?: Slide[];
|
|
}
|
|
|
|
const defaultSlides: Slide[] = [
|
|
{
|
|
title: 'AWS Cloud Services',
|
|
description: 'Professional cloud solutions for your business',
|
|
image: '/api/placeholder?width=800&height=400',
|
|
},
|
|
{
|
|
title: 'High Performance',
|
|
description: 'Optimized for speed and reliability',
|
|
image: '/api/placeholder?width=800&height=400',
|
|
},
|
|
{
|
|
title: '24/7 Support',
|
|
description: 'Round-the-clock technical support',
|
|
image: '/api/placeholder?width=800&height=400',
|
|
},
|
|
];
|
|
|
|
export default function HeroBanner({ slides = defaultSlides }: HeroBannerProps) {
|
|
const [currentSlide, setCurrentSlide] = useState(0);
|
|
|
|
useEffect(() => {
|
|
const timer = setInterval(() => {
|
|
setCurrentSlide((prev) => (prev + 1) % slides.length);
|
|
}, 5000);
|
|
return () => clearInterval(timer);
|
|
}, [slides.length]);
|
|
|
|
return (
|
|
<section className="relative h-64 sm:h-80 md:h-96 bg-gray-200 overflow-hidden">
|
|
<div
|
|
className="absolute inset-0 flex transition-transform duration-500 ease-in-out"
|
|
style={{ transform: `translateX(-${currentSlide * 100}%)` }}
|
|
>
|
|
{slides.map((slide, index) => (
|
|
<div key={index} className="w-full flex-shrink-0 relative">
|
|
<div className="absolute inset-0 bg-blue-600 bg-opacity-80"></div>
|
|
<div className="relative z-10 h-full flex items-center justify-center text-center text-white px-4">
|
|
<div>
|
|
<h1 className="text-2xl sm:text-3xl md:text-4xl lg:text-6xl font-bold mb-2 sm:mb-4">
|
|
{slide.title}
|
|
</h1>
|
|
<p className="text-sm sm:text-lg md:text-xl lg:text-2xl">
|
|
{slide.description}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
{/* Carousel indicators */}
|
|
<div className="absolute bottom-4 left-1/2 transform -translate-x-1/2 flex space-x-2">
|
|
{slides.map((_, index) => (
|
|
<button
|
|
key={index}
|
|
onClick={() => setCurrentSlide(index)}
|
|
className={`w-2 h-2 sm:w-3 sm:h-3 rounded-full ${
|
|
currentSlide === index ? 'bg-white' : 'bg-white bg-opacity-50'
|
|
}`}
|
|
aria-label={`Go to slide ${index + 1}`}
|
|
/>
|
|
))}
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|