Connect the storefront to Meshkee catalog, blogs, and static image slots.

Wire homepage specials, product/blog pages, instant search, and the customer portal so the live pharmacy site can be managed from the dashboard.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-08-19 23:51:41 +03:30
co-authored by Cursor
parent cd2f9dfc9d
commit 66e604c426
39 changed files with 1900 additions and 188 deletions
+68
View File
@@ -0,0 +1,68 @@
# Arjmand Pharmacy — AI context
Persian RTL pharmacy storefront for **arjmandpharmacy.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: `arjmandpharmacy.com` (`NEXT_PUBLIC_WEBSITE_DOMAIN` / `WEBSITE_DOMAIN` / `NEXT_PUBLIC_MESHKEE_DOMAIN`)
- Customer portal: `https://customer.arjmandpharmacy.com` (`NEXT_PUBLIC_CUSTOMER_PORTAL_URL`)
- Public reads: `/tenants/{domain}/...` (no auth). Cart/orders/favorites: `/businesses/{businessId}/...` + Bearer JWT.
- Do not invent CMS, upload, or dashboard APIs.
Login / user icon (and add-to-cart if not logged in) go 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` |
| `/blog/[slug]` | Blog details |
| `/meshkee/static-image-slots` | Slot catalog for the dashboard Refresh button |
| `/api/search?q=` | Instant store-item search (`name`, min 3 chars) |
| `/api/cart/items` | Proxies authenticated add-to-cart |
## Homepage carousels (store specials)
`GET /tenants/{domain}/store-specials` matched by `key`:
1. `special-sale`
2. `multi-vitamin`
3. `body-building-supplement`
If a special has no `items`, keep the current sample products. Use `variants[0].id` as the product URL.
## Catalog
- Mega menu: product categories **level 1 and 2** (`GET /tenants/{domain}/categories?entityType=product`). Links: `/products?categoryId={id}`.
- Instant search: header input, activate when query length **> 2**, `store-items?name=`.
- 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.
- Add to cart: `POST /businesses/{businessId}/cart/items` with `{ storeItemVariantId, quantity }`. No token → customer portal.
## Static image slots
Homepage images: `GET /tenants/{domain}/website/static-images?pageKey=home`. Catalog: `GET /meshkee/static-image-slots`.
| key | kind | itemCount |
| --- | --- | --- |
| `slider` | list | null |
| `two-banner-below-slider` | list | 2 |
| `categories` | list | null |
| `two-banner-row` | list | 2 |
| `three-banner-row` | list | 3 |
| `about-us-image` | single | 1 |
`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 `lib/static-images.ts` in the same change.
## Local fallbacks
- Slider: `src/assets/images/slides`, else `/placeholders/slider-*.svg`
- Logo: `src/assets/images/logo`, else `/placeholders/logo.svg`
- Other art / empty catalog: `/public/placeholders/*.svg` and sample products/posts in `lib/data.ts`