Redesign core pages and connect dynamic content

This commit is contained in:
amirhosein.ashourloo
2026-10-08 18:42:19 +03:30
parent 55d0fad2c8
commit 1d320b8f10
88 changed files with 1200 additions and 959 deletions
+72 -73
View File
@@ -1,99 +1,98 @@
import { ProjectGalleryLightbox } from "@/components/portfolios/ProjectGalleryLightbox";
import Image from "next/image";
import Link from "next/link";
import { NewsShareActions } from "@/components/news/NewsShareActions";
import { Reveal } from "@/components/Reveal";
import { PageCta } from "@/components/shared/PageCta";
import { PageHero } from "@/components/shared/PageHero";
import { SectionLabel } from "@/components/shared/SectionLabel";
import { newsAndBlogPage } from "@/data/site";
import type { DisplayNewsItem } from "@/lib/api";
/**
* Shared detail template for a single news or blog item — same rules as
* NewsListing keeps the two archives consistent, this keeps their detail
* pages consistent too, and mirrors the portfolio detail page's own
* jump-nav + gallery pattern since blog items carry the same gallery field.
* Body content is the item's real mainTextHtml from the API; nothing here
* is invented, and the gallery section only appears once a post actually
* has images to show.
*/
export function NewsArticleDetail({
item,
basePath,
sectionLabel,
sectionLabelEn,
}: {
item: DisplayNewsItem;
basePath: string;
sectionLabel: string;
sectionLabelEn: string;
}) {
const hasGallery = item.gallery.length > 0;
const navItems = [
{ id: "overview", label: "معرفی" },
...(hasGallery ? [{ id: "gallery", label: "گالری تصاویر" }] : []),
];
return (
<>
<PageHero
image={item.image}
title={item.title}
breadcrumb={[
{ label: "صفحه اصلی", href: "/" },
{ label: "مقالات و اخبار", href: "/news-and-blog" },
{ label: sectionLabel, href: basePath },
{ label: item.title, href: `${basePath}/${item.slug}` },
]}
/>
<article className="bg-paper text-ink">
<header className="px-5 pb-20 pt-[125px] lg:px-12 lg:pb-24 lg:pt-[132px]">
<div className="mx-auto max-w-[1400px]">
<div className="flex items-center justify-between gap-5 text-[11px] text-[#9b896d] lg:text-[12px]">
<Link
href={basePath}
className="bg-[#f1efec] px-4 py-2 text-ink transition-colors duration-300 hover:bg-ink hover:text-white"
>
{sectionLabel}
</Link>
<time>{item.date}</time>
</div>
{navItems.length > 1 && (
<nav aria-label="بخش‌های صفحه" className="border-b border-line bg-[#f1efec]">
<ul className="no-scrollbar mx-auto flex max-w-[1400px] items-center justify-center gap-10 overflow-x-auto px-6 lg:px-12">
{navItems.map((navItem) => (
<li key={navItem.id}>
<a
href={`#${navItem.id}`}
className="block scroll-mt-24 border-b-2 border-transparent py-5 text-sm font-bold whitespace-nowrap text-ink transition-colors duration-300 hover:border-gold hover:text-gold"
>
{navItem.label}
</a>
</li>
))}
</ul>
</nav>
)}
<section id="overview" className="scroll-mt-20 bg-paper py-24 lg:py-36">
<div className="mx-auto max-w-[1400px] px-6 lg:px-12">
<Reveal>
<SectionLabel fa={sectionLabel} en={sectionLabelEn} className="mb-14" />
<h1 className="mx-auto mt-14 max-w-[1050px] text-center text-[clamp(16px,2.55vw,34px)] leading-[1.65] font-normal text-ink lg:mt-12">
{item.title}
</h1>
</Reveal>
{item.bodyHtml && (
<Reveal delay={90}>
<div className="cms-body cms-body--editorial" dangerouslySetInnerHTML={{ __html: item.bodyHtml }} />
</Reveal>
)}
</div>
</header>
<Reveal>
<div className="relative h-[36vh] min-h-[300px] w-full overflow-hidden lg:h-[44vh] lg:min-h-[430px]">
<Image
src={item.image}
alt={item.title}
fill
priority
quality={88}
sizes="100vw"
className="object-cover"
/>
</div>
</Reveal>
<section className="px-5 pb-24 pt-32 lg:px-12 lg:pb-36 lg:pt-[clamp(13rem,27vw,28rem)]">
<Reveal>
<div
className="news-article-body mx-auto max-w-[880px] text-[15px] leading-[2.25] text-ink lg:text-[17px]"
dangerouslySetInnerHTML={{ __html: item.bodyHtml }}
/>
</Reveal>
</section>
{hasGallery && (
<section id="gallery" className="scroll-mt-20 bg-[#f1efec] py-24 lg:py-32">
<div className="mx-auto max-w-[1400px] px-6 lg:px-12">
<Reveal>
<SectionLabel fa="گالری تصاویر" en="GALLERY" className="mb-14" />
{item.gallery.length > 0 && (
<section className="mx-auto grid max-w-[1400px] grid-cols-1 gap-8 px-5 pb-36 md:grid-cols-12 lg:gap-x-8 lg:gap-y-44 lg:px-12 lg:pb-48">
{item.gallery.slice(0, 3).map((image, index) => (
<Reveal
key={`${image}-${index}`}
className={
index === 0
? "md:col-span-8"
: index === 1
? "md:col-span-4"
: "md:col-span-6 md:col-start-7"
}
delay={index * 80}
>
<div className={`relative overflow-hidden ${index === 0 ? "aspect-[16/8]" : "aspect-[16/9]"}`}>
<Image
src={image}
alt={`${item.title} - تصویر ${index + 1}`}
fill
quality={82}
sizes={index === 0 ? "(max-width: 768px) 100vw, 66vw" : "(max-width: 768px) 100vw, 42vw"}
className="object-cover transition-transform duration-[1200ms] ease-out-soft hover:scale-[1.025]"
/>
</div>
</Reveal>
<ProjectGalleryLightbox images={item.gallery} alt={item.title} />
</div>
))}
</section>
)}
<PageCta
caption={newsAndBlogPage.cta.caption}
title={newsAndBlogPage.cta.title}
action={newsAndBlogPage.cta.action}
/>
</>
<section className="pb-24 text-center lg:pb-32">
<p className="mb-6 text-sm text-ink">اشتراک‌گذاری خبر</p>
<NewsShareActions title={item.title} />
</section>
</article>
);
}