2026-04-03 18:30:31 +05:30

214 lines
9.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"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 weve reduced order mistakes drastically. Its 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. Weve cut down wastage and improved stock planning significantly. Its 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 were 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;