From 0ed0adc835abb3d0532032fdd9d4fb748cfcbbab Mon Sep 17 00:00:00 2001 From: Richie Date: Thu, 26 Mar 2026 08:42:16 +1100 Subject: [PATCH] Refine LineItem + PackageDetail from review feedback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit LineItem: - Bump font weight 400 → 500 (D019: Montserrat Regular too light) - Price text now text.secondary for readability hierarchy (name primary, price quieter) - Total row stays fully prominent (primary colour) - Item gap increased 12px → 16px in stories PackageDetail: - Restructure: sections (before total) + extras (after total) Essentials + Complimentary → Total → Extras (additional cost) - Add compareLoading prop — loading spinner on Compare button - Add CompareLoading story with simulated 1.5s load - T&C line height reduced 1.5 → 1.3 - Section gap increased for breathing room - Complimentary items now correctly shown before total - Default story includes onArrange + onCompare handlers Co-Authored-By: Claude Opus 4.6 (1M context) --- .../molecules/LineItem/LineItem.stories.tsx | 18 ++-- .../molecules/LineItem/LineItem.tsx | 6 +- .../PackageDetail/PackageDetail.stories.tsx | 59 +++++++++--- .../organisms/PackageDetail/PackageDetail.tsx | 95 +++++++++++-------- 4 files changed, 112 insertions(+), 66 deletions(-) diff --git a/src/components/molecules/LineItem/LineItem.stories.tsx b/src/components/molecules/LineItem/LineItem.stories.tsx index ed87387..7fb3e70 100644 --- a/src/components/molecules/LineItem/LineItem.stories.tsx +++ b/src/components/molecules/LineItem/LineItem.stories.tsx @@ -80,14 +80,14 @@ export const Total: Story = { // --- Package Contents -------------------------------------------------------- -/** Realistic package breakdown as seen on the Package Select page */ +/** Realistic package breakdown — Essentials, Complimentary, Total, then Extras */ export const PackageContents: Story = { render: () => ( - + Essentials - + @@ -99,24 +99,24 @@ export const PackageContents: Story = { - + - + Complimentary Items - + - + - + Extras - + diff --git a/src/components/molecules/LineItem/LineItem.tsx b/src/components/molecules/LineItem/LineItem.tsx index 326b631..ab3eb6b 100644 --- a/src/components/molecules/LineItem/LineItem.tsx +++ b/src/components/molecules/LineItem/LineItem.tsx @@ -75,7 +75,7 @@ export const LineItem = React.forwardRef( ( {formattedPrice && ( {formattedPrice} diff --git a/src/components/organisms/PackageDetail/PackageDetail.stories.tsx b/src/components/organisms/PackageDetail/PackageDetail.stories.tsx index 757dd28..52f9c54 100644 --- a/src/components/organisms/PackageDetail/PackageDetail.stories.tsx +++ b/src/components/organisms/PackageDetail/PackageDetail.stories.tsx @@ -29,14 +29,17 @@ const complimentary = [ { name: 'Viewing Fee', info: 'One private family viewing — included at no charge.' }, ]; -const extras = [ - { name: 'Allowance for Flowers', price: 1500, isAllowance: true, info: 'Seasonal floral arrangements for the service.' }, - { name: 'Allowance for Master of Ceremonies', price: 1500, isAllowance: true, info: 'Professional celebrant or MC for the funeral service.' }, - { name: 'After Business Hours Service Surcharge', price: 1500, info: 'Additional fee for services held outside standard business hours.' }, - { name: 'After Hours Prayers', price: 1500, info: 'Evening prayer service at the funeral home.' }, - { name: 'Coffin Bearing by Funeral Directors', price: 1500, info: 'Professional pallbearing by funeral directors.' }, - { name: 'Digital Recording', price: 1500, info: 'Professional video recording of the funeral service.' }, -]; +const extras = { + heading: 'Extras', + items: [ + { name: 'Allowance for Flowers', price: 1500, isAllowance: true, info: 'Seasonal floral arrangements for the service.' }, + { name: 'Allowance for Master of Ceremonies', price: 1500, isAllowance: true, info: 'Professional celebrant or MC for the funeral service.' }, + { name: 'After Business Hours Service Surcharge', price: 1500, info: 'Additional fee for services held outside standard business hours.' }, + { name: 'After Hours Prayers', price: 1500, info: 'Evening prayer service at the funeral home.' }, + { name: 'Coffin Bearing by Funeral Directors', price: 1500, info: 'Professional pallbearing by funeral directors.' }, + { name: 'Digital Recording', price: 1500, info: 'Professional video recording of the funeral service.' }, + ], +}; const termsText = '* This package includes a funeral service at a chapel or a church with a funeral procession following to the crematorium. It includes many of the most commonly selected funeral options preselected for you. Many people choose this package for the extended funeral rituals — of course, you can tailor the funeral service to meet your needs and budget as you go through the selections.'; @@ -74,7 +77,7 @@ type Story = StoryObj; // --- Default ----------------------------------------------------------------- -/** Full package detail panel with all sections */ +/** Full package detail panel — Essentials, Complimentary, Total, then Extras */ export const Default: Story = { args: { name: 'Everyday Funeral Package', @@ -82,16 +85,35 @@ export const Default: Story = { sections: [ { heading: 'Essentials', items: essentials }, { heading: 'Complimentary Items', items: complimentary }, - { heading: 'Extras', items: extras }, ], total: 2700, + extras, terms: termsText, + onArrange: () => alert('Make Arrangement clicked'), + onCompare: () => alert('Compare clicked'), + }, +}; + +// --- Compare Loading --------------------------------------------------------- + +/** Compare button in loading state — adding to comparison cart */ +export const CompareLoading: Story = { + args: { + name: 'Everyday Funeral Package', + price: 900, + sections: [ + { heading: 'Essentials', items: essentials.slice(0, 4) }, + ], + total: 6000, + onArrange: () => alert('Make Arrangement'), + onCompare: () => {}, + compareLoading: true, }, }; // --- Without Extras ---------------------------------------------------------- -/** Simpler package with essentials only */ +/** Simpler package with essentials and complimentary only */ export const WithoutExtras: Story = { args: { name: 'Essential Funeral Package', @@ -102,6 +124,8 @@ export const WithoutExtras: Story = { ], total: 9000, terms: termsText, + onArrange: () => alert('Make Arrangement'), + onCompare: () => alert('Compare'), }, }; @@ -119,6 +143,12 @@ export const PackageSelectPage: Story = { render: () => { const [selectedPkg, setSelectedPkg] = useState('everyday'); const [activeFilter, setActiveFilter] = useState('Cremation'); + const [comparing, setComparing] = useState(false); + + const handleCompare = () => { + setComparing(true); + setTimeout(() => setComparing(false), 1500); + }; return ( @@ -144,7 +174,7 @@ export const PackageSelectPage: Story = { alignItems: 'start', }} > - {/* Left column: back, heading, provider, filter, packages */} + {/* Left column */}