Add the reusable gating guard components on top of the #297 foundation: - UpsellGate: full locked screen (lock icon, tier title, per-feature description). Two CTAs: "Get <tier>" rendered VISIBLE but DISABLED with an "online purchase coming soon" note (per planning decision — #270 will activate it), and "I already have a key" navigating to /settings/users (LicenseCard). - RequireFeature: renders a neutral loader while the license is not ready (no upsell flash at boot), then children or UpsellGate. Renders <Outlet/> when children are omitted so it also works as a layout route grouping all routes of one feature. - requiredTierFor() pure helper in shared/entitlements.ts derives the minimum unlocking tier from matrix membership (not array order). - i18n: upsell.* (title, per-feature descriptions, CTAs) + nav.locked in BOTH locales; tier labels reuse the existing license.editions.* keys. - Tests: requiredTierFor mapping/minimality + upsell i18n coverage for every FeatureKey in fr and en (the components themselves are not testable without jsdom). Resolves #298 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| constants | ||
| types | ||
| entitlements.ts | ||