Scaffold arrangement demo slice with CompareBar wiring
Add a self-contained demo build target for the Providers → Packages → Comparison flow, deployable as a static SPA at /arrangement/. - vite.demo.config.ts: per-slice build via --mode, base path flips for dev vs prod, output to dist-demo/<slice>/ - src/demo/: shared fixtures (7 providers across verified/tier3/tier2 with real venue photography from brandassets) + Zustand basket store with ?compare= URL persistence - Verified-provider packages now share the nine canonical Essentials line items per FA convention; only Optionals/Extras vary - App-level CompareBar surfaces "Already added" / "Maximum 3" feedback via transient store error - ProviderCard logo objectFit cover→contain so wide logos don't crop - npm scripts demo:dev / demo:build, deps zustand + react-router-dom
This commit is contained in:
63
src/demo/apps/arrangement/routes/Packages.tsx
Normal file
63
src/demo/apps/arrangement/routes/Packages.tsx
Normal file
@@ -0,0 +1,63 @@
|
||||
import { useState } from 'react';
|
||||
import { Navigate, useNavigate, useParams } from 'react-router-dom';
|
||||
import { PackagesStep } from '../../../../components/pages/PackagesStep';
|
||||
import { providersById, toPackagesStepProvider } from '../../../shared/fixtures/providers';
|
||||
import {
|
||||
packagesByProvider,
|
||||
makeBasketKey,
|
||||
nearbyVerifiedSamples,
|
||||
} from '../../../shared/fixtures/packages';
|
||||
import { useComparisonBasket } from '../../../shared/state/useComparisonBasket';
|
||||
import { demoNav } from '../DemoNav';
|
||||
|
||||
export function PackagesRoute() {
|
||||
const { providerId = '' } = useParams();
|
||||
const navigate = useNavigate();
|
||||
const provider = providersById[providerId];
|
||||
const bundle = packagesByProvider[providerId];
|
||||
const basket = useComparisonBasket();
|
||||
|
||||
const [selectedId, setSelectedId] = useState<string | null>(bundle?.matching[0]?.id ?? null);
|
||||
|
||||
if (!provider || !bundle) return <Navigate to="/" replace />;
|
||||
|
||||
// Compare CTA on the PackageDetail panel just adds the selection to the
|
||||
// basket. The floating CompareBar (mounted in App.tsx) handles navigation
|
||||
// once the user has 2+ packages selected.
|
||||
const handleCompare = () => {
|
||||
if (selectedId) basket.add(makeBasketKey(provider.id, selectedId));
|
||||
};
|
||||
|
||||
// Tier-3 / tier-2 providers show "nearby verified" cards instead of
|
||||
// "more from this provider".
|
||||
const secondaryList =
|
||||
provider.tier === 'verified'
|
||||
? { kind: 'same-provider-more' as const, packages: bundle.other }
|
||||
: { kind: 'nearby-verified' as const, packages: nearbyVerifiedSamples };
|
||||
|
||||
return (
|
||||
<PackagesStep
|
||||
provider={toPackagesStepProvider(provider)}
|
||||
providerTier={provider.tier}
|
||||
packages={bundle.matching}
|
||||
secondaryList={secondaryList.packages.length > 0 ? secondaryList : undefined}
|
||||
selectedPackageId={selectedId}
|
||||
onSelectPackage={setSelectedId}
|
||||
onArrange={() =>
|
||||
alert(
|
||||
provider.tier === 'verified'
|
||||
? 'Make Arrangement — would route to next wizard step.'
|
||||
: 'Make an enquiry — would open enquiry form.',
|
||||
)
|
||||
}
|
||||
onCompare={handleCompare}
|
||||
onNearbyPackageClick={(key) => {
|
||||
const [otherProviderId] = key.split(':');
|
||||
if (otherProviderId) navigate(`/providers/${otherProviderId}/packages`);
|
||||
}}
|
||||
onProviderClick={() => alert('Provider profile — not built in this demo slice.')}
|
||||
onBack={() => navigate('/')}
|
||||
navigation={demoNav}
|
||||
/>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user