feat: add AboutSummary component with personal introduction and game preview

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
This commit is contained in:
2025-09-08 19:12:30 +02:00
parent fab7310436
commit a99b6353be
32 changed files with 1522 additions and 107 deletions

View File

@@ -0,0 +1,60 @@
"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;