Wire Meshkee catalog: products, blog, mega menu, and product search.

Catalog-only (no cart); search targets store items and products pages.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-08-21 16:04:31 +03:30
co-authored by Cursor
parent cfa21cbee9
commit 8e14748b48
29 changed files with 1460 additions and 244 deletions
+73 -77
View File
@@ -3,84 +3,95 @@
Persian RTL storefront for **brb-store.com** (فروشگاه و تعمیرگاه لوازم خانگی برادران برقعی، قم).
Next.js App Router rebuild of the original WillaMall/BeTheme site. Keep this file current — other AI tools read it first.
Live DNS for `www.brb-store.com` currently serves a different tenant; source of truth for copy, images, and palette is the archived original at `https://www.brb-store.ir/` (Wayback 2022) plus `Ai-data/prompt.txt`.
## Stack
- Next.js 16 (App Router, Turbopack) + React 19 + TypeScript + Tailwind v4
- Locale: `fa`, direction: `rtl`
- Fonts: Vazirmatn (Persian) + Montserrat (English kickers). Original site used **BYekan-Edited** + **IRANSans** + **Montserrat**; those files were not recoverable from Wayback (`WillaMall_SP/assets/Fonts/...` 404).
- Icons: Lucide, tinted with brand red (original used WillaMall `WMi-*` icon font, not archived).
- Fonts: Vazirmatn (Persian) + Montserrat (English kickers)
- Icons: Lucide
- Dev: `npm run dev`
## Brand
| Token | Value | Source |
| --- | --- | --- |
| Brand red | `#e7432b` | BeTheme `color-red` |
| Brand dark | `#c93621` | hover |
| Ink | `#1a1a1a` | |
| Muted | `#6c6363` | original about text |
| Paper | `#f6f3f1` | |
| Footer copy bar | `#efefef` | original `.footer_copy` |
Logo: oval **BRB** (black top / red bottom, “Borgheei Brothers”) at `public/images/brand/logo.png` and `src/assets/images/logo/logo.png`. Favicon from original `.ico`.
Design language comes from the original BeTheme Carpenter homepage, not a generic banner stack:
- Full-bleed kitchen photography with a **white 92% caption card** (the original slider’s 430px white panel), red 3px bar, Montserrat kicker.
- «قطعات ما» header: red bar + English kicker, title, short catalog note.
- Parts grid: **4 columns**, image cards with a **frosted glass** caption box on the photo (`backdrop-filter`), hover zoom + search icon.
- Red (`#e7432b`) as accent — numbers, icons, underlines — not a wash over every photo.
- Story: فروش / قطعات / تعمیرات, ۳۰+ years, two Qom branches, wholesale.
- Homepage **blog carousel** after the three-banner row: snap-scroll cards, arrows, link to `/blog`. Copy lives in `lib/data.ts` (`blogPosts`) until Meshkee.
- Original **category hover carousel** (`CategoryShowcase`): centered «دسته بندی ها» header, tall photo cards, dark bottom bar that expands on hover with «تماس با ما». Data: `showcaseCategories`.
Product tiles stay on **white backgrounds**. Lifestyle extras: `public/images/lifestyle/`.
## Routes (this pass)
Clone **only** these pages:
| Path | Content |
| Token | Value |
| --- | --- |
| `/` | Homepage + static image slots |
| `/about` | About us (original `/AboutUs`) |
| `/contact` | Contact us (original `/ContactUs`) |
| `/blog` | Article list (local placeholders until Meshkee blog is wired) |
| `/blog/[slug]` | Article detail |
| `/meshkee/static-image-slots` | Slot catalog for the dashboard Refresh button |
| Brand red | `#e7432b` |
| Brand dark | `#c93621` |
| Ink | `#161616` |
| Muted | `#6c6363` |
| Paper | `#f4f0ec` |
Account / user icon → `https://customer.brb-store.com` (`NEXT_PUBLIC_CUSTOMER_PORTAL_URL`). Do not build a local login page.
Logo: `public/images/brand/logo.png`. Dark glossy caption bars: `lib/glossy.ts`.
## 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: `brb-store.com` (`NEXT_PUBLIC_WEBSITE_DOMAIN` / `WEBSITE_DOMAIN`)
- Customer portal: `https://customer.brb-store.com` (`NEXT_PUBLIC_CUSTOMER_PORTAL_URL`)
- Public reads: `/tenants/{domain}/...` (no auth).
- Do not invent CMS, upload, or dashboard APIs.
This site is **catalog-only** (no shopping cart). Login / user icon goes to the customer portal. Do not build a local login page.
## Routes
| Path | Source |
| --- | --- |
| `/` | Homepage + static image slots + store specials + latest blogs |
| `/products` | Store items (`GET /tenants/{domain}/store-items`) |
| `/products?categoryId=` | Same, filtered |
| `/products/[variantId]` | Store item variant + product description/gallery + comments |
| `/blog` | `GET /tenants/{domain}/blogs` (falls back to `lib/data.ts` `blogPosts`) |
| `/blog/[slug]` | Blog details + comments |
| `/about` | About us |
| `/contact` | Contact us |
| `/meshkee/static-image-slots` | Slot catalog for the dashboard Refresh button |
| `/api/search?q=` | Instant product search (`store-items?name=`, min 3 chars) |
## Homepage order
`Hero` → `Services` (3 icons) → `CategoryShowcase` → `AboutPreview` → five-banner (2-col + 3-col) → `BlogCarousel` → `two-banner-row` → `Stats` → `WideBanner` → `Branches`.
`Hero` → `Services` → three product carousels → `CategoryShowcase` → `AboutPreview` → five-banner (2+3) → `BlogCarousel` → `two-banner-row` → `Stats` → `WideBanner` → `Branches`.
Caption bars on photos use dark glossy glass (`lib/glossy.ts` `glossyBar`). Hover the card to expand the bar and show `subtext`.
## Homepage carousels (store specials)
## Static image slots (wired)
`GET /tenants/{domain}/store-specials` matched by `key`:
`GET /tenants/brb-store.com/website/static-images?pageKey=home`. Catalog: `GET /meshkee/static-image-slots` from `STATIC_IMAGE_SLOTS` in `lib/static-images.ts`. Client: `overlaySlotImages` / `pickSlot`. Empty/fail → local placeholder. `url` → `<img src>`, `linkUrl` → wrap in a link, `titleFa` / `titleEn` / `subtext` → caption. Use `slot.aspectRatio`.
1. `consumeables` — اقلام مصرفی
2. `refrigrator-parts` — قطعات یخچال
3. `washing-machine-parts` — قطعات ماشین لباسشویی
If a slot’s CSS size or ratio changes, update `aspectRatio` and `recommendedWidth` in `STATIC_IMAGE_SLOTS` in the same change.
If a special has no `items`, keep sample products from `lib/data.ts`. Use `variants[0].id` as the product URL.
| key | kind | itemCount | ratio | Local fallback |
| --- | --- | --- | --- | --- |
| `slider` | list | null | 2:1 | `slides` peek carousel, center `1280px` |
| `three-icon-image` | list | 3 | 1:1 | Lucide icons if slot empty |
| `categories` | list | null | 14:23 | `showcaseCategories` tall cards |
| `about-us-image` | single | 1 | 4:3 | `public/images/about/store.jpg` |
| `five-banner-section` | list | 5 | 2:1 | `twoBannerRow` + `threeBannerRow` |
| `two-banner-row` | list | 2 | 2:1 | `bannersBelowSlider` (after blog) |
| `full-row-image` | single | 1 | 32:9 | `public/images/banners/wide.jpg` |
| `two-branch-image` | list | 2 | 2:1 | `branches` photos |
## Catalog
Do not invent upload APIs.
- Mega menu: product categories **level 1 and 2** (`GET /tenants/{domain}/categories?entityType=product`). Links: `/products?categoryId={id}`.
- Instant search: header input searches **products** when query length **> 2** (`/api/search` → `store-items?name=`). Enter or “مشاهده همه” → `/products?q=`.
- Product pages are display-only (price, gallery, description, comments). No cart / add-to-cart.
- Details gallery: product `images[].url` + thumbnail. Click = lightbox, hover = zoom.
- Details tabs: description (`descriptionHtml`) and comments (`GET /comments?entityType=product&entityId={productId}`). Unauthenticated users see a login box to the customer portal.
## Original business data (valid — do not invent replacements)
## Static image slots
**About:** 30+ years. Sells home appliances, spare parts, and repairs small appliances (vacuum, meat grinder, fan, juicer, mill, steam iron, kettle, mixer, blender, microwave, …). Wholesale and retail, Iran and abroad. Open to manufacturers/traders.
`GET /tenants/{domain}/website/static-images?pageKey=home`. Catalog: `GET /meshkee/static-image-slots` from `STATIC_IMAGE_SLOTS` in `lib/static-images.ts`.
| key | kind | itemCount |
| --- | --- | --- |
| `slider` | list | null |
| `three-icon-image` | list | 3 |
| `categories` | list | null |
| `about-us-image` | single | 1 |
| `five-banner-section` | list | 5 |
| `two-banner-row` | list | 2 |
| `full-row-image` | single | 1 |
| `two-branch-image` | list | 2 |
`url` → img, `linkUrl` → wrap in a link, empty/fail → placeholder. Use `slot.aspectRatio`. If a slot’s size/ratio changes in CSS, update `STATIC_IMAGE_SLOTS` in the same change.
## Original business data (do not invent replacements)
**About:** 30+ years. Sells home appliances, spare parts, and repairs small appliances. Wholesale and retail.
**Branches**
@@ -89,26 +100,11 @@ Do not invent upload APIs.
**Phones:** 0912-309-3407، 0912-651-7619، 025-36604454، 025-32404070، تلفکس 0253-6638866
**Telegram:** https://t.me/borgheeibrothers
**Email display:** Alireza borghei20@gmail.com (`alirezaborghei20@gmail.com`)
**Email:** `alirezaborghei20@gmail.com`
**Map:** 34.6564, 50.8696
**Part categories (homepage):** vacuum, juicer/blender/mill, steam cleaner, meat grinder, iron, microwave/toaster, kettle, fan/evaporative cooler, food processor/chopper/hand blender/mixer, battery, bearing, collector.
## Local fallbacks
Appliance mega-menu (household + industrial) is copied from the original header; links currently go to `/#parts` until the catalog is connected.
## Meshkee
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: `brb-store.com` (`NEXT_PUBLIC_WEBSITE_DOMAIN` / `WEBSITE_DOMAIN`).
Wired: homepage static images (`Ai-data/prompt-images-slot.txt`).
Later: `Ai-data/prompt-connect-backend.txt` — products, blog, portfolio, customer portal.
Public reads only. Do not invent CMS/upload/dashboard APIs. Product images are white-bg and will be read from the backend.
## Local content
All copy and nav live in `lib/data.ts`. Downloaded originals are under `public/images/`. Sample lifestyle photos: `assets/sample images/` (copied to `public/images/lifestyle/`).
- Copy / nav / sample products / local blog: `lib/data.ts`
- Empty catalog art: `/public/placeholders/*.svg`
- Downloaded originals: `public/images/`