Some checks failed
QA Gate (P0/P1) / Test affected app (pull_request) Has been cancelled
Adds a horizontal scrollable "Son ziyaret ettiklerin" strip above the main
brand grid. Renders only when the user has actually opened at least one
brand detail page before — silent in cold-start state.
Why localStorage, not a backend endpoint
- This is a behavioural shortcut, not authoritative state. Adding a
user_recent_brands table for data we don't have yet is premature.
- Keying by `sase-recent-brands-${userId}` mirrors the trial-banner
scoping pattern; a second user on the same browser doesn't inherit the
first user's list.
- localStorage failures (private mode, quota) silently degrade — the
strip just stays hidden, never throws.
How a brand gets added
- Tracked at the destination (`/catalog/:brandName` visit), not on the
link click. A click that never resolves into a real visit (auth gate,
slow nav cancel) shouldn't be a "recently used" signal.
- 12 entries stored, 8 surfaced. Headroom for future ranking (e.g.
weight by frequency × recency) without re-recording history.
Plan-lock awareness
- The strip cross-references the `/catalog/brands` access map, so a
brand the user opened while on Full and then lost on a downgrade
shows the same lock chip + amber upgrade route used by the main grid.
- New PostHog event: `catalog_recent_brand_clicked`. Locked recent
chips reuse `catalog_locked_brand_upgrade_clicked` with
`surface: "recents"` for funnel distinction.
i18n: `catalog.recentSection` (TR: "Son ziyaret ettiklerin" / EN:
"Recently visited").