# Ayoubi Gallery — AI / Project Context ## Source of truth - Live domain: `https://ayoubi.jewelry` - Design language: black ground, ivory type, gold lines, Doran + Cinzel, flat surfaces - Backend: https://api.meshkee.com/docs/website - Domain: `ayoubi.jewelry` (`NEXT_PUBLIC_WEBSITE_DOMAIN`) - API base: `https://api.meshkee.com/api/v1` (`NEXT_PUBLIC_MESHKEE_API_BASE`) - Tenant business id: `42` (`GET /tenants/ayoubi.jewelry`, nameFa: گالری ایوبی فخیم) - Enabled modules: `products`, `blog`, `finance`. `specialProductsSource`: `store_item` - Prompt reference: `https://api.meshkee.com/api/v1/public/ai-prompts/ayoubi-gallery/backend/253d39eea2a4047c39296d1a` ## Stack - Next.js 15 App Router + React 19 + TypeScript - `output: "standalone"` in `next.config.ts` (required for the Meshkee websites VM) - Language: `fa`, direction: `rtl` - Fonts: Doran (`--font-doran`), Cinzel (`--font-cinzel`) - Styling: `src/app/globals.css` only (no Tailwind) ## Color palette - Background: `#070708` (`--bg`) - Elevated: `#101012` - Ivory text: `#f3eee6` (`--fg`) - Muted: `rgba(243, 238, 230, 0.62)` - Gold: `#c9a86a` (`--accent`) - Hairline: `rgba(243, 238, 230, 0.14)` - Flat: no shadows, square corners, 1px borders - Header is fixed. Frosted over the home video; solid `#000` after scroll (`.header--solid`) - Header tools: account menu, cart (badge + popup), phone, Instagram ## Auth (customer dashboard) - Do **not** add `/login`, `/register`, `/cart`, or `/checkout` on this site - Anonymous account icon → `https://customer.ayoubi.jewelry` - Logged in (cookie `meshkee_customer_access_token`, may be chunked): show `{firstName|nameFa|name} عزیز` - Dropdown: `پروفایل من`, `خروج`, and if admin `مدیریت وبسایت` → `https://business.ayoubi.jewelry` - Session: `src/lib/auth.ts` + `src/lib/authUser.ts` via `GET /auth/me` ## Shopping cart (mini-cart only) - Header cart icon + quantity badge + popup (`CartButton` + `CartProvider` + `guestCart.ts`) - Persist `meshkee-guest-cart` in localStorage + cookie on `.ayoubi.jewelry` - Add-to-cart only when `GET .../store-items/by-product/{productId}` returns in-stock variants - Line `id` = `storeItemVariantId`; price = `discountedPrice ?? price` - Continue: logged in → `customer.../checkout/cart?guestCart=…`; else login with that redirect - Never call `/businesses/{id}/cart*` from this site ## Pages | Route | Purpose | | --- | --- | | `/` | Video hero, category studio, local/CMS gallery, follow, carousel, parallax, visit | | `/products` | Catalog from Meshkee products API + jewelry category filters + pagination | | `/products/[id]/[nameFaSlug]` | Product detail (canonical); redirect if slug drifts | | `/products/category/[id]/[nameFaSlug]` | Category product list | | `/portfolio` | Portfolio list (API; empty until CMS content) | | `/portfolio/[slug]` | Portfolio detail: lightbox gallery, zoom, similar row | | `/blog` | Blog list (API; empty until CMS content) | | `/blog/[slug]` | Blog detail | | `/about` | درباره گالری | | `/contact` | Contact facts + form → `POST /api/contact` → Meshkee contact-submissions | ## Product detail requirements - Media gallery with hover zoom (desktop) + lightbox - Tabs: توضیحات، مشخصات فنی (via `.../technical-info` join), دیدگاه‌ها - Comments: form only when authenticated; else login link to customer portal - Similar products from `relatedProducts` - Emit `product.schema.jsonLd` when present ## Homepage (visual gallery) - Local images in `public/assets/images/` / `gallery` in `src/data/site.ts` as fallbacks - CMS slots: `categories`, `four-banner`, `masonry-image`, `instagram-image`, `last-banner` (see Static image slots) - Homepage masonry is atmospheric; purchasable catalog is `/products` ## Brand copy (fallback) - Name: گالری طلا و جواهر ایوبی فخیم / Ayoubi Fakhim Jewelry - Tagline: این طلا همیشه مده - Address: قم - سالاریه - اریکه ملل - Phones: ۰۹۹۹ ۱۲۹ ۶۶۶۶ (`09991296666`), ۰۹۳۷ ۱۴۴ ۸۹۰۵ (`09371448905`) - Instagram: https://www.instagram.com/ayoubifakhim/ - Logo / favicon fallback: `public/Ayoobi-logo.png` ## Meshkee helpers - `src/lib/meshkee.ts` — business-info, favicon - `src/lib/catalog.ts` — products, categories, blogs, portfolios, comments, store-items, `/auth/me` - `src/lib/slug.ts` — canonical product/category/blog/portfolio hrefs - Favicon: `GET /website/favicon` → `metadata.icons`, else `/Ayoobi-logo.png` ### Static image slots Catalog: `GET /meshkee/static-image-slots` from `STATIC_IMAGE_SLOTS` in `src/lib/static-images.ts`. Fetch per page: `GET /tenants/{domain}/website/static-images?pageKey=…`. Empty/fail → keep local placeholders. `url` → ``; `linkUrl` → wrap in ``. Use `titleFa` / `titleEn` / `subtext` to match the original UI labels. Apply `slot.aspectRatio` from the API (fallback to catalog). **If an on-page frame’s size or aspect ratio changes in development, update the matching `STATIC_IMAGE_SLOTS` entry in the same change.** | key | kind | itemCount | aspectRatio | width | UI | | --- | --- | --- | --- | --- | --- | | `categories` | list | null | `1:1` | 320 | Category row — `titleFa`/`titleEn` beside image (icon fallback) | | `four-banner` | list | 4 | `3:4` | 1440 | Sticky “از فلز تا پوشیدن” — Fa/En/subtext + image | | `masonry-image` | list | null | `3:4` | 960 | Masonry gallery (free display height) | | `instagram-image` | single | 1 | `4:5` | 480 | Follow frame photo + optional Fa/En/subtext | | `last-banner` | single | 1 | `16:9` | 1600 | Parallax end banner | | `about-portrait` | single | 1 | `3:4` | 900 | About portrait | Helpers: `src/lib/home-slots.ts`, `SlotImage`. ### Tags & badges From `business-info`: `metaTags` as `{ html }` **or** `{ name, content }` → root `` via `CmsMeta`. `trustBadges[].embedHtml` → footer (scripts stripped). Empty → omit; do not hardcode eNamad/Samandehi. ### SEO - Do not ship local `sitemap.xml` / `robots.txt` / `app/sitemap.ts` / `app/robots.ts` - Static pages: `GET /meshkee/sitemap-config.json` - One H1 per page; content images have alt; use `seoMetaTitle` / `seoMetaDescription` when set - Organization JSON-LD from business-info; product/blog detail emit their own `schema.jsonLd` ## Important paths - Layout / providers: `src/app/layout.tsx`, `src/components/providers/*` - Header / footer: `src/components/Header.tsx`, `AccountMenu.tsx`, `CartButton.tsx`, `Footer.tsx` - Catalog UI: `MediaGallery.tsx`, `ProductTabs.tsx`, `AddToCart.tsx`, `CatalogCard.tsx`, `CommentSection.tsx` - Contact: `src/components/ContactForm.tsx` + toast, `src/app/api/contact/route.ts`