214 lines
9.1 KiB
TypeScript
214 lines
9.1 KiB
TypeScript
"use client";
|
||
import React, { useState, useEffect } from 'react';
|
||
import { motion, AnimatePresence } from 'framer-motion';
|
||
import Image from 'next/image';
|
||
import { ArrowLeft, ArrowRight, Star, Quote } from 'lucide-react';
|
||
|
||
const testimonials = [
|
||
{
|
||
id: 1,
|
||
name: "Rajesh Kumar",
|
||
role: "Owner, Urban Bites – Chennai",
|
||
quote: "“Peak hours used to feel chaotic. With Dine360, billing is faster, kitchen sync is smooth, and we’ve reduced order mistakes drastically. It’s like having full control over the entire floor.”",
|
||
rating: 5,
|
||
avatar: "https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?q=80&w=200&auto=format&fit=crop"
|
||
},
|
||
{
|
||
id: 2,
|
||
name: "Emily Carter",
|
||
role: "Founder, Brew & Bean Café",
|
||
quote: "“We switched from spreadsheets and manual tracking to Dine360. Now inventory, sales, and reservations are all connected. It saves us hours every week and gives us clear performance insights.”",
|
||
rating: 5,
|
||
avatar: "https://images.unsplash.com/photo-1494790108377-be9c29b29330?q=80&w=200&auto=format&fit=crop"
|
||
},
|
||
{
|
||
id: 3,
|
||
name: "Michael Tan",
|
||
role: "Operations Head, Spice Route Group (3 Branches)",
|
||
quote: "“Managing multiple outlets was stressful before. With centralized reporting and branch-wise dashboards, we finally have clarity. Dine360 made scaling much easier.”",
|
||
rating: 5,
|
||
avatar: "https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?q=80&w=200&auto=format&fit=crop"
|
||
},
|
||
{
|
||
id: 4,
|
||
name: "Anita Sharma",
|
||
role: "Owner, Sweet Cravings Bakery",
|
||
quote: "“The inventory tracking feature alone paid for itself. We’ve cut down wastage and improved stock planning significantly. It’s simple, reliable, and built for real restaurant challenges.”",
|
||
rating: 5,
|
||
avatar: "https://images.unsplash.com/photo-1580489944761-15a19d654956?q=80&w=200&auto=format&fit=crop"
|
||
},
|
||
{
|
||
id: 5,
|
||
name: "David Morales",
|
||
role: "Founder, QuickBite Food Truck",
|
||
quote: "“Running a mobile operation needs speed and flexibility. Dine360 works perfectly on tablets and keeps everything synced — even when we’re on the move.”",
|
||
rating: 5,
|
||
avatar: "https://images.unsplash.com/photo-1500648767791-00dcc994a43e?q=80&w=200&auto=format&fit=crop"
|
||
}
|
||
];
|
||
|
||
interface TestimonialsProps {
|
||
title?: string;
|
||
subtitle?: string;
|
||
}
|
||
|
||
const Testimonials = ({ title, subtitle }: TestimonialsProps) => {
|
||
const [currentIndex, setCurrentIndex] = useState(0);
|
||
|
||
// Auto-slide functionality
|
||
useEffect(() => {
|
||
const timer = setInterval(() => {
|
||
handleNext();
|
||
}, 5000); // Change every 5 seconds
|
||
return () => clearInterval(timer);
|
||
}, [currentIndex]);
|
||
|
||
const handleNext = () => {
|
||
setCurrentIndex((prev) => (prev + 1) % testimonials.length);
|
||
};
|
||
|
||
const handlePrev = () => {
|
||
setCurrentIndex((prev) => (prev - 1 + testimonials.length) % testimonials.length);
|
||
};
|
||
|
||
return (
|
||
<section className="relative w-full bg-brand-cream py-32 lg:py-32 overflow-hidden flex items-center justify-center text-black">
|
||
|
||
{/* Background Paper Texture Overlay (Optional) */}
|
||
<div className="absolute inset-0 opacity-40 mix-blend-multiply z-0 pointer-events-none" />
|
||
|
||
<div className="container mx-auto px-6 max-w-7xl relative z-20">
|
||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-12 lg:gap-20 items-center">
|
||
|
||
{/* Left Column: Chef Image */}
|
||
<div className="relative flex justify-center lg:justify-start">
|
||
{/* Pattern */}
|
||
<div className="absolute top-20 right-10 grid grid-cols-5 gap-2 opacity-30 text-black">
|
||
{[...Array(20)].map((_, i) => <span key={i} className="text-xs">+</span>)}
|
||
</div>
|
||
|
||
{/* Main Image */}
|
||
<motion.div
|
||
initial={{ opacity: 0, x: -50 }}
|
||
whileInView={{ opacity: 1, x: 0 }}
|
||
viewport={{ once: true }}
|
||
transition={{ duration: 0.8 }}
|
||
className="relative w-[300px] md:w-[450px] h-[400px] md:h-[600px] z-10"
|
||
>
|
||
<Image
|
||
src="https://images.unsplash.com/photo-1577219491135-ce391730fb2c?q=80&w=1000&auto=format&fit=crop"
|
||
alt="Happy Chef"
|
||
fill
|
||
className="object-cover rounded-2xl shadow-2xl"
|
||
/>
|
||
</motion.div>
|
||
|
||
{/* Floating Tomatoes Bottom Left */}
|
||
{/* <motion.div
|
||
animate={{ y: [0, 10, 0] }}
|
||
transition={{ duration: 4, repeat: Infinity, ease: "easeInOut" }}
|
||
className="absolute bottom-0 left-0 w-32 h-32 md:w-48 md:h-48 z-20"
|
||
>
|
||
<img
|
||
src="https://images.unsplash.com/photo-1592924357228-91a4daadcfea?q=80&w=600&auto=format&fit=crop"
|
||
alt="Tomatoes"
|
||
className="object-contain w-full h-full rounded-full border-4 border-white shadow-lg"
|
||
/>
|
||
</motion.div> */}
|
||
</div>
|
||
|
||
|
||
{/* Right Column: Content */}
|
||
<div className="relative space-y-8">
|
||
|
||
{/* Header */}
|
||
<div>
|
||
<motion.h3
|
||
initial={{ opacity: 0, y: 10 }}
|
||
whileInView={{ opacity: 1, y: 0 }}
|
||
viewport={{ once: true }}
|
||
className="text-brand-red text-4xl italic"
|
||
>
|
||
{title || "Testimonials"}
|
||
</motion.h3>
|
||
<motion.h2
|
||
initial={{ opacity: 0, y: 10 }}
|
||
whileInView={{ opacity: 1, y: 0 }}
|
||
viewport={{ once: true }}
|
||
transition={{ delay: 0.1 }}
|
||
className="text-4xl md:text-5xl font-black text-black mt-2"
|
||
>
|
||
{subtitle || "What Clients Say About Dine360"}
|
||
</motion.h2>
|
||
</div>
|
||
|
||
{/* Quote Icon */}
|
||
<div className="w-16 h-16 rounded-full bg-brand-red flex items-center justify-center text-white text-3xl mt-6 shadow-lg shadow-brand-red/30">
|
||
<Quote className="w-8 h-8 fill-current" />
|
||
</div>
|
||
|
||
{/* Animated Testimonial Content */}
|
||
<div className="h-[250px] md:h-[200px] relative">
|
||
<AnimatePresence mode="wait">
|
||
<motion.div
|
||
key={currentIndex}
|
||
initial={{ opacity: 0, x: 20 }}
|
||
animate={{ opacity: 1, x: 0 }}
|
||
exit={{ opacity: 0, x: -20 }}
|
||
transition={{ duration: 0.4 }}
|
||
className="absolute inset-0"
|
||
>
|
||
<p className="text-gray-600 text-lg leading-relaxed italic mb-8">
|
||
"{testimonials[currentIndex].quote}"
|
||
</p>
|
||
|
||
<div className="flex items-center gap-4">
|
||
<div className="relative w-16 h-16 rounded-full overflow-hidden border-2 border-brand-red">
|
||
<Image
|
||
src={testimonials[currentIndex].avatar}
|
||
alt={testimonials[currentIndex].name}
|
||
fill
|
||
className="object-cover"
|
||
/>
|
||
</div>
|
||
<div>
|
||
<div className="flex gap-1 text-brand-red mb-1">
|
||
{[...Array(5)].map((_, i) => (
|
||
<Star
|
||
key={i}
|
||
className={`w-4 h-4 ${i < testimonials[currentIndex].rating ? 'fill-current' : 'text-gray-300'}`}
|
||
/>
|
||
))}
|
||
</div>
|
||
<h4 className="font-bold text-black text-lg">{testimonials[currentIndex].name}</h4>
|
||
<span className="text-sm text-gray-500">{testimonials[currentIndex].role}</span>
|
||
</div>
|
||
</div>
|
||
</motion.div>
|
||
</AnimatePresence>
|
||
</div>
|
||
|
||
{/* Navigation Buttons */}
|
||
<div className="flex gap-4 mt-8">
|
||
<button
|
||
onClick={handlePrev}
|
||
className="w-12 h-12 rounded-full border border-gray-300 flex items-center justify-center text-black hover:bg-black hover:text-white hover:border-black transition-all"
|
||
>
|
||
<ArrowLeft className="w-5 h-5" />
|
||
</button>
|
||
<button
|
||
onClick={handleNext}
|
||
className="w-12 h-12 rounded-full border border-gray-300 flex items-center justify-center text-black hover:bg-black hover:text-white hover:border-black transition-all"
|
||
>
|
||
<ArrowRight className="w-5 h-5" />
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
);
|
||
};
|
||
|
||
export default Testimonials;
|