HomePage: initial build with hero, FuneralFinder, features, reviews, FAQ
- Hero section with display3 serif heading, warm bg, 50/50 split with image slot
- FuneralFinderV3 widget integrated as overlapping card (negative margin pattern)
- Partner logos carousel with CSS-only infinite scroll, prefers-reduced-motion
- 4 feature cards (outlined, compact padding, warm circular icon backgrounds)
- Reviews section (dark bg, Google aggregate rating, 3 testimonial cards)
- CTA banner with displaySm serif heading ("We Are Here When You Need Us")
- FAQ accordion (reuses SummaryStep pattern)
- Full a11y: section landmarks, aria-labelledby, heading hierarchy h1→h2→h3
- Grief-sensitive copy throughout (no urgency language, warm tone)
- Chromatic added as devDependency, build script updated
- 4 stories: Default, WithoutReviews, Minimal, Mobile
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
266
src/components/pages/HomePage/HomePage.stories.tsx
Normal file
266
src/components/pages/HomePage/HomePage.stories.tsx
Normal file
@@ -0,0 +1,266 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
import Box from '@mui/material/Box';
|
||||
import VerifiedOutlinedIcon from '@mui/icons-material/VerifiedOutlined';
|
||||
import AccessTimeIcon from '@mui/icons-material/AccessTime';
|
||||
import SearchIcon from '@mui/icons-material/Search';
|
||||
import SupportAgentOutlinedIcon from '@mui/icons-material/SupportAgentOutlined';
|
||||
import { HomePage } from './HomePage';
|
||||
import { Navigation } from '../../organisms/Navigation';
|
||||
import { Footer } from '../../organisms/Footer';
|
||||
|
||||
// ─── Shared helpers ──────────────────────────────────────────────────────────
|
||||
|
||||
const FALogo = () => (
|
||||
<Box sx={{ display: 'flex', alignItems: 'center' }}>
|
||||
<Box
|
||||
component="img"
|
||||
src="/brandlogo/logo-full.svg"
|
||||
alt="Funeral Arranger"
|
||||
sx={{ height: 28, display: { xs: 'none', md: 'block' } }}
|
||||
/>
|
||||
<Box
|
||||
component="img"
|
||||
src="/brandlogo/logo-short.svg"
|
||||
alt="Funeral Arranger"
|
||||
sx={{ height: 28, display: { xs: 'block', md: 'none' } }}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
|
||||
const FALogoInverse = () => (
|
||||
<Box
|
||||
component="img"
|
||||
src="/brandlogo/logo-full.svg"
|
||||
alt="Funeral Arranger"
|
||||
sx={{ height: 24, filter: 'brightness(0) invert(1)', opacity: 0.9 }}
|
||||
/>
|
||||
);
|
||||
|
||||
const nav = (
|
||||
<Navigation
|
||||
logo={<FALogo />}
|
||||
items={[
|
||||
{ label: 'FAQ', href: '/faq' },
|
||||
{ label: 'Contact Us', href: '/contact' },
|
||||
{ label: 'Log in', href: '/login' },
|
||||
]}
|
||||
/>
|
||||
);
|
||||
|
||||
const footer = (
|
||||
<Footer
|
||||
logo={<FALogoInverse />}
|
||||
tagline="Helping Australian families plan with confidence"
|
||||
linkGroups={[
|
||||
{
|
||||
heading: 'Services',
|
||||
links: [
|
||||
{ label: 'Find a Director', href: '/directors' },
|
||||
{ label: 'Compare Venues', href: '/venues' },
|
||||
{ label: 'Pricing Guide', href: '/pricing' },
|
||||
{ label: 'Start Planning', href: '/arrange' },
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: 'Support',
|
||||
links: [
|
||||
{ label: 'FAQ', href: '/faq' },
|
||||
{ label: 'Contact Us', href: '/contact' },
|
||||
{ label: 'Grief Resources', href: '/resources' },
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: 'Company',
|
||||
links: [
|
||||
{ label: 'About Us', href: '/about' },
|
||||
{ label: 'Provider Portal', href: '/provider-portal' },
|
||||
{ label: 'Partner With Us', href: '/partners' },
|
||||
],
|
||||
},
|
||||
]}
|
||||
phone="1800 987 888"
|
||||
email="support@funeralarranger.com.au"
|
||||
legalLinks={[
|
||||
{ label: 'Privacy Policy', href: '/privacy' },
|
||||
{ label: 'Terms of Service', href: '/terms' },
|
||||
{ label: 'Accessibility', href: '/accessibility' },
|
||||
]}
|
||||
/>
|
||||
);
|
||||
|
||||
// ─── Default data ────────────────────────────────────────────────────────────
|
||||
|
||||
const heroImage = (
|
||||
<Box
|
||||
sx={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
minHeight: 'inherit',
|
||||
background: 'linear-gradient(160deg, #d4bfa8 0%, #c4a882 40%, #8b7355 100%)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
color: 'rgba(255,255,255,0.3)',
|
||||
fontSize: 14,
|
||||
fontFamily: 'var(--fa-font-family-body)',
|
||||
textAlign: 'center',
|
||||
px: 4,
|
||||
}}
|
||||
>
|
||||
Hero image placeholder
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
|
||||
const partnerLogos = [
|
||||
{ src: '/partnerlogo/logo-placeholder-1.svg', alt: 'KFF Funerals' },
|
||||
{ src: '/partnerlogo/logo-placeholder-2.svg', alt: 'Mannings Funerals' },
|
||||
{ src: '/partnerlogo/logo-placeholder-3.svg', alt: 'Lady Anne Funerals' },
|
||||
{ src: '/partnerlogo/logo-placeholder-4.svg', alt: 'Rankins Funerals' },
|
||||
{ src: '/partnerlogo/logo-placeholder-5.svg', alt: 'City Funerals' },
|
||||
{ src: '/partnerlogo/logo-placeholder-6.svg', alt: 'Mackay Funerals' },
|
||||
{ src: '/partnerlogo/logo-placeholder-7.svg', alt: 'H. Parsons' },
|
||||
{ src: '/partnerlogo/logo-placeholder-8.svg', alt: 'Parsons Ladies' },
|
||||
{ src: '/partnerlogo/logo-placeholder-9.svg', alt: 'Botanical Funerals' },
|
||||
];
|
||||
|
||||
const features = [
|
||||
{
|
||||
icon: <VerifiedOutlinedIcon />,
|
||||
heading: 'Transparent, verified pricing',
|
||||
description:
|
||||
'All costs are itemised for verified partners. No surprise fees. See pricing and options before you commit.',
|
||||
},
|
||||
{
|
||||
icon: <AccessTimeIcon />,
|
||||
heading: 'Available 24 hours a day',
|
||||
description:
|
||||
'Compare, plan and arrange at your own pace, day or night. No pressure to commit online.',
|
||||
},
|
||||
{
|
||||
icon: <SearchIcon />,
|
||||
heading: 'Find local & compare',
|
||||
description: 'Search and compare local funeral directors to find the right choice for you.',
|
||||
},
|
||||
{
|
||||
icon: <SupportAgentOutlinedIcon />,
|
||||
heading: 'Support when you need it',
|
||||
description:
|
||||
'Arrange everything online or be guided through the steps by your preferred funeral director.',
|
||||
},
|
||||
];
|
||||
|
||||
const testimonials = [
|
||||
{
|
||||
name: 'Sarah H.',
|
||||
rating: 5,
|
||||
quote:
|
||||
'At the most difficult time in our lives, this site made comparing costs so straightforward. We saved over $800.',
|
||||
timeAgo: '3 weeks ago',
|
||||
},
|
||||
{
|
||||
name: 'James M.',
|
||||
rating: 5,
|
||||
quote:
|
||||
'The itemised quote builder meant we could personalise the service within our budget. Highly recommended.',
|
||||
timeAgo: '1 month ago',
|
||||
},
|
||||
{
|
||||
name: 'Tracy W.',
|
||||
rating: 5,
|
||||
quote:
|
||||
'I had no idea there was such a price difference between local directors. This saved us from overpaying.',
|
||||
timeAgo: '2 months ago',
|
||||
},
|
||||
];
|
||||
|
||||
const faqItems = [
|
||||
{
|
||||
question: 'What is Funeral Arranger?',
|
||||
answer:
|
||||
'Funeral Arranger is an online platform that helps Australian families find, compare and arrange funeral services. We connect you with trusted local funeral directors and provide transparent pricing so you can make informed decisions during a difficult time.',
|
||||
},
|
||||
{
|
||||
question: 'What makes Funeral Arranger different from other funeral service providers?',
|
||||
answer:
|
||||
'Unlike traditional funeral homes, we are an independent comparison platform. We show you transparent, itemised pricing from multiple verified providers in your area so you can compare options and choose what is right for your family and budget.',
|
||||
},
|
||||
{
|
||||
question: 'Do I need to complete all steps at once?',
|
||||
answer:
|
||||
'No. You can save your progress at any time and return when you are ready. Whether you are pre-planning or arranging at short notice, the process works at your pace with no time pressure.',
|
||||
},
|
||||
{
|
||||
question: 'How much does a funeral cost in Australia?',
|
||||
answer:
|
||||
'Funeral costs in Australia typically range from $4,000 for a simple cremation to $15,000 or more for a full traditional service. Costs vary by location, provider, and the options you choose. Our platform helps you compare real prices from local providers.',
|
||||
},
|
||||
{
|
||||
question: 'What is the cheapest funeral option?',
|
||||
answer:
|
||||
'A direct cremation (no service) is generally the most affordable option, starting from around $2,000\u2013$4,000 depending on your location. Our platform shows you all available options so you can find the right balance of service and cost.',
|
||||
},
|
||||
];
|
||||
|
||||
// ─── Meta ────────────────────────────────────────────────────────────────────
|
||||
|
||||
const meta: Meta<typeof HomePage> = {
|
||||
title: 'Pages/HomePage',
|
||||
component: HomePage,
|
||||
tags: ['autodocs'],
|
||||
parameters: {
|
||||
layout: 'fullscreen',
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof HomePage>;
|
||||
|
||||
// ─── Stories ─────────────────────────────────────────────────────────────────
|
||||
|
||||
/** Full homepage with all sections populated */
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
navigation: nav,
|
||||
footer,
|
||||
heroImage,
|
||||
partnerLogos,
|
||||
features,
|
||||
googleRating: 4.9,
|
||||
googleReviewCount: 2340,
|
||||
testimonials,
|
||||
faqItems,
|
||||
onSearch: (params) => console.log('Search:', params),
|
||||
onCtaClick: () => console.log('CTA clicked'),
|
||||
},
|
||||
};
|
||||
|
||||
/** Before reviews are gathered — testimonials section hidden */
|
||||
export const WithoutReviews: Story = {
|
||||
args: {
|
||||
...Default.args,
|
||||
googleRating: undefined,
|
||||
googleReviewCount: undefined,
|
||||
testimonials: [],
|
||||
},
|
||||
};
|
||||
|
||||
/** Minimal — no navigation, footer, or optional sections */
|
||||
export const Minimal: Story = {
|
||||
args: {
|
||||
heroImage,
|
||||
onSearch: (params) => console.log('Search:', params),
|
||||
},
|
||||
};
|
||||
|
||||
/** Mobile viewport */
|
||||
export const Mobile: Story = {
|
||||
args: { ...Default.args },
|
||||
parameters: {
|
||||
viewport: { defaultViewport: 'mobile1' },
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user