From 86f72c7b0bbc66039e62a9fdc31b5b2d35859bc6 Mon Sep 17 00:00:00 2001 From: selvi Date: Sat, 18 Apr 2026 18:28:21 +0530 Subject: [PATCH] google review integration updated --- app/about/AboutClient.tsx | 56 ++-- app/api/google-reviews/route.ts | 59 ++++ app/contact/ContactClient.tsx | 2 +- components/GoogleReviewsBranding.tsx | 60 ++++ components/slider/TestimonialSlider1.tsx | 345 +++++++++++++++++++++++ 5 files changed, 484 insertions(+), 38 deletions(-) create mode 100644 app/api/google-reviews/route.ts create mode 100644 components/GoogleReviewsBranding.tsx create mode 100644 components/slider/TestimonialSlider1.tsx diff --git a/app/about/AboutClient.tsx b/app/about/AboutClient.tsx index daa6ff4..053998d 100644 --- a/app/about/AboutClient.tsx +++ b/app/about/AboutClient.tsx @@ -3,19 +3,12 @@ import Link from 'next/link'; import Image from 'next/image'; import { useState, useEffect } from 'react'; +import TestimonialSlider1 from '@/components/slider/TestimonialSlider1'; +import GoogleReviewsBranding from '@/components/GoogleReviewsBranding'; export default function AboutPage() { - const [testIndex, setTestIndex] = useState(0); const [openFaq, setOpenFaq] = useState(null); - const testimonials = [ - { quote: "VG Fence consistently delivers high-quality materials on time. Their contractor pricing allows me to stay competitive, and their inventory is unmatched.", author: "Mark S.", role: "Local Fence Contractor" }, - { quote: "Their galvanized and black finish railings are top-notch. It's rare to find a supplier that combines durability with such an aesthetic appeal.", author: "Sarah L.", role: "Property Manager" }, - { quote: "The team at VG Fence is incredibly knowledgeable. They helped us select the right ornamental fencing for our latest residential development.", author: "David K.", role: "Construction Manager" } - ]; - - const nextTestimonial = () => setTestIndex((prev) => (prev + 1) % testimonials.length); - const prevTestimonial = () => setTestIndex((prev) => (prev - 1 + testimonials.length) % testimonials.length); const faqs = [ { question: "Do you offer contractor pricing?", answer: "Yes! We provide dedicated contractor accounts with specialized pricing. You need to create an account and verify your business details to unlock these rates." }, @@ -25,15 +18,6 @@ export default function AboutPage() { { question: "Can I order custom gate sizes?", answer: "Absolutely. We specialize in custom gate fabrication. You can provide us with your specific dimensions and requirements, and we will manufacture them to fit your project perfectly." }, ]; - // Auto-slide effect - useEffect(() => { - const interval = setInterval(() => { - nextTestimonial(); - }, 5000); // Change slide every 5 seconds - - return () => clearInterval(interval); - }, [testIndex]); // Reset timer when index changes (manual navigation) - return (
{/* Inner Banner */} @@ -109,27 +93,25 @@ export default function AboutPage() { */} {/* Testimonial Section (Slider) */} -
+
-
Testimonials
-

What Our Partners Say.

+
Google Reviews
+

What Our Clients Say.

+
+ +
-
-
- {testimonials.map((test, idx) => ( -
-
-
{test.quote}
-
{test.author}
-
{test.role}
-
-
- ))} -
-
- - -
+ + +
+ + Review us on Google +
diff --git a/app/api/google-reviews/route.ts b/app/api/google-reviews/route.ts new file mode 100644 index 0000000..f3b6bec --- /dev/null +++ b/app/api/google-reviews/route.ts @@ -0,0 +1,59 @@ +import { NextResponse } from 'next/server'; + +// Required for Next.js static export (output: 'export' in next.config.ts) +export const dynamic = 'force-static'; +export const revalidate = 3600; // Re-fetch at most every hour + +export async function GET() { + const apiKey = "37eb7f83988cfd76ffb5c5af9adc25652efe5607e39997fc7d0e054d690ef25e"; + // VG Fence Products, Ayr, ON - data_id from Google Maps + const dataId = "0x0:0xd39d64a69ab32c65"; + + try { + const url = `https://serpapi.com/search.json?engine=google_maps_reviews&hl=en&api_key=${apiKey}&data_id=${dataId}`; + + const response = await fetch(url); + + if (!response.ok) { + const errorText = await response.text(); + console.error(`SerpAPI error! Status: ${response.status}, Body: ${errorText}`); + return NextResponse.json({ + error: "SerpAPI Error", + status: response.status, + message: errorText + }, { status: 500 }); + } + + const data = await response.json(); + + if (data.error) { + console.error("SerpAPI Data Error:", data.error); + return NextResponse.json({ error: data.error }, { status: 500 }); + } + + // Normalize reviews to a consistent shape regardless of SerpAPI field names + const rawReviews = data.reviews || []; + // Return ALL reviews – let the UI filter if needed + const reviews = rawReviews.map((r: any) => ({ + name: r.user?.name || r.username || "Customer", + rating: r.rating || 5, + text: r.snippet || r.extracted_snippet?.original || r.description || "", + date: r.date || r.iso_date || "", + profilePhoto: r.user?.thumbnail || r.user_thumbnail || null, + reviewLink: r.link || null, + })); + + return NextResponse.json({ + reviews, + total: reviews.length, + place: data.place_info || null, + }); + + } catch (error: any) { + console.error("Critical error in /api/google-reviews:", error); + return NextResponse.json({ + error: "Internal Server Error", + message: error.message, + }, { status: 500 }); + } +} diff --git a/app/contact/ContactClient.tsx b/app/contact/ContactClient.tsx index 2686122..4604c3f 100644 --- a/app/contact/ContactClient.tsx +++ b/app/contact/ContactClient.tsx @@ -151,7 +151,7 @@ const ContactClient = () => {
{/* Map Placeholder */} -
+