# Dr Asadian — AI / Project Context Persian RTL rebuild of **drasadian.com** (مطب پوست، مو و زیبایی دکتر محمد اسدیان، قم). Keep this file current — other AI tools and later prompts read it first. ## Source of truth - Live site being cloned: https://www.drasadian.com/ - Prompt: Meshkee `basic-clone` then `backend` (`/api/v1/public/ai-prompts/dr-asadian/...`) - Backend / Meshkee Website API: https://api.meshkee.com/docs/website - OpenAPI: https://api.meshkee.com/docs/website/openapi.json - Apex domain: `drasadian.com` (no `www` / `api` / `customer` / `business`) - Tenant: `GET /tenants/drasadian.com` → `businessId` `31` - Enabled modules: `products`, `blog`, `finance` ## Stack - Next.js 15 (App Router) + React 19 + TypeScript - Tailwind CSS v4 (`@import "tailwindcss"` in `src/app/globals.css`) + custom CSS - Language: `fa`, direction: `rtl` - Fonts (downloaded from Meshkee CDN into `public/fonts/`): - `kalameh` (Persian UI: thin / regular / bold / black) - `a-glitch-in-time` (English kickers) ## Color palette (from live yoga3 theme CSS) - Primary / headings / body: `#17543E` - Theme gold (links, buttons, accents): `#D19C1D` (hover `#E9B948`) - Mint button: `#D5E8E0` on `#17543E` text - Footer: `#195C46` + `public/images/footer/footer-bg.jpg` - Page gray: `#F2F2F2` - Cards: `#F8F8F8` - Doctor band overlay: `#1F6C54` - Muted: `#A8A8A8` ## Routes | Route | Purpose | |-------|---------| | `/` | Homepage | | `/services` | خدمات ما (original `/services`) — hair / skin / other | | `/about` | درباره ما (original `/aboutus`) | | `/contact` | تماس با ما (original `/contactus`) | | `/gallery` | گالری تصاویر مطب (original `/gallery`) | | `/blog` | مقالات — Meshkee `GET /tenants/{domain}/blogs` | | `/blog/{id}/{titleSlug}` | مقاله — `GET /tenants/{domain}/blogs/by-id/{id}` | | `/blog/{id}` | Redirects to canonical `{id}/{titleSlug}` | Original also had `/hair`, `/skin`, `/otherservices` — not cloned as separate pages. Category cards on `/services` use in-page anchors (`#hair`, `#skin`, `#other`). Header: خدمات → `/services`, گالری → `/gallery`, مقالات → `/blog`. ## Homepage order 1. Hero slider (2 banners) 2. Visible H1 intro (clinic name + description) 3. Specialized service icons 4. Latest blogs (8 from Meshkee). If the API has no posts yet, the original three cloned teasers are shown and link to `/blog` 5. Testimonials (microneedling / microderm / e-light) 6. Skin repair + about CTA band ## Meshkee auth (customer portal) - Logged-out user icon → `https://customer.drasadian.com` (`customerPortalUrl` in `src/lib/config.ts`) - Logged-in: `{firstName lastName} عزیز` with dropdown: - پروفایل من → `https://customer.drasadian.com/profile` - خروج (clears shared tokens) - مدیریت وبسایت (admins/owners only) → `https://business.drasadian.com` via `POST /api/auth/handoff` - Session: `src/lib/session.tsx` + cookies `meshkee_customer_access_token` / `meshkee_customer_refresh_token` (shared with customer portal on `.drasadian.com`) - Current user: website `GET /api/auth/me` → Meshkee `GET /auth/me` - Header: `src/components/AccountMenu.tsx` ## Blog (Meshkee) - List: `GET /tenants/drasadian.com/blogs?page=&pageSize=` - Detail: `GET /tenants/drasadian.com/blogs/by-id/{id}` (preferred). Slug route exists but is not used for public URLs. - Helpers: `src/lib/blog.ts` (`blogHref`, `blogImage`, `fetchBlogs`, `fetchBlogById`) - Canonical URL: `/blog/{id}/{titleSlug}` — Farsi title slug (spaces → `-`, keep Persian letters) - Homepage fetches `pageSize=8` - Listing paginates 12 per page - Do not invent blog copy. Empty API → empty listing + homepage fallback teasers only - Blog CMS HTML is rendered as `mainTextHtml` (rich text) ## Motion - Header fades down on load - Sections use `Reveal` (`src/components/Reveal.tsx`) — Intersection Observer, one-shot - Children with `.stagger-child` fade up in sequence (`--i` delay, 130ms steps) - Slider slides crossfade (1.15s) - `prefers-reduced-motion: reduce` disables the above ## Inner page title - `PageHero` sits in `.page-hero-row` with a repeating minimal botanical-dot pattern (`public/images/patterns/title-pattern.svg`) ## Original business data (do not invent replacements) - Phone: `025-32907661` - Hours (contact): شنبه تا پنجشنبه، ۱۷ الی ۲۱ - Address: قم، میدان سپاه (جمهوری)، خیابان شهید اخلاقی، جنب مسجد امام حسن مجتبی، مطب دکترمحمد اسدیان - Login icon → `https://customer.drasadian.com` - Business dashboard → `https://business.drasadian.com` - Instagram/Telegram URLs on the live site pointed to `/` — no public handles cloned - Map coordinates were empty in site settings; contact page uses a Google Maps embed of the address ## Content & assets - Copy, hours table, testimonials, homepage teaser fallbacks: `src/data/site.ts` - Logo: `public/images/logo.png` (live theme `PMlhUjbrcj.png`) - Favicon: `public/favicon.png` (from logo; live favicon was empty) - Banners / icons / photos / gallery: `public/images/` - Fonts: `public/fonts/` - Remote CMS images: `meshkee-storage…`, `cdn.meshkee.com`, `c804387.parspack.net` (see `next.config.ts`) ## Footer Meshkee credit - Bottom row matches https://safeteb.com/ (site name + framed hover 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` (wraps `Providers` + session) - Header: `src/components/Header.tsx` (split logo, RTL) - Account menu: `src/components/AccountMenu.tsx` - Footer: `src/components/Footer.tsx` - Home: `src/app/page.tsx`, `src/components/HeroSlider.tsx` - Blog: `src/app/blog/page.tsx`, `src/app/blog/[id]/[slug]/page.tsx` - Meshkee client: `src/lib/meshkee.ts`, `src/lib/meshkee-server.ts`, `src/lib/config.ts` - Data: `src/data/site.ts` ## Env ```bash NEXT_PUBLIC_WEBSITE_DOMAIN=drasadian.com NEXT_PUBLIC_MESHKEE_API_BASE=https://api.meshkee.com/api/v1 # Optional overrides: # NEXT_PUBLIC_CUSTOMER_PORTAL_URL=https://customer.drasadian.com # NEXT_PUBLIC_BUSINESS_ORIGIN=https://business.drasadian.com ``` ## Commands ```bash npm install npm run dev npm run build npm run generate:sitemap-config ``` ## Sitemap + robots - **Do not** add `public/sitemap.xml` or `public/robots.txt` (nginx proxies to Meshkee API) - Live sitemap is an index: `/sitemap.xml` → `/sitemap-main.xml` + `/sitemap-products.xml` - Static pages config: `GET /meshkee/sitemap-config.json` (generated at build from app routes) - Generator: `scripts/generate-sitemap-config.mjs` → `src/lib/sitemap-config.generated.json` - Excludes `api`, `meshkee`, `admin`, `auth`, `login`, `checkout`, `cart`, `account` - Blog / product / portfolio details are **not** listed in sitemap-config (Meshkee XML covers CMS URLs) - After deploy: business dashboard → Website → Settings → Sync sitemap config (needed for static pages) ## Canonical URL shapes (Meshkee defaults — do not add `templates` unless customized) - Blog: `/blog/{id}/{titleSlug}` → `GET /tenants/{domain}/blogs/by-id/{id}` - Product: `/products/{id}/{nameFaSlug}` → `GET /tenants/{domain}/products/by-id/{id}` (not built yet; catalog empty) - Category: `/products/category/{id}/{nameFaSlug}` → `GET /tenants/{domain}/categories/by-id/{id}` - Portfolio: `/portfolios/{id}/{titleFaSlug}` → `GET /tenants/{domain}/portfolios/by-id/{id}` (not built yet) - Slugify (`src/lib/seo-slug.ts`): keep Farsi letters, spaces → `-`, strip other punctuation. Do not use legacy DB slug in public URLs. ## On-page SEO - Helper: `src/lib/seo.ts` (`pageMetadata`, unique absolute ``, clipped meta description ~158 chars, canonical, OG) - Inner-page titles append `| دکتر محمد اسدیان`. Homepage title is unique and does not use the Next.js default - Exactly one visible H1 per page (never `.sr-only` / CSS-hidden). Homepage H1 is `.home-intro` - Section headings default to `h2` (`SectionHeading`). Service cards / article cards use `h3` under a section `h2` - Prefer CMS `title` / `abstract` / image for blog metadata. Fallback teasers only when the API is empty - Content images have meaningful `alt` (CMS title when available). Decorative `deco.png` uses `alt=""` - `src/app/not-found.tsx`: unique title + one H1, `noindex` - Favicon: `public/favicon.png` (tenant favicon API currently returns null) ## Gallery - 12 photos from the live `/gallery` page in `public/images/gallery/01.jpg`–`12.jpg` - Lightbox: `src/components/GalleryGrid.tsx` (click to enlarge, arrows / Escape) - Header گالری → `/gallery` ## Next planned prompts 1. Products / portfolio pages if the clinic starts publishing through Meshkee 2. Image slots if a later prompt provides them