Wire live business contact data and refresh homepage/about branding.
Pull landline, cell, and address from Meshkee business-info across footer and contact surfaces, update brand spelling and 14-year messaging, and keep product cards free of placeholder call-to-action pricing. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Cursor
parent
3ffa43641d
commit
e2468a1ba1
@@ -20,6 +20,12 @@ Meshkee Website API (`https://api.meshkee.com/api/v1`, docs at
|
||||
sharing the same display name under different ids (backend data-entry
|
||||
artifact). The summary merges by name and links to whichever id holds
|
||||
the most products under that name.
|
||||
- Business contact data (`getBusinessInfo` /
|
||||
`getResolvedBusinessContact`) comes from
|
||||
`GET /tenants/{domain}/website/business-info` — landline/cell
|
||||
(`phoneNumbers`), addresses, emails, social. Footer, contact page,
|
||||
and `HomeContactStrip` consume the resolved helper. Empty/failed
|
||||
fetches keep the previous hardcoded address and phone fallbacks.
|
||||
|
||||
## Static image slots (business-managed overrides)
|
||||
|
||||
|
||||
+14
@@ -31,6 +31,20 @@ Dashboard import catalog: `GET /meshkee/static-image-slots` (`src/app/meshkee/st
|
||||
|
||||
If a rendered image size or crop ratio changes, update both the component container (`aspectRatioToCss`) and the matching catalog entry.
|
||||
|
||||
## Business contact (business-info)
|
||||
|
||||
`GET /tenants/aradarisman.com/website/business-info` → `getBusinessInfo` /
|
||||
`getResolvedBusinessContact` in `src/lib/meshkee.ts`.
|
||||
|
||||
| Field | UI |
|
||||
|---|---|
|
||||
| `phoneNumbers` (`landline` / `cell`) | Footer, `ContactInfo`, `HomeContactStrip` |
|
||||
| `addresses[0]` | Footer, `ContactInfo` (map pin is fixed coords on contact page) |
|
||||
| `emails` | Footer |
|
||||
| `socialMedia` | Contact page social icons (when set) |
|
||||
|
||||
Failed/empty responses keep local address + phone fallbacks so the page never blanks out.
|
||||
|
||||
## Other conventions
|
||||
|
||||
- Category tiles from live products (`getCategorySummary`) because the raw `/categories` taxonomy has duplicate display names.
|
||||
|
||||
+62
-34
@@ -4,36 +4,54 @@ import Link from "next/link";
|
||||
import Container from "@/components/Container";
|
||||
import PageBanner from "@/components/PageBanner";
|
||||
import MissionVision from "@/components/MissionVision";
|
||||
import ImportCountries from "@/components/ImportCountries";
|
||||
import Features from "@/components/Features";
|
||||
import { pageMetadata } from "@/lib/seo";
|
||||
import {
|
||||
getResolvedBusinessContact,
|
||||
phoneTelHref,
|
||||
} from "@/lib/meshkee";
|
||||
|
||||
export const metadata: Metadata = pageMetadata({
|
||||
title: "درباره ما | آراد آریسمان",
|
||||
title: "درباره ما | آراد اَریسمان",
|
||||
description:
|
||||
"آشنایی با شرکت آراد آریسمان؛ بیش از ۲۳ سال تجربه در تولید و عرضه مکملهای غذایی دام، طیور و زنبور عسل.",
|
||||
"آشنایی با شرکت آراد اَریسمان؛ بیش از ۲۳ سال تجربه در تولید و عرضه مکملهای غذایی دام، طیور و زنبور عسل.",
|
||||
path: "/about",
|
||||
});
|
||||
|
||||
export default function AboutPage() {
|
||||
export default async function AboutPage() {
|
||||
const contact = await getResolvedBusinessContact();
|
||||
const phone = contact.primaryPhone;
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageBanner
|
||||
title="درباره آراد آریسمان"
|
||||
title="درباره آراد اَریسمان"
|
||||
subtitle="بیش از دو دهه تجربه در تولید و عرضه مکملهای غذایی دام، طیور و زنبور عسل"
|
||||
breadcrumb="درباره ما"
|
||||
/>
|
||||
|
||||
<section className="py-16 sm:py-20">
|
||||
<Container className="grid grid-cols-1 lg:grid-cols-2 items-center gap-12">
|
||||
<div className="relative aspect-[4/3] rounded-3xl overflow-hidden shadow-xl bg-surface order-2 lg:order-1">
|
||||
<div className="relative aspect-[4/3] rounded-3xl overflow-hidden shadow-xl bg-secondary order-2 lg:order-1">
|
||||
<Image
|
||||
src="/images/category-3.jpg"
|
||||
alt="محصولات آراد آریسمان"
|
||||
src="/images/stats-banner.jpg"
|
||||
alt=""
|
||||
fill
|
||||
className="object-contain p-6"
|
||||
className="object-cover scale-110 blur-[6px]"
|
||||
sizes="(min-width: 1024px) 45vw, 90vw"
|
||||
aria-hidden
|
||||
/>
|
||||
<div className="absolute inset-0 bg-primary-dark/45" aria-hidden />
|
||||
<div className="absolute inset-0 flex items-center justify-center p-10">
|
||||
<Image
|
||||
src="/images/footer-logo.png"
|
||||
alt="آراد اَریسمان"
|
||||
width={220}
|
||||
height={62}
|
||||
className="relative z-10 h-auto w-44 sm:w-52 drop-shadow-lg"
|
||||
priority
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="order-1 lg:order-2 text-center lg:text-start">
|
||||
@@ -42,7 +60,7 @@ export default function AboutPage() {
|
||||
تغذیه مطمئن، پرورش موفق
|
||||
</h2>
|
||||
<p className="mt-6 leading-8 text-foreground">
|
||||
شرکت آراد آریسمان پیشرو در تولید و عرضه افزودنیهای خوراک، ویتامینها و
|
||||
شرکت آراد اَریسمان پیشرو در تولید و عرضه افزودنیهای خوراک، ویتامینها و
|
||||
مکملهای غذایی دام و طیور با بیش از ۲۳ سال فعالیت در بازار ایران میباشد.
|
||||
واردات این شرکت عمدتا از تولیدکنندگان معتبر بینالمللی غذای دام و طیور از
|
||||
کشورهای انگلستان، فرانسه، ترکیه، هندوستان و چین میباشد.
|
||||
@@ -53,18 +71,28 @@ export default function AboutPage() {
|
||||
نتیجهی این رویکرد، اعتماد پایدار بیش از ۲۳۰ مشتری در سراسر کشور است.
|
||||
</p>
|
||||
|
||||
<div className="mt-8 flex justify-center lg:justify-start gap-10">
|
||||
<div>
|
||||
<div className="text-3xl font-extrabold text-primary">۲۳+</div>
|
||||
<div className="mt-1 text-sm text-foreground">سال تجربه</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-3xl font-extrabold text-primary">۲۳۰+</div>
|
||||
<div className="mt-1 text-sm text-foreground">رضایت مشتری</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-3xl font-extrabold text-primary">۵</div>
|
||||
<div className="mt-1 text-sm text-foreground">کشور واردات</div>
|
||||
<div className="mt-8 flex justify-center lg:justify-start">
|
||||
<div className="inline-flex items-center gap-4 sm:gap-5">
|
||||
<div className="shrink-0 text-center lg:text-start">
|
||||
<p className="text-4xl sm:text-5xl font-extrabold tracking-tight leading-none text-primary">
|
||||
۱۴ سال
|
||||
</p>
|
||||
<p
|
||||
dir="ltr"
|
||||
className="mt-1.5 font-display text-xs sm:text-sm font-medium tracking-[0.06em] text-primary/55"
|
||||
>
|
||||
14 years of experience
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
className="hidden sm:block h-12 w-px shrink-0 bg-primary/20"
|
||||
aria-hidden
|
||||
/>
|
||||
<p className="text-sm sm:text-base font-medium leading-7 text-foreground text-start">
|
||||
تولید تخصصی محصولات
|
||||
<br />
|
||||
مکمل دام و طیور
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -75,16 +103,14 @@ export default function AboutPage() {
|
||||
|
||||
<section className="bg-surface">
|
||||
<Container className="pt-16 sm:pt-20 text-center max-w-xl mx-auto">
|
||||
<span className="text-sm font-bold text-accent">چرا آراد آریسمان</span>
|
||||
<span className="text-sm font-bold text-accent">چرا آراد اَریسمان</span>
|
||||
<h2 className="mt-3 text-3xl sm:text-4xl font-extrabold text-primary">
|
||||
مزایای مکملهای آراد آریسمان
|
||||
مزایای مکملهای آراد اَریسمان
|
||||
</h2>
|
||||
</Container>
|
||||
<Features />
|
||||
</section>
|
||||
|
||||
<ImportCountries />
|
||||
|
||||
<section className="py-16 sm:py-20">
|
||||
<Container>
|
||||
<div className="rounded-3xl bg-primary px-8 py-14 sm:px-16 text-center">
|
||||
@@ -92,7 +118,7 @@ export default function AboutPage() {
|
||||
برای مشاوره و خرید محصولات همین حالا با ما در تماس باشید
|
||||
</h2>
|
||||
<p className="mt-4 text-white/80 max-w-xl mx-auto">
|
||||
کارشناسان آراد آریسمان آماده پاسخگویی به سوالات شما درباره مکملها و
|
||||
کارشناسان آراد اَریسمان آماده پاسخگویی به سوالات شما درباره مکملها و
|
||||
نحوه مصرف آنها هستند.
|
||||
</p>
|
||||
<div className="mt-8 flex flex-wrap justify-center gap-4">
|
||||
@@ -102,13 +128,15 @@ export default function AboutPage() {
|
||||
>
|
||||
تماس با ما
|
||||
</Link>
|
||||
<a
|
||||
href="tel:09104067935"
|
||||
dir="ltr"
|
||||
className="rounded-full border border-white/30 px-7 py-3.5 text-white font-semibold hover:bg-white/10 transition-colors"
|
||||
>
|
||||
09104067935
|
||||
</a>
|
||||
{phone ? (
|
||||
<a
|
||||
href={phoneTelHref(phone.number)}
|
||||
dir="ltr"
|
||||
className="rounded-full border border-white/30 px-7 py-3.5 text-white font-semibold hover:bg-white/10 transition-colors"
|
||||
>
|
||||
{phone.number}
|
||||
</a>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</Container>
|
||||
|
||||
@@ -31,7 +31,7 @@ export async function generateMetadata({
|
||||
if (!post) return {};
|
||||
const title = postTitle(post);
|
||||
return pageMetadata({
|
||||
title: `${title} | آراد آریسمان`,
|
||||
title: `${title} | آراد اَریسمان`,
|
||||
description: postExcerpt(post, 160),
|
||||
path: blogPath(post),
|
||||
});
|
||||
@@ -114,7 +114,7 @@ export default async function BlogDetailPage({
|
||||
|
||||
<div className="mt-10 rounded-2xl bg-surface p-6 flex flex-wrap items-center justify-between gap-4">
|
||||
<div>
|
||||
<p className="font-bold text-secondary">نویسنده: تیم آراد آریسمان</p>
|
||||
<p className="font-bold text-secondary">نویسنده: تیم آراد اَریسمان</p>
|
||||
<p className="mt-1 text-sm text-foreground">
|
||||
برای مشاوره تخصصی تغذیه دام و طیور با ما در تماس باشید.
|
||||
</p>
|
||||
|
||||
@@ -6,9 +6,9 @@ import Pagination from "@/components/Pagination";
|
||||
import { getPosts } from "@/lib/meshkee";
|
||||
|
||||
export const metadata = pageMetadata({
|
||||
title: "مقالات | آراد آریسمان",
|
||||
title: "مقالات | آراد اَریسمان",
|
||||
description:
|
||||
"مقالات آموزشی درباره تغذیه دام، طیور و زنبور عسل از تیم آراد آریسمان.",
|
||||
"مقالات آموزشی درباره تغذیه دام، طیور و زنبور عسل از تیم آراد اَریسمان.",
|
||||
path: "/blog",
|
||||
});
|
||||
|
||||
@@ -33,7 +33,7 @@ export default async function BlogPage({
|
||||
return (
|
||||
<>
|
||||
<PageBanner
|
||||
title="مقالات آراد آریسمان"
|
||||
title="مقالات آراد اَریسمان"
|
||||
subtitle="نکات آموزشی و تخصصی درباره تغذیه دام، طیور و زنبور عسل"
|
||||
breadcrumb="مقالات"
|
||||
/>
|
||||
|
||||
+80
-45
@@ -3,24 +3,49 @@ import PageBanner from "@/components/PageBanner";
|
||||
import ContactInfo from "@/components/ContactInfo";
|
||||
import ContactForm from "@/components/ContactForm";
|
||||
import { pageMetadata } from "@/lib/seo";
|
||||
import {
|
||||
getResolvedBusinessContact,
|
||||
phoneTelHref,
|
||||
} from "@/lib/meshkee";
|
||||
|
||||
export const metadata = pageMetadata({
|
||||
title: "تماس با ما | آراد آریسمان",
|
||||
title: "تماس با ما | آراد اَریسمان",
|
||||
description:
|
||||
"راههای ارتباطی با شرکت آراد آریسمان؛ آدرس، تلفن تماس و فرم ارسال پیام.",
|
||||
"راههای ارتباطی با شرکت آراد اَریسمان؛ آدرس، تلفن تماس و فرم ارسال پیام.",
|
||||
path: "/contact",
|
||||
});
|
||||
|
||||
const mapQuery = encodeURIComponent(
|
||||
"قم، شهرک صنعتی شکوهیه، خیابان شهید بروجردی"
|
||||
);
|
||||
function telegramHref(handle: string): string {
|
||||
const trimmed = handle.trim();
|
||||
if (!trimmed) return "#";
|
||||
if (trimmed.startsWith("http")) return trimmed;
|
||||
return `https://t.me/${trimmed.replace(/^@/, "")}`;
|
||||
}
|
||||
|
||||
function whatsappHref(value: string): string {
|
||||
const trimmed = value.trim();
|
||||
if (!trimmed) return "#";
|
||||
if (trimmed.startsWith("http")) return trimmed;
|
||||
const digits = trimmed
|
||||
.replace(/[۰-۹]/g, (d) => String("۰۱۲۳۴۵۶۷۸۹".indexOf(d)))
|
||||
.replace(/[^\d]/g, "");
|
||||
return digits ? `https://wa.me/${digits}` : "#";
|
||||
}
|
||||
|
||||
const MAP_LAT = 34.79998060691881;
|
||||
const MAP_LNG = 50.8027208051919;
|
||||
|
||||
export default async function ContactPage() {
|
||||
const contact = await getResolvedBusinessContact();
|
||||
const telegram = contact.socialMedia.telegram?.trim() || "";
|
||||
const whatsapp = contact.socialMedia.whatsapp?.trim() || "";
|
||||
const primaryPhone = contact.primaryPhone;
|
||||
|
||||
export default function ContactPage() {
|
||||
return (
|
||||
<>
|
||||
<PageBanner
|
||||
title="تماس با ما"
|
||||
subtitle="سوالات، پیشنهادات یا درخواست مشاوره خود را برای ما بفرستید؛ کارشناسان آراد آریسمان در اسرع وقت پاسخگوی شما خواهند بود."
|
||||
subtitle="سوالات، پیشنهادات یا درخواست مشاوره خود را برای ما بفرستید؛ کارشناسان آراد اَریسمان در اسرع وقت پاسخگوی شما خواهند بود."
|
||||
breadcrumb="تماس با ما"
|
||||
/>
|
||||
|
||||
@@ -44,8 +69,8 @@ export default function ContactPage() {
|
||||
<div className="lg:col-span-2 flex flex-col gap-5">
|
||||
<div className="relative flex-1 min-h-[280px] rounded-2xl overflow-hidden border border-black/5 shadow-sm">
|
||||
<iframe
|
||||
title="نقشه آراد آریسمان"
|
||||
src={`https://www.google.com/maps?q=${mapQuery}&output=embed`}
|
||||
title="نقشه آراد اَریسمان"
|
||||
src={`https://www.google.com/maps?q=${MAP_LAT},${MAP_LNG}&z=17&output=embed`}
|
||||
className="absolute inset-0 h-full w-full border-0"
|
||||
loading="lazy"
|
||||
referrerPolicy="no-referrer-when-downgrade"
|
||||
@@ -55,42 +80,52 @@ export default function ContactPage() {
|
||||
<div className="rounded-2xl bg-secondary p-7 text-white">
|
||||
<h3 className="font-bold">ما را در شبکههای اجتماعی دنبال کنید</h3>
|
||||
<div className="mt-5 flex items-center gap-4">
|
||||
<a
|
||||
href="#"
|
||||
aria-label="تلگرام"
|
||||
className="flex h-10 w-10 items-center justify-center rounded-full bg-white/10 hover:bg-accent hover:text-secondary transition-colors"
|
||||
>
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none">
|
||||
<path
|
||||
d="M21.5 3.5 2.8 10.9c-1 .4-1 1.7.1 2l4.7 1.5 1.8 5.6c.2.6 1 .8 1.4.3l2.5-2.7 4.9 3.6c.6.5 1.6.1 1.8-.6l3-15.6c.2-1-.7-1.8-1.5-1.5z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
<a
|
||||
href="#"
|
||||
aria-label="واتساپ"
|
||||
className="flex h-10 w-10 items-center justify-center rounded-full bg-white/10 hover:bg-accent hover:text-secondary transition-colors"
|
||||
>
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none">
|
||||
<path
|
||||
d="M12 2a10 10 0 0 0-8.6 15.1L2 22l5-1.4A10 10 0 1 0 12 2Zm0 18.2a8.1 8.1 0 0 1-4.2-1.1l-.3-.2-3 .8.8-2.9-.2-.3A8.2 8.2 0 1 1 12 20.2Zm4.5-6.1c-.2-.1-1.5-.7-1.7-.8-.2-.1-.4-.1-.6.1-.2.2-.7.8-.8 1-.2.2-.3.2-.5.1a6.7 6.7 0 0 1-2-1.2 7.4 7.4 0 0 1-1.4-1.7c-.1-.2 0-.4.1-.5l.4-.4c.1-.2.2-.3.2-.5.1-.2 0-.4 0-.5-.1-.1-.6-1.5-.8-2-.2-.5-.4-.4-.6-.4h-.5c-.2 0-.5.1-.7.3-.2.2-.9.9-.9 2.2s.9 2.6 1.1 2.8c.1.2 1.9 3 4.7 4.1.7.3 1.2.4 1.6.6.7.2 1.3.2 1.8.1.5-.1 1.5-.6 1.7-1.2.2-.6.2-1.1.2-1.2-.1-.2-.3-.2-.5-.3Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
<a
|
||||
href="tel:09104067935"
|
||||
aria-label="تماس تلفنی"
|
||||
className="flex h-10 w-10 items-center justify-center rounded-full bg-white/10 hover:bg-accent hover:text-secondary transition-colors"
|
||||
>
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none">
|
||||
<path
|
||||
d="M6.6 10.8c1.4 2.8 3.8 5.1 6.6 6.6l2.2-2.2c.3-.3.7-.4 1-.2 1.1.4 2.3.6 3.6.6.6 0 1 .4 1 1V20c0 .6-.4 1-1 1C10.6 21 3 13.4 3 4c0-.6.4-1 1-1h3.5c.6 0 1 .4 1 1 0 1.3.2 2.5.6 3.6.1.4 0 .8-.2 1L6.6 10.8z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
{telegram ? (
|
||||
<a
|
||||
href={telegramHref(telegram)}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
aria-label="تلگرام"
|
||||
className="flex h-10 w-10 items-center justify-center rounded-full bg-white/10 hover:bg-accent hover:text-secondary transition-colors"
|
||||
>
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none">
|
||||
<path
|
||||
d="M21.5 3.5 2.8 10.9c-1 .4-1 1.7.1 2l4.7 1.5 1.8 5.6c.2.6 1 .8 1.4.3l2.5-2.7 4.9 3.6c.6.5 1.6.1 1.8-.6l3-15.6c.2-1-.7-1.8-1.5-1.5z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
) : null}
|
||||
{whatsapp ? (
|
||||
<a
|
||||
href={whatsappHref(whatsapp)}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
aria-label="واتساپ"
|
||||
className="flex h-10 w-10 items-center justify-center rounded-full bg-white/10 hover:bg-accent hover:text-secondary transition-colors"
|
||||
>
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none">
|
||||
<path
|
||||
d="M12 2a10 10 0 0 0-8.6 15.1L2 22l5-1.4A10 10 0 1 0 12 2Zm0 18.2a8.1 8.1 0 0 1-4.2-1.1l-.3-.2-3 .8.8-2.9-.2-.3A8.2 8.2 0 1 1 12 20.2Zm4.5-6.1c-.2-.1-1.5-.7-1.7-.8-.2-.1-.4-.1-.6.1-.2.2-.7.8-.8 1-.2.2-.3.2-.5.1a6.7 6.7 0 0 1-2-1.2 7.4 7.4 0 0 1-1.4-1.7c-.1-.2 0-.4.1-.5l.4-.4c.1-.2.2-.3.2-.5.1-.2 0-.4 0-.5-.1-.1-.6-1.5-.8-2-.2-.5-.4-.4-.6-.4h-.5c-.2 0-.5.1-.7.3-.2.2-.9.9-.9 2.2s.9 2.6 1.1 2.8c.1.2 1.9 3 4.7 4.1.7.3 1.2.4 1.6.6.7.2 1.3.2 1.8.1.5-.1 1.5-.6 1.7-1.2.2-.6.2-1.1.2-1.2-.1-.2-.3-.2-.5-.3Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
) : null}
|
||||
{primaryPhone ? (
|
||||
<a
|
||||
href={phoneTelHref(primaryPhone.number)}
|
||||
aria-label="تماس تلفنی"
|
||||
className="flex h-10 w-10 items-center justify-center rounded-full bg-white/10 hover:bg-accent hover:text-secondary transition-colors"
|
||||
>
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none">
|
||||
<path
|
||||
d="M6.6 10.8c1.4 2.8 3.8 5.1 6.6 6.6l2.2-2.2c.3-.3.7-.4 1-.2 1.1.4 2.3.6 3.6.6.6 0 1 .4 1 1V20c0 .6-.4 1-1 1C10.6 21 3 13.4 3 4c0-.6.4-1 1-1h3.5c.6 0 1 .4 1 1 0 1.3.2 2.5.6 3.6.1.4 0 .8-.2 1L6.6 10.8z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+2
-2
@@ -28,11 +28,11 @@ export async function generateMetadata(): Promise<Metadata> {
|
||||
return {
|
||||
metadataBase: new URL(SITE_URL),
|
||||
title: {
|
||||
default: "آراد آریسمان",
|
||||
default: "آراد اَریسمان",
|
||||
template: "%s",
|
||||
},
|
||||
description:
|
||||
"شرکت آراد آریسمان، تولید و عرضه مکملها، ویتامینها و افزودنیهای خوراک دام و طیور با بیش از ۲۳ سال تجربه.",
|
||||
"شرکت آراد اَریسمان، تولید و عرضه مکملها، ویتامینها و افزودنیهای خوراک دام و طیور با بیش از ۲۳ سال تجربه.",
|
||||
icons: {
|
||||
icon: iconUrl,
|
||||
shortcut: iconUrl,
|
||||
|
||||
+3
-3
@@ -11,9 +11,9 @@ import { categoryPath, resolveCategorySlotHref } from "@/lib/urls";
|
||||
import { pageMetadata } from "@/lib/seo";
|
||||
|
||||
export const metadata: Metadata = pageMetadata({
|
||||
title: "آراد آریسمان | صفحه اصلی",
|
||||
title: "آراد اَریسمان | صفحه اصلی",
|
||||
description:
|
||||
"شرکت آراد آریسمان، تولید و عرضه مکملها، ویتامینها و افزودنیهای خوراک دام و طیور با بیش از ۲۳ سال تجربه.",
|
||||
"شرکت آراد اَریسمان، تولید و عرضه مکملها، ویتامینها و افزودنیهای خوراک دام و طیور با بیش از ۲۳ سال تجربه.",
|
||||
path: "/",
|
||||
});
|
||||
|
||||
@@ -48,7 +48,7 @@ export default async function Home() {
|
||||
<HomeContactStrip />
|
||||
<CategoryProducts
|
||||
categoryNameEn="Poultry"
|
||||
className="py-14 sm:py-16"
|
||||
className="py-14 sm:py-16 bg-[#fbf8f3]"
|
||||
/>
|
||||
<Features />
|
||||
<Stats />
|
||||
|
||||
@@ -12,6 +12,8 @@ import {
|
||||
getCategoryAncestors,
|
||||
getProductById,
|
||||
getProducts,
|
||||
getResolvedBusinessContact,
|
||||
phoneTelHref,
|
||||
productCatalog,
|
||||
productImages,
|
||||
productPriceLabel,
|
||||
@@ -33,7 +35,7 @@ export async function generateMetadata({
|
||||
if (!product) return {};
|
||||
const description = product.summary || stripHtml(product.descriptionHtml, 160);
|
||||
return pageMetadata({
|
||||
title: `${product.nameFa} | آراد آریسمان`,
|
||||
title: `${product.nameFa} | آراد اَریسمان`,
|
||||
description,
|
||||
path: productPath(product),
|
||||
});
|
||||
@@ -58,7 +60,11 @@ export default async function ProductDetailPage({
|
||||
const catalog = productCatalog(product);
|
||||
const shortDesc = product.summary || stripHtml(product.descriptionHtml, 160);
|
||||
|
||||
const allCategories = await getCategories();
|
||||
const [allCategories, contact] = await Promise.all([
|
||||
getCategories(),
|
||||
getResolvedBusinessContact(),
|
||||
]);
|
||||
const phone = contact.primaryPhone;
|
||||
const categoryTrail = product.categoryId
|
||||
? getCategoryAncestors(product.categoryId, allCategories)
|
||||
: [];
|
||||
@@ -121,13 +127,15 @@ export default async function ProductDetailPage({
|
||||
</div>
|
||||
|
||||
<div className="mt-6 flex flex-wrap gap-3">
|
||||
<a
|
||||
href="tel:09104067935"
|
||||
dir="ltr"
|
||||
className="rounded-full bg-primary px-7 py-3.5 text-white font-semibold hover:bg-primary-dark transition-colors"
|
||||
>
|
||||
09104067935
|
||||
</a>
|
||||
{phone ? (
|
||||
<a
|
||||
href={phoneTelHref(phone.number)}
|
||||
dir="ltr"
|
||||
className="rounded-full bg-primary px-7 py-3.5 text-white font-semibold hover:bg-primary-dark transition-colors"
|
||||
>
|
||||
{phone.number}
|
||||
</a>
|
||||
) : null}
|
||||
<Link
|
||||
href="/contact"
|
||||
className="rounded-full border border-primary/30 px-7 py-3.5 text-primary font-semibold hover:bg-primary/5 transition-colors"
|
||||
|
||||
@@ -30,8 +30,8 @@ export async function generateMetadata({
|
||||
const category = await getCategoryById(id);
|
||||
if (!category) return {};
|
||||
return pageMetadata({
|
||||
title: `${category.nameFa} | محصولات آراد آریسمان`,
|
||||
description: `مشاهده محصولات دسته ${category.nameFa}؛ مکملهای غذایی آراد آریسمان.`,
|
||||
title: `${category.nameFa} | محصولات آراد اَریسمان`,
|
||||
description: `مشاهده محصولات دسته ${category.nameFa}؛ مکملهای غذایی آراد اَریسمان.`,
|
||||
path: categoryPath(category),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -11,9 +11,9 @@ import { categoryPath } from "@/lib/urls";
|
||||
import { slugifyFa } from "@/lib/slugify";
|
||||
|
||||
export const metadata = pageMetadata({
|
||||
title: "محصولات | آراد آریسمان",
|
||||
title: "محصولات | آراد اَریسمان",
|
||||
description:
|
||||
"مکملهای غذایی، ویتامینه و معدنی دام، طیور و زنبور عسل؛ محصولات آراد آریسمان را مشاهده کنید.",
|
||||
"مکملهای غذایی، ویتامینه و معدنی دام، طیور و زنبور عسل؛ محصولات آراد اَریسمان را مشاهده کنید.",
|
||||
path: "/products",
|
||||
});
|
||||
|
||||
@@ -62,7 +62,7 @@ export default async function ProductsPage({
|
||||
return (
|
||||
<>
|
||||
<PageBanner
|
||||
title="محصولات آراد آریسمان"
|
||||
title="محصولات آراد اَریسمان"
|
||||
subtitle="مکملهای غذایی، ویتامینه و معدنی برای دام، طیور و زنبور عسل"
|
||||
breadcrumb="محصولات"
|
||||
/>
|
||||
|
||||
@@ -7,7 +7,7 @@ export default async function About() {
|
||||
const slotImage = slot?.images?.[0];
|
||||
|
||||
const imageSrc = slotImage?.url || "/images/hero-2.jpg";
|
||||
const imageAlt = slotImage?.titleFa || "محصولات آراد آریسمان";
|
||||
const imageAlt = slotImage?.titleFa || "محصولات آراد اَریسمان";
|
||||
const objectPositionClass = slotImage ? "object-center" : "object-left";
|
||||
const image = (
|
||||
<Image
|
||||
@@ -38,10 +38,10 @@ export default async function About() {
|
||||
<div className="order-1 lg:order-2 text-center lg:text-start">
|
||||
<span className="text-sm font-bold text-accent">درباره ما</span>
|
||||
<h2 className="mt-3 text-3xl sm:text-4xl font-extrabold text-primary">
|
||||
آراد آریسمان
|
||||
آراد اَریسمان
|
||||
</h2>
|
||||
<p className="mt-6 leading-8 text-foreground">
|
||||
شرکت آراد آریسمان پیشرو در تولید و عرضه افزودنیهای خوراک، ویتامینها و
|
||||
شرکت آراد اَریسمان پیشرو در تولید و عرضه افزودنیهای خوراک، ویتامینها و
|
||||
مکملهای غذایی دام و طیور با بیش از ۲۳ سال فعالیت در بازار ایران میباشد.
|
||||
واردات این شرکت عمدتا از تولیدکنندگان معتبر بینالمللی غذای دام و طیور از
|
||||
کشورهای انگلستان، فرانسه، ترکیه، هندوستان و چین میباشد.
|
||||
|
||||
@@ -1,63 +1,78 @@
|
||||
const cards = [
|
||||
{
|
||||
title: "آدرس ما",
|
||||
lines: ["قم، شهرک صنعتی شکوهیه، فاز دو،", "خیابان شهید بروجردی، نبش کلاهدوز یک، پلاک ۸۶۶"],
|
||||
icon: (
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none">
|
||||
<path
|
||||
d="M12 22s7-6.3 7-12a7 7 0 1 0-14 0c0 5.7 7 12 7 12Zm0-9a3 3 0 1 1 0-6 3 3 0 0 1 0 6Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "تلفن تماس",
|
||||
lines: ["09104067935", "۰۲۵۳۳۳۴۲۶۳۳ ، ۰۲۵۳۳۳۴۲۹۶۷ ، ۰۲۵۳۳۳۴۲۹۸۳"],
|
||||
icon: (
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none">
|
||||
<path
|
||||
d="M6.6 10.8c1.4 2.8 3.8 5.1 6.6 6.6l2.2-2.2c.3-.3.7-.4 1-.2 1.1.4 2.3.6 3.6.6.6 0 1 .4 1 1V20c0 .6-.4 1-1 1C10.6 21 3 13.4 3 4c0-.6.4-1 1-1h3.5c.6 0 1 .4 1 1 0 1.3.2 2.5.6 3.6.1.4 0 .8-.2 1L6.6 10.8z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "ساعات کاری",
|
||||
lines: ["شنبه تا چهارشنبه: ۸ الی ۱۷", "پنجشنبه: ۸ الی ۱۳"],
|
||||
icon: (
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none">
|
||||
<path
|
||||
d="M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20Zm1-10.4 4 2.3-1 1.7-5-2.9V6h2v5.6Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
];
|
||||
import {
|
||||
getResolvedBusinessContact,
|
||||
phoneTelHref,
|
||||
type BusinessPhoneNumber,
|
||||
} from "@/lib/meshkee";
|
||||
|
||||
const hoursLines = ["شنبه تا پنجشنبه: ۷ الی ۱۸"];
|
||||
|
||||
function phoneLabel(phone: BusinessPhoneNumber): string {
|
||||
if (phone.type === "cell") return "موبایل";
|
||||
if (phone.type === "landline") return "تلفن ثابت";
|
||||
return phone.label?.trim() || "تلفن";
|
||||
}
|
||||
|
||||
export default async function ContactInfo() {
|
||||
const contact = await getResolvedBusinessContact();
|
||||
|
||||
export default function ContactInfo() {
|
||||
return (
|
||||
<div className="grid grid-cols-1 sm:grid-cols-3 gap-5">
|
||||
{cards.map((c) => (
|
||||
<div
|
||||
key={c.title}
|
||||
className="rounded-2xl border border-black/5 bg-white p-7 shadow-sm"
|
||||
>
|
||||
<div className="flex h-12 w-12 items-center justify-center rounded-xl bg-primary/5 text-primary">
|
||||
{c.icon}
|
||||
</div>
|
||||
<h3 className="mt-4 font-bold text-secondary">{c.title}</h3>
|
||||
<div className="mt-2 space-y-1 text-sm leading-7 text-foreground" dir={c.title === "تلفن تماس" ? "ltr" : undefined}>
|
||||
{c.lines.map((line) => (
|
||||
<p key={line} className={c.title === "تلفن تماس" ? "text-right" : undefined}>
|
||||
{line}
|
||||
</p>
|
||||
))}
|
||||
</div>
|
||||
<div className="rounded-2xl border border-black/5 bg-white p-7 shadow-sm">
|
||||
<div className="flex h-12 w-12 items-center justify-center rounded-xl bg-primary/5 text-primary">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none">
|
||||
<path
|
||||
d="M12 22s7-6.3 7-12a7 7 0 1 0-14 0c0 5.7 7 12 7 12Zm0-9a3 3 0 1 1 0-6 3 3 0 0 1 0 6Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
))}
|
||||
<h3 className="mt-4 font-bold text-secondary">آدرس ما</h3>
|
||||
<div className="mt-2 space-y-1 text-sm leading-7 text-foreground">
|
||||
<p>{contact.address}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="rounded-2xl border border-black/5 bg-white p-7 shadow-sm">
|
||||
<div className="flex h-12 w-12 items-center justify-center rounded-xl bg-primary/5 text-primary">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none">
|
||||
<path
|
||||
d="M6.6 10.8c1.4 2.8 3.8 5.1 6.6 6.6l2.2-2.2c.3-.3.7-.4 1-.2 1.1.4 2.3.6 3.6.6.6 0 1 .4 1 1V20c0 .6-.4 1-1 1C10.6 21 3 13.4 3 4c0-.6.4-1 1-1h3.5c.6 0 1 .4 1 1 0 1.3.2 2.5.6 3.6.1.4 0 .8-.2 1L6.6 10.8z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<h3 className="mt-4 font-bold text-secondary">تلفن تماس</h3>
|
||||
<div className="mt-2 space-y-1 text-sm leading-7 text-foreground" dir="ltr">
|
||||
{contact.phones.map((p) => (
|
||||
<p key={`${p.type}-${p.number}`} className="text-right">
|
||||
<span className="text-foreground/70">{phoneLabel(p)}: </span>
|
||||
<a
|
||||
href={phoneTelHref(p.number)}
|
||||
className="hover:text-primary transition-colors"
|
||||
>
|
||||
{p.number}
|
||||
</a>
|
||||
</p>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="rounded-2xl border border-black/5 bg-white p-7 shadow-sm">
|
||||
<div className="flex h-12 w-12 items-center justify-center rounded-xl bg-primary/5 text-primary">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none">
|
||||
<path
|
||||
d="M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20Zm1-10.4 4 2.3-1 1.7-5-2.9V6h2v5.6Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<h3 className="mt-4 font-bold text-secondary">ساعات کاری</h3>
|
||||
<div className="mt-2 space-y-1 text-sm leading-7 text-foreground">
|
||||
{hoursLines.map((line) => (
|
||||
<p key={line}>{line}</p>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
+29
-14
@@ -2,8 +2,7 @@ import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import Container from "./Container";
|
||||
import MeshkeeCredit from "./MeshkeeCredit";
|
||||
|
||||
const phones = ["09104067935", "۰۲۵۳۳۳۴۲۶۳۳", "۰۲۵۳۳۳۴۲۹۶۷", "۰۲۵۳۳۳۴۲۹۸۳"];
|
||||
import { getResolvedBusinessContact, phoneTelHref } from "@/lib/meshkee";
|
||||
|
||||
const quickLinks = [
|
||||
{ label: "صفحه اصلی", href: "/" },
|
||||
@@ -13,7 +12,9 @@ const quickLinks = [
|
||||
{ label: "تماس با ما", href: "/contact" },
|
||||
];
|
||||
|
||||
export default function Footer() {
|
||||
export default async function Footer() {
|
||||
const contact = await getResolvedBusinessContact();
|
||||
|
||||
return (
|
||||
<footer id="footer" className="relative bg-secondary text-white/80 overflow-hidden">
|
||||
<Image
|
||||
@@ -27,13 +28,13 @@ export default function Footer() {
|
||||
<div>
|
||||
<Image
|
||||
src="/images/footer-logo.png"
|
||||
alt="آراد آریسمان"
|
||||
alt="آراد اَریسمان"
|
||||
width={140}
|
||||
height={40}
|
||||
className="h-10 w-auto"
|
||||
/>
|
||||
<p className="mt-5 text-sm leading-7 text-white/60">
|
||||
شرکت آراد آریسمان، پیشرو در تولید و عرضه افزودنیهای خوراک، ویتامینها و
|
||||
شرکت آراد اَریسمان، پیشرو در تولید و عرضه افزودنیهای خوراک، ویتامینها و
|
||||
مکملهای غذایی دام و طیور با بیش از ۲۳ سال تجربه.
|
||||
</p>
|
||||
</div>
|
||||
@@ -53,22 +54,36 @@ export default function Footer() {
|
||||
|
||||
<div>
|
||||
<h4 className="text-white font-bold mb-5">آدرس ما</h4>
|
||||
<p className="text-sm leading-7 text-white/60">
|
||||
قم، شهرک صنعتی شکوهیه، فاز دو، خیابان شهید بروجردی، نبش کلاهدوز یک، پلاک ۸۶۶
|
||||
</p>
|
||||
<p className="text-sm leading-7 text-white/60">{contact.address}</p>
|
||||
<h4 className="text-white font-bold mt-6 mb-3">ساعات کاری</h4>
|
||||
<p className="text-sm leading-7 text-white/60">شنبه تا پنجشنبه: ۷ الی ۱۸</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h4 className="text-white font-bold mb-5">راههای ارتباطی</h4>
|
||||
<ul className="space-y-3 text-sm">
|
||||
{phones.map((p) => (
|
||||
<li key={p}>
|
||||
<a href={`tel:${p}`} dir="ltr" className="hover:text-accent transition-colors block text-right">
|
||||
{p}
|
||||
{contact.phones.map((p) => (
|
||||
<li key={`${p.type}-${p.number}`}>
|
||||
<a
|
||||
href={phoneTelHref(p.number)}
|
||||
dir="ltr"
|
||||
className="hover:text-accent transition-colors block text-start"
|
||||
>
|
||||
{p.number}
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
{contact.emails.map((email) => (
|
||||
<li key={email}>
|
||||
<a
|
||||
href={`mailto:${email}`}
|
||||
className="hover:text-accent transition-colors block"
|
||||
dir="ltr"
|
||||
>
|
||||
{email}
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
<li className="text-white/50">۰۲۵۳۳۳۴۲۹۴۲ (فاکس)</li>
|
||||
</ul>
|
||||
</div>
|
||||
</Container>
|
||||
@@ -76,7 +91,7 @@ export default function Footer() {
|
||||
<div className="footer-bottom">
|
||||
<Container>
|
||||
<div className="footer-bottom-bar">
|
||||
<div className="footer-bottom-site">آراد آریسمان</div>
|
||||
<div className="footer-bottom-site">آراد اَریسمان</div>
|
||||
<MeshkeeCredit />
|
||||
</div>
|
||||
</Container>
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
import { getTopLevelCategories } from "@/lib/meshkee";
|
||||
import { getResolvedBusinessContact, getTopLevelCategories } from "@/lib/meshkee";
|
||||
import { categoryPath } from "@/lib/urls";
|
||||
import HeaderNav from "./HeaderNav";
|
||||
|
||||
export default async function Header() {
|
||||
const categories = await getTopLevelCategories();
|
||||
const [categories, contact] = await Promise.all([
|
||||
getTopLevelCategories(),
|
||||
getResolvedBusinessContact(),
|
||||
]);
|
||||
|
||||
return (
|
||||
<HeaderNav
|
||||
phoneNumber={contact.primaryPhone?.number ?? ""}
|
||||
productCategories={categories.map((cat) => ({
|
||||
id: cat.id,
|
||||
nameFa: cat.nameFa,
|
||||
|
||||
@@ -22,8 +22,10 @@ const navLinks = [
|
||||
|
||||
export default function HeaderNav({
|
||||
productCategories,
|
||||
phoneNumber,
|
||||
}: {
|
||||
productCategories: NavCategory[];
|
||||
phoneNumber: string;
|
||||
}) {
|
||||
const pathname = usePathname();
|
||||
const [scrolledPast, setScrolledPast] = useState(false);
|
||||
@@ -84,18 +86,22 @@ export default function HeaderNav({
|
||||
<header className="fixed inset-x-0 top-0 z-50">
|
||||
<div className="relative z-[60] bg-secondary text-white">
|
||||
<Container className="flex h-11 items-center justify-between text-sm">
|
||||
<a
|
||||
href="tel:09104067935"
|
||||
className="flex items-center gap-2 text-white/90 hover:text-accent transition-colors"
|
||||
>
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" className="shrink-0">
|
||||
<path
|
||||
d="M6.6 10.8c1.4 2.8 3.8 5.1 6.6 6.6l2.2-2.2c.3-.3.7-.4 1-.2 1.1.4 2.3.6 3.6.6.6 0 1 .4 1 1V20c0 .6-.4 1-1 1C10.6 21 3 13.4 3 4c0-.6.4-1 1-1h3.5c.6 0 1 .4 1 1 0 1.3.2 2.5.6 3.6.1.4 0 .8-.2 1L6.6 10.8z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
<span dir="ltr">09104067935</span>
|
||||
</a>
|
||||
{phoneNumber ? (
|
||||
<a
|
||||
href={`tel:${phoneNumber.replace(/[^\d+]/g, "")}`}
|
||||
className="flex items-center gap-2 text-white/90 hover:text-accent transition-colors"
|
||||
>
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" className="shrink-0">
|
||||
<path
|
||||
d="M6.6 10.8c1.4 2.8 3.8 5.1 6.6 6.6l2.2-2.2c.3-.3.7-.4 1-.2 1.1.4 2.3.6 3.6.6.6 0 1 .4 1 1V20c0 .6-.4 1-1 1C10.6 21 3 13.4 3 4c0-.6.4-1 1-1h3.5c.6 0 1 .4 1 1 0 1.3.2 2.5.6 3.6.1.4 0 .8-.2 1L6.6 10.8z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
<span dir="ltr">{phoneNumber}</span>
|
||||
</a>
|
||||
) : (
|
||||
<span />
|
||||
)}
|
||||
<div className="flex items-center gap-4">
|
||||
<a href="#" aria-label="تلگرام" className="text-white/90 hover:text-accent transition-colors">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none">
|
||||
@@ -136,7 +142,7 @@ export default function HeaderNav({
|
||||
<Link href="/" className="shrink-0" onClick={() => setMobileOpen(false)}>
|
||||
<Image
|
||||
src={scrolled || mobileOpen ? "/images/logo-wordmark.png" : "/images/footer-logo.png"}
|
||||
alt="آراد آریسمان"
|
||||
alt="آراد اَریسمان"
|
||||
width={140}
|
||||
height={40}
|
||||
className="h-10 w-auto"
|
||||
|
||||
@@ -9,7 +9,7 @@ export default function Hero() {
|
||||
<div className="relative w-full aspect-[4/3] lg:aspect-auto lg:h-[480px] rounded-3xl overflow-hidden shadow-xl">
|
||||
<Image
|
||||
src="/images/hero-1.jpg"
|
||||
alt="محصولات آراد آریسمان در مزرعه گندم"
|
||||
alt="محصولات آراد اَریسمان در مزرعه گندم"
|
||||
fill
|
||||
priority
|
||||
className="object-cover object-left"
|
||||
@@ -39,7 +39,7 @@ export default function Hero() {
|
||||
|
||||
<div className="order-1 lg:order-2 text-center lg:text-start">
|
||||
<h1 className="text-4xl sm:text-5xl lg:text-6xl font-extrabold text-primary leading-[1.15]">
|
||||
آراد آریسمان
|
||||
آراد اَریسمان
|
||||
</h1>
|
||||
<p className="mt-5 text-lg sm:text-xl text-foreground max-w-md mx-auto lg:mx-0">
|
||||
قدرت رشد، از دل تغذیه سالم
|
||||
|
||||
@@ -130,7 +130,7 @@ export default function HeroSlider({
|
||||
<section
|
||||
role="region"
|
||||
aria-roledescription="carousel"
|
||||
aria-label="اسلایدر معرفی آراد آریسمان"
|
||||
aria-label="اسلایدر معرفی آراد اَریسمان"
|
||||
onMouseEnter={pause}
|
||||
onMouseLeave={resume}
|
||||
className="relative -mt-[125px] h-svh min-h-[520px] w-full overflow-hidden bg-secondary"
|
||||
@@ -149,7 +149,7 @@ export default function HeroSlider({
|
||||
<Link href={slide.linkUrl} className="absolute inset-0 block" aria-label={slide.title || "مشاهده"}>
|
||||
<Image
|
||||
src={slide.image}
|
||||
alt={slide.title || "آراد آریسمان"}
|
||||
alt={slide.title || "آراد اَریسمان"}
|
||||
fill
|
||||
priority={i === 0}
|
||||
className="object-cover"
|
||||
@@ -159,7 +159,7 @@ export default function HeroSlider({
|
||||
) : (
|
||||
<Image
|
||||
src={slide.image}
|
||||
alt={slide.title || "آراد آریسمان"}
|
||||
alt={slide.title || "آراد اَریسمان"}
|
||||
fill
|
||||
priority={i === 0}
|
||||
className="object-cover"
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
import Link from "next/link";
|
||||
import Container from "./Container";
|
||||
import ScrollReveal from "./ScrollReveal";
|
||||
import { getResolvedBusinessContact, phoneTelHref } from "@/lib/meshkee";
|
||||
|
||||
export default async function HomeContactStrip() {
|
||||
const contact = await getResolvedBusinessContact();
|
||||
const phone = contact.primaryPhone;
|
||||
|
||||
export default function HomeContactStrip() {
|
||||
return (
|
||||
<section className="bg-[#f1e7d9] text-secondary">
|
||||
<section className="bg-[#f7f1e8] text-secondary">
|
||||
<Container>
|
||||
<ScrollReveal>
|
||||
<div className="flex flex-col gap-6 py-10 sm:flex-row sm:items-center sm:justify-between sm:py-12">
|
||||
@@ -16,18 +20,20 @@ export default function HomeContactStrip() {
|
||||
</div>
|
||||
|
||||
<div className="flex flex-wrap items-center gap-4 sm:gap-5 shrink-0">
|
||||
<a
|
||||
href="tel:09104067935"
|
||||
className="inline-flex items-center gap-2 rounded-full border border-primary/20 bg-white/40 px-5 py-3 text-[15px] font-medium text-primary hover:bg-white/70 transition-colors"
|
||||
>
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" aria-hidden>
|
||||
<path
|
||||
d="M6.6 10.8c1.4 2.8 3.8 5.1 6.6 6.6l2.2-2.2c.3-.3.7-.4 1-.2 1.1.4 2.3.6 3.6.6.6 0 1 .4 1 1V20c0 .6-.4 1-1 1C10.6 21 3 13.4 3 4c0-.6.4-1 1-1h3.5c.6 0 1 .4 1 1 0 1.3.2 2.5.6 3.6.1.4 0 .8-.2 1L6.6 10.8z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
<span dir="ltr">09104067935</span>
|
||||
</a>
|
||||
{phone ? (
|
||||
<a
|
||||
href={phoneTelHref(phone.number)}
|
||||
className="inline-flex items-center gap-2 rounded-full border border-primary/20 bg-white/40 px-5 py-3 text-[15px] font-medium text-primary hover:bg-white/70 transition-colors"
|
||||
>
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" aria-hidden>
|
||||
<path
|
||||
d="M6.6 10.8c1.4 2.8 3.8 5.1 6.6 6.6l2.2-2.2c.3-.3.7-.4 1-.2 1.1.4 2.3.6 3.6.6.6 0 1 .4 1 1V20c0 .6-.4 1-1 1C10.6 21 3 13.4 3 4c0-.6.4-1 1-1h3.5c.6 0 1 .4 1 1 0 1.3.2 2.5.6 3.6.1.4 0 .8-.2 1L6.6 10.8z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
<span dir="ltr">{phone.number}</span>
|
||||
</a>
|
||||
) : null}
|
||||
<Link
|
||||
href="/contact"
|
||||
className="inline-flex items-center justify-center rounded-full bg-primary px-7 py-3 text-[15px] font-bold text-white hover:bg-primary-dark transition-colors"
|
||||
|
||||
@@ -18,7 +18,7 @@ export default function ImportCountries() {
|
||||
واردات از تولیدکنندگان معتبر جهانی
|
||||
</h2>
|
||||
<p className="mt-4 text-foreground">
|
||||
آراد آریسمان محصولات خود را عمدتا از تولیدکنندگان معتبر بینالمللی
|
||||
آراد اَریسمان محصولات خود را عمدتا از تولیدکنندگان معتبر بینالمللی
|
||||
این کشورها وارد میکند
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -52,9 +52,13 @@ export default function ProductCard({ product }: { product: Product }) {
|
||||
<p className="mt-2 text-sm text-foreground line-clamp-2">{excerpt}</p>
|
||||
)}
|
||||
<div className="mt-3 flex items-center justify-between">
|
||||
<span className="text-sm font-bold text-primary">
|
||||
{productPriceLabel(product)}
|
||||
</span>
|
||||
{product.store?.minPrice ? (
|
||||
<span className="text-sm font-bold text-primary">
|
||||
{productPriceLabel(product)}
|
||||
</span>
|
||||
) : (
|
||||
<span />
|
||||
)}
|
||||
<span className="flex h-8 w-8 items-center justify-center rounded-full bg-primary/5 text-primary rotate-180 group-hover:bg-primary group-hover:text-white transition-colors">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none">
|
||||
<path
|
||||
|
||||
+25
-14
@@ -1,14 +1,9 @@
|
||||
import Image from "next/image";
|
||||
import Container from "./Container";
|
||||
|
||||
const stats = [
|
||||
{ value: "۲۳۰+", label: "رضایت مشتری" },
|
||||
{ value: "۲۳", label: "سال تجربه" },
|
||||
];
|
||||
|
||||
export default function Stats() {
|
||||
return (
|
||||
<section className="relative py-20 sm:py-28">
|
||||
<section className="relative py-20 sm:py-28 overflow-hidden">
|
||||
<Image
|
||||
src="/images/stats-banner.jpg"
|
||||
alt=""
|
||||
@@ -18,15 +13,31 @@ export default function Stats() {
|
||||
/>
|
||||
<div className="absolute inset-0 bg-primary-dark/80" />
|
||||
<Container className="relative">
|
||||
<div className="grid grid-cols-2 max-w-xl mx-auto text-center gap-8">
|
||||
{stats.map((s) => (
|
||||
<div key={s.label}>
|
||||
<div className="text-4xl sm:text-5xl font-extrabold text-white">
|
||||
{s.value}
|
||||
</div>
|
||||
<div className="mt-3 text-white/80">{s.label}</div>
|
||||
<div className="flex justify-center text-white">
|
||||
<div className="inline-flex items-center gap-4 sm:gap-5">
|
||||
<div className="shrink-0 text-center">
|
||||
<p className="text-5xl sm:text-7xl md:text-8xl font-extrabold tracking-tight leading-none">
|
||||
۱۴ سال
|
||||
</p>
|
||||
<p
|
||||
dir="ltr"
|
||||
className="mt-2 font-display text-xs sm:text-sm font-medium tracking-[0.06em] text-white/75"
|
||||
>
|
||||
14 years of experience
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
|
||||
<div
|
||||
className="hidden sm:block h-14 sm:h-16 w-px shrink-0 bg-white/35"
|
||||
aria-hidden
|
||||
/>
|
||||
|
||||
<p className="text-base sm:text-xl md:text-2xl font-medium leading-8 sm:leading-10 text-white/90 text-start">
|
||||
تولید تخصصی محصولات
|
||||
<br />
|
||||
مکمل دام و طیور
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</Container>
|
||||
</section>
|
||||
|
||||
@@ -49,6 +49,125 @@ export async function getWebsiteFavicon(): Promise<WebsiteFavicon> {
|
||||
}
|
||||
}
|
||||
|
||||
/** Public business profile: about, phones, addresses, social (dashboard Business Data). */
|
||||
export type BusinessPhoneNumber = {
|
||||
label?: string;
|
||||
type: "landline" | "cell" | string;
|
||||
number: string;
|
||||
};
|
||||
|
||||
export type BusinessAddress = {
|
||||
id: string;
|
||||
name: string | null;
|
||||
province: string | null;
|
||||
city: string | null;
|
||||
address: string | null;
|
||||
postalCode: string | null;
|
||||
landline: string | null;
|
||||
};
|
||||
|
||||
export type BusinessSocialMedia = {
|
||||
whatsapp?: string;
|
||||
telegram?: string;
|
||||
instagram?: string;
|
||||
linkedin?: string;
|
||||
youtube?: string;
|
||||
aparat?: string;
|
||||
};
|
||||
|
||||
export type BusinessInfo = {
|
||||
id: string;
|
||||
name: string;
|
||||
nameFa: string;
|
||||
about: string;
|
||||
vision: string;
|
||||
logoUrl: string | null;
|
||||
logoDarkUrl: string | null;
|
||||
faviconUrl: string | null;
|
||||
emails: string[];
|
||||
phoneNumbers: BusinessPhoneNumber[];
|
||||
socialMedia: BusinessSocialMedia;
|
||||
addresses: BusinessAddress[];
|
||||
schema?: {
|
||||
enabled: boolean;
|
||||
type: string;
|
||||
jsonLd?: Record<string, unknown> | null;
|
||||
};
|
||||
};
|
||||
|
||||
const FALLBACK_ADDRESS =
|
||||
"قم، شهرک صنعتی شکوهیه، فاز دو، خیابان شهید بروجردی، نبش کلاهدوز یک، پلاک ۸۶۶";
|
||||
|
||||
const FALLBACK_PHONES: BusinessPhoneNumber[] = [
|
||||
{ type: "cell", number: "09128540059", label: "Cell" },
|
||||
{ type: "landline", number: "02533342633", label: "Landline" },
|
||||
];
|
||||
|
||||
export async function getBusinessInfo(): Promise<BusinessInfo | null> {
|
||||
try {
|
||||
return await meshkeeFetch<BusinessInfo>(
|
||||
`/tenants/${TENANT_DOMAIN}/website/business-info`,
|
||||
300
|
||||
);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/** Build a single-line Persian address from a Meshkee address object. */
|
||||
export function formatBusinessAddress(addr: BusinessAddress | null | undefined): string {
|
||||
if (!addr) return "";
|
||||
const parts: string[] = [];
|
||||
if (addr.province?.trim()) parts.push(addr.province.trim());
|
||||
if (addr.city?.trim() && addr.city.trim() !== addr.province?.trim()) {
|
||||
parts.push(addr.city.trim());
|
||||
}
|
||||
if (addr.address?.trim()) parts.push(addr.address.trim());
|
||||
return parts.join("، ");
|
||||
}
|
||||
|
||||
/** ASCII digits for `tel:` / `mailto:` hrefs (accepts Persian digits). */
|
||||
export function phoneTelHref(number: string): string {
|
||||
const ascii = number
|
||||
.replace(/[۰-۹]/g, (d) => String("۰۱۲۳۴۵۶۷۸۹".indexOf(d)))
|
||||
.replace(/[^\d+]/g, "");
|
||||
return ascii ? `tel:${ascii}` : "#";
|
||||
}
|
||||
|
||||
export type ResolvedBusinessContact = {
|
||||
address: string;
|
||||
phones: BusinessPhoneNumber[];
|
||||
cells: BusinessPhoneNumber[];
|
||||
landlines: BusinessPhoneNumber[];
|
||||
primaryPhone: BusinessPhoneNumber | null;
|
||||
emails: string[];
|
||||
socialMedia: BusinessSocialMedia;
|
||||
};
|
||||
|
||||
/** Contact fields for UI — API values when present, stable local fallbacks otherwise. */
|
||||
export async function getResolvedBusinessContact(): Promise<ResolvedBusinessContact> {
|
||||
const info = await getBusinessInfo();
|
||||
const phones =
|
||||
info?.phoneNumbers?.filter((p) => p.number?.trim()) ?? [];
|
||||
const resolvedPhones = phones.length > 0 ? phones : FALLBACK_PHONES;
|
||||
const cells = resolvedPhones.filter((p) => p.type === "cell");
|
||||
const landlines = resolvedPhones.filter((p) => p.type === "landline");
|
||||
const primaryPhone = cells[0] ?? landlines[0] ?? resolvedPhones[0] ?? null;
|
||||
|
||||
const formatted =
|
||||
formatBusinessAddress(info?.addresses?.[0]) || FALLBACK_ADDRESS;
|
||||
|
||||
return {
|
||||
address: formatted,
|
||||
phones: resolvedPhones,
|
||||
cells,
|
||||
landlines,
|
||||
primaryPhone,
|
||||
emails: info?.emails?.filter(Boolean) ?? [],
|
||||
socialMedia: info?.socialMedia ?? {},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Business-managed image overrides (hero category icons, category tiles,
|
||||
* feature icons, about photo, brand logos). Each slot has a stable `key`; when a
|
||||
|
||||
Reference in New Issue
Block a user