diff --git a/CONTEXT.md b/CONTEXT.md index 04fe2a8..3622483 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -12,7 +12,10 @@ ## Stack - Next.js 15 (App Router) + React 19 + TypeScript - Tailwind CSS v4 (utility import) + custom CSS in `src/app/globals.css` -- Language: `fa`, direction: `rtl` +- Language: `fa` (default, RTL), `en` (LTR), `ar` (RTL) +- Static copy lives in `src/i18n/fa.ts`, `src/i18n/en.ts`, `src/i18n/ar.ts` +- Locale cookie: `kaman-locale` (also mirrored in localStorage) +- Products and blog are **FA-only** for now (hidden in EN/AR nav, homepage, and redirected away) - Fonts: - `iran-yekan` from Meshkee CDN (Persian UI / body) - `Rajdhani` via `next/font/google` (English UI, class `.en`) @@ -37,12 +40,12 @@ | `/about` | درباره ما | | `/contact` | تماس با ما | -Header (RTL): logo + menu on the right; search, language (FA/EN), and account on the left. +Header (RTL for FA/AR, LTR for EN): logo + menu on the inline-start; search, language (FA/EN/AR), and account on the inline-end. - Signed out: icon links to `https://customer.kamancable.ir` - Signed in: `{firstName} عزیز` dropdown — پروفایل من, خروج, and مدیریت وبسایت if the user is a website admin - Session: shared cookies `meshkee_customer_access_token` / refresh, hydrated into localStorage; `/api/auth/me` proxies `GET /auth/me` -Homepage product cards are Meshkee `categories` slot teasers (duplicatable; empty API keeps `src/data/site.ts`). The full catalog is `/products`. +Homepage product cards and blog carousel are FA-only. EN and AR hide products/blog (nav, homepage, and `/products` `/blog` redirect home). The full catalog remains `/products` in FA. Homepage blog carousel prefers Meshkee blogs, with `src/data/site.ts` as fallback. ## Meshkee API integration @@ -120,6 +123,7 @@ Rules: ## Important paths - Layout / shell: `src/app/layout.tsx`, `src/components/Header.tsx`, `src/components/AccountMenu.tsx`, `src/components/Footer.tsx` - Home: `src/app/page.tsx`, `src/components/HeroSlider.tsx`, `src/components/ContactBar.tsx` +- i18n: `src/i18n/config.ts`, `src/i18n/fa.ts`, `src/i18n/en.ts`, `src/i18n/ar.ts`, `src/i18n/locale-context.tsx` - Products: `src/app/products/page.tsx`, `src/app/products/[id]/[slug]/page.tsx` - Blog: `src/app/blog/page.tsx`, `src/app/blog/[id]/[slug]/page.tsx` - Config: `src/lib/config.ts` diff --git a/src/app/about/page.tsx b/src/app/about/page.tsx index b23193a..22e5854 100644 --- a/src/app/about/page.tsx +++ b/src/app/about/page.tsx @@ -1,104 +1,102 @@ import SlotImage from "@/components/SlotImage"; -import { - aboutGallery, - aboutIntro, - laboratoryText, - machineryText, - qualityPolicy, - site, - stats, -} from "@/data/site"; +import { aboutGallery } from "@/data/site"; +import { getDictionary } from "@/i18n/get-locale"; import { pageMetadata } from "@/lib/seo"; import { fetchStaticImageSlots, overlaySlotImages, pickSlot } from "@/lib/static-images"; -export const metadata = pageMetadata({ - title: "درباره ما", - description: - "آشنایی با شرکت صنایع کابل کمان؛ تولیدکننده سیم و کابل فشار ضعیف، مخابراتی و ابزار دقیق از سال ۱۳۷۰ در زنجان.", - path: "/about", - image: "/images/samples/cables-coils.jpg", -}); +export async function generateMetadata() { + const { locale, t } = await getDictionary(); + return pageMetadata({ + title: t.aboutPage.title, + description: t.aboutPage.metaDescription, + path: "/about", + image: "/images/samples/cables-coils.jpg", + locale, + }); +} export default async function AboutPage() { + const { locale, t } = await getDictionary(); const slots = await fetchStaticImageSlots("about"); const hero = overlaySlotImages( pickSlot(slots, "about-hero"), - [{ id: "about-hero", image: "/images/samples/cables-coils.jpg", title: "درباره ما" }], + [{ id: "about-hero", image: "/images/samples/cables-coils.jpg", title: t.aboutPage.title }], "about-hero", ); const gallery = overlaySlotImages( pickSlot(slots, "about-gallery"), - aboutGallery.map((item) => ({ id: item.id, image: item.image, title: item.title })), + aboutGallery.map((item, index) => ({ + id: item.id, + image: item.image, + title: t.aboutPage.galleryItems[index] ?? item.title, + })), "about-gallery", ); return ( <>
- +
-

