// components/CaseStudySlider.tsx import { motion } from "framer-motion"; import { Activity, ArrowUpRight, Building2, ChevronLeft, ChevronRight, FlaskConical, Globe, Heart, Package, PartyPopper, ShoppingCart, Star, Tractor, TrendingUp, Trophy, Tv, Users, Utensils } from "lucide-react"; import { useEffect, useRef, useState } from "react"; import { useNavigate } from "react-router-dom"; import ambleCase from "../src/images/amble-case.webp"; import amozCase from "../src/images/amozCase.webp"; import dkCase from "../src/images/dkCase.webp"; import farmCase from "../src/images/farmCase.webp"; import gtCase from "../src/images/gt-case.webp"; import leanCase from "../src/images/leanCase.webp"; import niftyCase from "../src/images/niftyCase.webp"; import prospertyCase from "../src/images/prospertyCase.webp"; import ranoutofCase from "../src/images/ranoutof-case.webp"; import RrCase from "../src/images/resturant-reward-case.webp"; import seezunCase from "../src/images/seezun-case.webp"; import simplitendCase from "../src/images/simplitendCase.webp"; import tcCase from "../src/images/tc-case.webp"; import vib360Case from "../src/images/vib360Case.webp"; import wokaCase from "../src/images/woka-case.webp"; import { ImageWithFallback } from "./figma/ImageWithFallback"; import { Badge } from "./ui/badge"; import { Button } from "./ui/button"; import { Card, CardContent } from "./ui/card"; // Internal data (no need to pass props) const defaultCaseStudies = [ { id: 1, title: "RanOutOf", image: ranoutofCase, category: "Lifestyle", industry: "Consumer", featured: true, link: "/projects/ranoutof", icon: Package }, { id: 2, title: "Seezun", image: seezunCase, category: "E-commerce", industry: "Retail", featured: true, link: "/projects/seezun", icon: ShoppingCart }, { id: 3, title: "Woka", image: wokaCase, category: "Health & Fitness", industry: "Healthcare", featured: true, link: "/projects/woka", icon: Tv }, { id: 6, title: "Traders Circuit", image: tcCase, category: "FinTech", industry: "Finance", featured: true, link: "/projects/traderscircuit", icon: TrendingUp }, { id: 7, title: "Good Times", image: gtCase, category: "Events", industry: "Entertainment", featured: true, link: "/projects/goodtimes", icon: PartyPopper }, { id: 8, title: "Resturant Reward App", image: RrCase, category: "Loyalty & Rewards", industry: "Hospitality", featured: false, link: "/comming-soon", icon: Utensils }, { id: 9, title: "Amble", image: ambleCase, category: "Social", industry: "Heritage", featured: false, link: "/projects/amble", icon: Users }, { id: 10, title: "Amoz", image: amozCase, category: "Lifestyle", industry: "Consumer", featured: false, link: "/projects/amoz", icon: Heart }, { id: 11, title: "Dorf Ketal", image: dkCase, category: "Lifestyle", industry: "Chemicals", featured: false, link: "/comming-soon", icon: FlaskConical }, { id: 12, title: "VIB360", image: vib360Case, category: "Lifestyle", industry: "Consumer", featured: false, link: "/projects/vib360", icon: Activity }, { id: 13, title: "Nifty 11", image: niftyCase, category: "Lifestyle", industry: "Consumer", featured: false, link: "/comming-soon", icon: Trophy }, { id: 14, title: "Prosperty", image: prospertyCase, category: "Lifestyle", industry: "Real Estate", featured: false, link: "/projects/prosperty", icon: Building2 }, { id: 15, title: "Simpletend", image: simplitendCase, category: "Health & Fitness", industry: "Healthcare", featured: false, link: "/projects/simpletend", icon: Activity }, { id: 16, title: "Farm Feeder", image: farmCase, category: "AgriTech", industry: "Agriculture", featured: false, link: "/comming-soon", icon: Tractor }, { id: 17, title: "Lean In World", image: leanCase, category: "AgriTech", industry: "Agriculture", featured: false, link: "/comming-soon", icon: Globe }, ]; interface CaseStudySliderProps { autoPlay?: boolean; autoPlayInterval?: number; } export const CaseStudySlider = ({ autoPlay = false, autoPlayInterval = 4000, }: CaseStudySliderProps) => { const [currentIndex, setCurrentIndex] = useState(0); const [isAutoPlaying, setIsAutoPlaying] = useState(autoPlay); const [visibleSlides, setVisibleSlides] = useState(3); const sliderRef = useRef(null); const containerRef = useRef(null); const navigate = useNavigate(); const caseStudies = defaultCaseStudies; const nextSlide = () => { setCurrentIndex((prev) => { const nextIndex = prev + 1; return nextIndex > caseStudies.length - visibleSlides ? 0 : nextIndex; }); }; const prevSlide = () => { setCurrentIndex((prev) => { const prevIndex = prev - 1; return prevIndex < 0 ? caseStudies.length - visibleSlides : prevIndex; }); }; const goToSlide = (index: number) => { setCurrentIndex(Math.min(index, caseStudies.length - visibleSlides)); }; useEffect(() => { if (!isAutoPlaying || !autoPlay) return; const interval = setInterval(nextSlide, autoPlayInterval); return () => clearInterval(interval); }, [isAutoPlaying, autoPlay, autoPlayInterval, visibleSlides]); // Calculate visible slides on resize useEffect(() => { const updateVisibleSlides = () => { if (!containerRef.current) return; const width = containerRef.current.offsetWidth; if (width < 640) setVisibleSlides(1); else if (width < 1024) setVisibleSlides(2); else setVisibleSlides(3); }; updateVisibleSlides(); window.addEventListener('resize', updateVisibleSlides); return () => window.removeEventListener('resize', updateVisibleSlides); }, []); const maxIndex = Math.max(0, caseStudies.length - visibleSlides); // Calculate the actual translation percentage const getTranslationPercentage = () => { if (visibleSlides >= caseStudies.length) return 0; return (currentIndex * (100 / visibleSlides)); }; return (
setIsAutoPlaying(false)} onMouseLeave={() => setIsAutoPlaying(autoPlay)} ref={containerRef} >
{/* Header */}
{caseStudies.length > visibleSlides && (
)}
{/* Slider Container */}
{caseStudies.map((study, index) => { const IconComponent = study.icon; return ( navigate(study.link)} > {/* Image */}
{/* Category Badge */}
{study.category}
{/* Featured Badge */} {study.featured && (
Featured
)} {/* Icon */}
); })}
{/* Dots Indicator */} {caseStudies.length > visibleSlides && (
{Array.from({ length: maxIndex + 1 }).map((_, index) => (
)}
); };