PackagesStep: surface verified providers via 2-col MiniCard grid
The unverified-tier "similar packages" section previously rendered a list of NearbyPackageCards — one per package. Swap to MiniCard, showing the provider itself: image, verified badge, location, rating, "From $X". 2-col on sm+, 1-col on xs, capped at 4. Heading dropped "nearby" to "Similar packages from verified providers". Data shape renamed NearbyVerifiedPackage → NearbyVerifiedProvider; `verified` is implicit (the section is verified-only by definition). Callback renamed onNearbyPackageClick → onNearbyProviderClick, routing directly on provider id. Demo fixture now derives the list from the main providers fixture (filtered to verified + imageUrl). NearbyPackageCard is now orphaned — kept in place pending registry cleanup in a follow-up. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,7 +2,7 @@ import { useState } from 'react';
|
|||||||
import type { Meta, StoryObj } from '@storybook/react';
|
import type { Meta, StoryObj } from '@storybook/react';
|
||||||
import Box from '@mui/material/Box';
|
import Box from '@mui/material/Box';
|
||||||
import { PackagesStep } from './PackagesStep';
|
import { PackagesStep } from './PackagesStep';
|
||||||
import type { NearbyVerifiedPackage, PackageData, PackagesStepProvider } from './PackagesStep';
|
import type { NearbyVerifiedProvider, PackageData, PackagesStepProvider } from './PackagesStep';
|
||||||
import { Navigation } from '../../organisms/Navigation';
|
import { Navigation } from '../../organisms/Navigation';
|
||||||
|
|
||||||
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
||||||
@@ -211,34 +211,43 @@ const manyOtherPackages: PackageData[] = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const nearbyVerifiedPackages: NearbyVerifiedPackage[] = [
|
const nearbyVerifiedProviders: NearbyVerifiedProvider[] = [
|
||||||
{
|
{
|
||||||
id: 'rankins-standard',
|
id: 'rankins',
|
||||||
packageName: 'Standard Cremation Package',
|
name: 'Rankins Funerals',
|
||||||
price: 2450,
|
imageUrl: '/images/placeholder/hparsonsvenue.jpg',
|
||||||
providerName: 'Rankins Funerals',
|
|
||||||
location: 'Warrawong, NSW',
|
location: 'Warrawong, NSW',
|
||||||
|
startingPrice: 2450,
|
||||||
rating: 4.8,
|
rating: 4.8,
|
||||||
reviewCount: 23,
|
reviewCount: 23,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'easy-essential',
|
id: 'mannings',
|
||||||
packageName: 'Essential Funeral Service',
|
name: 'Mannings Funerals',
|
||||||
price: 1950,
|
imageUrl: '/images/placeholder/hparsonsvenue.jpg',
|
||||||
providerName: 'Easy Funerals',
|
location: 'Bega, NSW',
|
||||||
location: 'Sydney, NSW',
|
startingPrice: 1950,
|
||||||
rating: 4.5,
|
rating: 4.7,
|
||||||
reviewCount: 42,
|
reviewCount: 42,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'killick-classic',
|
id: 'killick',
|
||||||
packageName: 'Classic Farewell Package',
|
name: 'Killick Family Funerals',
|
||||||
price: 3100,
|
imageUrl: '/images/placeholder/hparsonsvenue.jpg',
|
||||||
providerName: 'Killick Family Funerals',
|
location: 'Kingaroy, QLD',
|
||||||
location: 'Shellharbour, NSW',
|
startingPrice: 3100,
|
||||||
rating: 4.9,
|
rating: 4.9,
|
||||||
reviewCount: 15,
|
reviewCount: 15,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'mackay',
|
||||||
|
name: 'Mackay Family Funerals',
|
||||||
|
imageUrl: '/images/placeholder/hparsonsvenue.jpg',
|
||||||
|
location: 'Ourimbah, NSW',
|
||||||
|
startingPrice: 2780,
|
||||||
|
rating: 4.6,
|
||||||
|
reviewCount: 19,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const tier2Packages: PackageData[] = [
|
const tier2Packages: PackageData[] = [
|
||||||
@@ -362,12 +371,12 @@ export const Tier3: Story = {
|
|||||||
provider={unverifiedProvider}
|
provider={unverifiedProvider}
|
||||||
providerTier="tier3"
|
providerTier="tier3"
|
||||||
packages={matchedPackages}
|
packages={matchedPackages}
|
||||||
secondaryList={{ kind: 'nearby-verified', packages: nearbyVerifiedPackages }}
|
secondaryList={{ kind: 'nearby-verified', providers: nearbyVerifiedProviders }}
|
||||||
selectedPackageId={selectedId}
|
selectedPackageId={selectedId}
|
||||||
onSelectPackage={setSelectedId}
|
onSelectPackage={setSelectedId}
|
||||||
onArrange={() => alert('Make an enquiry')}
|
onArrange={() => alert('Make an enquiry')}
|
||||||
onCompare={() => alert('Open compare view')}
|
onCompare={() => alert('Open compare view')}
|
||||||
onNearbyPackageClick={(id) => alert(`Route to nearby package: ${id}`)}
|
onNearbyProviderClick={(id) => alert(`Route to verified provider: ${id}`)}
|
||||||
onProviderClick={() => alert('Open provider profile (future)')}
|
onProviderClick={() => alert('Open provider profile (future)')}
|
||||||
onBack={() => alert('Back')}
|
onBack={() => alert('Back')}
|
||||||
navigation={nav}
|
navigation={nav}
|
||||||
@@ -388,12 +397,12 @@ export const Tier2: Story = {
|
|||||||
provider={unverifiedProvider}
|
provider={unverifiedProvider}
|
||||||
providerTier="tier2"
|
providerTier="tier2"
|
||||||
packages={tier2Packages}
|
packages={tier2Packages}
|
||||||
secondaryList={{ kind: 'nearby-verified', packages: nearbyVerifiedPackages }}
|
secondaryList={{ kind: 'nearby-verified', providers: nearbyVerifiedProviders }}
|
||||||
selectedPackageId={selectedId}
|
selectedPackageId={selectedId}
|
||||||
onSelectPackage={setSelectedId}
|
onSelectPackage={setSelectedId}
|
||||||
onArrange={() => alert('Make an enquiry')}
|
onArrange={() => alert('Make an enquiry')}
|
||||||
onCompare={() => alert('Open compare view')}
|
onCompare={() => alert('Open compare view')}
|
||||||
onNearbyPackageClick={(id) => alert(`Route to nearby package: ${id}`)}
|
onNearbyProviderClick={(id) => alert(`Route to verified provider: ${id}`)}
|
||||||
onProviderClick={() => alert('Open provider profile (future)')}
|
onProviderClick={() => alert('Open provider profile (future)')}
|
||||||
onBack={() => alert('Back')}
|
onBack={() => alert('Back')}
|
||||||
navigation={nav}
|
navigation={nav}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import type { SxProps, Theme } from '@mui/material/styles';
|
|||||||
import { WizardLayout } from '../../templates/WizardLayout';
|
import { WizardLayout } from '../../templates/WizardLayout';
|
||||||
import { ProviderCardCompact } from '../../molecules/ProviderCardCompact';
|
import { ProviderCardCompact } from '../../molecules/ProviderCardCompact';
|
||||||
import { ServiceOption } from '../../molecules/ServiceOption';
|
import { ServiceOption } from '../../molecules/ServiceOption';
|
||||||
import { NearbyPackageCard } from '../../molecules/NearbyPackageCard';
|
import { MiniCard } from '../../molecules/MiniCard';
|
||||||
import { PackageDetail } from '../../organisms/PackageDetail';
|
import { PackageDetail } from '../../organisms/PackageDetail';
|
||||||
import { Typography } from '../../atoms/Typography';
|
import { Typography } from '../../atoms/Typography';
|
||||||
import { Divider } from '../../atoms/Divider';
|
import { Divider } from '../../atoms/Divider';
|
||||||
@@ -18,7 +18,7 @@ import type { PackageData, PackagesStepProvider, ProviderTier, SecondaryList } f
|
|||||||
export type {
|
export type {
|
||||||
PackageData,
|
PackageData,
|
||||||
PackagesStepProvider,
|
PackagesStepProvider,
|
||||||
NearbyVerifiedPackage,
|
NearbyVerifiedProvider,
|
||||||
ProviderTier,
|
ProviderTier,
|
||||||
SecondaryList,
|
SecondaryList,
|
||||||
} from './types';
|
} from './types';
|
||||||
@@ -75,6 +75,10 @@ const TIER_COPY: Record<ProviderTier, TierCopy> = {
|
|||||||
// switching to "top N + See all →" behaviour.
|
// switching to "top N + See all →" behaviour.
|
||||||
const SAME_PROVIDER_INLINE_LIMIT = 3;
|
const SAME_PROVIDER_INLINE_LIMIT = 3;
|
||||||
|
|
||||||
|
// Max number of verified provider MiniCards in the "Similar packages from
|
||||||
|
// verified providers" grid on unverified pages.
|
||||||
|
const NEARBY_VERIFIED_LIMIT = 4;
|
||||||
|
|
||||||
// ─── Props ───────────────────────────────────────────────────────────────────
|
// ─── Props ───────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
export interface PackagesStepProps {
|
export interface PackagesStepProps {
|
||||||
@@ -98,8 +102,8 @@ export interface PackagesStepProps {
|
|||||||
* basket. When true, PackageDetail swaps its Compare button into the
|
* basket. When true, PackageDetail swaps its Compare button into the
|
||||||
* "In comparison" selected-state (inert; removal via CompareBar). */
|
* "In comparison" selected-state (inert; removal via CompareBar). */
|
||||||
isSelectedPackageInCart?: boolean;
|
isSelectedPackageInCart?: boolean;
|
||||||
/** Callback when a nearby-verified package card is clicked (route change to that provider) */
|
/** Callback when a nearby-verified provider card is clicked (route change to that provider's PackagesStep) */
|
||||||
onNearbyPackageClick?: (id: string) => void;
|
onNearbyProviderClick?: (id: string) => void;
|
||||||
/**
|
/**
|
||||||
* Callback when "See all N packages from [Provider]" is clicked.
|
* Callback when "See all N packages from [Provider]" is clicked.
|
||||||
* Expected to route to the same PackagesStep with `showAllFromProvider` set.
|
* Expected to route to the same PackagesStep with `showAllFromProvider` set.
|
||||||
@@ -177,7 +181,8 @@ function GroupHeading({
|
|||||||
* shows top 3 + "See all N packages from [Provider] →" link that routes
|
* shows top 3 + "See all N packages from [Provider] →" link that routes
|
||||||
* to the same page with `showAllFromProvider`.
|
* to the same page with `showAllFromProvider`.
|
||||||
* - `nearby-verified` (unverified tiers): primary list + "Similar packages
|
* - `nearby-verified` (unverified tiers): primary list + "Similar packages
|
||||||
* from verified providers nearby" list (NearbyPackageCard).
|
* from verified providers" 2-column MiniCard grid, capped at 4. Every
|
||||||
|
* card is verified by definition.
|
||||||
*
|
*
|
||||||
* When `showAllFromProvider` is true, renders a flat "All packages from
|
* When `showAllFromProvider` is true, renders a flat "All packages from
|
||||||
* [Provider]" list with no grouping and no secondary list. The caller
|
* [Provider]" list with no grouping and no secondary list. The caller
|
||||||
@@ -197,7 +202,7 @@ export const PackagesStep: React.FC<PackagesStepProps> = ({
|
|||||||
onArrange,
|
onArrange,
|
||||||
onCompare,
|
onCompare,
|
||||||
isSelectedPackageInCart = false,
|
isSelectedPackageInCart = false,
|
||||||
onNearbyPackageClick,
|
onNearbyProviderClick,
|
||||||
onSeeAllPackages,
|
onSeeAllPackages,
|
||||||
onProviderClick,
|
onProviderClick,
|
||||||
onBack,
|
onBack,
|
||||||
@@ -429,29 +434,37 @@ export const PackagesStep: React.FC<PackagesStepProps> = ({
|
|||||||
|
|
||||||
{/* ─── Secondary: nearby-verified ─── */}
|
{/* ─── Secondary: nearby-verified ─── */}
|
||||||
{activeSecondaryList?.kind === 'nearby-verified' &&
|
{activeSecondaryList?.kind === 'nearby-verified' &&
|
||||||
activeSecondaryList.packages.length > 0 && (
|
activeSecondaryList.providers.length > 0 && (
|
||||||
<>
|
<>
|
||||||
<Divider sx={{ my: 8 }} />
|
<Divider sx={{ my: 8 }} />
|
||||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 2 }}>
|
<Box sx={{ display: 'flex', alignItems: 'flex-start', gap: 1, mb: 2 }}>
|
||||||
<VerifiedOutlinedIcon sx={{ fontSize: 16, color: 'primary.main' }} aria-hidden />
|
<VerifiedOutlinedIcon
|
||||||
|
sx={{ fontSize: 16, color: 'primary.main', mt: '3px' }}
|
||||||
|
aria-hidden
|
||||||
|
/>
|
||||||
<Typography variant="body2" sx={{ fontWeight: 600, color: 'text.primary' }}>
|
<Typography variant="body2" sx={{ fontWeight: 600, color: 'text.primary' }}>
|
||||||
Similar packages from verified providers nearby
|
Similar packages from verified providers
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
<Box
|
<Box
|
||||||
aria-label="Similar packages from nearby verified providers"
|
aria-label="Similar packages from verified providers"
|
||||||
sx={{ display: 'flex', flexDirection: 'column', gap: 2, mb: 3 }}
|
sx={{
|
||||||
|
display: 'grid',
|
||||||
|
gridTemplateColumns: { xs: '1fr', sm: 'repeat(2, 1fr)' },
|
||||||
|
gap: 2,
|
||||||
|
mb: 3,
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{activeSecondaryList.packages.map((pkg) => (
|
{activeSecondaryList.providers.slice(0, NEARBY_VERIFIED_LIMIT).map((p) => (
|
||||||
<NearbyPackageCard
|
<MiniCard
|
||||||
key={pkg.id}
|
key={p.id}
|
||||||
packageName={pkg.packageName}
|
title={p.name}
|
||||||
price={pkg.price}
|
imageUrl={p.imageUrl}
|
||||||
providerName={pkg.providerName}
|
verified
|
||||||
location={pkg.location}
|
price={p.startingPrice}
|
||||||
rating={pkg.rating}
|
location={p.location}
|
||||||
reviewCount={pkg.reviewCount}
|
rating={p.rating}
|
||||||
onClick={onNearbyPackageClick ? () => onNearbyPackageClick(pkg.id) : undefined}
|
onClick={onNearbyProviderClick ? () => onNearbyProviderClick(p.id) : undefined}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -55,19 +55,26 @@ export interface PackageData {
|
|||||||
terms?: string;
|
terms?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A package offered by a nearby verified provider (promoted on unverified pages). */
|
/**
|
||||||
export interface NearbyVerifiedPackage {
|
* A verified provider surfaced on an unverified provider's PackagesStep.
|
||||||
/** Unique ID */
|
*
|
||||||
|
* By definition every entry in this list is verified — the section is a
|
||||||
|
* curated "here are the real partners near you" promotion — so there is no
|
||||||
|
* `verified` flag on the data shape. Components that render this list pass
|
||||||
|
* a hard-coded `verified={true}` to their card.
|
||||||
|
*/
|
||||||
|
export interface NearbyVerifiedProvider {
|
||||||
|
/** Provider ID — routes to `/providers/:id/packages` */
|
||||||
id: string;
|
id: string;
|
||||||
/** Package name */
|
|
||||||
packageName: string;
|
|
||||||
/** Package price in dollars */
|
|
||||||
price: number;
|
|
||||||
/** Provider name */
|
/** Provider name */
|
||||||
providerName: string;
|
name: string;
|
||||||
/** Provider location */
|
/** Hero image URL (verified providers always have one) */
|
||||||
|
imageUrl: string;
|
||||||
|
/** Location (suburb, state) */
|
||||||
location: string;
|
location: string;
|
||||||
/** Provider rating */
|
/** Starting price — formatted as "From $X" on the card */
|
||||||
|
startingPrice: number;
|
||||||
|
/** Average rating */
|
||||||
rating?: number;
|
rating?: number;
|
||||||
/** Number of reviews */
|
/** Number of reviews */
|
||||||
reviewCount?: number;
|
reviewCount?: number;
|
||||||
@@ -82,9 +89,10 @@ export interface NearbyVerifiedPackage {
|
|||||||
* Rendered as a ServiceOption list. If more than 3, the list shows the
|
* Rendered as a ServiceOption list. If more than 3, the list shows the
|
||||||
* first 3 + a "See all N packages from [Provider]" link that navigates
|
* first 3 + a "See all N packages from [Provider]" link that navigates
|
||||||
* to the same PackagesStep with preference filters off.
|
* to the same PackagesStep with preference filters off.
|
||||||
* - `nearby-verified`: Similar packages from nearby verified providers,
|
* - `nearby-verified`: Verified providers promoted on unverified-tier pages
|
||||||
* promoted on unverified-tier pages. Rendered as NearbyPackageCard list.
|
* under the heading "Similar packages from verified providers". Rendered
|
||||||
* Clicking a card is a route change to that provider's PackagesStep.
|
* as a 2-col MiniCard grid capped at 4. Clicking a card routes to that
|
||||||
|
* provider's PackagesStep.
|
||||||
*/
|
*/
|
||||||
export type SecondaryList =
|
export type SecondaryList =
|
||||||
| {
|
| {
|
||||||
@@ -93,5 +101,5 @@ export type SecondaryList =
|
|||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
kind: 'nearby-verified';
|
kind: 'nearby-verified';
|
||||||
packages: NearbyVerifiedPackage[];
|
providers: NearbyVerifiedProvider[];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { providersById, toPackagesStepProvider } from '../../../shared/fixtures/
|
|||||||
import {
|
import {
|
||||||
packagesByProvider,
|
packagesByProvider,
|
||||||
makeBasketKey,
|
makeBasketKey,
|
||||||
nearbyVerifiedSamples,
|
nearbyVerifiedProviders,
|
||||||
} from '../../../shared/fixtures/packages';
|
} from '../../../shared/fixtures/packages';
|
||||||
import { useComparisonBasket } from '../../../shared/state/useComparisonBasket';
|
import { useComparisonBasket } from '../../../shared/state/useComparisonBasket';
|
||||||
import { demoNav } from '../DemoNav';
|
import { demoNav } from '../DemoNav';
|
||||||
@@ -34,19 +34,28 @@ export function PackagesRoute() {
|
|||||||
// the Compare button into its "In comparison" selected state.
|
// the Compare button into its "In comparison" selected state.
|
||||||
const isSelectedInCart = selectedId ? basket.has(makeBasketKey(provider.id, selectedId)) : false;
|
const isSelectedInCart = selectedId ? basket.has(makeBasketKey(provider.id, selectedId)) : false;
|
||||||
|
|
||||||
// Tier-3 / tier-2 providers show "nearby verified" cards instead of
|
// Tier-3 / tier-2 providers show verified-provider MiniCards instead of
|
||||||
// "more from this provider".
|
// "more from this provider". Exclude the current provider from the
|
||||||
|
// "similar" list in case we ever add a verified id that collides.
|
||||||
const secondaryList =
|
const secondaryList =
|
||||||
provider.tier === 'verified'
|
provider.tier === 'verified'
|
||||||
? { kind: 'same-provider-more' as const, packages: bundle.other }
|
? { kind: 'same-provider-more' as const, packages: bundle.other }
|
||||||
: { kind: 'nearby-verified' as const, packages: nearbyVerifiedSamples };
|
: {
|
||||||
|
kind: 'nearby-verified' as const,
|
||||||
|
providers: nearbyVerifiedProviders.filter((p) => p.id !== provider.id),
|
||||||
|
};
|
||||||
|
|
||||||
|
const secondaryHasItems =
|
||||||
|
secondaryList.kind === 'same-provider-more'
|
||||||
|
? secondaryList.packages.length > 0
|
||||||
|
: secondaryList.providers.length > 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PackagesStep
|
<PackagesStep
|
||||||
provider={toPackagesStepProvider(provider)}
|
provider={toPackagesStepProvider(provider)}
|
||||||
providerTier={provider.tier}
|
providerTier={provider.tier}
|
||||||
packages={bundle.matching}
|
packages={bundle.matching}
|
||||||
secondaryList={secondaryList.packages.length > 0 ? secondaryList : undefined}
|
secondaryList={secondaryHasItems ? secondaryList : undefined}
|
||||||
selectedPackageId={selectedId}
|
selectedPackageId={selectedId}
|
||||||
onSelectPackage={setSelectedId}
|
onSelectPackage={setSelectedId}
|
||||||
onArrange={() =>
|
onArrange={() =>
|
||||||
@@ -58,10 +67,7 @@ export function PackagesRoute() {
|
|||||||
}
|
}
|
||||||
onCompare={handleCompare}
|
onCompare={handleCompare}
|
||||||
isSelectedPackageInCart={isSelectedInCart}
|
isSelectedPackageInCart={isSelectedInCart}
|
||||||
onNearbyPackageClick={(key) => {
|
onNearbyProviderClick={(id) => navigate(`/providers/${id}/packages`)}
|
||||||
const [otherProviderId] = key.split(':');
|
|
||||||
if (otherProviderId) navigate(`/providers/${otherProviderId}/packages`);
|
|
||||||
}}
|
|
||||||
onProviderClick={() => alert('Provider profile — not built in this demo slice.')}
|
onProviderClick={() => alert('Provider profile — not built in this demo slice.')}
|
||||||
onBack={() => navigate('/')}
|
onBack={() => navigate('/')}
|
||||||
navigation={demoNav}
|
navigation={demoNav}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import type { PackageData, NearbyVerifiedPackage } from '../../../components/pages/PackagesStep';
|
import type { PackageData, NearbyVerifiedProvider } from '../../../components/pages/PackagesStep';
|
||||||
import type { PackageSection, PackageLineItem } from '../../../components/organisms/PackageDetail';
|
import type { PackageSection, PackageLineItem } from '../../../components/organisms/PackageDetail';
|
||||||
import type {
|
import type {
|
||||||
ComparisonPackage,
|
ComparisonPackage,
|
||||||
ComparisonSection,
|
ComparisonSection,
|
||||||
} from '../../../components/organisms/ComparisonTable';
|
} from '../../../components/organisms/ComparisonTable';
|
||||||
import { providersById } from './providers';
|
import { providers, providersById } from './providers';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Packages live keyed by providerId. Each provider has TWO PackageData lists
|
* Packages live keyed by providerId. Each provider has TWO PackageData lists
|
||||||
@@ -876,33 +876,22 @@ export function resolveComparisonPackage(key: BasketKey): ComparisonPackage | nu
|
|||||||
return bundle.forComparison.find((p) => p.id === parsed.packageId) ?? null;
|
return bundle.forComparison.find((p) => p.id === parsed.packageId) ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** "Nearby verified" cards shown under tier-3 / tier-2 lists. */
|
/**
|
||||||
export const nearbyVerifiedSamples: NearbyVerifiedPackage[] = [
|
* Verified providers surfaced under the "Similar packages from verified
|
||||||
{
|
* providers" grid on unverified tier-2 / tier-3 pages. Derived from the
|
||||||
id: 'rankins:standard',
|
* main `providers` fixture filtered to tier === 'verified', with
|
||||||
packageName: 'Standard Cremation Package',
|
* `startingPrice` taken from their first matching package. Only providers
|
||||||
price: rankinsForStep[0].price,
|
* that actually have an image in the fixture are eligible (MiniCard
|
||||||
providerName: 'Rankins Funeral Services',
|
* requires `imageUrl`).
|
||||||
location: 'Wollongong, NSW',
|
*/
|
||||||
rating: 4.8,
|
export const nearbyVerifiedProviders: NearbyVerifiedProvider[] = providers
|
||||||
reviewCount: 23,
|
.filter((p) => p.tier === 'verified' && p.imageUrl)
|
||||||
},
|
.map((p) => ({
|
||||||
{
|
id: p.id,
|
||||||
id: 'mannings:standard',
|
name: p.name,
|
||||||
packageName: 'Standard Cremation Package',
|
imageUrl: p.imageUrl!,
|
||||||
price: manningsForStep[0].price,
|
location: p.location,
|
||||||
providerName: 'Mannings Funerals',
|
startingPrice: packagesByProvider[p.id]?.matching[0]?.price ?? p.startingPrice ?? 0,
|
||||||
location: 'Bega, NSW',
|
rating: p.rating,
|
||||||
rating: 4.7,
|
reviewCount: p.reviewCount,
|
||||||
reviewCount: 31,
|
}));
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'killick:classic',
|
|
||||||
packageName: 'Classic Farewell Package',
|
|
||||||
price: killickForStep[0].price,
|
|
||||||
providerName: 'Killick Family Funerals',
|
|
||||||
location: 'Kingaroy, QLD',
|
|
||||||
rating: 4.9,
|
|
||||||
reviewCount: 15,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|||||||
Reference in New Issue
Block a user