'use client' import { useState, useEffect } from 'react' import Image from 'next/image' import styles from './Testimonials.module.css' import { Swiper, SwiperSlide } from 'swiper/react' import { Autoplay, Navigation } from 'swiper/modules' import 'swiper/css' import 'swiper/css/navigation' import { FaStar, FaChevronLeft, FaChevronRight } from 'react-icons/fa' interface Review { text?: string; description?: string; snippet?: string; review_text?: string; body?: string; content?: string; rating: number; profile_photo_url?: string; author_profile_photo_url?: string; user?: { thumbnail?: string; name?: string; }; author_name?: string; } export default function Testimonials() { const [reviews, setReviews] = useState([]); const [loading, setLoading] = useState(true); const [expandedReview, setExpandedReview] = useState(null); const [swiperInstance, setSwiperInstance] = useState(null); const testimonial_list_slider: any = { spaceBetween: 30, slidesPerView: 3, navigation: { prevEl: `.${styles.prevArrow}`, nextEl: `.${styles.nextArrow}`, }, pagination: false, loop: true, autoplay: { delay: 3000, disableOnInteraction: false, }, modules: [Autoplay, Navigation], breakpoints: { 0: { slidesPerView: 1, }, 768: { slidesPerView: 2, }, 1024: { slidesPerView: 3, }, } }; // Auto-collapse expanded review after 10 seconds and handle autoplay useEffect(() => { if (expandedReview !== null) { // Stop autoplay when a review is expanded if (swiperInstance && swiperInstance.autoplay) { swiperInstance.autoplay.stop(); } const timer = setTimeout(() => { setExpandedReview(null); }, 10000); // 10 seconds return () => { clearTimeout(timer); }; } else { // Resume autoplay when reviews are collapsed if (swiperInstance && swiperInstance.autoplay) { swiperInstance.autoplay.start(); } } }, [expandedReview, swiperInstance]); useEffect(() => { async function loadReviews() { try { const res = await fetch("/api/reviews"); if (!res.ok) { let details = "Unknown error"; try { const errorData = await res.json(); details = errorData.details || errorData.error || "No details"; } catch (e) { } console.error(`HTTP error! status: ${res.status} - ${details}`); setLoading(false); return; } const text = await res.text(); let dataAt; try { dataAt = JSON.parse(text); } catch (e) { console.error("Home: Invalid JSON response", text.slice(0, 100)); return; } const cleaned = (dataAt.reviews || []).filter((r: Review) => (r.text || r.description || r.snippet || r.review_text || r.body || r.content) && r.rating >= 4 ); setReviews(cleaned); } catch (error) { console.error("Home: Failed to fetch reviews", error); } finally { setLoading(false); } } loadReviews(); }, []); const displayedReviews = reviews.length > 0 && reviews.length < 3 ? [...reviews, ...reviews, ...reviews] : reviews; function renderStars(rating: number) { return [...Array(5)].map((_, i) => ( )); } function getReviewText(r: Review) { return r.text || r.description || r.snippet || r.review_text || r.body || r.content || ""; } function truncateText(text: string) { return text.length > 150 ? text.substring(0, 150) + "..." : text; } function getProfileImage(r: Review) { const url = r.profile_photo_url || r.author_profile_photo_url || r.user?.thumbnail; if (!url) return null; return url.startsWith("http") ? url : `https://lh3.googleusercontent.com/${url}`; } function getInitials(name: string) { if (!name) return "U"; return name.split(' ').map(n => n[0]).join('').substring(0, 2).toUpperCase(); } return (
Antalya Dinner Icon ANTALYA Antalya Cutlery Icon

Testimonials

{loading ? (

Loading reviews...

) : ( <> {displayedReviews.map((r, index) => { const fullText = getReviewText(r); const isExpanded = expandedReview === index; const profileImg = getProfileImage(r); const name = r.user?.name || r.author_name || "Customer"; return (
{profileImg ? ( {name} ((e.target as HTMLImageElement).src = '/images/placeholder.png')} /> ) : (
{getInitials(name)}
)}

{name}

{renderStars(r.rating)}

"{isExpanded ? fullText : truncateText(fullText)}"

); })}
)}
) }