ios changes pending
This commit is contained in:
@@ -1,291 +1,449 @@
|
||||
import React, { useState, useEffect, useRef } from "react";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
import { ChevronLeft, ChevronRight } from "lucide-react";
|
||||
import { Card, CardContent } from "./ui/card";
|
||||
import { Button } from "./ui/button";
|
||||
import { motion, useAnimationControls } from "framer-motion";
|
||||
import { Star } from "lucide-react";
|
||||
import { ImageWithFallback } from "./figma/ImageWithFallback";
|
||||
|
||||
// High-quality Clutch logo placeholder
|
||||
const clutchLogo = "https://images.unsplash.com/photo-1560472354-b33ff0c44a43?w=120&h=60&fit=crop&auto=format";
|
||||
|
||||
import clutchLogo from '../assets/images/clutch-logo.png';
|
||||
import { useState, useEffect, useRef } from "react";
|
||||
import React from "react";
|
||||
|
||||
const testimonials = [
|
||||
{
|
||||
id: 1,
|
||||
name: "Sarah Chen",
|
||||
position: "CTO",
|
||||
company: "FinTech Innovations",
|
||||
image: "https://images.unsplash.com/photo-1494790108755-2616b332c5cd?w=150&h=150&fit=crop&auto=format",
|
||||
quote: "WDI brought SimpliTend to life with precision. A complex MVP, flawlessly executed and beautifully designed.",
|
||||
author: "Sayeed Saachi",
|
||||
title: "Founder, SimpliTend",
|
||||
rating: 5,
|
||||
text: "WDI transformed our legacy banking system into a modern, scalable platform. Their expertise in financial technology is unmatched.",
|
||||
projectType: "Banking Platform Modernization"
|
||||
projectName: "SimpliTend",
|
||||
projectLogo: "https://images.unsplash.com/photo-1559757148-5c350d0d3c56?w=60&h=60&fit=crop&auto=format"
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "Michael Rodriguez",
|
||||
position: "Founder & CEO",
|
||||
company: "HealthTech Solutions",
|
||||
image: "https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=150&h=150&fit=crop&auto=format",
|
||||
quote: "WDI turned a complex, multi-layered vision into a streamlined digital product. A highly capable and responsive team.",
|
||||
author: "Aimee Zoho",
|
||||
title: "Founder, Lean In World",
|
||||
rating: 5,
|
||||
text: "The mobile health app WDI developed has revolutionized patient care delivery. Exceptional attention to healthcare compliance and user experience.",
|
||||
projectType: "Healthcare Mobile App"
|
||||
projectName: "Lean In World",
|
||||
projectLogo: "https://images.unsplash.com/photo-1551434678-e076c223a692?w=60&h=60&fit=crop&auto=format"
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "Emily Watson",
|
||||
position: "VP of Digital Strategy",
|
||||
company: "RetailMax Corp",
|
||||
image: "https://images.unsplash.com/photo-1580489944761-15a19d654956?w=150&h=150&fit=crop&auto=format",
|
||||
quote: "WDI guided us from hybrid frustration to native transformation. Rock-solid delivery, scalable systems, and impressive uptime.",
|
||||
author: "Akarsh K Hebbar",
|
||||
title: "Founder, WOKA",
|
||||
rating: 5,
|
||||
text: "Our e-commerce platform's performance improved by 300% after WDI's optimization. Their technical expertise is outstanding.",
|
||||
projectType: "E-commerce Platform Enhancement"
|
||||
projectName: "WOKA",
|
||||
projectLogo: "https://images.unsplash.com/photo-1518186285589-2f7649de83e0?w=60&h=60&fit=crop&auto=format"
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: "James Thompson",
|
||||
position: "Chief Innovation Officer",
|
||||
company: "EduTech Pioneers",
|
||||
image: "https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=150&h=150&fit=crop&auto=format",
|
||||
quote: "WDI executed our vision perfectly. The design, user flow, and admin controls are just what we needed.",
|
||||
author: "Al Yusuf-Humaira",
|
||||
title: "Founder, SSA",
|
||||
rating: 5,
|
||||
text: "WDI's AI-powered learning platform has transformed how our students engage with content. Incredible innovation and execution.",
|
||||
projectType: "AI-Powered EdTech Platform"
|
||||
projectName: "SSA",
|
||||
projectLogo: "https://images.unsplash.com/photo-1503676260728-1c00da094a0b?w=60&h=60&fit=crop&auto=format"
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: "Lisa Park",
|
||||
position: "Operations Director",
|
||||
company: "LogiFlow Systems",
|
||||
image: "https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=150&h=150&fit=crop&auto=format",
|
||||
quote: "WDI delivered exactly what we needed—a scalable, secure, and smart RFQ engine.",
|
||||
author: "Amol Kasar",
|
||||
title: "Manager, Dorf Ketal",
|
||||
rating: 5,
|
||||
text: "The supply chain management system WDI built has streamlined our operations and reduced costs by 40%. Highly recommended.",
|
||||
projectType: "Supply Chain Management System"
|
||||
projectName: "Dorf Ketal",
|
||||
projectLogo: "https://images.unsplash.com/photo-1556742049-0cfed4f6a45d?w=60&h=60&fit=crop&auto=format"
|
||||
},
|
||||
{
|
||||
quote: "WDI helped us modernize our digital presence quickly—professional, responsive, and pixel-perfect.",
|
||||
author: "Anesh Kavle",
|
||||
title: "Founder, Dayal Tours & Travel",
|
||||
rating: 5,
|
||||
projectName: "Dayal Tours & Travel",
|
||||
projectLogo: "https://images.unsplash.com/photo-1571019613454-1cb2f99b2d8b?w=60&h=60&fit=crop&auto=format"
|
||||
},
|
||||
{
|
||||
quote: "WDI delivered beyond expectations. Their speed, structure, and collaborative energy made this complex platform a reality.",
|
||||
author: "Edward",
|
||||
title: "Founder, ReGroup",
|
||||
rating: 5,
|
||||
projectName: "ReGroup",
|
||||
projectLogo: "https://images.unsplash.com/photo-1611224923853-80b023f02d71?w=60&h=60&fit=crop&auto=format"
|
||||
},
|
||||
{
|
||||
quote: "WDI translated a complex financial vision into a user-friendly app. Their execution was on point.",
|
||||
author: "Faisal",
|
||||
title: "Founder, Tanami Capital",
|
||||
rating: 5,
|
||||
projectName: "Tanami Capital",
|
||||
projectLogo: "https://images.unsplash.com/photo-1590283603385-17ffb3a7f29f?w=60&h=60&fit=crop&auto=format"
|
||||
},
|
||||
{
|
||||
quote: "WDI's CRM gave us an exhibition edge—OCR scanning changed the game.",
|
||||
author: "Hiten Dedhia",
|
||||
title: "Director, Exhibition CRM System",
|
||||
rating: 5,
|
||||
projectName: "Exhibition CRM System",
|
||||
projectLogo: "https://images.unsplash.com/photo-1560472354-b33ff0c44a43?w=60&h=60&fit=crop&auto=format"
|
||||
},
|
||||
{
|
||||
quote: "WDI made fintech frictionless. From onboarding to investment, it flows like a smart conversation.",
|
||||
author: "Rakesh Bunathar",
|
||||
title: "Founder, SuperMoney Advisor App",
|
||||
rating: 5,
|
||||
projectName: "SuperMoney Advisor App",
|
||||
projectLogo: "https://images.unsplash.com/photo-1579621970563-ebec7560ff3e?w=60&h=60&fit=crop&auto=format"
|
||||
},
|
||||
{
|
||||
quote: "WDI helped us turn complex property cycles into an intuitive digital experience.",
|
||||
author: "Team Prosperty",
|
||||
title: "Team, Prosperty Platform",
|
||||
rating: 5,
|
||||
projectName: "Prosperty Platform",
|
||||
projectLogo: "https://images.unsplash.com/photo-1560518883-ce09059eeffa?w=60&h=60&fit=crop&auto=format"
|
||||
},
|
||||
{
|
||||
quote: "WDI executed my multi-phase platform with confidence and clarity. They turned ideas into an integrated system faster than expected.",
|
||||
author: "Mr. Oja Paul",
|
||||
title: "Founder, Angel-Driven Marketplace Platform",
|
||||
rating: 5,
|
||||
projectName: "Angel-Driven Marketplace Platform",
|
||||
projectLogo: "https://images.unsplash.com/photo-1611224923853-80b023f02d71?w=60&h=60&fit=crop&auto=format"
|
||||
},
|
||||
{
|
||||
quote: "WDI helped bring Moving Cargo to life—from vision to delivery, the process was smooth and professional.",
|
||||
author: "Mr Nicholas Shaak",
|
||||
title: "Founder, Moving Cargo",
|
||||
rating: 5,
|
||||
projectName: "Moving Cargo",
|
||||
projectLogo: "https://images.unsplash.com/photo-1586528116311-ad8dd3c8310d?w=60&h=60&fit=crop&auto=format"
|
||||
},
|
||||
{
|
||||
quote: "WDI transformed our leadership vision into a smart, scalable platform our teams love.",
|
||||
author: "KLC",
|
||||
title: "Team, KLC Learning and Content Management Platform",
|
||||
rating: 5,
|
||||
projectName: "KLC Learning and Content Management Platform",
|
||||
projectLogo: "https://images.unsplash.com/photo-1503676260728-1c00da094a0b?w=60&h=60&fit=crop&auto=format"
|
||||
},
|
||||
{
|
||||
quote: "WDI delivered a full-stack health-tech solution with precision and transparency.",
|
||||
author: "Priyank Mehta",
|
||||
title: "Founder, GSF Mobie App",
|
||||
rating: 5,
|
||||
projectName: "GSF Mobie App",
|
||||
projectLogo: "https://images.unsplash.com/photo-1559757148-5c350d0d3c56?w=60&h=60&fit=crop&auto=format"
|
||||
},
|
||||
{
|
||||
quote: "WDI built more than an app—they engineered a habit-forming digital solution with beautiful UX and great scalability.",
|
||||
author: "Rishabh Jain",
|
||||
title: "Founder, Grocery List Mobile Application",
|
||||
rating: 5,
|
||||
projectName: "Grocery List Mobile Application",
|
||||
projectLogo: "https://images.unsplash.com/photo-1556742049-0cfed4f6a45d?w=60&h=60&fit=crop&auto=format"
|
||||
},
|
||||
{
|
||||
quote: "WDI built more than an app—they digitized our entire feed ecosystem.",
|
||||
author: "Kevin",
|
||||
title: "Founder, Farm Feeder App",
|
||||
rating: 5,
|
||||
projectName: "Farm Feeder App",
|
||||
projectLogo: "https://images.unsplash.com/photo-1518186285589-2f7649de83e0?w=60&h=60&fit=crop&auto=format"
|
||||
},
|
||||
{
|
||||
quote: "WDI didn't just deliver code—they delivered a digital transformation. Scalable, stable, and beautifully engineered.",
|
||||
author: "Jay Ruparel",
|
||||
title: "Founder, Melbourne City Card",
|
||||
rating: 5,
|
||||
projectName: "Melbourne City Card",
|
||||
projectLogo: "https://images.unsplash.com/photo-1571019613454-1cb2f99b2d8b?w=60&h=60&fit=crop&auto=format"
|
||||
},
|
||||
{
|
||||
quote: "WDI turned our idea into a highly usable mobile platform—sleek, stable, and scalable.",
|
||||
author: "Shannon",
|
||||
title: "Founder, Cheers to the Season Mobile App Redesign",
|
||||
rating: 5,
|
||||
projectName: "Cheers to the Season Mobile App Redesign",
|
||||
projectLogo: "https://images.unsplash.com/photo-1580489944761-15a19d654956?w=60&h=60&fit=crop&auto=format"
|
||||
},
|
||||
{
|
||||
quote: "WDI gave us a high-performance platform to blend financial learning with fun. Seamless and smart.",
|
||||
author: "Ravi Sharma",
|
||||
title: "Founder, Nifty Eleven Fantasy Trading App",
|
||||
rating: 5,
|
||||
projectName: "Nifty Eleven Fantasy Trading App",
|
||||
projectLogo: "https://images.unsplash.com/photo-1579621970563-ebec7560ff3e?w=60&h=60&fit=crop&auto=format"
|
||||
},
|
||||
{
|
||||
quote: "The new Amble App makes heritage immersive, intuitive, and scalable—exactly what we envisioned.",
|
||||
author: "RPG Foundation",
|
||||
title: "Team, Amble App - New Version",
|
||||
rating: 5,
|
||||
projectName: "Amble App - New Version",
|
||||
projectLogo: "https://images.unsplash.com/photo-1611224923853-80b023f02d71?w=60&h=60&fit=crop&auto=format"
|
||||
},
|
||||
{
|
||||
quote: "WDI delivered a deeply integrated, future-ready system that cut our admin overheads drastically.",
|
||||
author: "Ravi Bajaj",
|
||||
title: "Manager, Travel Portal Module Addition to ZingHR System",
|
||||
rating: 5,
|
||||
projectName: "Travel Portal Module Addition to ZingHR System",
|
||||
projectLogo: "https://images.unsplash.com/photo-1586528116311-ad8dd3c8310d?w=60&h=60&fit=crop&auto=format"
|
||||
},
|
||||
{
|
||||
quote: "WDI executed my multi-phase platform with confidence and clarity. They turned ideas into an integrated system faster than expected.",
|
||||
author: "Matt Weightman",
|
||||
title: "Founder, MOT & Vehicle Management Portal",
|
||||
rating: 5,
|
||||
projectName: "MOT & Vehicle Management Portal",
|
||||
projectLogo: "https://images.unsplash.com/photo-1560472354-b33ff0c44a43?w=60&h=60&fit=crop&auto=format"
|
||||
}
|
||||
];
|
||||
|
||||
export const CarouselTestimonials = () => {
|
||||
const [currentIndex, setCurrentIndex] = useState(0);
|
||||
const [isAutoPlaying, setIsAutoPlaying] = useState(true);
|
||||
const intervalRef = useRef<NodeJS.Timeout | null>(null);
|
||||
// Star rating component
|
||||
const StarRating = ({ rating }: { rating: number }) => {
|
||||
return (
|
||||
<div className="flex gap-1">
|
||||
{Array.from({ length: 5 }).map((_, i) => (
|
||||
<Star
|
||||
key={i}
|
||||
className={`w-4 h-4 ${
|
||||
i < rating
|
||||
? 'text-yellow-400 fill-yellow-400'
|
||||
: 'text-gray-600 fill-gray-600'
|
||||
}`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// Auto-play functionality
|
||||
useEffect(() => {
|
||||
if (isAutoPlaying) {
|
||||
intervalRef.current = setInterval(() => {
|
||||
setCurrentIndex((prevIndex) =>
|
||||
prevIndex === testimonials.length - 1 ? 0 : prevIndex + 1
|
||||
);
|
||||
}, 5000);
|
||||
// Individual testimonial card
|
||||
const TestimonialCard = ({
|
||||
testimonial,
|
||||
onHover,
|
||||
onLeave
|
||||
}: {
|
||||
testimonial: typeof testimonials[0];
|
||||
onHover?: () => void;
|
||||
onLeave?: () => void;
|
||||
}) => {
|
||||
return (
|
||||
<div
|
||||
className="bg-card rounded-[10px] border border-border p-6 w-[400px] flex-shrink-0 hover:border-border/80 hover:shadow-lg transition-all duration-300 select-none"
|
||||
onMouseEnter={onHover}
|
||||
onMouseLeave={onLeave}
|
||||
style={{ userSelect: 'none' }}
|
||||
role="article"
|
||||
aria-label={`Testimonial from ${testimonial.author} at ${testimonial.projectName}`}
|
||||
>
|
||||
{/* Project Header - Image removed, text-only project name */}
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="font-medium text-foreground text-base">
|
||||
{testimonial.projectName}
|
||||
</span>
|
||||
</div>
|
||||
<StarRating rating={testimonial.rating} />
|
||||
</div>
|
||||
|
||||
{/* Quote */}
|
||||
<p className="text-muted-foreground leading-relaxed text-base mb-6">
|
||||
"{testimonial.quote}"
|
||||
</p>
|
||||
|
||||
{/* Author Info - Without Avatar */}
|
||||
<div className="pt-2 border-t border-border/50">
|
||||
<div className="font-medium text-foreground text-base">
|
||||
{testimonial.author}
|
||||
</div>
|
||||
<div className="text-muted-foreground text-sm mt-1">
|
||||
{testimonial.title}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// Single marquee component
|
||||
const MarqueeRow = ({ testimonials: rowTestimonials }: { testimonials: typeof testimonials }) => {
|
||||
const [isPaused, setIsPaused] = useState(false);
|
||||
const controls = useAnimationControls();
|
||||
const currentPositionRef = useRef(0);
|
||||
const animationRef = useRef<any>(null);
|
||||
const startTimeRef = useRef<number>(0);
|
||||
const pauseTimeRef = useRef<number>(0);
|
||||
|
||||
const ANIMATION_DURATION = 60; // seconds
|
||||
const TOTAL_DISTANCE = -100 * rowTestimonials.length; // total distance to travel
|
||||
|
||||
const startAnimation = async (fromPosition: number = 0) => {
|
||||
const remainingDistance = TOTAL_DISTANCE - fromPosition;
|
||||
const remainingDuration = (Math.abs(remainingDistance) / Math.abs(TOTAL_DISTANCE)) * ANIMATION_DURATION;
|
||||
|
||||
startTimeRef.current = Date.now();
|
||||
|
||||
try {
|
||||
await controls.start({
|
||||
x: [fromPosition, TOTAL_DISTANCE],
|
||||
transition: {
|
||||
duration: remainingDuration,
|
||||
ease: "linear",
|
||||
repeat: Infinity,
|
||||
repeatType: "loop",
|
||||
repeatDelay: 0,
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
// Animation was interrupted (paused)
|
||||
}
|
||||
};
|
||||
|
||||
const pauseAnimation = () => {
|
||||
controls.stop();
|
||||
pauseTimeRef.current = Date.now();
|
||||
|
||||
// Calculate current position based on elapsed time
|
||||
const elapsedTime = (pauseTimeRef.current - startTimeRef.current) / 1000;
|
||||
const progress = (elapsedTime % ANIMATION_DURATION) / ANIMATION_DURATION;
|
||||
currentPositionRef.current = TOTAL_DISTANCE * progress;
|
||||
};
|
||||
|
||||
const resumeAnimation = () => {
|
||||
startAnimation(currentPositionRef.current);
|
||||
};
|
||||
|
||||
// Start initial animation
|
||||
useEffect(() => {
|
||||
startAnimation();
|
||||
return () => {
|
||||
if (intervalRef.current) {
|
||||
clearInterval(intervalRef.current);
|
||||
}
|
||||
controls.stop();
|
||||
};
|
||||
}, [isAutoPlaying]);
|
||||
}, []);
|
||||
|
||||
const goToPrevious = () => {
|
||||
setIsAutoPlaying(false);
|
||||
setCurrentIndex(currentIndex === 0 ? testimonials.length - 1 : currentIndex - 1);
|
||||
};
|
||||
|
||||
const goToNext = () => {
|
||||
setIsAutoPlaying(false);
|
||||
setCurrentIndex(currentIndex === testimonials.length - 1 ? 0 : currentIndex + 1);
|
||||
};
|
||||
|
||||
const goToSlide = (index: number) => {
|
||||
setIsAutoPlaying(false);
|
||||
setCurrentIndex(index);
|
||||
};
|
||||
|
||||
// Resume auto-play after user interaction
|
||||
// Handle pause/resume
|
||||
useEffect(() => {
|
||||
if (!isAutoPlaying) {
|
||||
const resumeTimer = setTimeout(() => {
|
||||
setIsAutoPlaying(true);
|
||||
}, 10000); // Resume after 10 seconds
|
||||
|
||||
return () => clearTimeout(resumeTimer);
|
||||
if (isPaused) {
|
||||
pauseAnimation();
|
||||
} else {
|
||||
resumeAnimation();
|
||||
}
|
||||
}, [isAutoPlaying]);
|
||||
}, [isPaused]);
|
||||
|
||||
const handleCardHover = () => {
|
||||
setIsPaused(true);
|
||||
};
|
||||
|
||||
const handleCardLeave = () => {
|
||||
setIsPaused(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<section className="py-32 bg-background">
|
||||
<div className="container mx-auto px-6 lg:px-8">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8 }}
|
||||
viewport={{ once: true }}
|
||||
className="text-center mb-20"
|
||||
>
|
||||
<h2 className="text-4xl lg:text-5xl font-semibold text-foreground mb-6">
|
||||
What Our <span className="text-accent">Clients Say</span>
|
||||
</h2>
|
||||
<p className="text-xl text-muted-foreground max-w-3xl mx-auto leading-relaxed">
|
||||
Hear from industry leaders who have transformed their businesses with our innovative solutions.
|
||||
</p>
|
||||
</motion.div>
|
||||
<div
|
||||
className="flex overflow-hidden"
|
||||
role="region"
|
||||
aria-label="Client testimonials carousel"
|
||||
aria-live="polite"
|
||||
>
|
||||
<motion.div
|
||||
className="flex gap-6"
|
||||
animate={controls}
|
||||
onMouseEnter={handleCardHover}
|
||||
onMouseLeave={handleCardLeave}
|
||||
>
|
||||
{/* First set */}
|
||||
{rowTestimonials.map((testimonial, index) => (
|
||||
<TestimonialCard
|
||||
key={`first-${index}`}
|
||||
testimonial={testimonial}
|
||||
onHover={handleCardHover}
|
||||
onLeave={handleCardLeave}
|
||||
/>
|
||||
))}
|
||||
{/* Duplicate set for seamless loop */}
|
||||
{rowTestimonials.map((testimonial, index) => (
|
||||
<TestimonialCard
|
||||
key={`second-${index}`}
|
||||
testimonial={testimonial}
|
||||
onHover={handleCardHover}
|
||||
onLeave={handleCardLeave}
|
||||
/>
|
||||
))}
|
||||
</motion.div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
<div className="relative max-w-6xl mx-auto">
|
||||
{/* Main Testimonial Display */}
|
||||
<div className="relative overflow-hidden rounded-3xl">
|
||||
<AnimatePresence mode="wait">
|
||||
<motion.div
|
||||
key={currentIndex}
|
||||
initial={{ opacity: 0, x: 100 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
exit={{ opacity: 0, x: -100 }}
|
||||
transition={{ duration: 0.5, ease: "easeInOut" }}
|
||||
>
|
||||
<Card className="bg-card/50 backdrop-blur-md border-white/10 shadow-2xl">
|
||||
<CardContent className="p-12">
|
||||
<div className="grid lg:grid-cols-3 gap-12 items-center">
|
||||
{/* Client Photo and Info */}
|
||||
<div className="lg:col-span-1 text-center lg:text-left">
|
||||
<div className="relative mb-8">
|
||||
<div className="w-32 h-32 mx-auto lg:mx-0 rounded-full overflow-hidden border-4 border-accent/20">
|
||||
<ImageWithFallback
|
||||
src={testimonials[currentIndex].image}
|
||||
alt={testimonials[currentIndex].name}
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
{/* Rating Stars */}
|
||||
<div className="flex justify-center lg:justify-start gap-1 mt-6">
|
||||
{[...Array(testimonials[currentIndex].rating)].map((_, i) => (
|
||||
<Star key={i} className="w-5 h-5 fill-accent text-accent" />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<h3 className="text-2xl font-semibold text-foreground">
|
||||
{testimonials[currentIndex].name}
|
||||
</h3>
|
||||
<p className="text-accent font-medium">
|
||||
{testimonials[currentIndex].position}
|
||||
</p>
|
||||
<p className="text-muted-foreground">
|
||||
{testimonials[currentIndex].company}
|
||||
</p>
|
||||
<div className="pt-4">
|
||||
<span className="inline-block px-4 py-2 bg-accent/10 text-accent text-sm rounded-full border border-accent/20">
|
||||
{testimonials[currentIndex].projectType}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Testimonial Content */}
|
||||
<div className="lg:col-span-2">
|
||||
<div className="relative">
|
||||
{/* Quote Icon */}
|
||||
<div className="absolute -top-4 -left-4 text-6xl text-accent/20 font-serif">"</div>
|
||||
|
||||
<blockquote className="text-2xl lg:text-3xl text-foreground leading-relaxed font-medium pl-8">
|
||||
{testimonials[currentIndex].text}
|
||||
</blockquote>
|
||||
|
||||
{/* Clutch Logo */}
|
||||
<div className="flex items-center justify-end mt-8">
|
||||
<div className="text-sm text-muted-foreground mr-4">
|
||||
Verified Review on
|
||||
</div>
|
||||
<ImageWithFallback
|
||||
src={clutchLogo}
|
||||
alt="Clutch"
|
||||
className="h-8 w-auto opacity-70 hover:opacity-100 transition-opacity duration-300"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</motion.div>
|
||||
</AnimatePresence>
|
||||
</div>
|
||||
|
||||
{/* Navigation Controls */}
|
||||
<div className="flex items-center justify-center mt-12 gap-8">
|
||||
{/* Previous Button */}
|
||||
<Button
|
||||
variant="outline"
|
||||
size="lg"
|
||||
onClick={goToPrevious}
|
||||
className="w-14 h-14 rounded-full border-white/20 hover:border-accent/50 hover:bg-accent/10 transition-all duration-300"
|
||||
>
|
||||
<ChevronLeft className="w-6 h-6" />
|
||||
</Button>
|
||||
|
||||
{/* Dots Indicator */}
|
||||
<div className="flex gap-3">
|
||||
{testimonials.map((_, index) => (
|
||||
<button
|
||||
key={index}
|
||||
onClick={() => goToSlide(index)}
|
||||
className={`w-3 h-3 rounded-full transition-all duration-300 ${
|
||||
index === currentIndex
|
||||
? 'bg-accent scale-125'
|
||||
: 'bg-white/30 hover:bg-white/50'
|
||||
}`}
|
||||
aria-label={`Go to testimonial ${index + 1}`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Next Button */}
|
||||
<Button
|
||||
variant="outline"
|
||||
size="lg"
|
||||
onClick={goToNext}
|
||||
className="w-14 h-14 rounded-full border-white/20 hover:border-accent/50 hover:bg-accent/10 transition-all duration-300"
|
||||
>
|
||||
<ChevronRight className="w-6 h-6" />
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{/* Auto-play Indicator */}
|
||||
<div className="text-center mt-6">
|
||||
<button
|
||||
onClick={() => setIsAutoPlaying(!isAutoPlaying)}
|
||||
className="text-sm text-muted-foreground hover:text-foreground transition-colors duration-300"
|
||||
>
|
||||
{isAutoPlaying ? '⏸ Pause Auto-play' : '▶ Resume Auto-play'}
|
||||
</button>
|
||||
</div>
|
||||
// Clutch rating component
|
||||
const ClutchRating = () => {
|
||||
return (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, scale: 0.9 }}
|
||||
whileInView={{ opacity: 1, scale: 1 }}
|
||||
transition={{ duration: 0.6 }}
|
||||
viewport={{ once: true }}
|
||||
className="flex items-center gap-4 bg-card rounded-[10px] border border-border p-6 shadow-sm w-full max-w-sm mx-auto"
|
||||
>
|
||||
{/* Clutch Logo */}
|
||||
<div className="flex-shrink-0">
|
||||
<ImageWithFallback
|
||||
src={clutchLogo}
|
||||
alt="Clutch"
|
||||
className="w-16 h-16 object-contain rounded-lg"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Rating Info */}
|
||||
<div className="flex-1">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<span className="font-semibold text-foreground text-xl">4.9</span>
|
||||
<StarRating rating={5} />
|
||||
</div>
|
||||
<div className="text-muted-foreground text-base mb-1">
|
||||
(47 reviews)
|
||||
</div>
|
||||
<div className="text-muted-foreground text-sm">
|
||||
Top Web Development Company on Clutch
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
};
|
||||
|
||||
{/* Additional Social Proof */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8, delay: 0.3 }}
|
||||
viewport={{ once: true }}
|
||||
className="text-center mt-20 pt-16 border-t border-white/10"
|
||||
>
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-8 max-w-4xl mx-auto">
|
||||
<div className="space-y-2">
|
||||
<div className="text-3xl font-bold text-accent">98%</div>
|
||||
<div className="text-sm text-muted-foreground">Client Satisfaction</div>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<div className="text-3xl font-bold text-accent">150+</div>
|
||||
<div className="text-sm text-muted-foreground">Projects Delivered</div>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<div className="text-3xl font-bold text-accent">5.0</div>
|
||||
<div className="text-sm text-muted-foreground">Average Rating</div>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<div className="text-3xl font-bold text-accent">24/7</div>
|
||||
<div className="text-sm text-muted-foreground">Support Available</div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
export const CarouselTestimonials = () => {
|
||||
return (
|
||||
<section className="relative py-20 overflow-hidden">
|
||||
<div className="container mx-auto px-6 lg:px-8">
|
||||
{/* Centered Header */}
|
||||
<div className="text-center mb-16">
|
||||
<motion.h2
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8 }}
|
||||
viewport={{ once: true }}
|
||||
className="text-4xl lg:text-5xl font-semibold text-foreground mb-4"
|
||||
>
|
||||
What Our Clients Say
|
||||
</motion.h2>
|
||||
<motion.p
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8, delay: 0.2 }}
|
||||
viewport={{ once: true }}
|
||||
className="text-muted-foreground text-xl max-w-2xl mx-auto"
|
||||
>
|
||||
Don't just take our word for it. Here's what founders and product leaders say about working with us.
|
||||
</motion.p>
|
||||
</div>
|
||||
|
||||
{/* Single Row Marquee Testimonials */}
|
||||
<div className="mb-16">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 40 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8, delay: 0.3 }}
|
||||
viewport={{ once: true }}
|
||||
>
|
||||
<MarqueeRow testimonials={testimonials} />
|
||||
</motion.div>
|
||||
</div>
|
||||
|
||||
{/* Centered Clutch Rating */}
|
||||
<div className="flex justify-center">
|
||||
<ClutchRating />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
|
||||
@@ -1,272 +1,232 @@
|
||||
import React from "react";
|
||||
import { motion } from "framer-motion";
|
||||
import { Card, CardContent } from "./ui/card";
|
||||
import { ArrowRight, ExternalLink } from "lucide-react";
|
||||
import { Button } from "./ui/button";
|
||||
import { Badge } from "./ui/badge";
|
||||
import { ArrowRight, ExternalLink, TrendingUp, Users, Clock, Star } from "lucide-react";
|
||||
import { GridPattern } from "./GridPattern";
|
||||
import { ImageWithFallback } from "./figma/ImageWithFallback";
|
||||
import { navigateTo } from "../App";
|
||||
import regroupImage from '../assets/images/regroup.webp';
|
||||
import seezunImage from '../assets/images/seezun.webp';
|
||||
// import wokaImage from '../assets/images/woka.webp';
|
||||
import wokaAwardImage from '../assets/images/woka.webp';
|
||||
import tanamiImage from '../assets/images/tanami.webp';
|
||||
|
||||
// High-quality project images
|
||||
const regroupImage = "https://images.unsplash.com/photo-1551650975-87deedd944c3?w=600&h=400&fit=crop&auto=format";
|
||||
const seezunImage = "https://images.unsplash.com/photo-1512941937669-90a1b58e7e9c?w=600&h=400&fit=crop&auto=format";
|
||||
const wokaAwardImage = "https://images.unsplash.com/photo-1517077304055-6e89abbf09b0?w=600&h=400&fit=crop&auto=format";
|
||||
const featuredCaseStudy = {
|
||||
title: "Woka",
|
||||
description: "Developed Woka as a vibrant platform where learning meets play. With a safe and fun environment to explore, learn, and grow effortlessly.",
|
||||
achievement: "+300% User Retention",
|
||||
industryTags: ["Education", "Learning Platform"],
|
||||
image: wokaAwardImage,
|
||||
metrics: [
|
||||
{ label: "Active Users", value: "500K+" },
|
||||
{ label: "User Retention", value: "+300%" },
|
||||
{ label: "Learning Hours", value: "+180%" }
|
||||
]
|
||||
};
|
||||
|
||||
const caseStudies = [
|
||||
{
|
||||
id: 1,
|
||||
title: "Regroup",
|
||||
subtitle: "Social Networking Revolution",
|
||||
description: "A comprehensive social platform that connects communities worldwide with advanced messaging, group management, and content sharing capabilities.",
|
||||
image: regroupImage,
|
||||
category: "Social Platform",
|
||||
client: "Regroup Technologies",
|
||||
duration: "8 months",
|
||||
teamSize: "12 developers",
|
||||
technologies: ["React Native", "Node.js", "MongoDB", "WebRTC", "AWS"],
|
||||
results: [
|
||||
{ metric: "User Engagement", value: "+240%" },
|
||||
{ metric: "Active Communities", value: "50K+" },
|
||||
{ metric: "Daily Messages", value: "2.5M+" }
|
||||
],
|
||||
awards: ["Best Social App 2023", "Innovation Award"],
|
||||
link: "/projects/regroup",
|
||||
featured: true
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: "Seezun",
|
||||
subtitle: "Next-Gen E-commerce Platform",
|
||||
description: "Revolutionary e-commerce solution with AI-powered recommendations, seamless checkout, and integrated inventory management for modern retailers.",
|
||||
image: seezunImage,
|
||||
category: "E-commerce",
|
||||
client: "Seezun Retail",
|
||||
duration: "6 months",
|
||||
teamSize: "8 developers",
|
||||
technologies: ["React", "Python", "PostgreSQL", "Redis", "Stripe"],
|
||||
results: [
|
||||
{ metric: "Conversion Rate", value: "+180%" },
|
||||
{ metric: "Page Load Speed", value: "2.1s" },
|
||||
{ metric: "Customer Satisfaction", value: "4.9/5" }
|
||||
],
|
||||
awards: ["E-commerce Excellence Award"],
|
||||
link: "/projects/seezun",
|
||||
featured: true
|
||||
description: "Created Seezun as a dynamic customer-driven platform connecting buyers, sellers, and renters for a seamless marketplace that renders fashion accessible, sustainable, and affordable.",
|
||||
achievement: "+85% Brand Recognition",
|
||||
industryTags: ["Branding", "Fashion"],
|
||||
image: seezunImage
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: "Woka",
|
||||
subtitle: "Award-Winning Fitness App",
|
||||
description: "Comprehensive fitness and wellness platform with personalized workout plans, nutrition tracking, and community features that won multiple industry awards.",
|
||||
image: wokaAwardImage,
|
||||
category: "Health & Fitness",
|
||||
client: "Woka Wellness",
|
||||
duration: "10 months",
|
||||
teamSize: "15 developers",
|
||||
technologies: ["Flutter", "Firebase", "TensorFlow", "Apple HealthKit", "Google Fit"],
|
||||
results: [
|
||||
{ metric: "User Retention", value: "+320%" },
|
||||
{ metric: "Workout Completions", value: "1M+" },
|
||||
{ metric: "App Store Rating", value: "4.8/5" }
|
||||
],
|
||||
awards: ["App of the Year 2023", "Health Innovation Award", "User Choice Award"],
|
||||
link: "/projects/woka",
|
||||
featured: true
|
||||
title: "Regroup",
|
||||
description: "Built Regroup as a social platform that brings together passion, global connections, teamwork, and love for sports through a vibrant online community.",
|
||||
achievement: "+150% User Engagement",
|
||||
industryTags: ["Social Media", "Digital Products"],
|
||||
image: regroupImage
|
||||
},
|
||||
{
|
||||
title: "Tanami",
|
||||
description: "Revolutionized Tanami Capital into a powerful, intuitive platform that streamlines portfolio management and empowers users to grow their wealth effortlessly.",
|
||||
achievement: "+200% Portfolio Growth",
|
||||
industryTags: ["FinTech", "Wealth Management"],
|
||||
image: tanamiImage
|
||||
}
|
||||
];
|
||||
|
||||
const SmallCaseStudyCard = ({ study, index }: { study: typeof caseStudies[0]; index: number }) => {
|
||||
const getNavigationPath = (title: string) => {
|
||||
switch (title) {
|
||||
case 'Seezun':
|
||||
return '/projects/seezun';
|
||||
case 'Woka':
|
||||
return '/projects/woka';
|
||||
case 'Tanami':
|
||||
return '/projects/tanami';
|
||||
case 'Regroup':
|
||||
return '/projects/regroup';
|
||||
default:
|
||||
return '/case-studies';
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 50 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, delay: index * 0.1 }}
|
||||
viewport={{ once: true }}
|
||||
className="group bg-card rounded-[10px] overflow-hidden hover:bg-card/80 hover:shadow-lg hover:scale-[1.02] transition-all duration-300 cursor-pointer border border-transparent hover:border-border/50"
|
||||
onClick={() => navigateTo(getNavigationPath(study.title))}
|
||||
>
|
||||
<div className="relative aspect-[4/3] overflow-hidden bg-muted/30 px-2 rounded-[10px]">
|
||||
<ImageWithFallback
|
||||
src={study.image}
|
||||
alt={
|
||||
study.title === "Seezun" ? "Seezun fashion marketplace app banner showcasing mobile shopping experience" :
|
||||
study.title === "Woka" ? "Woka learning platform banner showcasing educational mobile app features" :
|
||||
study.title === "Tanami" ? "Tanami Capital financial platform banner showcasing investment portfolio management" :
|
||||
study.title === "Regroup" ? "Regroup mobile app banner showcasing sports networking features" :
|
||||
study.title
|
||||
}
|
||||
className={`w-full h-full ${["Seezun", "Woka", "Tanami", "Regroup"].includes(study.title) ? "object-contain" : "object-cover"} object-center ${["Seezun", "Woka", "Tanami", "Regroup"].includes(study.title) ? "group-hover:scale-[1.02]" : "group-hover:scale-105"} transition-transform duration-500 rounded-[10px]`}
|
||||
/>
|
||||
<div className="absolute top-4 left-4 z-10">
|
||||
<span className="px-3 py-1 bg-accent text-accent-foreground text-sm font-medium rounded-[10px]">
|
||||
{study.achievement}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="p-6">
|
||||
<h3 className="text-xl font-semibold text-foreground mb-3 group-hover:text-accent transition-colors duration-300">
|
||||
{study.title}
|
||||
</h3>
|
||||
<p className="text-muted-foreground text-sm mb-4 leading-relaxed">
|
||||
{study.description}
|
||||
</p>
|
||||
|
||||
<div className="flex flex-wrap gap-2 mb-4">
|
||||
{study.industryTags.map((tag) => (
|
||||
<span
|
||||
key={tag}
|
||||
className="px-3 py-1 bg-muted text-muted-foreground text-xs rounded-[10px]"
|
||||
>
|
||||
{tag}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<button
|
||||
className="text-accent text-sm font-medium hover:text-foreground transition-colors duration-300 flex items-center gap-2 group-hover:translate-x-1 transition-transform duration-300"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
navigateTo(getNavigationPath(study.title));
|
||||
}}
|
||||
>
|
||||
View Case Study <ArrowRight className="w-4 h-4" />
|
||||
</button>
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
};
|
||||
|
||||
export const CaseStudyHighlight = () => {
|
||||
return (
|
||||
<section className="py-32 bg-background">
|
||||
<div className="container mx-auto px-6 lg:px-8">
|
||||
{/* Section Header */}
|
||||
<section className="relative py-20 bg-background overflow-hidden">
|
||||
<GridPattern strokeDasharray="4 2" />
|
||||
|
||||
<div className="relative z-10 container mx-auto px-6 lg:px-8">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8 }}
|
||||
viewport={{ once: true }}
|
||||
className="text-center mb-20"
|
||||
className="text-center mb-16"
|
||||
>
|
||||
<Badge variant="outline" className="mb-6 border-accent/20 text-accent">
|
||||
Featured Work
|
||||
</Badge>
|
||||
<h2 className="text-4xl lg:text-5xl font-semibold text-foreground mb-6">
|
||||
Success Stories That <span className="text-accent">Define Excellence</span>
|
||||
<h2 className="text-3xl lg:text-4xl font-semibold text-foreground mb-4">
|
||||
See What We've Built
|
||||
</h2>
|
||||
<p className="text-xl text-muted-foreground max-w-3xl mx-auto leading-relaxed">
|
||||
Explore our award-winning projects that have transformed businesses and delighted millions of users worldwide.
|
||||
<p className="text-muted-foreground text-lg max-w-2xl mx-auto">
|
||||
Real results from real projects. Here's how we've helped companies scale their digital products.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
{/* Featured Case Studies Grid */}
|
||||
<div className="grid lg:grid-cols-3 gap-8 mb-16">
|
||||
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 50 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8 }}
|
||||
viewport={{ once: true }}
|
||||
className="bg-card rounded-[10px] overflow-hidden mb-12 group cursor-pointer hover:bg-card/80 hover:shadow-xl hover:scale-[1.01] transition-all duration-300 border border-transparent hover:border-accent/20"
|
||||
onClick={() => navigateTo('/projects/woka')}
|
||||
>
|
||||
<div className="grid lg:grid-cols-3 gap-0">
|
||||
<div className="lg:col-span-2 relative aspect-[16/10] sm:aspect-[16/9] overflow-hidden bg-muted/30 px-2 rounded-[10px]">
|
||||
<ImageWithFallback
|
||||
src={featuredCaseStudy.image}
|
||||
alt="Woka educational platform mobile app interface with award recognition and interactive learning features for children"
|
||||
className="w-full h-full object-contain object-center group-hover:scale-[1.02] transition-transform duration-700 rounded-[10px]"
|
||||
/>
|
||||
<div className="absolute top-6 left-6 z-10">
|
||||
<span className="px-4 py-2 bg-accent text-accent-foreground font-semibold rounded-[10px]">
|
||||
{featuredCaseStudy.achievement}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="p-8 lg:p-12 flex flex-col justify-center">
|
||||
<h3 className="text-3xl lg:text-4xl font-semibold text-foreground mb-6 group-hover:text-accent transition-colors duration-300">
|
||||
{featuredCaseStudy.title}
|
||||
</h3>
|
||||
<p className="text-muted-foreground mb-8 leading-relaxed">
|
||||
{featuredCaseStudy.description}
|
||||
</p>
|
||||
|
||||
<div className="space-y-4 mb-8">
|
||||
{featuredCaseStudy.metrics.map((metric) => (
|
||||
<div key={metric.label} className="flex justify-between items-center">
|
||||
<span className="text-muted-foreground text-sm">{metric.label}</span>
|
||||
<span className="text-foreground font-semibold">{metric.value}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="flex flex-wrap gap-2 mb-8">
|
||||
{featuredCaseStudy.industryTags.map((tag) => (
|
||||
<span
|
||||
key={tag}
|
||||
className="px-3 py-1 bg-muted text-muted-foreground text-sm rounded-[10px]"
|
||||
>
|
||||
{tag}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<button
|
||||
className="text-accent font-medium hover:text-foreground transition-colors duration-300 flex items-center gap-3 group-hover:translate-x-2 transition-transform duration-300"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
navigateTo('/projects/woka');
|
||||
}}
|
||||
>
|
||||
View Full Case Study <ArrowRight className="w-5 h-5" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8 mb-12">
|
||||
{caseStudies.map((study, index) => (
|
||||
<motion.div
|
||||
key={study.id}
|
||||
initial={{ opacity: 0, y: 40 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8, delay: index * 0.2 }}
|
||||
viewport={{ once: true }}
|
||||
whileHover={{ y: -8, scale: 1.02 }}
|
||||
className="group cursor-pointer"
|
||||
onClick={() => navigateTo(study.link)}
|
||||
>
|
||||
<Card className="bg-card/50 backdrop-blur-md border-white/10 hover:border-accent/30 transition-all duration-500 shadow-lg hover:shadow-2xl hover:shadow-accent/10 rounded-2xl overflow-hidden h-full">
|
||||
<CardContent className="p-0 flex flex-col h-full">
|
||||
{/* Image Header */}
|
||||
<div className="relative overflow-hidden">
|
||||
<ImageWithFallback
|
||||
src={study.image}
|
||||
alt={study.title}
|
||||
className="w-full h-64 object-cover transition-transform duration-500 group-hover:scale-110"
|
||||
/>
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-black/60 via-transparent to-transparent" />
|
||||
|
||||
{/* Category Badge */}
|
||||
<div className="absolute top-4 left-4">
|
||||
<Badge className="bg-accent/90 text-white border-0">
|
||||
{study.category}
|
||||
</Badge>
|
||||
</div>
|
||||
|
||||
{/* Awards */}
|
||||
{study.awards.length > 0 && (
|
||||
<div className="absolute top-4 right-4">
|
||||
<div className="bg-amber-500/90 text-white px-3 py-1 rounded-full text-xs font-medium flex items-center gap-1">
|
||||
<Star className="w-3 h-3 fill-current" />
|
||||
Award Winner
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Project Title Overlay */}
|
||||
<div className="absolute bottom-4 left-4 right-4">
|
||||
<h3 className="text-2xl font-bold text-white mb-1">
|
||||
{study.title}
|
||||
</h3>
|
||||
<p className="text-white/80 text-sm">
|
||||
{study.subtitle}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Content */}
|
||||
<div className="p-8 flex-1 flex flex-col">
|
||||
<p className="text-muted-foreground leading-relaxed mb-6 flex-1">
|
||||
{study.description}
|
||||
</p>
|
||||
|
||||
{/* Key Metrics */}
|
||||
<div className="grid grid-cols-3 gap-4 mb-6 p-4 bg-accent/5 rounded-lg border border-accent/10">
|
||||
{study.results.slice(0, 3).map((result, idx) => (
|
||||
<div key={idx} className="text-center">
|
||||
<div className="text-lg font-bold text-accent">
|
||||
{result.value}
|
||||
</div>
|
||||
<div className="text-xs text-muted-foreground">
|
||||
{result.metric}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Technologies */}
|
||||
<div className="mb-6">
|
||||
<p className="text-sm font-medium text-foreground mb-2">Technologies:</p>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{study.technologies.slice(0, 3).map((tech) => (
|
||||
<Badge key={tech} variant="secondary" className="text-xs bg-muted/50">
|
||||
{tech}
|
||||
</Badge>
|
||||
))}
|
||||
{study.technologies.length > 3 && (
|
||||
<Badge variant="secondary" className="text-xs bg-muted/50">
|
||||
+{study.technologies.length - 3} more
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Project Details */}
|
||||
<div className="grid grid-cols-2 gap-4 mb-6 text-sm">
|
||||
<div className="flex items-center gap-2 text-muted-foreground">
|
||||
<Clock className="w-4 h-4" />
|
||||
{study.duration}
|
||||
</div>
|
||||
<div className="flex items-center gap-2 text-muted-foreground">
|
||||
<Users className="w-4 h-4" />
|
||||
{study.teamSize}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Awards List */}
|
||||
{study.awards.length > 0 && (
|
||||
<div className="mb-6">
|
||||
<p className="text-sm font-medium text-foreground mb-2">Awards:</p>
|
||||
<div className="space-y-1">
|
||||
{study.awards.slice(0, 2).map((award, idx) => (
|
||||
<div key={idx} className="flex items-center gap-2 text-sm text-amber-600">
|
||||
<Star className="w-3 h-3 fill-current" />
|
||||
{award}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* CTA Button */}
|
||||
<Button
|
||||
variant="ghost"
|
||||
className="w-full justify-between text-accent hover:text-accent hover:bg-accent/10 group-hover:translate-x-1 transition-all duration-300 mt-auto"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
navigateTo(study.link);
|
||||
}}
|
||||
>
|
||||
<span>View Case Study</span>
|
||||
<ArrowRight className="w-4 h-4" />
|
||||
</Button>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</motion.div>
|
||||
<SmallCaseStudyCard key={study.title} study={study} index={index} />
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Call-to-Action */}
|
||||
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8, delay: 0.6 }}
|
||||
transition={{ duration: 0.6, delay: 0.8 }}
|
||||
viewport={{ once: true }}
|
||||
className="text-center"
|
||||
>
|
||||
<div className="bg-gradient-to-r from-accent/10 via-accent/5 to-accent/10 rounded-2xl p-8 border border-accent/20">
|
||||
<h3 className="text-2xl font-semibold text-foreground mb-4">
|
||||
Ready to Create Your Success Story?
|
||||
</h3>
|
||||
<p className="text-muted-foreground mb-6 max-w-2xl mx-auto">
|
||||
Join the ranks of industry leaders who have transformed their businesses with our innovative solutions.
|
||||
</p>
|
||||
<div className="flex flex-col sm:flex-row gap-4 justify-center">
|
||||
<Button
|
||||
size="lg"
|
||||
className="bg-accent hover:bg-accent/90 text-white"
|
||||
onClick={() => navigateTo("/case-studies")}
|
||||
>
|
||||
View All Case Studies
|
||||
<ExternalLink className="w-4 h-4 ml-2" />
|
||||
</Button>
|
||||
<Button
|
||||
size="lg"
|
||||
variant="outline"
|
||||
onClick={() => navigateTo("/start-a-project")}
|
||||
>
|
||||
Start Your Project
|
||||
<ArrowRight className="w-4 h-4 ml-2" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
onClick={() => navigateTo('/case-studies')}
|
||||
className="bg-accent hover:bg-accent/90 text-accent-foreground px-8 py-3 rounded-[10px]"
|
||||
>
|
||||
View All Case Studies <ExternalLink className="w-4 h-4 ml-2" />
|
||||
</Button>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Button } from "./ui/button";
|
||||
import { GridPattern } from "./GridPattern";
|
||||
import { SplineFallback } from "./SplineFallback";
|
||||
import { Calendar, Briefcase } from "lucide-react";
|
||||
import { navigateTo } from "../App";
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
export function HeroSection() {
|
||||
return (
|
||||
@@ -11,9 +11,20 @@ export function HeroSection() {
|
||||
|
||||
<div className="container mx-auto px-6 lg:px-8">
|
||||
<div className="flex flex-col-reverse lg:flex-row items-center gap-12 w-full py-24 relative z-10">
|
||||
<div className="w-full lg:w-1/2">
|
||||
{/* Left Content */}
|
||||
<motion.div
|
||||
className="w-full lg:w-1/2"
|
||||
initial={{ opacity: 0, x: -50 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ duration: 0.8 }}
|
||||
>
|
||||
{/* Animated Badge */}
|
||||
<div className="group relative inline-flex items-center rounded-full px-4 py-1.5 shadow-[inset_0_-8px_10px_#8fdfff1f] transition-shadow duration-500 ease-out hover:shadow-[inset_0_-5px_10px_#8fdfff3f] mb-6">
|
||||
<motion.div
|
||||
className="group relative inline-flex items-center rounded-full px-4 py-1.5 shadow-[inset_0_-8px_10px_#8fdfff1f] transition-shadow duration-500 ease-out hover:shadow-[inset_0_-5px_10px_#8fdfff3f] mb-6"
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, delay: 0.2 }}
|
||||
>
|
||||
<span
|
||||
className="absolute inset-0 block h-full w-full animate-gradient rounded-[inherit] bg-gradient-to-r from-[#ffaa40]/50 via-[#9c40ff]/50 to-[#ffaa40]/50 bg-[length:300%_100%] p-[1px]"
|
||||
style={{
|
||||
@@ -37,17 +48,32 @@ export function HeroSection() {
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
<h1 className="text-4xl sm:text-5xl md:text-6xl font-semibold tracking-tight text-white max-w-3xl">
|
||||
Architecting Digital Success for Startups & Enterprises
|
||||
</h1>
|
||||
<motion.h1
|
||||
className="text-4xl sm:text-5xl md:text-6xl font-semibold tracking-tight text-white max-w-3xl"
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8, delay: 0.3 }}
|
||||
>
|
||||
Architecting Digital Success for Startups & Enterprises
|
||||
</motion.h1>
|
||||
|
||||
<p className="mt-6 max-w-2xl text-lg text-gray-400">
|
||||
<motion.p
|
||||
className="mt-6 max-w-2xl text-lg text-gray-400"
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8, delay: 0.4 }}
|
||||
>
|
||||
We design and build secure, AI-powered apps and software tailored for scale, speed, and user engagement.
|
||||
</p>
|
||||
</motion.p>
|
||||
|
||||
<div className="mt-10 flex flex-col sm:flex-row gap-3">
|
||||
<motion.div
|
||||
className="mt-10 flex flex-col sm:flex-row gap-3"
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8, delay: 0.5 }}
|
||||
>
|
||||
<Button size="lg" className="whitespace-nowrap" onClick={() => navigateTo('/contact')}>
|
||||
<Calendar className="w-4 h-4" />
|
||||
Book a Free Consultation
|
||||
@@ -57,33 +83,109 @@ export function HeroSection() {
|
||||
<Briefcase className="w-4 h-4" />
|
||||
Explore Services
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
|
||||
<div className="w-full lg:w-1/2 h-[320px] md:h-[480px] lg:h-[560px] shrink-0 relative">
|
||||
{/* Animated Background Elements */}
|
||||
<div className="absolute inset-0 overflow-hidden rounded-xl">
|
||||
<div className="absolute top-1/4 left-1/4 w-32 h-32 bg-gradient-to-r from-[#E5195E]/20 to-purple-500/20 rounded-full blur-3xl animate-pulse"></div>
|
||||
<div className="absolute top-3/4 right-1/4 w-24 h-24 bg-gradient-to-r from-blue-500/20 to-cyan-500/20 rounded-full blur-2xl animate-pulse delay-1000"></div>
|
||||
<div className="absolute bottom-1/4 left-1/3 w-20 h-20 bg-gradient-to-r from-green-500/20 to-emerald-500/20 rounded-full blur-2xl animate-pulse delay-2000"></div>
|
||||
</div>
|
||||
|
||||
{/* Interactive 3D-like Animation */}
|
||||
<div className="relative w-full h-full rounded-xl overflow-hidden border border-gray-800/50 bg-gradient-to-br from-gray-900/50 to-gray-800/30 backdrop-blur-sm">
|
||||
<div className="absolute inset-0 bg-gradient-to-br from-[#E5195E]/5 to-purple-500/5 rounded-xl"></div>
|
||||
<div className="relative z-10 w-full h-full">
|
||||
<SplineFallback />
|
||||
{/* Right Side - Animated Gradient Background */}
|
||||
<motion.div
|
||||
className="w-full lg:w-1/2 h-[320px] md:h-[480px] lg:h-[560px] shrink-0 relative"
|
||||
initial={{ opacity: 0, x: 50 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ duration: 0.8, delay: 0.2 }}
|
||||
>
|
||||
<div className="w-full h-full relative overflow-hidden rounded-2xl">
|
||||
{/* Animated gradient background */}
|
||||
<div className="absolute inset-0 bg-gradient-to-r from-[#E5195E]/20 via-[#9c40ff]/20 to-[#ffaa40]/20 animate-gradient bg-[length:400%_400%]" />
|
||||
|
||||
{/* Floating orbs */}
|
||||
<div className="absolute inset-0">
|
||||
<motion.div
|
||||
className="absolute top-1/4 left-1/4 w-32 h-32 bg-[#E5195E]/30 rounded-full blur-xl"
|
||||
animate={{
|
||||
scale: [1, 1.2, 1],
|
||||
opacity: [0.3, 0.6, 0.3],
|
||||
}}
|
||||
transition={{
|
||||
duration: 4,
|
||||
repeat: Infinity,
|
||||
ease: "easeInOut",
|
||||
}}
|
||||
/>
|
||||
<motion.div
|
||||
className="absolute top-1/2 right-1/4 w-24 h-24 bg-[#9c40ff]/30 rounded-full blur-xl"
|
||||
animate={{
|
||||
scale: [1, 1.3, 1],
|
||||
opacity: [0.3, 0.5, 0.3],
|
||||
}}
|
||||
transition={{
|
||||
duration: 3,
|
||||
repeat: Infinity,
|
||||
ease: "easeInOut",
|
||||
delay: 1,
|
||||
}}
|
||||
/>
|
||||
<motion.div
|
||||
className="absolute bottom-1/3 left-1/2 w-20 h-20 bg-[#ffaa40]/30 rounded-full blur-xl"
|
||||
animate={{
|
||||
scale: [1, 1.1, 1],
|
||||
opacity: [0.3, 0.7, 0.3],
|
||||
}}
|
||||
transition={{
|
||||
duration: 5,
|
||||
repeat: Infinity,
|
||||
ease: "easeInOut",
|
||||
delay: 2,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Tech grid overlay */}
|
||||
<div className="absolute inset-0 opacity-10">
|
||||
<div
|
||||
className="w-full h-full"
|
||||
style={{
|
||||
backgroundImage: `
|
||||
linear-gradient(rgba(255,255,255,0.1) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(255,255,255,0.1) 1px, transparent 1px)
|
||||
`,
|
||||
backgroundSize: '40px 40px',
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Central focus point */}
|
||||
<div className="absolute inset-0 flex items-center justify-center">
|
||||
<motion.div
|
||||
className="w-3 h-3 bg-white rounded-full shadow-lg"
|
||||
animate={{
|
||||
scale: [1, 1.5, 1],
|
||||
opacity: [0.8, 1, 0.8],
|
||||
}}
|
||||
transition={{
|
||||
duration: 2,
|
||||
repeat: Infinity,
|
||||
ease: "easeInOut",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Subtle border */}
|
||||
<div className="absolute inset-0 rounded-2xl border border-white/10" />
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
|
||||
{/* Floating Elements */}
|
||||
<div className="absolute bottom-10 left-1/2 transform -translate-x-1/2 animate-bounce">
|
||||
{/* Floating scroll indicator */}
|
||||
<motion.div
|
||||
className="absolute bottom-10 left-1/2 transform -translate-x-1/2 animate-bounce"
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8, delay: 1.0 }}
|
||||
>
|
||||
<svg className="w-6 h-6 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 14l-7 7m0 0l-7-7m7 7V3" />
|
||||
</svg>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user