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
@@ -4,6 +4,7 @@ import type {
|
||||
ApiCategory,
|
||||
ApiProduct,
|
||||
AuthUser,
|
||||
BrandAssets,
|
||||
BusinessInfo,
|
||||
ContactFormInput,
|
||||
EntityComment,
|
||||
@@ -86,6 +87,13 @@ export function getBusinessInfo(): Promise<BusinessInfo> {
|
||||
return apiGet<BusinessInfo>(t("/website/business-info"));
|
||||
}
|
||||
|
||||
// Single documented source for header/footer logos and the browser-tab
|
||||
// icon — see AGENTS.md "Branding". Prefer this over reading logoUrl off
|
||||
// getTenant()/getBusinessInfo() directly.
|
||||
export function getFavicon(): Promise<BrandAssets> {
|
||||
return apiGet<BrandAssets>(t("/website/favicon"));
|
||||
}
|
||||
|
||||
export function getSliders(): Promise<SliderItem[]> {
|
||||
return apiGet<{ items: SliderItem[] }>(t("/website/sliders")).then((r) => r.items);
|
||||
}
|
||||
|
||||
@@ -23,6 +23,16 @@ export interface Tenant {
|
||||
faviconUrl: string | null;
|
||||
}
|
||||
|
||||
// GET /tenants/{domain}/website/favicon — the documented single source for
|
||||
// header/footer logos and the browser-tab icon (falls back to the light
|
||||
// logo when hasDedicatedFavicon is false).
|
||||
export interface BrandAssets {
|
||||
faviconUrl: string | null;
|
||||
logoUrl: string | null;
|
||||
logoDarkUrl: string | null;
|
||||
hasDedicatedFavicon: boolean;
|
||||
}
|
||||
|
||||
// This tenant has no emails/phones/addresses filled in yet, so the loose
|
||||
// shapes are read defensively at render time.
|
||||
export interface BusinessInfo {
|
||||
|
||||
Reference in New Issue
Block a user