Align slot catalog with slider / our-experts / two-service-banner and send guests to customer portal /login. Co-authored-by: Cursor <cursoragent@cursor.com>
7.7 KiB
7.7 KiB
Clinic Samen — AI / Project Context
Source of truth
- Live site being cloned: https://www.clinicsamen.com/
- Prompt instructions:
Ai-data/prompt.txt - Backend / Meshkee Website API: https://api.meshkee.com/docs/website
- Static image slots prompt:
Ai-data/prompt-images-slot.txt - Backend connect prompt:
Ai-data/prompt-connect-backend.txt - SEO prompt:
Ai-data/prompt-seo.txt - Domain:
clinicsamen.com(NEXT_PUBLIC_WEBSITE_DOMAIN) - Tenant business id:
21(fromGET /tenants/clinicsamen.com)
Stack
- Next.js 15 (App Router) + React 19 + TypeScript
- Tailwind CSS v4 (utility import) + custom CSS in
src/app/globals.css - Language:
fa, direction:rtl - Fonts (downloaded from Meshkee CDN into
public/fonts/):iran-sans(default body / Persian UI)montserrat(English labels)
Color palette (from live site CSS vars / accents)
- Primary soft blue:
#DFEAFE(--wb-primary-color) - Secondary / brand blue:
#0141C5(--wb-secondary-color) - Accent blue:
#0946C7 - Mint accent:
#3ED2A7 - Footer navy:
#0B1F4D - Muted text:
#707070
Pages
| Route | Purpose |
|---|---|
/ |
Homepage |
/about |
درباره ما |
/contact |
تماس با ما |
/ourdr |
درمانگران |
/blog |
مقالات (Meshkee blogs API) |
/blog/{id}/{titleSlug} |
جزئیات مقاله |
/workshops |
کارگاهها (Meshkee workshops API) |
/workshops/{slug} |
جزئیات کارگاه |
Meshkee API integration
Base: {NEXT_PUBLIC_MESHKEE_API_BASE}/tenants/{domain}/...
Helpers: src/lib/meshkee.ts → meshkeeGet, tenantPath, getTenant, getBusinessId
Blog
- List:
GET /blogs?page=&pageSize= - Detail:
GET /blogs/by-id/{id}(canonical URL/blog/{id}/{titleSlug}) - Legacy redirect:
/blog/{slug}→ canonical - Comments:
GET /comments?entityType=blog&entityId={id} - Lib:
src/lib/blog.ts
Workshops
- List:
GET /workshops?page=&pageSize= - Detail:
GET /workshops/{slug}(URL/workshops/{slug}) - Register (auth):
POST /workshops/{workshopId}/registerviasrc/app/api/workshops/[workshopId]/register/route.ts - Cancel registration (auth):
DELETE /workshops/{workshopId}/register - Comments: included on workshop detail when API provides
comments; otherwise empty - Lib:
src/lib/workshops.ts - Note: Tenant currently has no published workshops in API; homepage/list fall back to static samples in
src/data/site.ts.
Auth / customer portal
- Login / user icon →
https://customer.{domain}/login(customerPortalUrlinsrc/lib/config.ts→customer.clinicsamen.com) - Session:
src/lib/session.tsx+ shared cookies (src/lib/shared-auth-cookie.ts) — readsmeshkee_customer_access_tokenfrom parent domain - Profile API proxy:
GET /api/auth/me→ Meshkee/auth/me - Admin handoff:
POST /api/auth/handoff→ Meshkee/auth/handoff→https://business.clinicsamen.com - Logged-in header:
{firstName lastName} عزیزviauserDisplayName - Dropdown (
AccountMenu): پروفایل من →/profile; مدیریت وبسایت (admins/owners/team only, handoff ticket); خروج (clears shared cookies) - Component:
src/components/AccountMenu.tsx(wired inHeadertopbar)
Static image slots
API: GET /tenants/{domain}/website/static-images?pageKey=home
Catalog for dashboard Refresh: GET /meshkee/static-image-slots → STATIC_IMAGE_SLOTS in src/lib/static-images.ts
| key | kind | itemCount | aspectRatio | recommendedWidth | homepage section |
|---|---|---|---|---|---|
slider |
list (duplicatable) | null | 1920:740 |
1180 | Hero slider |
our-experts |
list (duplicatable) | null | 325:356 |
280 | Home therapists / experts row |
two-service-banner |
list | 2 | 540:312 |
560 | Dual promo banners under services |
Field → UI mapping (match original homepage; empty API → local placeholders):
slider:url→ slide image;linkUrl→ wrap slide.titleFa/titleEn/subtextnot rendered in hero (image-only).our-experts:url→ photo;linkUrl→ card link (fallback/ourdr);titleFa→ name (h3);subtext→ role (p).titleEnnot shown (original therapist cards have no English line).two-service-banner:url→ banner background;linkUrl→ CTA href;titleFa→ banner title (h3).titleEn/subtextnot shown on banners.
Service icons on the homepage stay local (serviceCards in src/data/site.ts) — not a Meshkee static-image slot.
Rules:
- Use
slot.images(all ifkind=list, first ifkind=single) url→<img src>;linkUrl→ wrap in link- Empty / fail → keep local placeholders from
src/data/site.ts/public/images/ - Use
slot.aspectRatio(viaparseAspectRatio) - If a slot’s on-page size or aspect ratio changes in CSS, update
STATIC_IMAGE_SLOTSin the same change (Meshkee reads the catalog as the static-image source of truth)
Helpers: src/lib/static-images.ts, src/components/SlotImage.tsx, src/components/SlotLink.tsx
Home wiring: src/app/page.tsx
Content & assets
- Site copy, therapists bios, phones, address, socials live in
src/data/site.ts - Static workshop/article fallbacks in
src/data/site.ts(used when API empty) - Logos, banners, therapist photos, icons in
public/images/ - Favicon:
/favicon.png
Footer Meshkee credit
- Bottom row matches Safeteb-style Meshkee credit
- Component:
src/components/Footer.tsx→.meshkee-credit - Styles:
src/app/globals.css - Links to
https://meshkee.com - Logo:
public/images/footer/MeshkeeLogo-White.png
Important paths
- Layout / shell:
src/app/layout.tsx,src/components/Providers.tsx - Header + account:
src/components/Header.tsx,src/components/AccountMenu.tsx - Footer:
src/components/Footer.tsx - Home:
src/app/page.tsx,src/components/HeroSlider.tsx,src/components/HomeSections.tsx - Blog:
src/app/blog/,src/components/ArticlesCarousel.tsx - Workshops:
src/app/workshops/,src/components/WorkshopGallery.tsx,src/components/WorkshopRegistration.tsx,src/components/EntityTabs.tsx - Config:
src/lib/config.ts - Data:
src/data/site.ts
Contact
- Phones:
025-32706211,025-32702623,09936221511 - Address: بنیاد - میدان جوان - بلوار آفرینش - خیابان ذوالفقار - نبش کوچه ۳
- Socials: Instagram
@Psy.samen, WhatsApp, Telegram, Eitaa - Map embed: OpenStreetMap iframe on contact page
Env
NEXT_PUBLIC_WEBSITE_DOMAIN=clinicsamen.com
NEXT_PUBLIC_MESHKEE_API_BASE=https://api.meshkee.com/api/v1
# Optional overrides:
# NEXT_PUBLIC_CUSTOMER_PORTAL_URL=https://customer.clinicsamen.com
# NEXT_PUBLIC_BUSINESS_ORIGIN=https://business.clinicsamen.com
Commands
npm install
npm run dev
npm run build
SEO canonical URLs
- Blog:
/blog/{id}/{titleSlug}→GET /blogs/by-id/{id} - Workshop:
/workshops/{slug}→GET /workshops/{slug} - Slugify helper:
src/lib/seo-slug.ts - Page metadata helper:
src/lib/seo.ts→pageMetadata()(title, description, canonical, Open Graph)
Sitemap + robots
- Do not add
public/sitemap.xmlorpublic/robots.txt(nginx proxies to Meshkee API) - Live sitemap index:
/sitemap.xml→/sitemap-main.xml+ CMS URLs - Static pages config:
GET /meshkee/sitemap-config.json - 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
On-page SEO rules
- Unique
<title>+ meta description on every public page (viapageMetadataorgenerateMetadata) - Exactly one
<h1>per page (homepage: header brand; inner pages: page hero) - Section headings use
<h2>/<h3> - CMS images use meaningful
alt(title when available)