Compare commits
5 Commits
b41a0c0ee2
...
f0d1cf08ac
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f0d1cf08ac | ||
| 4a8a46f3d9 | |||
|
|
626ad80ee8 | ||
|
|
a960f2a6c1 | ||
|
|
72e588b3a7 |
@ -9464,12 +9464,20 @@ ul.social-box li a:hover {
|
||||
|
||||
.blogbanner-shape {
|
||||
|
||||
width: 45%;
|
||||
width: 60%;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@media only screen and (min-width: 320px) and (max-width: 1600px){
|
||||
|
||||
.blogbanner-shape {
|
||||
|
||||
display: none;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@media only screen and (min-width: 320px) and (max-width: 992px){
|
||||
|
||||
|
||||
|
||||
BIN
public/assets/images/blog/blog-cards/boost-card.webp
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
public/assets/images/blog/blog-cards/google-business-card.webp
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
public/assets/images/blog/blog-cards/google-maps-card.webp
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
public/assets/images/blog/blog-cards/local-customers-card.webp
Normal file
|
After Width: | Height: | Size: 7.8 KiB |
BIN
public/assets/images/blog/blog-cards/seo-services-card.webp
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
public/assets/images/blog/blog-cards/small-card.webp
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
public/assets/images/blog/blog-details/boost-big-img.webp
Normal file
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 22 KiB |
BIN
public/assets/images/blog/blog-details/google-maps-big-img.webp
Normal file
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 16 KiB |
BIN
public/assets/images/blog/blog-details/seo-services-big-img.webp
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
public/assets/images/blog/blog-details/small-big-img.webp
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
public/assets/images/portfolio/shopify/2.0.png
Normal file
|
After Width: | Height: | Size: 567 KiB |
BIN
public/assets/images/portfolio/web-development/Cybus.png
Normal file
|
After Width: | Height: | Size: 304 KiB |
|
After Width: | Height: | Size: 362 KiB |
|
After Width: | Height: | Size: 702 KiB |
BIN
public/assets/images/portfolio/web-development/Sixty5Street.png
Normal file
|
After Width: | Height: | Size: 210 KiB |
BIN
public/assets/images/portfolio/web-development/TCA.png
Normal file
|
After Width: | Height: | Size: 309 KiB |
BIN
public/assets/images/portfolio/web-development/repharehab.png
Normal file
|
After Width: | Height: | Size: 235 KiB |
BIN
public/assets/images/portfolio/wordpress/TNCSC.png
Normal file
|
After Width: | Height: | Size: 983 KiB |
@ -39,7 +39,7 @@ const staticLinks = [
|
||||
{ url: '/services-digital-solutions/', changefreq: 'daily', priority: 0.7 },
|
||||
{ url: '/about/', changefreq: 'weekly', priority: 0.7 },
|
||||
{ url: '/careers/', changefreq: 'weekly', priority: 0.7 },
|
||||
{ url: '/portfolio/', changefreq: 'weekly', priority: 0.7 },
|
||||
{ url: '/portfolio/', changefreq: 'weekly', priority: 0.7 },
|
||||
{ url: '/blog/', changefreq: 'weekly', priority: 0.7 },
|
||||
{ url: '/contact/', changefreq: 'monthly', priority: 0.5 },
|
||||
{ url: '/faq/', changefreq: 'monthly', priority: 0.5 },
|
||||
@ -82,6 +82,12 @@ const blogPosts = [
|
||||
{ slug: 'mastering-omnichannel-marketing-strategies-for-2026' },
|
||||
{ slug: 'how-metatroncube-solutions-improve-local-seo-waterloo' },
|
||||
{ slug: 'why-metatroncube-solutions-top-choice-social-media-marketing-waterloo' },
|
||||
{ slug: 'how-does-metatroncube-solutions-help-businesses-get-more-local-customers-through-search-engines' },
|
||||
{ slug: 'can-metatroncube-solutions-optimize-my-google-business-profile' },
|
||||
{ slug: 'seo-services-waterloo-small-businesses-metatroncube' },
|
||||
{ slug: 'boost-google-maps-ranking-waterloo-metatroncube' },
|
||||
{ slug: 'how-metatroncube-solutions-uses-ai-tools-to-boost-your-marketing-in-toronto' },
|
||||
{ slug: 'what-types-of-social-media-ads-does-metatroncube-solutions-recommend-for-small-businesses-in-toronto' },
|
||||
|
||||
];
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { useState, useEffect, useRef } from "react";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import { PortfolioData } from "@/utils/constant.utils";
|
||||
@ -11,18 +11,46 @@ const tabs = [
|
||||
{ label: "Graphic Design", value: "graphic" },
|
||||
{ label: "Google Meta Ads", value: "meta" },
|
||||
{ label: "Shopify Store", value: "shopify" },
|
||||
{ label: "WordPress", value: "wordpress" },
|
||||
{ label: "Logo Branding", value: "logo" },
|
||||
{ label: "Video Editing", value: "video" },
|
||||
];
|
||||
|
||||
const CaseStudies = () => {
|
||||
const [activeTab, setActiveTab] = useState("*");
|
||||
const [visibleCount, setVisibleCount] = useState(6);
|
||||
const observerRef = useRef(null);
|
||||
|
||||
const filteredItems =
|
||||
activeTab === "*"
|
||||
? PortfolioData
|
||||
: PortfolioData.filter((item) => item.category === activeTab);
|
||||
|
||||
useEffect(() => {
|
||||
setVisibleCount(6);
|
||||
}, [activeTab]);
|
||||
|
||||
useEffect(() => {
|
||||
const observer = new IntersectionObserver(
|
||||
(entries) => {
|
||||
if (entries[0].isIntersecting) {
|
||||
setVisibleCount((prev) => prev + 6);
|
||||
}
|
||||
},
|
||||
{ threshold: 0.1 }
|
||||
);
|
||||
|
||||
if (observerRef.current) {
|
||||
observer.observe(observerRef.current);
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (observerRef.current) {
|
||||
observer.unobserve(observerRef.current);
|
||||
}
|
||||
};
|
||||
}, [filteredItems]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* Title Section */}
|
||||
@ -81,7 +109,7 @@ const CaseStudies = () => {
|
||||
|
||||
{/* Portfolio Grid */}
|
||||
<div className="row image_load">
|
||||
{filteredItems.map((item) => (
|
||||
{filteredItems.slice(0, visibleCount).map((item) => (
|
||||
<div
|
||||
key={item.id}
|
||||
className={`${item.colClass} grid-item ${item.category} ${item.itemClass || ""}`}
|
||||
@ -187,6 +215,12 @@ const CaseStudies = () => {
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Sentinel Element for Infinite Scroll */}
|
||||
<div
|
||||
ref={observerRef}
|
||||
style={{ height: "20px", marginBottom: "20px" }}
|
||||
></div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||