Dejband.com clone — Next.js, RTL Persian
- Homepage faithfully matching dejband.com (hero, services, consulting,
stats, about block, timeline, portfolio, articles) + About/Contact/
Portfolios/Articles pages under source URLs
- Meshkee API integration: live blog content, favicon, user menu,
sitemap/robots proxy, canonical /blog/{id}/{slug}
- SEO pass: one H1 per page, unique metadata + canonicals, alt text
- Contact form wired to /api/contact with toast + reset
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
import { redirect } from "next/navigation";
|
||||
import { getBlog, blogPath } from "@/lib/api";
|
||||
|
||||
export const revalidate = 300;
|
||||
|
||||
// Legacy path — 308-redirect to the canonical /blog/{id}/{slug}.
|
||||
export default async function LegacyArticleRedirect({ params }) {
|
||||
const { slug } = await params;
|
||||
const blog = await getBlog(slug);
|
||||
redirect(blog ? encodeURI(blogPath(blog)) : "/articles");
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import PageTitle from "@/components/PageTitle";
|
||||
import { getBlogs, formatFaDate, blogPath, SITE_URL } from "@/lib/api";
|
||||
import { ARTICLES as FALLBACK } from "@/lib/site";
|
||||
|
||||
export const metadata = {
|
||||
title: "مقالات و مطالب آموزشی",
|
||||
description:
|
||||
"مقالات تخصصی مهندسین مشاور دژبند قم درباره طراحی و ساخت سوله صنعتی، سازههای فلزی، نقشههای برق و مکانیک و استانداردهای ایمنی.",
|
||||
alternates: { canonical: `${SITE_URL}/articles` },
|
||||
};
|
||||
|
||||
export const revalidate = 300;
|
||||
|
||||
export default async function ArticlesPage() {
|
||||
const blogs = await getBlogs();
|
||||
|
||||
const items = blogs.length
|
||||
? blogs.map((b) => ({
|
||||
href: blogPath(b),
|
||||
img: b.image || "/images/articles/a-1.jpg",
|
||||
category: b.category,
|
||||
date: formatFaDate(b.date),
|
||||
title: b.title,
|
||||
external: false,
|
||||
}))
|
||||
: FALLBACK.map((a) => ({ ...a, external: true }));
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageTitle title="مقالات" en="ARTICLES" />
|
||||
|
||||
<section className="art-section" style={{ padding: "60px 0" }}>
|
||||
<div className="art-grid-wrap" style={{ marginTop: 0 }}>
|
||||
<ul className="art-grid art-grid-page">
|
||||
{items.map((a) => {
|
||||
const Card = (
|
||||
<>
|
||||
<div className="art-image">
|
||||
<Image src={a.img} alt={`تصویر مقاله: ${a.title}`} width={600} height={500} />
|
||||
<div className="art-image-overlay" />
|
||||
</div>
|
||||
<div className="art-details">
|
||||
<span className="art-category">{a.category}</span>
|
||||
<div className="art-bottom">
|
||||
<span className="art-date">{a.date}</span>
|
||||
<h2>{a.title}</h2>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
return (
|
||||
<li className="art-item" key={a.title}>
|
||||
{a.external ? (
|
||||
<a href={a.href} target="_blank" rel="noopener noreferrer">
|
||||
{Card}
|
||||
</a>
|
||||
) : (
|
||||
<Link href={a.href}>{Card}</Link>
|
||||
)}
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user