diff --git a/AGENTS.md b/AGENTS.md index 31ffe03..1822352 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -31,7 +31,7 @@ fallbacks should update it. | `/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` | phones/addresses/socialMedia still empty; `logoUrl`/`faviconUrl` are now set but point to a **different business's** mark (see "Brand") | +| `/website/business-info` | phones/addresses/socialMedia still empty; `logoUrl`/`faviconUrl` point to a **different business's** mark and are deliberately unused (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) | @@ -42,7 +42,6 @@ fallbacks should update it. | No prices | `src/lib/demoPricing.ts`, gated by `NEXT_PUBLIC_DEMO_PRICING=1` — deterministic price per product id | store-items exist | | No blog posts | `src/data/fallbackBlogs.ts` — the real posts from moalem.shop/articles, shown on the homepage and `/blog` as square-thumbnail cards that link to a real local `/blog/{id}/{slug}` page (`getFallbackBlogById()`); that page shows title/category/image plus a "coming soon" note since only those three fields are real, no scraped body content | `/blogs` returns items | | 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 @@ -50,21 +49,15 @@ 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. -- Header (desktop) logo renders at `h-[70px]`; footer logo stays at - `h-[108px]` (3x the original `h-9`/36px, on request) — the two were sized - independently, on request, so don't assume they should match. If the wrong - logo above still looks small at either size, it's because that specific - PNG has a lot of baked-in transparent padding around the mark — - `object-contain` can't fix that, only the replacement asset can. +- Logo: **bundled, not from the API** — `public/images/logo.png` (200x48 + wordmark, supplied by the business), referenced via `LOGO_SRC`/`LOGO_WIDTH`/ + `LOGO_HEIGHT` in `src/lib/config.ts` by `Header.tsx`, `Footer.tsx` and the + og:image in `layout.tsx`. This was an explicit decision (2026-09-20): the + API's `/website/favicon` returned another business's mark, so + `getFavicon()` was removed entirely — don't re-add it. Tab icon is the + bundled `public/favicon.png`. To change the logo, replace the file (keep + the same name; update `LOGO_WIDTH`/`LOGO_HEIGHT` if its shape changes). +- Header (desktop) and footer logos both render at `h-[70px] w-auto`. - 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`/ diff --git a/public/images/logo.png b/public/images/logo.png index 608fca3..b135bb9 100644 Binary files a/public/images/logo.png and b/public/images/logo.png differ diff --git a/src/app/layout.tsx b/src/app/layout.tsx index aae9216..7b880df 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -6,16 +6,14 @@ import Header from "@/components/Header"; import Footer from "@/components/Footer"; import TopBar from "@/components/TopBar"; import MobileBottomNav from "@/components/MobileBottomNav"; -import { getCategories, getFavicon, safe } from "@/lib/api"; +import { getCategories, safe } from "@/lib/api"; import { buildCategoryTree, carouselCategories } from "@/lib/categoryTree"; import { getSession } from "@/lib/auth"; import { SITE_NAME } from "@/data/site"; -import { SITE_URL } from "@/lib/config"; +import { LOGO_HEIGHT, LOGO_SRC, LOGO_WIDTH, SITE_URL } from "@/lib/config"; import { ToastProvider } from "@/components/providers/ToastProvider"; import { CartProvider } from "@/components/providers/CartProvider"; -const NO_BRAND_ASSETS = { faviconUrl: null, logoUrl: null, logoDarkUrl: null, hasDedicatedFavicon: false }; - // Montserrat is the Latin face the live moalem.shop theme pairs with IRANYekan. const montserrat = Montserrat({ variable: "--font-en", @@ -27,13 +25,9 @@ const montserrat = Montserrat({ const BASE_DESCRIPTION = "خرید اینترنتی گوشی موبایل، لپ‌تاپ، تبلت، کنسول بازی و لوازم جانبی با ضمانت اصالت کالا از فروشگاه موبایل معلم."; -// generateMetadata (not a static export) because the tab icon comes from -// GET /tenants/{domain}/website/favicon — once the business uploads a real -// one in the dashboard this picks it up with no code change. Falls back to -// the bundled /favicon.png only while that API field is empty. -export async function generateMetadata(): Promise { - const brand = await safe(getFavicon(), NO_BRAND_ASSETS); - +// Tab icon and og:image use the bundled brand files in /public — on purpose +// not GET /website/favicon (that endpoint served another business's mark). +export function generateMetadata(): Metadata { return { metadataBase: new URL(SITE_URL), title: { @@ -41,7 +35,7 @@ export async function generateMetadata(): Promise { template: `%s | ${SITE_NAME}`, }, description: BASE_DESCRIPTION, - icons: [{ url: brand.faviconUrl || "/favicon.png", type: "image/png" }], + icons: [{ url: "/favicon.png", type: "image/png" }], openGraph: { type: "website", locale: "fa_IR", @@ -49,24 +43,17 @@ export async function generateMetadata(): Promise { title: `${SITE_NAME} | خرید موبایل، لپ‌تاپ و لوازم جانبی`, description: BASE_DESCRIPTION, url: SITE_URL, - // The dashboard logo is a square mark; the bundled fallback is a wide - // wordmark — the two aren't the same shape, so their og:image sizes - // can't share one hardcoded pair. - images: brand.logoUrl - ? [{ url: brand.logoUrl, width: 512, height: 512, alt: SITE_NAME }] - : [{ url: "/images/logo.png", width: 130, height: 36, alt: SITE_NAME }], + images: [{ url: LOGO_SRC, width: LOGO_WIDTH, height: LOGO_HEIGHT, alt: SITE_NAME }], }, }; } export default async function RootLayout({ children }: LayoutProps<"/">) { - const [categories, user, brand] = await Promise.all([ + const [categories, user] = await Promise.all([ safe(getCategories().then(buildCategoryTree), []), getSession(), - safe(getFavicon(), NO_BRAND_ASSETS), ]); const menu = carouselCategories(categories); - const logoUrl = brand.logoUrl || "/images/logo.png"; return ( @@ -74,9 +61,9 @@ export default async function RootLayout({ children }: LayoutProps<"/">) { -
+
{children}
-