# Dcorya — AI context Persian RTL decorative home-goods storefront for **dcorya.com** (دکوریا). Next.js App Router. ## Meshkee API - Docs: https://api.meshkee.com/docs/website - OpenAPI: https://api.meshkee.com/docs/website/openapi.json - Base: `https://api.meshkee.com/api/v1` - Tenant domain: `dcorya.com` (`WEBSITE_DOMAIN` in `src/lib/meshkee.ts`) - Customer portal: `https://customer.dcorya.com` - Public reads: `/tenants/{domain}/...` (no auth). Cart: `/businesses/{businessId}/...` + Bearer JWT. - Do not invent CMS, upload, or dashboard APIs. ## Stack - Next.js 16 (App Router) + React 19 + TypeScript + Tailwind CSS v4 - `output: "standalone"` in `next.config.ts` (required for Meshkee websites VM deploy) - Helpers: `src/lib/meshkee.ts`, static images: `src/lib/static-images.ts` ## Routes | Path | Source | | --- | --- | | `/` | Homepage + static image slots + 3 store-special carousels | | `/products` | Product catalog | | `/products/[id]/[slug]` | Product details | | `/products/category/[id]/[slug]` | Category listing | | `/blog`, `/blog/[id]/[slug]` | Blog | | `/about`, `/contact`, `/cart`, `/purchaseguide`, `/satisfaction` | Static / form pages | | `/meshkee/static-image-slots` | Slot catalog for the dashboard Refresh button | | `/meshkee/sitemap-config.json` | Sitemap config | ## Static image slots Homepage images: `GET /tenants/{domain}/website/static-images?pageKey=home`. Catalog: `GET /meshkee/static-image-slots` → `STATIC_IMAGE_SLOTS` in `src/lib/static-images.ts`. | key | kind | itemCount | UI section | aspectRatio | | --- | --- | --- | --- | --- | | `slider` | list | null | `Hero` full-bleed | `1920:1100` | | `categories` | list | null | `ProductCategories` icons | `1:1` | | `two-banner-below-slider` | list | 2 | `BannerRow` | `2:1` | | `second-categories` | list | null | `ConsoleCategories` | `1:1` | | `about-us-image` | single | 1 | `AboutDcorya` photo | `4:3` | Rules: - `url` → ``; `linkUrl` → wrap in `` / `Link` - Use `titleFa` → Persian label, `titleEn` → English subtitle, `subtext` when the original UI shows them - Empty/fail → keep current local placeholders under `/public/images/` - Use `slot.aspectRatio` from the API (catalog fallback if missing) - **If a slot’s CSS size or aspect ratio changes during development, update `STATIC_IMAGE_SLOTS` in the same change** — Meshkee reads the catalog as the source of truth ## Local fallbacks - Slider: `/images/slide-1.jpg` … `slide-4.jpg` - Categories: `/images/cat-*.png` - Banners: `/images/banner-1.png`, `/images/console-cat-4.jpg` - Second categories: `/images/console-cat-*.png|jpg` - About: `/images/product-2.jpg` ## Auth / account menu - Login / user icon → `https://customer.dcorya.com` (`CUSTOMER_PORTAL_URL`) - Detect session from parent-domain cookies `meshkee_customer_access_token` / `meshkee_customer_refresh_token` (storefront only reads; customer dashboard writes) - Logged in: show `{name} عزیز` with dropdown **پروفایل من**, **خروج**, and if website admin **مدیریت وبسایت** - Admin handoff: `POST /api/auth/handoff` → `https://business.dcorya.com?handoff=…` - Admin = super_admin or membership on this business (`isOwner` / `teamRole`) - Favicon: `GET /tenants/{domain}/website/favicon` → `faviconUrl` / `logoUrl`, else `/images/logo.png` ## Shopping cart (mini-cart only) - Header cart icon + quantity badge + popup (lines, qty, remove, total, **ادامه خرید**) - Guest cart key `meshkee-guest-cart` in `localStorage` + parent-domain cookie - Line `id` = `storeItemVariantId`; price = `discountedPrice ?? price` - Continue → `customer.dcorya.com/checkout/cart?guestCart=…` (or login redirect when logged out) - Do **not** build storefront `/cart`, checkout, or call `/businesses/.../cart` ## Catalog - Listings / carousels / search: `GET /tenants/{domain}/store-items` (not `/products` list) - Detail still uses `GET /products/by-id/{id}` for description/gallery/comments + `store-items/by-product/{id}` for variants - Mega menu on **محصولات**: categories level 1–2. Links: `/products/category/{id}/{slug}` - Product card: shared `ProductCard` (1:1 image, `object-cover`); no price → **تماس بگیرید** ## Homepage product carousels `GET /tenants/{domain}/store-specials` (`source` mirrors `specialProductsSource`). Shared card: `ProductCard` (1:1 image box, `object-contain`). | key | eyebrow | placement | | --- | --- | --- | | `new-collection` | NEW ARRIVALS | After categories | | `special-sale` | SPECIAL SALE | After console categories | | `our-handmades` | HANDCRAFTED | After about (muted bg) | Empty special `items` → local placeholders (`new-collection` also tries latest products first). Title comes from the special when set.