feat: create Chip component for displaying technology tags feat: implement ExperienceCard component to showcase job experiences feat: add Experience component to list multiple job experiences feat: create Footer component with social links and copyright information feat: implement Hero component for the landing section with social links feat: add ImageCarousel component for displaying project images feat: create Navbar component with scroll effect and navigation links feat: implement ProjectItem component to display individual project details feat: add Skills component to showcase technical skills feat: create data module with skills, jobs, and projects information feat: define types for Skill, Job, and Project in types module chore: update package.json with new dependencies for Tailwind CSS and Lucide icons chore: add CV PDF file to public directory chore: remove unused SVG files from public directory chore: add new images for background and hero sections feat: implement formatDate utility function for date formatting
61 lines
1.6 KiB
TypeScript
61 lines
1.6 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
import Image from "next/image";
|
|
|
|
interface ImageCarouselProps {
|
|
id: string;
|
|
thumbnails: string[];
|
|
}
|
|
|
|
const ImageCarousel = ({ id, thumbnails }: ImageCarouselProps) => {
|
|
const [currentIndex, setCurrentIndex] = useState(0);
|
|
|
|
const goToSlide = (slideIndex: number) => {
|
|
setCurrentIndex(slideIndex);
|
|
};
|
|
|
|
return (
|
|
<div
|
|
id={id}
|
|
className="carousel relative shadow-lg w-full max-w-full md:max-w-[50hw] h-[40rem]"
|
|
>
|
|
<div className="relative w-full h-full overflow-hidden carousel-inner">
|
|
{thumbnails.map((thumbnail, index) => (
|
|
<div
|
|
key={index}
|
|
className={`absolute inset-0 w-full h-full transition-opacity duration-500 ease-in-out delay-250 ${
|
|
currentIndex === index ? "opacity-100" : "opacity-0"
|
|
}`}
|
|
>
|
|
<Image
|
|
alt={`Slide ${index + 1}`}
|
|
src={thumbnail}
|
|
fill
|
|
style={{ objectFit: "scale-down" }}
|
|
priority={index === 0}
|
|
/>
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
<div className="absolute bottom-0 z-10 flex justify-center w-full gap-2 py-2">
|
|
{thumbnails.map((_, index) => (
|
|
<button
|
|
key={index}
|
|
onClick={() => goToSlide(index)}
|
|
className={`text-2xl leading-none ${
|
|
currentIndex === index ? "text-white" : "text-white/50"
|
|
}`}
|
|
aria-label={`Go to slide ${index + 1}`}
|
|
>
|
|
•
|
|
</button>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default ImageCarousel;
|