Add the Kaman Cable Next.js storefront with Meshkee catalog, blog, auth, and static-image slots.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,213 @@
|
||||
import type { CSSProperties } from "react";
|
||||
|
||||
import AboutTabs from "@/components/AboutTabs";
|
||||
import BlogCarousel from "@/components/BlogCarousel";
|
||||
import ContactBar from "@/components/ContactBar";
|
||||
import HeroSlider from "@/components/HeroSlider";
|
||||
import Reveal from "@/components/Reveal";
|
||||
import SectionTitle from "@/components/SectionTitle";
|
||||
import SlotImage from "@/components/SlotImage";
|
||||
import SlotLink from "@/components/SlotLink";
|
||||
import { blogHref, blogImage, fetchBlogs } from "@/lib/blog";
|
||||
import { blogPosts, clients, products, site, slides } from "@/data/site";
|
||||
import { pageMetadata } from "@/lib/seo";
|
||||
import { fetchStaticImageSlots, overlaySlotImages, pickSlot, slotRatioStyle } from "@/lib/static-images";
|
||||
|
||||
export const metadata = pageMetadata({
|
||||
title: `${site.shortName} | ${site.name}`,
|
||||
description: site.description,
|
||||
path: "/",
|
||||
image: "/images/slider/bg1.jpg",
|
||||
absolute: true,
|
||||
});
|
||||
|
||||
export default async function HomePage() {
|
||||
const slots = await fetchStaticImageSlots("home");
|
||||
const slider = overlaySlotImages(
|
||||
pickSlot(slots, "slider"),
|
||||
slides.map((slide) => ({
|
||||
id: slide.id,
|
||||
image: slide.image,
|
||||
title: slide.title,
|
||||
kicker: slide.kicker,
|
||||
})),
|
||||
"slider",
|
||||
);
|
||||
const aboutImage = overlaySlotImages(
|
||||
pickSlot(slots, "about-us-image"),
|
||||
[{ id: "about", image: "/images/about/factory.jpg", title: "کارخانه صنایع کابل کمان" }],
|
||||
"about-us-image",
|
||||
);
|
||||
const productItems = overlaySlotImages(
|
||||
pickSlot(slots, "categories"),
|
||||
products.map((product) => ({
|
||||
id: product.id,
|
||||
image: product.image,
|
||||
title: product.title,
|
||||
kicker: product.titleEn,
|
||||
text: product.text,
|
||||
})),
|
||||
"categories",
|
||||
);
|
||||
const clientItems = overlaySlotImages(
|
||||
pickSlot(slots, "partners"),
|
||||
clients.map((client) => ({
|
||||
id: client.id,
|
||||
image: client.image,
|
||||
title: client.title,
|
||||
})),
|
||||
"partners",
|
||||
);
|
||||
const apiBlogs = await fetchBlogs({ pageSize: 6 });
|
||||
const blogFallbacks = apiBlogs.items.length
|
||||
? apiBlogs.items.map((post) => ({
|
||||
id: post.id,
|
||||
image: blogImage(post),
|
||||
title: post.title,
|
||||
text: post.abstract || undefined,
|
||||
href: blogHref(post),
|
||||
}))
|
||||
: blogPosts.map((post) => ({
|
||||
id: post.id,
|
||||
image: post.image,
|
||||
title: post.title,
|
||||
kicker: post.date,
|
||||
text: post.text,
|
||||
href: blogHref(post),
|
||||
}));
|
||||
const blogItems = overlaySlotImages(pickSlot(slots, "home-blog"), blogFallbacks, "home-blog");
|
||||
|
||||
return (
|
||||
<>
|
||||
<h1 className="sr-only">{site.name}</h1>
|
||||
<HeroSlider slides={slider.items} aspectRatio={slider.aspectRatio} />
|
||||
|
||||
<section className="app-strip">
|
||||
<Reveal>
|
||||
<div className="container app-strip-inner">
|
||||
<h2>اپلیکیشن اختصاصی</h2>
|
||||
<a className="btn btn-gold" href={site.appUrl} target="_blank" rel="noopener noreferrer">
|
||||
دانلود اپلیکیشن
|
||||
</a>
|
||||
</div>
|
||||
</Reveal>
|
||||
</section>
|
||||
|
||||
<section className="section">
|
||||
<div className="container about-grid">
|
||||
<Reveal variant="right">
|
||||
<div className="about-photo" style={slotRatioStyle(aboutImage.aspectRatio)}>
|
||||
<SlotLink href={aboutImage.items[0]?.href}>
|
||||
<SlotImage
|
||||
src={aboutImage.items[0]?.image || "/images/about/factory.jpg"}
|
||||
alt={aboutImage.items[0]?.title || "کارخانه صنایع کابل کمان"}
|
||||
fill
|
||||
/>
|
||||
</SlotLink>
|
||||
</div>
|
||||
</Reveal>
|
||||
<Reveal variant="left" delay={140}>
|
||||
<div>
|
||||
<SectionTitle
|
||||
index="01"
|
||||
en="About"
|
||||
title="صنایع کابل کمان"
|
||||
text={site.tagline}
|
||||
/>
|
||||
<AboutTabs />
|
||||
<p className="about-cta">
|
||||
<a className="about-contact-link" href="#contact">
|
||||
تماس با ما
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" aria-hidden>
|
||||
<path
|
||||
d="M7.2 3.8h2.6l1.2 3-1.6 1.1a12.5 12.5 0 0 0 5.7 5.7l1.1-1.6 3 1.2v2.6c0 .7-.6 1.4-1.3 1.5-2 .3-6.3-.2-10.1-4S5.4 6.9 5.7 4.9c.1-.7.8-1.1 1.5-1.1Z"
|
||||
stroke="currentColor"
|
||||
strokeWidth="1.6"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</Reveal>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<Reveal>
|
||||
<ContactBar />
|
||||
</Reveal>
|
||||
|
||||
<section className="section" id="products">
|
||||
<div className="container">
|
||||
<Reveal>
|
||||
<SectionTitle
|
||||
index="02"
|
||||
en="Products"
|
||||
title="محصولات کابل و سیم"
|
||||
text="تنوع کامل سیم و کابل فشار ضعیف، مخابراتی، شبکه و ابزار دقیق، تولیدشده مطابق با استانداردهای ملی و بینالمللی."
|
||||
/>
|
||||
</Reveal>
|
||||
<Reveal stagger className="product-grid" style={slotRatioStyle(productItems.aspectRatio)}>
|
||||
{productItems.items.map((item, index) => (
|
||||
<article
|
||||
key={item.id}
|
||||
className="product-card"
|
||||
id={`product-${item.id}`}
|
||||
style={{ "--d": index } as CSSProperties}
|
||||
>
|
||||
<div className="thumb">
|
||||
<SlotLink href={item.href}>
|
||||
<SlotImage src={item.image} alt={item.title || "محصول کابل کمان"} fill />
|
||||
</SlotLink>
|
||||
</div>
|
||||
<div className="body">
|
||||
<h3>{item.title}</h3>
|
||||
{item.kicker ? <p className="en">{item.kicker}</p> : null}
|
||||
{item.text ? <p className="product-excerpt">{item.text}</p> : null}
|
||||
</div>
|
||||
</article>
|
||||
))}
|
||||
</Reveal>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="section" id="blog" style={{ paddingTop: 0 }}>
|
||||
<div className="container">
|
||||
<Reveal>
|
||||
<SectionTitle
|
||||
index="03"
|
||||
en="Blog"
|
||||
title="آخرین اخبار و مقالات"
|
||||
text="تازهترین دانستنیهای فنی و اخبار صنایع سیم و کابل کمان را در این بخش دنبال کنید."
|
||||
/>
|
||||
</Reveal>
|
||||
<Reveal delay={80} style={slotRatioStyle(blogItems.aspectRatio)}>
|
||||
<BlogCarousel posts={blogItems.items} />
|
||||
</Reveal>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="section" style={{ paddingTop: 0 }}>
|
||||
<div className="container">
|
||||
<Reveal>
|
||||
<SectionTitle
|
||||
index="04"
|
||||
en="Partners"
|
||||
title="همکاران و مشتریان"
|
||||
text="برندها و مجموعههایی که کیفیت تولید کابل کمان را برای پروژههای خود انتخاب کردهاند."
|
||||
/>
|
||||
</Reveal>
|
||||
<Reveal stagger className="clients" style={slotRatioStyle(clientItems.aspectRatio)}>
|
||||
{clientItems.items.map((item, index) => (
|
||||
<div key={item.id} className="client" style={{ "--d": index } as CSSProperties}>
|
||||
<SlotLink href={item.href}>
|
||||
<SlotImage src={item.image} alt={item.title || "همکار کابل کمان"} />
|
||||
</SlotLink>
|
||||
</div>
|
||||
))}
|
||||
</Reveal>
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user