diff --git a/app/page.tsx b/app/page.tsx index 638d1dc..2f4f388 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,3 +1,4 @@ +import ServiceCarousel from "@/components/ServiceCarousel"; import { Carousel, CarouselContent, @@ -347,13 +348,7 @@ export default function Home() { Strategic excellence across every dimension of modern PR
- - - {serviceCarousel.map(({ id, content }) => ( - {content} - ))} - - +
{/*Approach*/} diff --git a/components/ServiceCarousel.tsx b/components/ServiceCarousel.tsx new file mode 100644 index 0000000..bec0980 --- /dev/null +++ b/components/ServiceCarousel.tsx @@ -0,0 +1,139 @@ +"use client"; + +import { useState } from "react"; +import { + Carousel, + CarouselContent, + CarouselItem, +} from "@/components/ui/carousel"; +import CurrentSlide from "@/hooks/CurrentSlide"; +import Image from "next/image"; + +export default function CarouselWrapper() { + const serviceCarousel = [ + { + id: 0, + content: ( + <> +
+
+ campaign-strategy +
+
+

+ 01 +

+

+ Campaign Strategy +

+

+ Comprehensive planning from research to execution, crafted to + win hearts and minds. +

+
+
+
+
+
+
+
+
+
+ + ), + }, + { + id: 1, + content: ( + <> +
+
+ media-production +
+
+

+ 02 +

+

+ Media Production +

+

+ Cinematic storytelling through video, photography, and + multimedia content that captivates. +

+
+
+
+
+
+
+
+
+
+ + ), + }, + { + id: 2, + content: ( + <> +
+
+ research +
+
+

+ 03 +

+

+ Research & Analytics +

+

+ Data-driven insights that inform every decision and optimize + every outcome +

+
+
+
+
+
+
+
+
+
+ + ), + }, + ]; + const [api, setApi] = useState(); + + return ( + <> + + + {serviceCarousel.map(({ id, content }) => ( + {content} + ))} + + + + {/* All slide reading logic happens inside this component */} + + + ); +} diff --git a/hooks/CurrentSlide.tsx b/hooks/CurrentSlide.tsx new file mode 100644 index 0000000..8ccfb1e --- /dev/null +++ b/hooks/CurrentSlide.tsx @@ -0,0 +1,77 @@ +"use client"; + +import { useEffect, useState } from "react"; +import type { CarouselApi } from "@/components/ui/carousel"; + +export default function CurrentSlide({ + api, + total = 3, +}: { + api?: CarouselApi; + total?: number; +}) { + const [current, setCurrent] = useState(0); + + useEffect(() => { + if (!api) return; + + // Set initial slide + setCurrent(api.selectedScrollSnap()); + + const handler = () => setCurrent(api.selectedScrollSnap()); + api.on("select", handler); + + return () => api.off("select", handler); + }, [api]); + + const handleClick = (index: number) => { + if (!api) return; + api.scrollTo(index); // embla API command to jump to slide + }; + + return ( +
+ {Array.from({ length: total }).map((_, i) => { + const isActive = i === current; + + return ( + + ); + })} +
+ ); +}