diff --git a/src/app/globals.css b/src/app/globals.css index cc2537f..ab06696 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -26,3 +26,13 @@ body { color: var(--foreground); font-family: var(--font-outfit-sans), sans-serif; } + +/* Utility to hide scrollbars while maintaining functionality */ +.scrollbar-hide { + -ms-overflow-style: none; /* IE and Edge */ + scrollbar-width: none; /* Firefox */ +} + +.scrollbar-hide::-webkit-scrollbar { + display: none; /* Chrome, Safari and Opera */ +} diff --git a/src/app/volunteers/CarouselAssignments.tsx b/src/app/volunteers/CarouselAssignments.tsx index f15fb11..f5d72cb 100644 --- a/src/app/volunteers/CarouselAssignments.tsx +++ b/src/app/volunteers/CarouselAssignments.tsx @@ -13,7 +13,7 @@ async function AssignmentsCarousel() { return ( {assignments.map((e, i) => ( - +
{e.title}{i}

{e.description}

{/*Unused code from Figma:*/}

{e.id}

diff --git a/src/app/volunteers/CarouselTestimony.tsx b/src/app/volunteers/CarouselTestimony.tsx index c46dc44..b35b523 100644 --- a/src/app/volunteers/CarouselTestimony.tsx +++ b/src/app/volunteers/CarouselTestimony.tsx @@ -13,8 +13,8 @@ async function TestimonyCarousel() { }/**/ return ( - {testimony.map((e, i) => ( - + {testimony.map((e) => ( + {/*Unused code from Figma design
{e.title}{i}
*/}

{e.quote}

diff --git a/src/app/volunteers/CarouselVolunteer.tsx b/src/app/volunteers/CarouselVolunteer.tsx index 0873ccb..a4e00a4 100644 --- a/src/app/volunteers/CarouselVolunteer.tsx +++ b/src/app/volunteers/CarouselVolunteer.tsx @@ -14,8 +14,8 @@ async function VolunteerCarousel() { } return ( - {volunteers.map((e, i) => ( - + {volunteers.map((e) => ( + {e.name}
diff --git a/src/components/Carousel.tsx b/src/components/Carousel.tsx index d084541..cbc59bb 100644 --- a/src/components/Carousel.tsx +++ b/src/components/Carousel.tsx @@ -1,32 +1,113 @@ 'use client'; -import {useState, createContext, useContext} from 'react'; +import {useState, createContext, useRef, useEffect} from 'react'; const PageContext = createContext({page: 1,size:1}); function Carousel({children, pages, size, className}:{children: Array, pages:number, size:number, className?:string}) { const [page, setPage] = useState(0); + const scrollContainerRef = useRef(null); + function setter (p: number) { setPage(p); + // Scroll to the corresponding page + if (scrollContainerRef.current) { + const scrollContainer = scrollContainerRef.current; + const pageWidth = scrollContainer.offsetWidth; + scrollContainer.scrollTo({ + left: pageWidth * p, + behavior: 'smooth' + }); + } } + + // Handle scroll events to update active dot + useEffect(() => { + const scrollContainer = scrollContainerRef.current; + if (!scrollContainer || pages <= 1) return; + + const handleScroll = () => { + const scrollLeft = scrollContainer.scrollLeft; + const pageWidth = scrollContainer.offsetWidth; + const currentPage = Math.round(scrollLeft / pageWidth); + if (currentPage !== page && currentPage >= 0 && currentPage < pages) { + setPage(currentPage); + } + }; + + scrollContainer.addEventListener('scroll', handleScroll); + return () => scrollContainer.removeEventListener('scroll', handleScroll); + }, [pages, page]); + + // Create pages with items + const createPages = () => { + const pageElements = []; + for (let i = 0; i < pages; i++) { + const pageItems = []; + for (let j = i * size; j < Math.min((i + 1) * size, children.length); j++) { + const childElement = children[j] as React.ReactElement<{className?: string, children: React.ReactNode}>; + pageItems.push( + + {childElement.props.children} + + ); + } + + pageElements.push( +
    + + {pageItems} + +
+ ); + } + return pageElements; + }; + let dots; - if (pages>1){ - dots = (
- {[...Array(pages).keys()].map(i => ({setter(i)}} className={`${(page==i)?'opacity-100':'opacity-50'} select-none m-0.5 hover:opacity-70`}>●))} -
) + if (pages > 1) { + dots = ( +
+
+ {[...Array(pages).keys()].map(i => ( + + ))} +
+
+ ); } + return ( -
    - {children} - {dots} -
-); +
+
+ {createPages()} +
+ {dots} +
+ ); } -function CI ({children, className, index}:{children: Array, className:string, index:number}) { - const context = useContext(PageContext); - const visible = (index>=(context.size*context.page))&&(index<(context.size*(context.page+1))); +function CI ({children, className}:{children: React.ReactNode, className:string}) { return ( -
  • +
  • {children}
  • );