From e7e5381b80f7a1fb02184cc3b459f71da139ebc6 Mon Sep 17 00:00:00 2001 From: Alireza Hassani Date: Thu, 1 Oct 2026 21:23:22 +0330 Subject: [PATCH] Update homepage static-image slots and customer login links. Align slot catalog with slider / our-experts / two-service-banner and send guests to customer portal /login. Co-authored-by: Cursor --- Ai-data/prompt-images-slot.txt | 10 ++++---- CONTEXT.md | 25 ++++++++++++------- src/app/page.tsx | 33 ++++++++++++------------- src/components/AccountMenu.tsx | 6 ++++- src/components/EntityTabs.tsx | 2 +- src/components/HomeSections.tsx | 5 +--- src/components/WorkshopRegistration.tsx | 2 +- src/lib/static-images.ts | 19 ++++---------- 8 files changed, 50 insertions(+), 52 deletions(-) diff --git a/Ai-data/prompt-images-slot.txt b/Ai-data/prompt-images-slot.txt index e5cda02..4299d2f 100644 --- a/Ai-data/prompt-images-slot.txt +++ b/Ai-data/prompt-images-slot.txt @@ -3,11 +3,11 @@ Wire this page to clinicsamen.com, static-image slots. Read http://meshkee.com/docs/website (static-images). Env is already set. Fetch slots, match by key: -- slider > duplicatable -- 4 people image > 4 slot -- our-services-icon > 4 slot -- two-banner-bg > 2 slot +- slider > duplicatable +- our-experts > duplicatable +- two-service-banner > 2 slot +check the original UI, use name fa, name en and subtex according to it Use slot.images (all of them if kind=list, first if kind=single). url → . linkUrl → wrap in . Empty or fail → keep current placeholder. @@ -15,4 +15,4 @@ Use slot.aspectRatio from the API. Do not invent upload APIs. If image size or aspect ratio has changed during development, please update it for statics image reader. Add this as rule -update context md for better use in other Ai and systems - update it on every prompt (If required) \ No newline at end of file +update context md for better use in other Ai and systems - update it on every prompt (If required) diff --git a/CONTEXT.md b/CONTEXT.md index 8e2a032..155c895 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -59,12 +59,13 @@ Helpers: `src/lib/meshkee.ts` → `meshkeeGet`, `tenantPath`, `getTenant`, `getB - **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 icon → `https://customer.clinicsamen.com` (`customerPortalUrl` in `src/lib/config.ts`) -- Session: `src/lib/session.tsx` + shared cookies (`src/lib/shared-auth-cookie.ts`) +- Login / user icon → `https://customer.{domain}/login` (`customerPortalUrl` in `src/lib/config.ts` → `customer.clinicsamen.com`) +- Session: `src/lib/session.tsx` + shared cookies (`src/lib/shared-auth-cookie.ts`) — reads `meshkee_customer_access_token` from 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: user name + «عزیز»; dropdown: پروفایل من، خروج، مدیریت وبسایت (admins only) -- Component: `src/components/AccountMenu.tsx` +- Logged-in header: `{firstName lastName} عزیز` via `userDisplayName` +- Dropdown (`AccountMenu`): پروفایل من → `/profile`; مدیریت وبسایت (admins/owners/team only, handoff ticket); خروج (clears shared cookies) +- Component: `src/components/AccountMenu.tsx` (wired in `Header` topbar) ## Static image slots API: `GET /tenants/{domain}/website/static-images?pageKey=home` @@ -72,17 +73,23 @@ Catalog for dashboard Refresh: `GET /meshkee/static-image-slots` → `STATIC_IMA | key | kind | itemCount | aspectRatio | recommendedWidth | homepage section | | --- | --- | --- | --- | --- | --- | -| `slider` | list | null | `1920:740` | 1180 | Hero slider | -| `4-people-image` | list | 4 | `325:356` | 280 | Home therapists row | -| `our-services-icon` | list | 4 | `1:1` | 110 | Services icons | -| `two-banner-bg` | list | 2 | `540:312` | 560 | Dual promo banners | +| `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` / `subtext` not rendered in hero (image-only). +- `our-experts`: `url` → photo; `linkUrl` → card link (fallback `/ourdr`); `titleFa` → name (`h3`); `subtext` → role (`p`). `titleEn` not shown (original therapist cards have no English line). +- `two-service-banner`: `url` → banner background; `linkUrl` → CTA href; `titleFa` → banner title (`h3`). `titleEn` / `subtext` not 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 if `kind=list`, first if `kind=single`) - `url` → ``; `linkUrl` → wrap in link - Empty / fail → keep local placeholders from `src/data/site.ts` / `public/images/` - Use `slot.aspectRatio` (via `parseAspectRatio`) -- **If a slot’s on-page size or aspect ratio changes in CSS, update `STATIC_IMAGE_SLOTS` in the same change** +- **If a slot’s on-page size or aspect ratio changes in CSS, update `STATIC_IMAGE_SLOTS` in 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` diff --git a/src/app/page.tsx b/src/app/page.tsx index 9b33c2e..cb9886b 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -27,6 +27,7 @@ export default async function HomePage() { : getLocalBlogPosts(); const workshops = workshopResult.items; + // slider: titleFa / titleEn / subtext unused in hero UI (image + optional linkUrl only) const slider = overlaySlotImages( pickSlot(slots, "slider"), slides.map((slide, index) => { @@ -41,8 +42,9 @@ export default async function HomePage() { "slider", ); + // our-experts: titleFa → name, subtext → role (titleEn not shown in original therapist cards) const people = overlaySlotImages( - pickSlot(slots, "4-people-image"), + pickSlot(slots, "our-experts"), homeTherapists.map((person, index) => ({ id: `person-${index}`, image: person.image, @@ -50,23 +52,21 @@ export default async function HomePage() { title: person.name, text: person.role, })), - "4-people-image", + "our-experts", ); - const serviceIcons = overlaySlotImages( - pickSlot(slots, "our-services-icon"), - serviceCards.map((service, index) => ({ - id: `service-${index}`, - image: service.image, - href: service.href, - title: service.title, - kicker: service.english, - })), - "our-services-icon", - ); + // Local service icons (not a Meshkee static-image slot) + const serviceIcons = serviceCards.map((service, index) => ({ + id: `service-${index}`, + image: service.image, + href: service.href, + title: service.title, + kicker: service.english, + })); + // two-service-banner: titleFa → banner title (titleEn / subtext not shown in original banner UI) const banners = overlaySlotImages( - pickSlot(slots, "two-banner-bg"), + pickSlot(slots, "two-service-banner"), [ { id: "banner-workshops", @@ -81,7 +81,7 @@ export default async function HomePage() { title: "مشاوره فردی", }, ], - "two-banner-bg", + "two-service-banner", ); return ( @@ -90,8 +90,7 @@ export default async function HomePage() { + ورود / ثبت‌نام diff --git a/src/components/EntityTabs.tsx b/src/components/EntityTabs.tsx index 08f224f..e0d9542 100644 --- a/src/components/EntityTabs.tsx +++ b/src/components/EntityTabs.tsx @@ -74,7 +74,7 @@ export default function EntityTabs({

