Add image carousel to expertise section
This commit is contained in:
10
frontend/website/package-lock.json
generated
10
frontend/website/package-lock.json
generated
@@ -16,6 +16,7 @@
|
||||
"@types/node": "^22.13.5",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"embla-carousel-autoplay": "^8.5.2",
|
||||
"embla-carousel-react": "^8.5.2",
|
||||
"lucide-react": "^0.476.0",
|
||||
"react": "^19.0.0",
|
||||
@@ -2602,6 +2603,15 @@
|
||||
"integrity": "sha512-xQ9oVLrun/eCG/7ru3R+I5bJ7shsD8fFwLEY7yPe27/+fDHCNj0OT5EoG5ZbFyOxOcG6yTwW8oTz/dWyFnyGpg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/embla-carousel-autoplay": {
|
||||
"version": "8.5.2",
|
||||
"resolved": "https://registry.npmjs.org/embla-carousel-autoplay/-/embla-carousel-autoplay-8.5.2.tgz",
|
||||
"integrity": "sha512-27emJ0px3q/c0kCHCjwRrEbYcyYUPfGO3g5IBWF1i7714TTzE6L9P81V6PHLoSMAKJ1aHoT2e7YFOsuFKCbyag==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"embla-carousel": "8.5.2"
|
||||
}
|
||||
},
|
||||
"node_modules/embla-carousel-react": {
|
||||
"version": "8.5.2",
|
||||
"resolved": "https://registry.npmjs.org/embla-carousel-react/-/embla-carousel-react-8.5.2.tgz",
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
"@types/node": "^22.13.5",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"embla-carousel-autoplay": "^8.5.2",
|
||||
"embla-carousel-react": "^8.5.2",
|
||||
"lucide-react": "^0.476.0",
|
||||
"react": "^19.0.0",
|
||||
|
||||
@@ -12,16 +12,20 @@ const About = () => {
|
||||
<ExpertiseSection
|
||||
title="Computer Vision"
|
||||
content="Expertise in developing and deploying computer vision models for various applications, including object detection, image classification, and more. Ask me about state-of-the-art real-time models for your business."
|
||||
imageUrl="https://gifs.cc/congratulation/congrats-animation-smiley-2018.gif"
|
||||
imageAlt="Computer Vision"
|
||||
images={[
|
||||
{ url: "https://gifs.cc/congratulation/congrats-animation-smiley-2018.gif", alt: "Computer Vision 1" },
|
||||
{ url: "https://example.com/image2.jpg", alt: "Computer Vision 2" },
|
||||
]}
|
||||
viewMoreLink="/computer-vision"
|
||||
imageOnLeft={true}
|
||||
/>
|
||||
<ExpertiseSection
|
||||
title="Natural Language Processing"
|
||||
content="Building NLP models for tasks such as sentiment analysis, text classification, and language generation. If you need a chatbot for your business and care about privacy, or a simple text classification algorithm to understand your data, I can help."
|
||||
imageUrl="/path/to/nlp-image.jpg"
|
||||
imageAlt="Natural Language Processing"
|
||||
images={[
|
||||
{ url: "/path/to/nlp-image.jpg", alt: "NLP 1" },
|
||||
{ url: "/path/to/nlp-image2.jpg", alt: "NLP 2" },
|
||||
]}
|
||||
viewMoreLink="/nlp"
|
||||
imageOnLeft={false}
|
||||
/>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import React from 'react';
|
||||
import { Button } from "@/components/ui/button";
|
||||
import ImageCarousel from './ImageCarousel';
|
||||
|
||||
interface ExpertiseSectionProps {
|
||||
title: string;
|
||||
content: string;
|
||||
imageUrl: string;
|
||||
imageAlt: string;
|
||||
images: { url: string; alt: string }[];
|
||||
viewMoreLink: string;
|
||||
imageOnLeft?: boolean;
|
||||
}
|
||||
@@ -13,18 +13,17 @@ interface ExpertiseSectionProps {
|
||||
const ExpertiseSection: React.FC<ExpertiseSectionProps> = ({
|
||||
title,
|
||||
content,
|
||||
imageUrl,
|
||||
imageAlt,
|
||||
images,
|
||||
viewMoreLink,
|
||||
imageOnLeft = false,
|
||||
}) => {
|
||||
return (
|
||||
<section className="expertise-section py-20 bg-gray-100">
|
||||
<div className={`container mx-auto flex flex-col md:flex-row items-center ${imageOnLeft ? 'md:flex-row-reverse' : ''}`}>
|
||||
<div className="md:w-1/2 mb-8 md:mb-0">
|
||||
<img src={imageUrl} alt={imageAlt} className="rounded-lg shadow-md" />
|
||||
<div className="md:w-1/3 mb-8 mx-10 md:mb-0">
|
||||
<ImageCarousel images={images} />
|
||||
</div>
|
||||
<div className="md:w-1/2 md:px-8">
|
||||
<div className="md:w-2/3 md:px-8">
|
||||
<h2 className="text-3xl font-bold mb-4">{title}</h2>
|
||||
<p className="text-lg mb-4">{content}</p>
|
||||
<Button asChild>
|
||||
|
||||
40
frontend/website/src/components/ImageCarousel.tsx
Normal file
40
frontend/website/src/components/ImageCarousel.tsx
Normal file
@@ -0,0 +1,40 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
Carousel,
|
||||
CarouselContent,
|
||||
CarouselItem,
|
||||
CarouselNext,
|
||||
CarouselPrevious,
|
||||
} from "@/components/ui/carousel";
|
||||
import Autoplay from "embla-carousel-autoplay";
|
||||
|
||||
interface ImageCarouselProps {
|
||||
images: { url: string; alt: string }[];
|
||||
delay?: number;
|
||||
}
|
||||
|
||||
const ImageCarousel: React.FC<ImageCarouselProps> = ({ images, delay = 8000 }) => {
|
||||
return (
|
||||
<div className="relative">
|
||||
<Carousel
|
||||
plugins={[
|
||||
Autoplay({
|
||||
delay,
|
||||
}),
|
||||
]}
|
||||
>
|
||||
<CarouselContent>
|
||||
{images.map((image, index) => (
|
||||
<CarouselItem key={index}>
|
||||
<img src={image.url} alt={image.alt} className="rounded-lg shadow-md" />
|
||||
</CarouselItem>
|
||||
))}
|
||||
</CarouselContent>
|
||||
<CarouselPrevious />
|
||||
<CarouselNext />
|
||||
</Carousel>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ImageCarousel;
|
||||
Reference in New Issue
Block a user