import React from 'react'; import Box from '@mui/material/Box'; import type { SxProps, Theme } from '@mui/material/styles'; import { WizardLayout } from '../../templates/WizardLayout'; import { ProviderCard } from '../../molecules/ProviderCard'; import { SearchBar } from '../../molecules/SearchBar'; import { Chip } from '../../atoms/Chip'; import { Typography } from '../../atoms/Typography'; import { Button } from '../../atoms/Button'; // ─── Types ─────────────────────────────────────────────────────────────────── /** Provider data for display in the list */ export interface ProviderData { /** Unique provider ID (funeralBrandID) */ id: string; /** Provider display name */ name: string; /** Location text (suburb, city) */ location: string; /** Whether this is a verified/trusted partner */ verified?: boolean; /** Hero image URL */ imageUrl?: string; /** Provider logo URL */ logoUrl?: string; /** Average rating (e.g. 4.8) */ rating?: number; /** Number of reviews */ reviewCount?: number; /** Starting price in dollars */ startingPrice?: number; /** Distance from user in km */ distanceKm?: number; /** Brief description */ description?: string; } /** Filter chip state */ export interface ProviderFilter { /** Filter label */ label: string; /** Whether this filter is active */ active: boolean; } /** Props for the ProvidersStep page component */ export interface ProvidersStepProps { /** List of providers to display */ providers: ProviderData[]; /** Currently selected provider ID */ selectedProviderId: string | null; /** Callback when a provider is selected */ onSelectProvider: (id: string) => void; /** Search query value */ searchQuery: string; /** Callback when search query changes */ onSearchChange: (query: string) => void; /** Callback when search is submitted */ onSearch?: (query: string) => void; /** Filter chips */ filters?: ProviderFilter[]; /** Callback when a filter chip is toggled */ onFilterToggle?: (index: number) => void; /** Callback for the Continue button */ onContinue: () => void; /** Callback for the Back button */ onBack: () => void; /** Validation error message */ error?: string; /** Whether the Continue action is loading */ loading?: boolean; /** Map panel content — slot for future map integration */ mapPanel?: React.ReactNode; /** Navigation bar — passed through to WizardLayout */ navigation?: React.ReactNode; /** Whether this is a pre-planning flow (shows softer copy) */ isPrePlanning?: boolean; /** MUI sx prop for the root */ sx?: SxProps; } // ─── Component ─────────────────────────────────────────────────────────────── /** * Step 2 — Provider selection page for the FA arrangement wizard. * * List + Map split layout. Left panel shows a scrollable list of * provider cards with search and filter chips. Right panel is a * slot for future map integration. * * Uses radiogroup pattern for card selection — arrow keys navigate * between cards, Space/Enter selects. * * Pure presentation component — props in, callbacks out. * * Spec: documentation/steps/steps/02_providers.yaml */ export const ProvidersStep: React.FC = ({ providers, selectedProviderId, onSelectProvider, searchQuery, onSearchChange, onSearch, filters, onFilterToggle, onContinue, onBack, error, loading = false, mapPanel, navigation, isPrePlanning = false, sx, }) => { const subheading = isPrePlanning ? 'Take your time exploring providers. You can always come back and choose a different one.' : 'These providers are near your location. Each has their own packages and pricing.'; return ( Map coming soon ) } > {/* Sticky header — stays pinned while card list scrolls */} Choose a funeral provider {subheading} {/* Search bar */} {/* Filter chips */} {filters && filters.length > 0 && ( {filters.map((filter, index) => ( onFilterToggle(index) : undefined} variant="outlined" size="small" /> ))} )} {/* Results count */} {providers.length} provider{providers.length !== 1 ? 's' : ''} found {/* Error message */} {error && ( {error} )} {/* Provider list — radiogroup pattern */} {providers.map((provider) => ( onSelectProvider(provider.id)} role="radio" aria-checked={selectedProviderId === provider.id} aria-label={`${provider.name}, ${provider.location}${provider.rating ? `, rated ${provider.rating}` : ''}${provider.startingPrice ? `, from $${provider.startingPrice}` : ''}`} /> ))} {providers.length === 0 && ( No providers found matching your search. Try adjusting your search or clearing filters. )} {/* Continue button */} ); }; ProvidersStep.displayName = 'ProvidersStep'; export default ProvidersStep;