'use client'; import React, { useRef, useState } from 'react'; import Link from 'next/link'; import { ArrowRight, ChevronLeft, ChevronRight } from 'lucide-react'; import { Swiper, SwiperSlide } from 'swiper/react'; import { Navigation, A11y } from 'swiper/modules'; import type { Swiper as SwiperType } from 'swiper'; import { getImageUrl } from '@/lib/utils'; import { DEFAULT_BLOG_ARTICLES, getSectionTitle, } from '@/lib/homepageDefaults'; import 'swiper/css'; import 'swiper/css/navigation'; interface ArticleItem { id: string; title: string; excerpt: string; image: string; link: string; } interface ArticlesSectionProps { config?: any; } function mapArticles(raw: any[]): ArticleItem[] { return raw .filter((a) => a && (a.title || a.image)) .map((a: any, idx: number) => { const fallback = DEFAULT_BLOG_ARTICLES[idx % DEFAULT_BLOG_ARTICLES.length]; const img = a.image || a.image_url || ''; return { id: String(a.id || `article-${idx + 1}`), title: String(a.title || fallback.title), excerpt: String(a.excerpt || a.subtitle || a.description || fallback.excerpt), image: img ? getImageUrl(img) : fallback.image, link: String(a.link || a.url || a.href || `/blog`), }; }); } export const ArticlesSection: React.FC = ({ config }) => { const raw = config?.metadata_json?.articles || config?.metadata?.articles || []; const articles = Array.isArray(raw) && raw.length > 0 ? mapArticles(raw) : DEFAULT_BLOG_ARTICLES; const title = getSectionTitle(config, 'tech_blog'); const viewAllHref = config?.metadata_json?.view_all_url || config?.metadata?.view_all_url || '/blog'; const swiperRef = useRef(null); const [canPrev, setCanPrev] = useState(false); const [canNext, setCanNext] = useState(false); const [showNav, setShowNav] = useState(false); const syncNav = (swiper: SwiperType) => { const overflow = !swiper.isLocked && swiper.slides.length > 0; setShowNav(overflow); setCanPrev(overflow && !swiper.isBeginning); setCanNext(overflow && !swiper.isEnd); }; if (articles.length === 0) return null; return (
{/* Header + full-width rule — TechShop reference */}

{title}

View All
{showNav ? ( <> ) : null} { swiperRef.current = swiper; requestAnimationFrame(() => syncNav(swiper)); }} onSlideChange={syncNav} onResize={syncNav} onBreakpoint={syncNav} onLock={() => { setShowNav(false); setCanPrev(false); setCanNext(false); }} onUnlock={(swiper) => syncNav(swiper)} watchOverflow spaceBetween={22} slidesPerView={1.15} breakpoints={{ 640: { slidesPerView: 2, spaceBetween: 20 }, 1024: { slidesPerView: 3, spaceBetween: 22 }, 1280: { slidesPerView: 4, spaceBetween: 24 }, }} className="!overflow-visible" > {articles.map((article) => (
{/* eslint-disable-next-line @next/next/no-img-element */} {article.title}

{article.title}

{article.excerpt ? (

{article.excerpt}

) : null}
))}
); };