311 lines
16 KiB
JavaScript
311 lines
16 KiB
JavaScript
'use client'
|
||
|
||
import { useEffect, useState } from "react"
|
||
import Link from "next/link"
|
||
import { Swiper, SwiperSlide } from "swiper/react"
|
||
import { Autoplay, Pagination, Navigation } from "swiper/modules"
|
||
import GallerySlider1 from '@/components/slider/GallerySlider1'
|
||
import GoogleReviewsBranding from "@/components/GoogleReviewsBranding"
|
||
|
||
const swiperOptions = {
|
||
modules: [Autoplay, Pagination, Navigation],
|
||
slidesPerView: 1,
|
||
spaceBetween: 30,
|
||
loop: true,
|
||
autoplay: {
|
||
delay: 3000,
|
||
disableOnInteraction: false,
|
||
},
|
||
navigation: {
|
||
nextEl: '.srn',
|
||
prevEl: '.srp',
|
||
},
|
||
pagination: {
|
||
el: '.swiper-pagination',
|
||
clickable: true,
|
||
},
|
||
}
|
||
|
||
const testimonialSwiperOptions = {
|
||
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 AboutContent() {
|
||
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) => (
|
||
<span key={i} className={`fa fa-star ${i < rating ? "text-warning" : ""}`}></span>
|
||
));
|
||
}
|
||
|
||
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) {
|
||
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 (
|
||
<>
|
||
|
||
{/* History Section */}
|
||
<section className="history-section-two">
|
||
<div className="auto-container">
|
||
<div className="row clearfix align-items-center">
|
||
|
||
{/* Image Column */}
|
||
<div className="image-column col-lg-7 col-md-12 col-sm-12">
|
||
<div className="inner-column">
|
||
<div className="image">
|
||
<img src="/assets/images/about/about-us.webp" alt="About Sixty5 Street restaurant in Brampton Ontario" loading="lazy"/>
|
||
</div>
|
||
<div className="image-two mb-4">
|
||
<img src="/assets/images/about/about-us-element.webp" alt="Sixty5 Street about page design element Brampton" loading="lazy"/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Content Column */}
|
||
<div className="content-column col-lg-5 col-md-12 col-sm-12">
|
||
<div className="inner-column">
|
||
{/* Sec Title */}
|
||
<div className="sec-title about-sec">
|
||
<div className="title custome-style">About Us</div>
|
||
<h2>Street Fresh. <span className="theme_color"> Full of Flavour.</span></h2>
|
||
|
||
<div className="text">At Sixty5 Street, we believe great food starts with freshness and ends with bold, memorable flavour. Our menu is inspired by the vibrant energy of street-style eats, where every dish and every blend is crafted to feel lively, colourful, and satisfying. Whether it’s one of our refreshing fruit mixes or a flavour-packed bowl, everything we serve is designed to bring you real taste made from real ingredients.</div>
|
||
|
||
</div>
|
||
<ul className="list-style-two">
|
||
<li>Fresh fruits and ingredients in every blend</li>
|
||
<li>Street-inspired flavours prepared with care</li>
|
||
<li>A vibrant experience that keeps you feeling energized</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
</section>
|
||
{/* End History Section */}
|
||
|
||
{/* Menu Page Section */}
|
||
<section className="menu-page-section">
|
||
<div className="auto-container">
|
||
<div className="row clearfix">
|
||
<div className="menu-block-two col-lg-4 col-md-6 col-sm-12">
|
||
<div className="inner-box">
|
||
<div className="icon">
|
||
<img src="/assets/images/about/card-1.webp" alt="Sixty5 Street fresh ingredients card Brampton ON" loading="lazy" />
|
||
</div>
|
||
<h3>Bold Flavours</h3>
|
||
<div className="text">Every item is created to deliver bright, bold flavour. From our signature blends to our colourful bowls, we make sure each serving tastes fresh, lively, and instantly enjoyable.</div>
|
||
</div>
|
||
</div>
|
||
<div className="menu-block-two col-lg-4 col-md-6 col-sm-12">
|
||
<div className="inner-box">
|
||
<div className="icon">
|
||
<img src="/assets/images/about/card-2.webp" alt="Sixty5 Street fast service card Brampton Ontario" loading="lazy" />
|
||
</div>
|
||
<h3>Real Fruits</h3>
|
||
<div className="text">We use high-quality fruits chosen for their natural sweetness and freshness. This ensures every mix, topping, and serving brings out authentic, clean flavour.</div>
|
||
</div>
|
||
</div>
|
||
<div className="menu-block-two col-lg-4 col-md-6 col-sm-12">
|
||
<div className="inner-box">
|
||
<div className="icon">
|
||
<img src="/assets/images/about/card-3.webp" alt="Sixty5 Street unique flavours card Brampton ON" loading="lazy"/>
|
||
</div>
|
||
<h3>Healthy Blends</h3>
|
||
<div className="text">Our blends are crafted to be both nourishing and delicious. Light, refreshing, and made fresh to order — perfect for energizing your day without compromise.</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
{/* Fluid Section */}
|
||
<section className="fluid-section-one">
|
||
<div className="outer-container clearfix">
|
||
<div className="content-column">
|
||
<div className="icon-box" style={{ backgroundImage: 'url(/assets/images/about/fresh-flavour-left-bottom-element.webp)' }} ></div>
|
||
<div className="inner-column">
|
||
<div className="sec-title">
|
||
<h2>Fresh Flavour <br /> Fusion</h2>
|
||
<div className="separate"></div>
|
||
<div className="text">At Sixty5 Street, we are always creating something new, fresh, and full of flavour. Our upcoming beverage range is crafted with real fruits, clean ingredients, and creative blends that bring a refreshing twist to your day. These new additions are designed to energize, hydrate, and satisfy—all while staying true to our vibrant, street-style taste.</div>
|
||
</div>
|
||
<div className="button-box">
|
||
<Link href="/menu" className="theme-btn btn-style-two clearfix"><span className="icon"></span>View Menu</Link>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div className="image-column" style={{ backgroundImage: 'url(/assets/images/about/fresh-flavour-right.webp)' }}></div>
|
||
</div>
|
||
</section>
|
||
|
||
{/* Testimonial Section */}
|
||
<section className="testimonial-section-two">
|
||
<div className="icon-layer-two" style={{ backgroundImage: "url(/assets/images/about/review-right-bottom-element.webp)" }}></div>
|
||
<div className="auto-container">
|
||
<div className="sec-title centered">
|
||
<div className="title">Google Reviews</div>
|
||
<h2>What Our Happy Customers Say</h2>
|
||
<div className="separate"></div>
|
||
<GoogleReviewsBranding centered={true} />
|
||
</div>
|
||
|
||
<div className="inner-container">
|
||
{loading && <p className="text-center">Loading reviews...</p>}
|
||
|
||
{!loading && isClient && displayedReviews.length > 0 && (
|
||
<Swiper {...testimonialSwiperOptions} className="single-item-carousel">
|
||
{displayedReviews.map((r, index) => {
|
||
const fullText = getReviewText(r);
|
||
const isExpanded = expandedReview === index;
|
||
|
||
return (
|
||
<SwiperSlide key={index}>
|
||
<div className="google-review-card equal-height">
|
||
<div className="google-review-header">
|
||
<div className="google-avatar">
|
||
<img
|
||
src={getProfileImage(r)}
|
||
alt={r.author_name || r.user?.name || "User"}
|
||
onError={(e) => (e.target.src = "/default-user.png")}
|
||
/>
|
||
</div>
|
||
|
||
<div className="google-user-info">
|
||
<h4 className="google-name">
|
||
{r.author_name || r.user?.name || "Customer"}
|
||
</h4>
|
||
<div className="google-stars">{renderStars(r.rating)}</div>
|
||
</div>
|
||
</div>
|
||
|
||
<p className="google-text">
|
||
{isExpanded ? fullText : truncateText(fullText)}
|
||
</p>
|
||
|
||
{r.images &&
|
||
r.images.length > 0 &&
|
||
r.images.some(img => img && img !== "ky") && (
|
||
<div className="google-review-images">
|
||
{r.images.map((img, i) => {
|
||
if (!img || img === "ky") return null;
|
||
const fixedImg = img.startsWith("http")
|
||
? img
|
||
: `https://lh3.googleusercontent.com/${img}`;
|
||
return (
|
||
<img
|
||
key={i}
|
||
src={fixedImg}
|
||
alt="Review image"
|
||
className="google-review-photo"
|
||
onError={(e) => (e.target.style.display = "none")}
|
||
/>
|
||
);
|
||
})}
|
||
</div>
|
||
)}
|
||
|
||
{fullText.length > 150 && (
|
||
<button
|
||
className="read-more-btn mt-3"
|
||
onClick={(e) => {
|
||
e.stopPropagation();
|
||
setExpandedReview(isExpanded ? null : index);
|
||
}}
|
||
>
|
||
{isExpanded ? "Read Less" : "Read More"}
|
||
</button>
|
||
)}
|
||
</div>
|
||
</SwiperSlide>
|
||
);
|
||
})}
|
||
</Swiper>
|
||
)}
|
||
|
||
<div className="btns-box text-center mt-4">
|
||
<Link
|
||
href="https://www.google.com/search?sca_esv=0fe16c1f02c217b7&sxsrf=AE3TifOLptPQLUmmtN31E_3elXLW6TFOQw:1762618049873&si=AMgyJEtREmoPL4P1I5IDCfuA8gybfVI2d5Uj7QMwYCZHKDZ-E-aY0flGiK9jtBbvWKno0yJxYW9CK-ZYgm0G70i4ON2SMlNBNsid-fMvQPqNzI7FcY1u8NR67M0xsy1G8HMAZhtgOP2m&q=Sixty5+Street+Reviews&sa=X&ved=2ahUKEwjY5_L19-KQAxW89DgGHdw0AesQ0bkNegQILRAE&biw=1366&bih=633&dpr=1&sei=MHYRadbjFKWo4-EPlrjFkAs&zx=1762752154509&no_sw_cr=1#lrd=0x882b3dbb0e18ed73:0xbdb3783d6e6393c9,3,,,,"
|
||
target="_blank"
|
||
className="theme-btn btn-style-one clearfix"
|
||
>
|
||
<span className="icon"></span> Review us on Google
|
||
</Link>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
{/* Gallery Section */}
|
||
{/* <section className="gallery-section">
|
||
<div className="outer-container">
|
||
<GallerySlider1 />
|
||
</div>
|
||
</section> */}
|
||
</>
|
||
)
|
||
}
|