برای ثبت نظر وارد شوید

نظرات فقط برای کاربران واردشده فعال است.

- + ورود / ثبت‌نام
diff --git a/src/components/HomeSections.tsx b/src/components/HomeSections.tsx index 49f5de0..18acd31 100644 --- a/src/components/HomeSections.tsx +++ b/src/components/HomeSections.tsx @@ -14,7 +14,6 @@ type Props = { people: SlotMediaItem[]; peopleAspectRatio?: string; serviceIcons: SlotMediaItem[]; - serviceIconsAspectRatio?: string; banners: SlotMediaItem[]; bannersAspectRatio?: string; workshops: Workshop[]; @@ -25,14 +24,12 @@ export default function HomeSections({ people, peopleAspectRatio, serviceIcons, - serviceIconsAspectRatio, banners, bannersAspectRatio, workshops, articles, }: Props) { const peopleRatio = parseAspectRatio(peopleAspectRatio) ?? "325 / 356"; - const iconRatio = parseAspectRatio(serviceIconsAspectRatio) ?? "1 / 1"; const bannerRatio = parseAspectRatio(bannersAspectRatio) ?? "540 / 312"; return ( @@ -129,7 +126,7 @@ export default function HomeSections({
{serviceIcons.map((item) => ( -
+

برای ثبت‌نام در کارگاه وارد شوید

- + ورود / ثبت‌نام
diff --git a/src/lib/static-images.ts b/src/lib/static-images.ts index 834fc82..095a740 100644 --- a/src/lib/static-images.ts +++ b/src/lib/static-images.ts @@ -55,26 +55,17 @@ export const STATIC_IMAGE_SLOTS: StaticImageSlotCatalogItem[] = [ recommendedWidth: 1180, }, { - key: "4-people-image", - label: "Four people images", + key: "our-experts", + label: "Our experts", kind: "list", pageKey: "home", aspectRatio: "325:356", - itemCount: 4, + itemCount: null, recommendedWidth: 280, }, { - key: "our-services-icon", - label: "Our services icons", - kind: "list", - pageKey: "home", - aspectRatio: "1:1", - itemCount: 4, - recommendedWidth: 110, - }, - { - key: "two-banner-bg", - label: "Two banner backgrounds", + key: "two-service-banner", + label: "Two service banners", kind: "list", pageKey: "home", aspectRatio: "540:312",