Add the FarrokhWin Next.js site for Meshkee hosting.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-08-31 09:18:26 +03:30
co-authored by Cursor
commit 4dec4eb92c
116 changed files with 13456 additions and 0 deletions
+151
View File
@@ -0,0 +1,151 @@
# FarrokhWin — AI / Project Context
## Source of truth
- Live reference: https://www.farrokhwin.com/
- Backend / Meshkee Website API: https://api.meshkee.com/docs/website
- Domain: `farrokhwin.com` (`NEXT_PUBLIC_WEBSITE_DOMAIN`)
- Tenant business id: `28` (`GET /tenants/farrokhwin.com`)
- `enabledModules`: products, portfolio, blog, finance
- Customer portal (login / profile / cart): `https://customer.farrokhwin.com`
- Business dashboard: `https://business.farrokhwin.com`
- Language: `fa`, direction: `rtl`
## Stack
- Next.js 15 (App Router) + React 19 + TypeScript
- Tailwind CSS v4 (utility import) + custom CSS in `src/app/globals.css`
- Fonts (downloaded from the live Meshkee CDN into `public/fonts/`):
- `morabba` — default UI / headings
- `iran-yekan` — numbers / accent figures
- `Montserrat` via `next/font/google` (English labels, class `.en`)
## Color palette (from live site `:root`)
- Primary: `#19377d`
- Secondary / accent: `#34ace0`
- Header: `#23242D`
- Page background: `#1F2128` / `#23262D`
- Muted text: `#8F8F8F`
- White: `#FFFFFF`
## Pages
| Route | Purpose |
|-------|---------|
| `/` | Homepage (hero, stats, intro, Aparat video, glass article, window types, why us, features, **latest blogs carousel**, CTA, **latest products carousel**, brands) |
| `/about` | درباره ما |
| `/contact` | تماس با ما (info + FAQ + Meshkee contact form) |
| `/products` | Meshkee product catalog (`GET /tenants/{domain}/products`) |
| `/products/category/{id}/{nameFaSlug}` | Product category (`GET /tenants/{domain}/categories/by-id/{id}`) |
| `/products/{id}/{nameFaSlug}` | Product details (gallery, zoom, tabs, comments, similar products) |
| `/blog` | Meshkee blog list (`GET /tenants/{domain}/blogs`) |
| `/blog/{id}/{titleSlug}` | Blog details (body HTML + comments) |
| `/portfolio` | Meshkee portfolio list (`GET /tenants/{domain}/portfolios`) |
| `/portfolios/{id}/{titleFaSlug}` | Portfolio details (`GET /tenants/{domain}/portfolios/by-id/{id}`) |
| `/videos` | Placeholder — videos from Meshkee later |
Header: logo + phones + **AccountMenu** + hamburger overlay (image panel + RTL menu). Cart still in the hamburger.
## Auth / account menu
- Login / user icon → `https://customer.farrokhwin.com` (`customerPortalUrl` in `src/lib/config.ts`)
- Shared session cookies: `src/lib/shared-auth-cookie.ts` + `src/lib/session.tsx`
- `GET /api/auth/me` proxies Meshkee `/auth/me`
- Logged in: show `{name} عزیز` with dropdown **پروفایل من**, **خروج**, and if website admin **مدیریت وبسایت**
- Admin handoff: `POST /api/auth/handoff` → `business.farrokhwin.com?handoff=…`
- Admin = super_admin or membership on business id `28` (`isOwner` or `teamRole`)
- Comments: form only when authenticated; otherwise a login box linking to the customer portal. `POST /api/comments` → Meshkee tenant comments
## Meshkee API
Base: `{NEXT_PUBLIC_MESHKEE_API_BASE}/tenants/{domain}/...`
Helpers: `src/lib/meshkee.ts` → `meshkeeGet`, `meshkeeGetOrNull`, `tenantPath`, `getTenant`, `getBusinessId`
| Resource | List | Detail |
|----------|------|--------|
| Products | `GET /tenants/{domain}/products` (`src/lib/products.ts`) | `GET /tenants/{domain}/products/by-id/{id}` + `/technical-info` |
| Blogs | `GET /tenants/{domain}/blogs` (`src/lib/blog.ts`) | `GET /tenants/{domain}/blogs/by-id/{id}` |
| Comments | `GET /tenants/{domain}/comments?entityType=&entityId=` | `POST` via `/api/comments` |
| Portfolio | `GET /tenants/{domain}/portfolios` | not wired yet |
| Contact | `POST /tenants/{domain}/contact-submissions` via `POST /api/contact` | Body: `{ title, name, text, email?, cellNumber? }` |
Canonical URLs:
- Product: `/products/{id}/{nameFaSlug}` (`productHref` / `slugifyForUrl`)
- Blog: `/blog/{id}/{titleSlug}` (`blogHref`)
Product details:
- Lightbox gallery + hover zoom (`src/components/ProductGallery.tsx`)
- Tabs: توضیحات / مشخصات فنی / نظرات (`src/components/ProductTabs.tsx`)
- Similar products from `relatedProducts`, else other catalog items
Homepage carousels (`src/components/MediaCarousel.tsx`): latest blogs and latest products, **max 12** each. API items are primary; static slot images overlay by index when present.
## Static image slots
API: `GET /tenants/{domain}/website/static-images?pageKey=home|about|contact`
Catalog: `GET /meshkee/static-image-slots` → `STATIC_IMAGE_SLOTS` in `src/lib/static-images.ts`
| key | kind | itemCount | aspectRatio | recommendedWidth | section |
| --- | --- | --- | --- | --- | --- |
| `slider` | list | null | `1920:1080` | 1920 | Homepage hero banners |
| `home-video-poster` | single | 1 | `16:9` | 1280 | Homepage video |
| `home-windows` | list | 4 | `12:17` | 720 | Window type cards |
| `home-why-image` | single | 1 | `1:1` | 640 | Why Farrokh graphic |
| `home-blog` | list | 12 | `1:1` | 720 | Homepage latest-blog carousel (square overlay cards) |
| `home-products` | list | 12 | `4:3` | 640 | Homepage latest-products carousel (equal 4:3 boxes, contain) |
| `home-clients` | list | 4 | `3:2` | 320 | Brand logos |
| `about-hero` | single | 1 | `1920:480` | 1440 | About hero (currently CSS navy band) |
| `about-photo` | single | 1 | `4:3` | 800 | About photo |
| `contact-hero` | single | 1 | `1920:480` | 1440 | Contact hero band |
| `contact-faq-image` | single | 1 | `4:3` | 960 | Contact FAQ photo |
Rules:
- Use `slot.images` (all if `kind=list`, first if `kind=single`)
- `url` → image src; `linkUrl` → wrap in link
- Empty / fail → local fallbacks from `src/data/site.ts` / `public/images/`
- Homepage blog/product carousels keep Meshkee API items (ids, titles, hrefs); slot images only replace `image` at the same index
- **If a slot’s on-page size or aspect ratio changes in CSS, update `STATIC_IMAGE_SLOTS` in the same change**
## Content & assets
- Site copy, phones, addresses, FAQs: `src/data/site.ts`
- Logo: `public/images/logo/logo.png` (from live `kC9gmfo7ef.png`)
- Hero banners: `public/images/hero/slide-1.jpg` … `slide-3.jpg`
- Favicon: `/favicon.png`
- Meshkee footer credit (same as safeteb.com): `public/images/footer/MeshkeeLogo-White.png`
- Contact: `02538203597` · `09002032333` · `02533342698`
- Office: قم، بلوار امام رضا(ع)، مجتمع فردوس، واحد ۱۳۸
- Factory: قم، شهرک صنعتی شکوهیه، فاز دو، خیابان فکوری، کوچه ۲، پلاک KH214
- Social: Instagram / Telegram `@farrokhwin`, WhatsApp `989002032333`
- Homepage video: Aparat `w21jpe0` via official embed script (`src/components/AparatVideo.tsx`)
## Important paths
- Layout / shell: `src/app/layout.tsx`, `src/components/Header.tsx`, `src/components/Footer.tsx`, `src/components/Providers.tsx`
- Account: `src/components/AccountMenu.tsx`, `src/lib/session.tsx`
- Home: `src/app/page.tsx`, `src/components/HeroSlider.tsx`, `src/components/MediaCarousel.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`
- About / contact: `src/app/about/page.tsx`, `src/app/contact/page.tsx`
- Config: `src/lib/config.ts`
## Env
```bash
NEXT_PUBLIC_WEBSITE_DOMAIN=farrokhwin.com
NEXT_PUBLIC_MESHKEE_API_BASE=https://api.meshkee.com/api/v1
NEXT_PUBLIC_CUSTOMER_PORTAL_URL=https://customer.farrokhwin.com
NEXT_PUBLIC_BUSINESS_ORIGIN=https://business.farrokhwin.com
```
## Commands
```bash
npm install
npm run dev
npm run build
```
## Sitemap + robots
- **Do not** add `public/sitemap.xml` or `public/robots.txt` (nginx proxies both to the Meshkee API)
- Publish `GET /meshkee/sitemap-config.json` (generated at build from app routes)
- Generated at build: `scripts/generate-sitemap-config.mjs` → `src/lib/sitemap-config.generated.json`
- Run manually: `npm run generate:sitemap-config`
- After deploy: business dashboard → Website → Settings → Sync sitemap config
- Dynamic `/products/{id}/{slug}`, `/products/category/{id}/{slug}`, `/blog/{id}/{slug}`, and `/portfolios/{id}/{slug}` are not listed in the static sitemap config; Meshkee CMS syncs those URLs
### On-page SEO rules
- Unique `<title>` + meta description on every crawlable page (`src/lib/seo.ts` → `pageMetadata`)
- Exactly one `<h1>` per page; section headings use `<h2>` / `<h3>`
- Content images have meaningful `alt`
- Footer bottom Meshkee credit must stay in the safeteb.com style (animated frame + white logo + “Designed And Developed By Meshkee E-Commerce Team”)