Comparison route: always include system-recommended package

The ComparisonPage's `recommendedPackage` prop was never wired in the
demo — users only saw their basket contents. Now always surface a
default recommended package (parsons:deluxe) as an extra column, deduped
against the basket so it never appears twice.

Basket mechanics are unchanged: the 3-package cap counts user selections
only, and the recommended is layered on top as an editorial suggestion.

The empty state only renders when there is genuinely nothing to show —
since the recommended is static, it's effectively defensive for a future
state where resolution could fail.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-23 14:03:04 +10:00
parent e5579a4d67
commit ac598ea7b1
2 changed files with 20 additions and 2 deletions

View File

@@ -4,7 +4,7 @@ import { ComparisonPage } from '../../../../components/pages/ComparisonPage';
import { Typography } from '../../../../components/atoms/Typography';
import { Button } from '../../../../components/atoms/Button';
import { useComparisonBasket } from '../../../shared/state/useComparisonBasket';
import { resolveComparisonPackage } from '../../../shared/fixtures/packages';
import { resolveComparisonPackage, DEMO_RECOMMENDED_KEY } from '../../../shared/fixtures/packages';
import { demoNav } from '../DemoNav';
export function ComparisonRoute() {
@@ -12,7 +12,12 @@ export function ComparisonRoute() {
const packageKeys = useComparisonBasket((s) => s.packageKeys);
const remove = useComparisonBasket((s) => s.remove);
// The system-recommended package is shown as an extra column on top of
// the user's basket. Dedupe against the basket so it never renders twice.
const recommendedPackage = resolveComparisonPackage(DEMO_RECOMMENDED_KEY) ?? undefined;
const packages = packageKeys
.filter((key) => key !== DEMO_RECOMMENDED_KEY)
.map((key) => {
const resolved = resolveComparisonPackage(key);
return resolved ? { key, pkg: resolved } : null;
@@ -22,7 +27,9 @@ export function ComparisonRoute() {
x !== null,
);
if (packages.length === 0) {
// Empty state only when there's genuinely nothing to show — normally the
// recommended package will always resolve, so this branch is defensive.
if (packages.length === 0 && !recommendedPackage) {
return (
<Box sx={{ minHeight: '100vh', display: 'flex', flexDirection: 'column' }}>
{demoNav}
@@ -51,6 +58,7 @@ export function ComparisonRoute() {
return (
<ComparisonPage
packages={packages.map((p) => p.pkg)}
recommendedPackage={recommendedPackage}
onArrange={(id) => alert(`Arrange "${id}" — would route to next wizard step.`)}
onRemove={(id) => {
// ComparisonPackage.id is the bare package id; we need the basket's

View File

@@ -1245,6 +1245,16 @@ export function resolveComparisonPackage(key: BasketKey): ComparisonPackage | nu
return bundle.forComparison.find((p) => p.id === parsed.packageId) ?? null;
}
/**
* Demo recommendation: the package ComparisonPage always surfaces as the
* system-recommended option. Not part of the user's basket and doesn't
* count against the 3-package basket cap — it's an editorial suggestion
* layered on top of whatever the user has selected. If the same package
* is already in the basket, the Comparison route dedupes so it appears
* once (as the recommended column).
*/
export const DEMO_RECOMMENDED_KEY: BasketKey = 'parsons:deluxe';
/**
* Verified providers surfaced under the "Similar packages from verified
* providers" grid on unverified tier-2 / tier-3 pages. Derived from the