'use client' import { useEffect, useState } from "react"; import Link from "next/link"; import { Autoplay } from "swiper/modules"; import { Swiper, SwiperSlide } from "swiper/react"; import "swiper/css"; import "swiper/css/autoplay"; const swiperOptions = { modules: [Autoplay], slidesPerView: 3, spaceBetween: 20, loop: true, autoplay: { delay: 2000, disableOnInteraction: false, pauseOnMouseEnter: false, }, breakpoints: { 0: { slidesPerView: 1 }, 768: { slidesPerView: 2 }, 1024: { slidesPerView: 3 }, }, }; export default function Testimonial() { const [reviews, setReviews] = useState([]); const [loading, setLoading] = useState(true); const [expandedReview, setExpandedReview] = useState(null); const [isClient, setIsClient] = useState(false); useEffect(() => { setIsClient(true); }, []); useEffect(() => { async function loadReviews() { try { const res = await fetch("/api/reviews"); const data = await res.json(); const cleaned = (data.reviews || []).filter(r => (r.text || r.description || r.snippet || r.review_text || r.body || r.content) && r.rating >= 4 ); setReviews(cleaned); } catch (error) { console.error("Failed to fetch reviews", error); } finally { setLoading(false); } } loadReviews(); }, []); const displayedReviews = reviews.length > 0 && reviews.length < 3 ? [...reviews, ...reviews, ...reviews] : reviews; function renderStars(rating) { return [...Array(5)].map((_, i) => ( )); } function getReviewText(r) { return r.text || r.description || r.snippet || r.review_text || r.body || r.content || ""; } function truncateText(text) { return text.length > 150 ? text.substring(0, 150) + "..." : text; } function getProfileImage(r) { // Normalize profile photo URLs const url = r.profile_photo_url || r.author_profile_photo_url || r.user?.thumbnail; if (!url) return "/default-user.png"; return url.startsWith("http") ? url : `https://lh3.googleusercontent.com/${url}`; } return (
Google Reviews

Hear from our happy customers

{loading &&

Loading reviews...

} {!loading && isClient && displayedReviews.length > 0 && ( {displayedReviews.map((r, index) => { const fullText = getReviewText(r); const isExpanded = expandedReview === index; return (
{r.author_name (e.target.src = "/default-user.png")} />

{r.author_name || r.user?.name || "Customer"}

{renderStars(r.rating)}

{isExpanded ? fullText : truncateText(fullText)}

{r.images && r.images.length > 0 && r.images.some(img => img && img !== "ky") && (
{r.images.map((img, i) => { if (!img || img === "ky") return null; const fixedImg = img.startsWith("http") ? img : `https://lh3.googleusercontent.com/${img}`; return ( Review image (e.target.style.display = "none")} /> ); })}
)} {fullText.length > 150 && ( )}
); })}
)}
Review us on Google
); }