The /contacts route had no bootstrap.staticPages entry at all (the old
hardcoded contacts page was intentionally removed per app.routes.ts's
comment, in favor of the generic staticPath -> CMS resolver). Added a
placeholder entry (route/title/html per locale) so the link resolves
instead of 404ing. Placeholder text explicitly says the real contact
details go through the admin panel - per user decision, real content
belongs to whoever runs a given marketplace, not something to fabricate.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sprint A: storefront header profile control (login/logout only, no menu),
wired to existing customer Telegram auth (AuthService).
Sprint B: backoffice/reports page, reuses AdminAnalyticsFacade (Sales,
Top Products, Marketplace Health cards + CSV export).
Sprint C: backoffice/settings page, admin UI density preference
(comfortable/compact), localStorage-persisted, applied to app-table
across all admin list pages.
Sprint D: admin bottom-nav Help -> mailto using existing supportEmail,
Documentation -> external link via new TenantConfig.documentationUrl.
AdminNavLink gains externalHref for non-routerLink nav entries.
Docs: docs/GLOBAL-SPRINT-PLAN.md tracks the full sprint breakdown.
docs/COMING-SOON-AUDIT.md removed, folded into docs/KNOWN-ISSUES.md.
docs/BACKEND.md updated with the new documentationUrl bootstrap field.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- product-carousel-widget: implicit CSS grid track had no min-width:0,
so the flex scroller's intrinsic content width (fixed 220px product
cards) overflowed the grid item and pushed body width to ~2187px on
a 1440px viewport, squeezing the entire homepage into a ~340px column.
Added min-width:0 to the track and scroller (standard grid/flex
overflow fix).
- bootstrap.json mock fixture: about-us/privacy-policy/terms-of-service
static pages (the real CMS pages served via bootstrap.staticPages,
per docs/PROJECT_INDEX.md) used a 'content' field, but
content-page.service.ts's normalizePage() only reads 'html' -
ContentPageBootstrapInput has no 'content' field. Title rendered,
body was always empty. Renamed the 3 fixture entries' field from
content to html to match the schema; content now renders.
- compare-table: colour row rendered raw hex/name values as plain text
(e.g. '#fCfCfC') with no swatch, inconsistent with variant-selector's
established colour-swatch pattern used on the product page. Added a
small circular swatch (reusing the same border-radius:50% pattern)
next to the value.
Verified live via ng serve: overflow gone (body/viewport width match
at 1440/1280/375), static pages render real content, compare swatch
displays. tsc --noEmit and ng build both clean (pre-existing bundle-
budget warning only, already tracked in KNOWN-ISSUES item 12).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Cart item description showed a stray literal "..." when the item had no
description text (cart.component.html) — now only renders the trailing
ellipsis when a description is present.
- Compare table showed raw internal stock enum values ("high"/"low"/etc.)
instead of localized labels (compare-table.component.ts) — now reuses the
same stock-label mapping used by product cards.
- Search with zero results incorrectly showed the empty-category messaging
("browse categories" / "go to parent category") stacked on top of the
search's own "nothing found" message (catalog-container.component.ts) —
isEmptyCategoryState now excludes active search queries so only the
search-appropriate empty state renders.
- Footer "About" link pointed to /about, which 404s; the actual CMS page
route is /about-us (bootstrap.json mock nav data) — corrected the route.
- Added missing public/assets/images/placeholder.svg, the fallback image
referenced by getMainImage() for items without photos (previously 404s
if that fallback path is ever hit).
Investigated and left as-is (not code bugs): /images/*.webp 404s on
product cards are references to a real backend/CDN not present in local
dev (confirmed via mock-data.interceptor.ts and api.service.ts image-URL
resolution) — expected dev-only gap. Footer "Contacts" link (/contacts)
has no corresponding static page content at all in mock data; flagging
for a content decision rather than fabricating copy.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
P0-3: hero widget text rendered hardcoded English on every locale
(ru/hy included) because HeroWidgetData source props were plain
strings with no per-locale variant, unlike nav labels which already
support a locale map (NavigationLocalizedText).
DataSourceResolverService.toHeroData() now accepts either a plain
string (existing tenants unaffected) or a per-locale text map for
title/subtitle/ctaLabel and each slide's fields, resolved against
the active language the same way footer group titles already are
(LocalizedTextContent, current lang -> en -> first available).
Updated the mock bootstrap fixture's hero props to a real ru/en/hy
map so the demo tenant shows translated copy instead of English on
every locale. No editor UI change needed: the Widgets section's
existing JSON-fallback editor already accepts arbitrary prop shapes.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>