From dbb83267b2882594b8a9c3b0e360ab23248696ae Mon Sep 17 00:00:00 2001 From: "agentfarmx[bot]" <198411105+agentfarmx[bot]@users.noreply.github.com> Date: Wed, 26 Feb 2025 12:16:40 +0000 Subject: [PATCH 1/2] feat: add carousel component for feature cards display --- components/home.tsx | 209 ++++++++++++++++++++++++------------- components/ui/carousel.tsx | 112 ++++++++++++++++++++ 2 files changed, 251 insertions(+), 70 deletions(-) create mode 100644 components/ui/carousel.tsx diff --git a/components/home.tsx b/components/home.tsx index 713b596..a2a2b99 100644 --- a/components/home.tsx +++ b/components/home.tsx @@ -8,6 +8,7 @@ declare global { import { Button } from "@/components/ui/button"; import { Card } from "@/components/ui/card"; +import { Carousel } from "@/components/ui/carousel"; import { Downloads } from "@/lib/types"; import { DeviceDetails } from "@/lib/ua"; import { @@ -21,6 +22,9 @@ import { CheckCircle2, Sprout, Play, + Rocket, + Shield, + Globe, } from "lucide-react"; import Image from "next/image"; import Link from "next/link"; @@ -243,78 +247,143 @@ export default function Component({ {/* Feature Cards */}
-
- } - title="Zero Setup" - description="GitHub native integration" - gradient="from-[#ff6bfd] to-indigo-500" - details={[ - { - icon: , - text: "One-Click Setup", - }, - { - icon: , - text: "10-second task creation", - }, - { - icon: ( - - ), - text: "Parallel Execution", - }, - ]} - /> - } - title="Iterate on PR" - description="Automated PR workflow" - gradient="from-indigo-400 to-cyan-400" - details={[ - { - icon: , - text: "Smart PR suggestions", - }, - { - icon: , - text: "Automatic code reviews", - }, - { - icon: ( - - ), - text: "Continuous improvements", - }, - ]} - /> - } - title="Parallel Execution" - description="Run agents in parallel" - gradient="from-cyan-400 to-[#ff6bfd]" - details={[ - { - icon: , - text: "AGENTS AGENTS AGENTS", - }, - { - icon: , - text: "Efficient task distribution", - }, - { - icon: ( - - ), - text: "Real-time progress tracking", - }, - ]} - /> -
-
+

+ Our Features +

+ + {[ + } + title="Zero Setup" + description="GitHub native integration" + gradient="from-[#ff6bfd] to-indigo-500" + details={[ + { + icon: , + text: "One-Click Setup", + }, + { + icon: , + text: "10-second task creation", + }, + { + icon: , + text: "Parallel Execution", + }, + ]} + />, + } + title="Iterate on PR" + description="Automated PR workflow" + gradient="from-indigo-400 to-cyan-400" + details={[ + { + icon: , + text: "Smart PR suggestions", + }, + { + icon: , + text: "Automatic code reviews", + }, + { + icon: , + text: "Continuous improvements", + }, + ]} + />, + } + title="Parallel Execution" + description="Run agents in parallel" + gradient="from-cyan-400 to-[#ff6bfd]" + details={[ + { + icon: , + text: "AGENTS AGENTS AGENTS", + }, + { + icon: , + text: "Efficient task distribution", + }, + { + icon: , + text: "Real-time progress tracking", + }, + ]} + />, + } + title="Accelerated Development" + description="Boost your productivity" + gradient="from-green-400 to-blue-500" + details={[ + { + icon: , + text: "Automated code generation", + }, + { + icon: , + text: "Intelligent refactoring", + }, + { + icon: , + text: "Optimized workflows", + }, + ]} + />, + } + title="Enhanced Security" + description="Protect your codebase" + gradient="from-red-400 to-yellow-400" + details={[ + { + icon: , + text: "Vulnerability scanning", + }, + { + icon: , + text: "Security best practices", + }, + { + icon: , + text: "Compliance monitoring", + }, + ]} + />, + } + title="Global Collaboration" + description="Work together seamlessly" + gradient="from-purple-400 to-pink-400" + details={[ + { + icon: , + text: "Real-time collaboration", + }, + { + icon: , + text: "Cross-team integration", + }, + { + icon: , + text: "Unified workflow", + }, + ]} + />, + ]} + +
); -} +} \ No newline at end of file diff --git a/components/ui/carousel.tsx b/components/ui/carousel.tsx new file mode 100644 index 0000000..01a027c --- /dev/null +++ b/components/ui/carousel.tsx @@ -0,0 +1,112 @@ +"use client"; + +import React, { useState, useEffect } from "react"; +import { motion, AnimatePresence } from "framer-motion"; +import { ChevronLeft, ChevronRight } from "lucide-react"; +import { cn } from "@/lib/utils"; + +interface CarouselProps { + children: React.ReactNode[]; + autoPlay?: boolean; + interval?: number; + showArrows?: boolean; + showDots?: boolean; + className?: string; +} + +export function Carousel({ + children, + autoPlay = true, + interval = 5000, + showArrows = true, + showDots = true, + className, +}: CarouselProps) { + const [currentIndex, setCurrentIndex] = useState(0); + const [isPaused, setIsPaused] = useState(false); + + const handleNext = () => { + setCurrentIndex((prevIndex) => + prevIndex === children.length - 1 ? 0 : prevIndex + 1 + ); + }; + + const handlePrev = () => { + setCurrentIndex((prevIndex) => + prevIndex === 0 ? children.length - 1 : prevIndex - 1 + ); + }; + + const handleDotClick = (index: number) => { + setCurrentIndex(index); + }; + + useEffect(() => { + if (autoPlay && !isPaused) { + const timer = setTimeout(() => { + handleNext(); + }, interval); + + return () => clearTimeout(timer); + } + }, [currentIndex, autoPlay, interval, isPaused]); + + return ( +
setIsPaused(true)} + onMouseLeave={() => setIsPaused(false)} + > +
+ + + {children[currentIndex]} + + +
+ + {showArrows && ( + <> + + + + )} + + {showDots && ( +
+ {children.map((_, index) => ( +
+ )} +
+ ); +} \ No newline at end of file From 5854ecb4e1ae8c308e27ecc6eecb1f3cd1842f1a Mon Sep 17 00:00:00 2001 From: "agentfarmx[bot]" <198411105+agentfarmx[bot]@users.noreply.github.com> Date: Wed, 26 Feb 2025 12:28:00 +0000 Subject: [PATCH 2/2] feat(carousel): add responsive multi-card display to carousel component --- components/home.tsx | 2 +- components/ui/carousel.tsx | 97 +++++++++++++++++++++++++++++--------- 2 files changed, 75 insertions(+), 24 deletions(-) diff --git a/components/home.tsx b/components/home.tsx index a2a2b99..e41372f 100644 --- a/components/home.tsx +++ b/components/home.tsx @@ -250,7 +250,7 @@ export default function Component({

Our Features

- + {[ { + const handleResize = () => { + if (typeof window !== 'undefined') { + if (window.innerWidth < 640) { + setVisibleCardCount(1); + } else if (window.innerWidth < 768) { + setVisibleCardCount(2); + } else { + setVisibleCardCount(cardsToShow); + } + } + }; + + // Set initial value + handleResize(); + + // Add event listener + window.addEventListener('resize', handleResize); + + // Cleanup + return () => window.removeEventListener('resize', handleResize); + }, [cardsToShow]); + + // Calculate the total number of "pages" based on the number of cards to show + const totalPages = Math.ceil(children.length / visibleCardCount); const handleNext = () => { - setCurrentIndex((prevIndex) => - prevIndex === children.length - 1 ? 0 : prevIndex + 1 - ); + setCurrentIndex((prevIndex) => { + const nextIndex = prevIndex + visibleCardCount; + return nextIndex >= children.length ? 0 : nextIndex; + }); }; const handlePrev = () => { - setCurrentIndex((prevIndex) => - prevIndex === 0 ? children.length - 1 : prevIndex - 1 - ); + setCurrentIndex((prevIndex) => { + const nextIndex = prevIndex - visibleCardCount; + return nextIndex < 0 ? Math.max(0, children.length - visibleCardCount) : nextIndex; + }); }; - const handleDotClick = (index: number) => { - setCurrentIndex(index); + const handleDotClick = (pageIndex: number) => { + setCurrentIndex(pageIndex * visibleCardCount); }; useEffect(() => { @@ -51,6 +83,18 @@ export function Carousel({ } }, [currentIndex, autoPlay, interval, isPaused]); + // Get the current visible cards + const visibleCards = () => { + const cards = []; + for (let i = 0; i < visibleCardCount; i++) { + const index = currentIndex + i; + if (index < children.length) { + cards.push(children[index]); + } + } + return cards; + }; + return (
- {children[currentIndex]} + {visibleCards().map((card, index) => ( +
+ {card} +
+ ))}
@@ -91,20 +139,23 @@ export function Carousel({ )} - {showDots && ( + {showDots && totalPages > 1 && (
- {children.map((_, index) => ( -
)}