Add about/contact/installments pages, fix category slot bugs, wire live branding
- Enlarge category carousel thumbnails (90px -> 104-140px responsive) and
confirm the slider/categories/banner static-image slots are all reading
correctly from the CMS (verified live, not a wiring bug)
- Fix installments page dropping "هندزفری و هدفون": it's a level-3 category,
not level-2, so level2.find() silently missed it - use findNode() over the
whole tree instead
- Extend gen-category-placeholders.mjs to generate a placeholder for every
category at every level (was level-2 only), needed for the fix above
- Add /about, /contact, /installments pages
- About: real copy transcribed from the live moalem.shop theme, real
product photos from the API, text-only brand strip (no scraped logos)
- Contact: ContactForm.tsx posts to the real POST /contact-submissions,
branch cards with key-less Google Maps embeds
- Installments: flat brand-colored hero (no photo/gradient), category
highlights reusing the same categories slot images as the homepage
- Replace the placeholder header/footer phone number with the real one, add
real branch addresses and Instagram/Telegram links (src/data/site.ts),
pulled from the live theme's footer
- Wire logo/favicon to GET /website/favicon (getFavicon() in api.ts) instead
of the static bundled files, so a dashboard upload now shows automatically;
layout.tsx metadata is now generateMetadata() to support this. The tenant's
uploaded logo/favicon currently belongs to a different business - the
wiring is correct and will self-correct once that's fixed in the dashboard
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
09a409b3e7
commit
db7d00e473
@@ -19,7 +19,7 @@ fallbacks should update it.
|
||||
empty or failing module degrades one section instead of the page.
|
||||
- Never invent CMS/admin endpoints. If OpenAPI and any prose conflict, OpenAPI wins.
|
||||
|
||||
### What the tenant actually returns today (2026-08-31)
|
||||
### What the tenant actually returns today (2026-09-06)
|
||||
|
||||
| Endpoint | State |
|
||||
|---|---|
|
||||
@@ -27,9 +27,10 @@ fallbacks should update it.
|
||||
| `/products` | **479 items**, real titles, images, categories |
|
||||
| `/categories?entityType=product` | **48 items**, 3 levels under «کالای دیجیتال». Products are filed on **leaf** categories only — a parent category page/carousel must query its whole subtree (`subtreeIds`/`subtreeIdsAll` in `src/lib/categoryTree.ts`). |
|
||||
| `/store-items`, `/store-specials` | **empty** → no prices, no discounts, everything `inStock:false`. `/store-items/by-product/{id}` returns a single `{ storeItem }` (or null) — for a product's full variant list use `/store-items?productId=&pageSize=100` (`{ items }`) instead, see `getStoreItemsByProduct` in `src/lib/api.ts`. |
|
||||
| `/website/sliders`, `/website/static-images`, `/website/category-groups` | **empty** |
|
||||
| `/website/sliders`, `/website/category-groups` | **empty** |
|
||||
| `/website/static-images` | **filled** — `slider` (2), `categories` (8 of 15), `one/two/three-banner-bg` all have real images. Verified live and rendering correctly; if a future check finds otherwise, suspect a stale build/deploy before suspecting the wiring. |
|
||||
| `/blogs` | **empty** (module enabled) |
|
||||
| `/website/business-info`, `/website/favicon` | present but blank (no logo, no phone, no socials) |
|
||||
| `/website/business-info` | phones/addresses/socialMedia still empty; `logoUrl`/`faviconUrl` are now set but point to a **different business's** mark (see "Brand") |
|
||||
| `/products/by-id/{id}/technical-info` | `{ form: null, values: [] }` — empty on every product checked so far |
|
||||
| `/comments` | **empty**, but `POST` works (no bearer required by the API itself) |
|
||||
|
||||
@@ -38,18 +39,31 @@ fallbacks should update it.
|
||||
| Gap | Fallback | Remove when |
|
||||
|---|---|---|
|
||||
| No prices | `src/lib/demoPricing.ts`, gated by `NEXT_PUBLIC_DEMO_PRICING=1` — deterministic price per product id | store-items exist |
|
||||
| No sliders | `src/app/page.tsx`'s local `FALLBACK_SLIDES` (banners downloaded from the live moalem.shop theme into `public/images/banners/`) — used only when the `slider` static-image slot is also empty, see "Static-image slots" below | `/website/sliders` or the `slider` slot returns items |
|
||||
| No blog posts | `src/data/fallbackBlogs.ts` — the real posts from moalem.shop/articles, shown on the homepage and `/blog` as non-clickable cards (no real detail page exists for them) | `/blogs` returns items |
|
||||
| No category art | placeholder SVGs in `public/images/categories/{id}.svg`, generated by `scripts/gen-category-placeholders.mjs` — overridden per-slide by the `categories` static-image slot when it has images | real thumbnails are dropped in, or the `categories` slot is filled |
|
||||
| No branding in API | logo/favicon copied from the live theme into `public/` | `logoUrl` is set on the tenant |
|
||||
| No banner art (`one/two/three-banner-bg`) | `src/components/PromoBanners.tsx` renders a flat dashed placeholder per slot cell, labelled with the recommended size/ratio | the matching static-image slot is filled |
|
||||
| No category art past slot position 8 | placeholder SVGs in `public/images/categories/{id}.svg`, generated by `scripts/gen-category-placeholders.mjs` for every category at every level, not just level-2 | the `categories` slot has an image for that position |
|
||||
| Wrong logo/favicon in API | `getFavicon()` is wired live (see "Brand") but the uploaded asset itself is wrong; no code fallback needed once the dashboard upload is fixed | the correct asset is uploaded |
|
||||
|
||||
## Brand
|
||||
|
||||
Taken from the live moalem.shop theme, not invented:
|
||||
Colors taken from the live moalem.shop theme, not invented:
|
||||
primary `#E51E22`, dark `#B10123`, ink `#2E2E2E`, body `#7C7C7C`.
|
||||
Fonts: IRANYekan (fa, local `public/fonts`) + Montserrat (latin, next/font).
|
||||
|
||||
- Logo/favicon: `getFavicon()` in `src/lib/api.ts` reads
|
||||
`GET /tenants/moalem.shop/website/favicon` — the documented single source —
|
||||
and `Header.tsx`/`Footer.tsx`/`generateMetadata()` in `layout.tsx` all use
|
||||
it, falling back to the bundled `/images/logo.png` / `/favicon.png` only
|
||||
when the API field is null. **As of 2026-09-06 the dashboard has a logo/
|
||||
favicon uploaded, but it's the wrong business's** (a home-appliances store's
|
||||
mark, not موبایل معلم) — the wiring is correct and will pick up the right
|
||||
asset automatically the moment it's replaced in the dashboard; don't
|
||||
"fix" this by hardcoding the local fallback again.
|
||||
- Contact data (phone, mobile, branch addresses, Instagram/Telegram) in
|
||||
`src/data/site.ts` is real, pulled from the live theme's footer — `GET
|
||||
/website/business-info` still returns empty `phoneNumbers`/`addresses`/
|
||||
`socialMedia` for this tenant, so these stay hand-maintained here until
|
||||
that's filled in. Update both together when it is.
|
||||
|
||||
## Layout conventions
|
||||
|
||||
- Content width `--container-boxed: 1200px`, applied with the `boxed` utility.
|
||||
@@ -127,6 +141,24 @@ layout): hero → categories → hot deals → **three-banner-bg** → موبا
|
||||
carousel → **two-banner-bg** → لوازم جانبی → لپ تاپ → **one-banner-bg** →
|
||||
کنسول بازی → مجله.
|
||||
|
||||
## Static pages
|
||||
|
||||
- `/about` — real copy transcribed from the live moalem.shop theme's
|
||||
about-us module (verified against its cached HTML, not invented); brand
|
||||
strip is plain text wordmarks (no scraped logo images — avoids a
|
||||
trademark/asset-licensing headache for names we don't have real logo files
|
||||
for) with real product photos pulled from the API.
|
||||
- `/contact` — `ContactForm.tsx` posts to the real `POST /contact-submissions`
|
||||
(no bearer required); branch cards use `BRANCHES` from `src/data/site.ts`
|
||||
plus a key-less Google Maps `output=embed` iframe per branch (no API key
|
||||
needed for a query-based embed).
|
||||
- `/installments` — flat, brand-colored hero (no photo, no gradient — this
|
||||
site stays flat) instead of the reference design's photographic banner;
|
||||
category highlights reuse the same `categories` static-image slot images
|
||||
as the homepage carousel, matched by the same positional index. One
|
||||
reference category ("خانه هوشمند") has no equivalent on this tenant and is
|
||||
swapped for "لوازم برقی" — see `HIGHLIGHT_IDS` in the page for the mapping.
|
||||
|
||||
## Product / blog pages
|
||||
|
||||
- `/products` — full catalog, `?name=` search, `?page=`.
|
||||
|
||||
Reference in New Issue
Block a user