درباره ما

-

About Us

+

{t.aboutPage.title}

+ {locale !== "en" ?

{t.aboutPage.kicker}

: null}
- {stats.map((stat) => ( + {t.aboutPage.stats.map((stat) => (
{stat.value}
{stat.label}
-

{stat.labelEn}

+ {stat.kicker && stat.kicker !== stat.label ?

{stat.kicker}

: null}
))}
-

شرکت کابل کمان

-

{aboutIntro}

+

{t.aboutPage.companyTitle}

+

{t.aboutPage.intro}

-

اهداف

-

Quality Policy

-

صداقت بهترین روش است.

-

- شرکت صنایع کابل کمان به‌عنوان یکی از تولیدکنندگان سیم و کابل، رضایت مشتریان را از طریق ارتقاء کیفیت و - رعایت کلیه قوانین و الزامات حاکم بر محصول خود، به‌عنوان برترین هدف برگزیده است. -

+

{t.aboutPage.goalsTitle}

+ {locale !== "en" ?

{t.aboutPage.goalsKicker}

: null} +

{t.aboutPage.honesty}

+

{t.aboutPage.goalsBody}

    - {qualityPolicy.map((item) => ( + {t.aboutTabs.qualityPolicy.map((item) => (
  1. {item}
  2. ))}
-

آزمایشگاه صنایع کابل کمان

-

Laboratory

-

{laboratoryText}

+

{t.aboutPage.labTitle}

+ {locale !== "en" ?

{t.aboutPage.labKicker}

: null} +

{t.aboutPage.labText}

-

تجهیزات و ماشین‌آلات

-

Equipment & Machinery

-

{machineryText}

+

{t.aboutPage.machineryTitle}

+ {locale !== "en" ?

{t.aboutPage.machineryKicker}

: null} +

{t.aboutPage.machineryText}

-

ضمانت‌نامه شرکت

-

Guarantee

-

{machineryText}

+

{t.aboutPage.guaranteeTitle}

+ {locale !== "en" ?

{t.aboutPage.guaranteeKicker}

: null} +

{t.aboutPage.machineryText}

-

گالری

-

Gallery

+

{t.aboutPage.galleryTitle}

+ {locale !== "en" ?

{t.aboutPage.galleryKicker}

: null}
{gallery.items.map((item) => (
- +
))}
diff --git a/src/app/contact/page.tsx b/src/app/contact/page.tsx index fdced0a..714feb1 100644 --- a/src/app/contact/page.tsx +++ b/src/app/contact/page.tsx @@ -1,50 +1,57 @@ import ContactForm from "@/components/ContactForm"; import SlotImage from "@/components/SlotImage"; import { site } from "@/data/site"; +import { getDictionary } from "@/i18n/get-locale"; import { pageMetadata } from "@/lib/seo"; import { fetchStaticImageSlots, overlaySlotImages, pickSlot } from "@/lib/static-images"; -export const metadata = pageMetadata({ - title: "تماس با ما", - description: `ارتباط با صنایع کابل کمان. دفتر تهران: ${site.address}. تلفن ${site.phoneFa}.`, - path: "/contact", - image: "/images/slider/bg3.jpg", -}); +export async function generateMetadata() { + const { locale, t } = await getDictionary(); + return pageMetadata({ + title: t.contactPage.title, + description: `${t.contactPage.metaDescription} ${t.contactInfo.address}. ${t.contactInfo.phoneLabel} ${site.phone}.`, + path: "/contact", + image: "/images/slider/bg3.jpg", + locale, + }); +} export default async function ContactPage() { + const { locale, t } = await getDictionary(); const slots = await fetchStaticImageSlots("contact"); const hero = overlaySlotImages( pickSlot(slots, "contact-hero"), - [{ id: "contact-hero", image: "/images/slider/bg3.jpg", title: "تماس با ما" }], + [{ id: "contact-hero", image: "/images/slider/bg3.jpg", title: t.contactPage.title }], "contact-hero", ); + const phone = locale === "fa" ? site.phoneFa : site.phone; return ( <>
- +
-

با ما در ارتباط باشید

-

Contact Us

+

{t.contactPage.heading}

+ {locale !== "en" ?

{t.contactPage.kicker}

: null}
-

اطلاعات تماس

+

{t.contactPage.infoTitle}

- Address -

{site.address}

+ {t.contactInfo.addressEn} +

{t.contactInfo.address}

- Factory -

{site.factory}

+ {t.contactInfo.factoryEn} +

{t.contactInfo.factory}

- Phone + {t.contactInfo.phoneEn}

- {site.phoneFa} + {phone}

@@ -52,7 +59,7 @@ export default async function ContactPage() {