mirror of
https://git.meshkee.com/Meshkee-Websites/havaran.git
synced 2026-08-11 20:40:58 +04:30
Build Havaran storefront with Meshkee-backed blogs and portfolios.
Clone product, solution, and company pages from the original site and wire articles/projects to the Meshkee Website API with pagination and media from the backend CDN. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Cursor
parent
65da23bd0f
commit
c49347061c
@@ -0,0 +1,167 @@
|
||||
import Image from "next/image";
|
||||
|
||||
type PageHeroProps = {
|
||||
title: string;
|
||||
titleEn?: string;
|
||||
breadcrumb?: { label: string; href: string }[];
|
||||
};
|
||||
|
||||
export function PageHero({ title, titleEn, breadcrumb }: PageHeroProps) {
|
||||
return (
|
||||
<section className="border-b border-[#eee] bg-[#f7f7f7]">
|
||||
<div className="container-page py-10 text-center sm:py-12">
|
||||
{breadcrumb ? (
|
||||
<nav className="mb-4 flex flex-wrap items-center justify-center gap-2 text-xs text-[#888]">
|
||||
{breadcrumb.map((item, i) => (
|
||||
<span key={item.href} className="inline-flex items-center gap-2">
|
||||
{i > 0 ? <span>/</span> : null}
|
||||
<a href={item.href} className="hover:text-brand">
|
||||
{item.label}
|
||||
</a>
|
||||
</span>
|
||||
))}
|
||||
</nav>
|
||||
) : null}
|
||||
<h1 className="mb-2 text-2xl font-bold text-[#232323] sm:text-[32px]">
|
||||
{title}
|
||||
</h1>
|
||||
{titleEn ? (
|
||||
<p className="text-sm tracking-[2px] text-[#9a9a9a] uppercase">
|
||||
{titleEn}
|
||||
</p>
|
||||
) : null}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
type CatalogCardProps = {
|
||||
href: string;
|
||||
image: string;
|
||||
title: string;
|
||||
titleEn: string;
|
||||
description: string;
|
||||
};
|
||||
|
||||
export function CatalogCard({
|
||||
href,
|
||||
image,
|
||||
title,
|
||||
titleEn,
|
||||
description,
|
||||
}: CatalogCardProps) {
|
||||
return (
|
||||
<article className="card-shadow flex h-full flex-col bg-white p-5 text-center">
|
||||
<a href={href} className="mb-4 flex h-[120px] items-center justify-center">
|
||||
<Image
|
||||
src={image}
|
||||
alt={title}
|
||||
width={160}
|
||||
height={120}
|
||||
unoptimized
|
||||
className="max-h-[120px] w-auto object-contain"
|
||||
style={{ width: "auto", height: 120 }}
|
||||
/>
|
||||
</a>
|
||||
<h2 className="mb-1 text-[16px] font-bold text-[#232323]">
|
||||
<a href={href}>{title}</a>
|
||||
</h2>
|
||||
<p className="mb-3 text-xs font-semibold tracking-wide text-[#999]">
|
||||
{titleEn}
|
||||
</p>
|
||||
<p className="mb-5 line-clamp-3 flex-1 text-sm leading-7 text-[#666]">
|
||||
{description}
|
||||
</p>
|
||||
<a href={href} className="btn-more mx-auto">
|
||||
بیشتر بدانید
|
||||
</a>
|
||||
</article>
|
||||
);
|
||||
}
|
||||
|
||||
type ContentSectionProps = {
|
||||
title: string;
|
||||
titleEn?: string;
|
||||
image?: string;
|
||||
imageAlt?: string;
|
||||
children: React.ReactNode;
|
||||
reverse?: boolean;
|
||||
};
|
||||
|
||||
export function ContentSection({
|
||||
title,
|
||||
titleEn,
|
||||
image,
|
||||
imageAlt,
|
||||
children,
|
||||
reverse,
|
||||
}: ContentSectionProps) {
|
||||
return (
|
||||
<section className="section">
|
||||
<div
|
||||
className={`container-page grid items-center gap-8 md:grid-cols-2 ${
|
||||
reverse ? "md:[&>*:first-child]:order-2" : ""
|
||||
}`}
|
||||
>
|
||||
{image ? (
|
||||
<div
|
||||
className={`relative aspect-[4/3] overflow-hidden ${
|
||||
image.endsWith(".png") ? "" : "bg-[#f7f7f7]"
|
||||
}`}
|
||||
>
|
||||
<Image
|
||||
src={image}
|
||||
alt={imageAlt || title}
|
||||
fill
|
||||
className="object-contain p-4"
|
||||
sizes="(max-width: 768px) 100vw, 50vw"
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
<div className={image ? "" : "md:col-span-2"}>
|
||||
<h2 className="mb-2 text-xl font-bold text-[#232323] sm:text-2xl">
|
||||
{title}
|
||||
</h2>
|
||||
{titleEn ? (
|
||||
<p className="mb-4 text-sm tracking-wide text-[#999]">{titleEn}</p>
|
||||
) : null}
|
||||
<div className="space-y-3 text-sm leading-8 text-[#666]">{children}</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
export function SpecList({ items }: { items: string[] }) {
|
||||
return (
|
||||
<div className="mt-4">
|
||||
<h3 className="mb-3 text-base font-bold text-[#232323]">مشخصات فنـــــی</h3>
|
||||
<ul className="space-y-2">
|
||||
{items.map((item) => (
|
||||
<li
|
||||
key={item}
|
||||
className="flex gap-2 border-b border-[#f0f0f0] py-2 text-sm leading-7 text-[#555]"
|
||||
>
|
||||
<span className="mt-2 h-1.5 w-1.5 shrink-0 rounded-full bg-accent-green" />
|
||||
<span>{item}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function UpdatingNotice() {
|
||||
return (
|
||||
<div className="container-page py-20 text-center">
|
||||
<Image
|
||||
src="/images/pages/shared/updating.png"
|
||||
alt="در حال بروز رسانی"
|
||||
width={120}
|
||||
height={120}
|
||||
className="mx-auto mb-6 opacity-70"
|
||||
/>
|
||||
<p className="text-lg font-bold text-[#666]">در حال بروز رسانی ...</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user