Packages fixtures: drop 'unknown' treatment + add 10 verified packages
Dash fix: PackageDetail no longer renders em-dash placeholder rows for Optionals. The 10 fixture entries that used `treatment: 'unknown'` are removed; the Optional type narrows to IncludedTreatment only; the dead 'unknown' branch in optionalsForStep/optionalsForComparison is gone. The rule going forward: an Optional/Extra exists on a package when the package actually offers it. ComparisonTable already handles absence correctly via buildMergedSections + lookupValue → 'Not Included'. Package distribution expanded (max 5 per provider, randomised): parsons: 3 → 5 (+ traditional-burial, memorial-service) rankins: 2 → 3 (+ direct-cremation) killick: 2 → 3 (+ traditional-burial) mackay: 1 → 4 (+ premium, simple, memorial-service) mannings: 1 → 4 (+ premium, simple, direct-cremation) Each new package follows the canonical-essentials rule: same 9 Essentials line items, only prices/treatments vary. Optionals + Extras composed per package. Mackay + Mannings comparison maps rewritten from single-package to the indexed-array pattern used by parsons/rankins/killick, and their bundle entries now slice(0,1)/slice(1) so an "Other packages from this provider" section appears. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -134,26 +134,32 @@ const sumEssentials = (p: EssentialsPrices): number => {
|
||||
};
|
||||
|
||||
// ─── Optionals helpers ───────────────────────────────────────────────────────
|
||||
//
|
||||
// Rule: Optionals an Extras list an item ONLY when that package actually
|
||||
// offers it. Missing items are not placeholders — they're just absent. In
|
||||
// PackageDetail that means the row isn't rendered. In ComparisonTable the
|
||||
// cross-join (see `buildMergedSections` + `lookupValue`) surfaces the row
|
||||
// as "Not Included" for any column that doesn't include it.
|
||||
|
||||
interface Optional {
|
||||
name: string;
|
||||
treatment: IncludedTreatment | 'unknown';
|
||||
treatment: IncludedTreatment;
|
||||
}
|
||||
|
||||
const optionalsForStep = (items: Optional[]): PackageSection => ({
|
||||
heading: 'Optionals',
|
||||
items: items.map<PackageLineItem>((it) =>
|
||||
it.treatment === 'unknown'
|
||||
? { name: it.name, price: 0, priceLabel: '—' }
|
||||
: { name: it.name, price: 0, priceLabel: labelFor(it.treatment) },
|
||||
),
|
||||
items: items.map<PackageLineItem>((it) => ({
|
||||
name: it.name,
|
||||
price: 0,
|
||||
priceLabel: labelFor(it.treatment),
|
||||
})),
|
||||
});
|
||||
|
||||
const optionalsForComparison = (items: Optional[]): ComparisonSection => ({
|
||||
heading: 'Optionals',
|
||||
items: items.map((it) => ({
|
||||
name: it.name,
|
||||
value: { type: it.treatment === 'unknown' ? 'unknown' : it.treatment },
|
||||
value: { type: it.treatment },
|
||||
})),
|
||||
});
|
||||
|
||||
@@ -226,6 +232,28 @@ const parsonsDeluxeEssentials: EssentialsPrices = {
|
||||
service: 5384.9,
|
||||
transport: 'complimentary',
|
||||
};
|
||||
const parsonsTraditionalEssentials: EssentialsPrices = {
|
||||
coffin: 2200,
|
||||
cremationCert: 350,
|
||||
crematorium: 660,
|
||||
deathReg: 70,
|
||||
dressing: 'complimentary',
|
||||
govLevy: 45.1,
|
||||
mortuary: 440,
|
||||
service: 4534.9,
|
||||
transport: 'complimentary',
|
||||
};
|
||||
const parsonsMemorialEssentials: EssentialsPrices = {
|
||||
coffin: 900,
|
||||
cremationCert: 350,
|
||||
crematorium: 660,
|
||||
deathReg: 70,
|
||||
dressing: 'complimentary',
|
||||
govLevy: 45.1,
|
||||
mortuary: 440,
|
||||
service: 3034.9,
|
||||
transport: 'complimentary',
|
||||
};
|
||||
|
||||
const parsonsForStep: PackageData[] = [
|
||||
{
|
||||
@@ -290,10 +318,58 @@ const parsonsForStep: PackageData[] = [
|
||||
{ name: 'Saturday Service Fee', value: 'complimentary' },
|
||||
]),
|
||||
},
|
||||
{
|
||||
id: 'traditional-burial',
|
||||
name: 'Traditional Burial Package',
|
||||
price: sumEssentials(parsonsTraditionalEssentials),
|
||||
description:
|
||||
'A traditional funeral service followed by burial, including a full procession and graveside committal.',
|
||||
sections: [
|
||||
essentialsForStep(parsonsTraditionalEssentials),
|
||||
optionalsForStep([
|
||||
{ name: 'Digital Recording', treatment: 'complimentary' },
|
||||
{ name: 'Online Notice', treatment: 'complimentary' },
|
||||
{ name: 'Viewing Fee', treatment: 'complimentary' },
|
||||
{ name: 'Flowers', treatment: 'complimentary' },
|
||||
]),
|
||||
],
|
||||
extras: extrasForStep([
|
||||
{ name: 'Allowance for Celebrant', value: { allowance: 600 } },
|
||||
{ name: 'Catering', value: 1100 },
|
||||
{ name: 'Newspaper Notice', value: 350 },
|
||||
{ name: 'Saturday Service Fee', value: 880 },
|
||||
]),
|
||||
},
|
||||
{
|
||||
id: 'memorial-service',
|
||||
name: 'Memorial Service Package',
|
||||
price: sumEssentials(parsonsMemorialEssentials),
|
||||
description:
|
||||
'A memorial service held after the cremation, giving families time to plan a personalised gathering.',
|
||||
sections: [
|
||||
essentialsForStep(parsonsMemorialEssentials),
|
||||
optionalsForStep([
|
||||
{ name: 'Online Notice', treatment: 'complimentary' },
|
||||
{ name: 'Viewing Fee', treatment: 'complimentary' },
|
||||
{ name: 'Flowers', treatment: 'complimentary' },
|
||||
]),
|
||||
],
|
||||
extras: extrasForStep([
|
||||
{ name: 'Allowance for Celebrant', value: { allowance: 500 } },
|
||||
{ name: 'Catering', value: 'poa' },
|
||||
{ name: 'Newspaper Notice', value: 280 },
|
||||
]),
|
||||
},
|
||||
];
|
||||
|
||||
const parsonsForComparison: ComparisonPackage[] = parsonsForStep.map((pkg, idx) => {
|
||||
const ess = [parsonsEverydayEssentials, parsonsEssentialEssentials, parsonsDeluxeEssentials][idx];
|
||||
const ess = [
|
||||
parsonsEverydayEssentials,
|
||||
parsonsEssentialEssentials,
|
||||
parsonsDeluxeEssentials,
|
||||
parsonsTraditionalEssentials,
|
||||
parsonsMemorialEssentials,
|
||||
][idx];
|
||||
const allOptionals: Optional[][] = [
|
||||
[
|
||||
{ name: 'Digital Recording', treatment: 'complimentary' },
|
||||
@@ -312,6 +388,17 @@ const parsonsForComparison: ComparisonPackage[] = parsonsForStep.map((pkg, idx)
|
||||
{ name: 'Flowers', treatment: 'complimentary' },
|
||||
{ name: 'Webstreaming', treatment: 'complimentary' },
|
||||
],
|
||||
[
|
||||
{ name: 'Digital Recording', treatment: 'complimentary' },
|
||||
{ name: 'Online Notice', treatment: 'complimentary' },
|
||||
{ name: 'Viewing Fee', treatment: 'complimentary' },
|
||||
{ name: 'Flowers', treatment: 'complimentary' },
|
||||
],
|
||||
[
|
||||
{ name: 'Online Notice', treatment: 'complimentary' },
|
||||
{ name: 'Viewing Fee', treatment: 'complimentary' },
|
||||
{ name: 'Flowers', treatment: 'complimentary' },
|
||||
],
|
||||
];
|
||||
const optionals = allOptionals[idx];
|
||||
const extras: Extra[] = [
|
||||
@@ -331,6 +418,17 @@ const parsonsForComparison: ComparisonPackage[] = parsonsForStep.map((pkg, idx)
|
||||
{ name: 'Newspaper Notice', value: 350 },
|
||||
{ name: 'Saturday Service Fee', value: 'complimentary' as const },
|
||||
],
|
||||
[
|
||||
{ name: 'Allowance for Celebrant', value: { allowance: 600 } },
|
||||
{ name: 'Catering', value: 1100 },
|
||||
{ name: 'Newspaper Notice', value: 350 },
|
||||
{ name: 'Saturday Service Fee', value: 880 },
|
||||
],
|
||||
[
|
||||
{ name: 'Allowance for Celebrant', value: { allowance: 500 } },
|
||||
{ name: 'Catering', value: 'poa' as const },
|
||||
{ name: 'Newspaper Notice', value: 280 },
|
||||
],
|
||||
][idx];
|
||||
return {
|
||||
id: pkg.id,
|
||||
@@ -376,6 +474,17 @@ const rankinsPremiumEssentials: EssentialsPrices = {
|
||||
service: 4034.9,
|
||||
transport: 'included',
|
||||
};
|
||||
const rankinsDirectEssentials: EssentialsPrices = {
|
||||
coffin: 800,
|
||||
cremationCert: 350,
|
||||
crematorium: 660,
|
||||
deathReg: 70,
|
||||
dressing: 'included',
|
||||
govLevy: 45.1,
|
||||
mortuary: 440,
|
||||
service: 434.9,
|
||||
transport: 'included',
|
||||
};
|
||||
|
||||
const rankinsForStep: PackageData[] = [
|
||||
{
|
||||
@@ -386,7 +495,6 @@ const rankinsForStep: PackageData[] = [
|
||||
sections: [
|
||||
essentialsForStep(rankinsStandardEssentials),
|
||||
optionalsForStep([
|
||||
{ name: 'Digital Recording', treatment: 'unknown' },
|
||||
{ name: 'Online Notice', treatment: 'included' },
|
||||
{ name: 'Viewing Fee', treatment: 'included' },
|
||||
{ name: 'Flowers', treatment: 'included' },
|
||||
@@ -418,13 +526,20 @@ const rankinsForStep: PackageData[] = [
|
||||
{ name: 'Newspaper Notice', value: 280 },
|
||||
]),
|
||||
},
|
||||
{
|
||||
id: 'direct-cremation',
|
||||
name: 'Direct Cremation',
|
||||
price: sumEssentials(rankinsDirectEssentials),
|
||||
description: 'An unattended cremation with no service — the lowest-cost option.',
|
||||
sections: [essentialsForStep(rankinsDirectEssentials), optionalsForStep([])],
|
||||
extras: extrasForStep([]),
|
||||
},
|
||||
];
|
||||
|
||||
const rankinsForComparison: ComparisonPackage[] = rankinsForStep.map((pkg, idx) => {
|
||||
const ess = [rankinsStandardEssentials, rankinsPremiumEssentials][idx];
|
||||
const ess = [rankinsStandardEssentials, rankinsPremiumEssentials, rankinsDirectEssentials][idx];
|
||||
const allOptionals: Optional[][] = [
|
||||
[
|
||||
{ name: 'Digital Recording', treatment: 'unknown' },
|
||||
{ name: 'Online Notice', treatment: 'included' },
|
||||
{ name: 'Viewing Fee', treatment: 'included' },
|
||||
{ name: 'Flowers', treatment: 'included' },
|
||||
@@ -435,6 +550,7 @@ const rankinsForComparison: ComparisonPackage[] = rankinsForStep.map((pkg, idx)
|
||||
{ name: 'Viewing Fee', treatment: 'included' },
|
||||
{ name: 'Flowers', treatment: 'included' },
|
||||
],
|
||||
[],
|
||||
];
|
||||
const optionals = allOptionals[idx];
|
||||
const extras: Extra[] = [
|
||||
@@ -448,6 +564,7 @@ const rankinsForComparison: ComparisonPackage[] = rankinsForStep.map((pkg, idx)
|
||||
{ name: 'Catering', value: 950 },
|
||||
{ name: 'Newspaper Notice', value: 280 },
|
||||
],
|
||||
[],
|
||||
][idx];
|
||||
return {
|
||||
id: pkg.id,
|
||||
@@ -495,6 +612,18 @@ const killickSimpleEssentials: EssentialsPrices = {
|
||||
service: 1534.9,
|
||||
transport: 'complimentary',
|
||||
};
|
||||
const killickTraditionalEssentials: EssentialsPrices = {
|
||||
coffin: 2500,
|
||||
cremationCert: 350,
|
||||
crematorium: 660,
|
||||
deathReg: 70,
|
||||
dressing: 'complimentary',
|
||||
govLevy: 45.1,
|
||||
govLevyLabel: 'Government Levy — Cremation',
|
||||
mortuary: 440,
|
||||
service: 4234.9,
|
||||
transport: 'complimentary',
|
||||
};
|
||||
|
||||
const killickForStep: PackageData[] = [
|
||||
{
|
||||
@@ -508,7 +637,6 @@ const killickForStep: PackageData[] = [
|
||||
{ name: 'Digital Recording', treatment: 'complimentary' },
|
||||
{ name: 'Online Notice', treatment: 'complimentary' },
|
||||
{ name: 'Viewing Fee', treatment: 'complimentary' },
|
||||
{ name: 'Flowers', treatment: 'unknown' },
|
||||
]),
|
||||
],
|
||||
extras: extrasForStep([
|
||||
@@ -524,27 +652,47 @@ const killickForStep: PackageData[] = [
|
||||
description: 'A direct cremation without a service.',
|
||||
sections: [
|
||||
essentialsForStep(killickSimpleEssentials),
|
||||
optionalsForStep([
|
||||
{ name: 'Online Notice', treatment: 'complimentary' },
|
||||
{ name: 'Viewing Fee', treatment: 'unknown' },
|
||||
]),
|
||||
optionalsForStep([{ name: 'Online Notice', treatment: 'complimentary' }]),
|
||||
],
|
||||
extras: extrasForStep([{ name: 'Allowance for Celebrant', value: { allowance: 350 } }]),
|
||||
},
|
||||
{
|
||||
id: 'traditional-burial',
|
||||
name: 'Traditional Burial Package',
|
||||
price: sumEssentials(killickTraditionalEssentials),
|
||||
description:
|
||||
'A traditional burial service with chapel use, full procession, and graveside committal.',
|
||||
sections: [
|
||||
essentialsForStep(killickTraditionalEssentials),
|
||||
optionalsForStep([
|
||||
{ name: 'Digital Recording', treatment: 'complimentary' },
|
||||
{ name: 'Online Notice', treatment: 'complimentary' },
|
||||
{ name: 'Viewing Fee', treatment: 'complimentary' },
|
||||
]),
|
||||
],
|
||||
extras: extrasForStep([
|
||||
{ name: 'Allowance for Celebrant', value: { allowance: 550 } },
|
||||
{ name: 'Catering', value: 'poa' },
|
||||
{ name: 'Saturday Service Fee', value: 800 },
|
||||
]),
|
||||
},
|
||||
];
|
||||
|
||||
const killickForComparison: ComparisonPackage[] = killickForStep.map((pkg, idx) => {
|
||||
const ess = [killickClassicEssentials, killickSimpleEssentials][idx];
|
||||
const ess = [killickClassicEssentials, killickSimpleEssentials, killickTraditionalEssentials][
|
||||
idx
|
||||
];
|
||||
const allOptionals: Optional[][] = [
|
||||
[
|
||||
{ name: 'Digital Recording', treatment: 'complimentary' },
|
||||
{ name: 'Online Notice', treatment: 'complimentary' },
|
||||
{ name: 'Viewing Fee', treatment: 'complimentary' },
|
||||
{ name: 'Flowers', treatment: 'unknown' },
|
||||
],
|
||||
[{ name: 'Online Notice', treatment: 'complimentary' }],
|
||||
[
|
||||
{ name: 'Digital Recording', treatment: 'complimentary' },
|
||||
{ name: 'Online Notice', treatment: 'complimentary' },
|
||||
{ name: 'Viewing Fee', treatment: 'unknown' },
|
||||
{ name: 'Viewing Fee', treatment: 'complimentary' },
|
||||
],
|
||||
];
|
||||
const optionals = allOptionals[idx];
|
||||
@@ -555,6 +703,11 @@ const killickForComparison: ComparisonPackage[] = killickForStep.map((pkg, idx)
|
||||
{ name: 'Saturday Service Fee', value: 800 },
|
||||
],
|
||||
[{ name: 'Allowance for Celebrant', value: { allowance: 350 } }],
|
||||
[
|
||||
{ name: 'Allowance for Celebrant', value: { allowance: 550 } },
|
||||
{ name: 'Catering', value: 'poa' as const },
|
||||
{ name: 'Saturday Service Fee', value: 800 },
|
||||
],
|
||||
][idx];
|
||||
return {
|
||||
id: pkg.id,
|
||||
@@ -589,6 +742,39 @@ const mackayEverydayEssentials: EssentialsPrices = {
|
||||
service: 2430.35,
|
||||
transport: 'included',
|
||||
};
|
||||
const mackayPremiumEssentials: EssentialsPrices = {
|
||||
coffin: 2200,
|
||||
cremationCert: 350,
|
||||
crematorium: 660,
|
||||
deathReg: 70,
|
||||
dressing: 'included',
|
||||
govLevy: 45.1,
|
||||
mortuary: 440,
|
||||
service: 4034.9,
|
||||
transport: 'included',
|
||||
};
|
||||
const mackaySimpleEssentials: EssentialsPrices = {
|
||||
coffin: 800,
|
||||
cremationCert: 350,
|
||||
crematorium: 660,
|
||||
deathReg: 70,
|
||||
dressing: 'included',
|
||||
govLevy: 45.1,
|
||||
mortuary: 440,
|
||||
service: 434.9,
|
||||
transport: 'included',
|
||||
};
|
||||
const mackayMemorialEssentials: EssentialsPrices = {
|
||||
coffin: 900,
|
||||
cremationCert: 350,
|
||||
crematorium: 660,
|
||||
deathReg: 70,
|
||||
dressing: 'included',
|
||||
govLevy: 45.1,
|
||||
mortuary: 440,
|
||||
service: 2834.9,
|
||||
transport: 'included',
|
||||
};
|
||||
|
||||
const mackayForStep: PackageData[] = [
|
||||
{
|
||||
@@ -599,7 +785,6 @@ const mackayForStep: PackageData[] = [
|
||||
sections: [
|
||||
essentialsForStep(mackayEverydayEssentials),
|
||||
optionalsForStep([
|
||||
{ name: 'Digital Recording', treatment: 'unknown' },
|
||||
{ name: 'Online Notice', treatment: 'included' },
|
||||
{ name: 'Viewing Fee', treatment: 'included' },
|
||||
{ name: 'Flowers', treatment: 'included' },
|
||||
@@ -611,35 +796,119 @@ const mackayForStep: PackageData[] = [
|
||||
{ name: 'Saturday Service Fee', value: 750 },
|
||||
]),
|
||||
},
|
||||
{
|
||||
id: 'premium',
|
||||
name: 'Premium Funeral Service',
|
||||
price: sumEssentials(mackayPremiumEssentials),
|
||||
description: 'An enhanced service with premium coffin selection and expanded inclusions.',
|
||||
sections: [
|
||||
essentialsForStep(mackayPremiumEssentials),
|
||||
optionalsForStep([
|
||||
{ name: 'Digital Recording', treatment: 'included' },
|
||||
{ name: 'Online Notice', treatment: 'included' },
|
||||
{ name: 'Viewing Fee', treatment: 'included' },
|
||||
{ name: 'Flowers', treatment: 'included' },
|
||||
]),
|
||||
],
|
||||
extras: extrasForStep([
|
||||
{ name: 'Allowance for Celebrant', value: { allowance: 600 } },
|
||||
{ name: 'Catering', value: 1100 },
|
||||
{ name: 'Newspaper Notice', value: 320 },
|
||||
]),
|
||||
},
|
||||
{
|
||||
id: 'simple',
|
||||
name: 'Simple Cremation',
|
||||
price: sumEssentials(mackaySimpleEssentials),
|
||||
description: 'A direct cremation without a formal service.',
|
||||
sections: [
|
||||
essentialsForStep(mackaySimpleEssentials),
|
||||
optionalsForStep([{ name: 'Online Notice', treatment: 'included' }]),
|
||||
],
|
||||
extras: extrasForStep([{ name: 'Allowance for Celebrant', value: { allowance: 350 } }]),
|
||||
},
|
||||
{
|
||||
id: 'memorial-service',
|
||||
name: 'Memorial Service Package',
|
||||
price: sumEssentials(mackayMemorialEssentials),
|
||||
description:
|
||||
'A memorial service held separately from the cremation, allowing time for planning and family gatherings.',
|
||||
sections: [
|
||||
essentialsForStep(mackayMemorialEssentials),
|
||||
optionalsForStep([
|
||||
{ name: 'Online Notice', treatment: 'included' },
|
||||
{ name: 'Viewing Fee', treatment: 'included' },
|
||||
]),
|
||||
],
|
||||
extras: extrasForStep([
|
||||
{ name: 'Allowance for Celebrant', value: { allowance: 500 } },
|
||||
{ name: 'Catering', value: 'poa' },
|
||||
]),
|
||||
},
|
||||
];
|
||||
|
||||
const mackayForComparison: ComparisonPackage[] = mackayForStep.map((pkg) => ({
|
||||
id: pkg.id,
|
||||
name: pkg.name,
|
||||
price: pkg.price,
|
||||
provider: {
|
||||
name: 'Mackay Family Funeral Directors',
|
||||
location: 'Ourimbah, NSW',
|
||||
logoUrl: providersById['mackay'].logoUrl,
|
||||
rating: 4.6,
|
||||
reviewCount: 87,
|
||||
verified: true,
|
||||
},
|
||||
sections: [
|
||||
essentialsForComparison(mackayEverydayEssentials),
|
||||
optionalsForComparison([
|
||||
{ name: 'Digital Recording', treatment: 'unknown' },
|
||||
const mackayForComparison: ComparisonPackage[] = mackayForStep.map((pkg, idx) => {
|
||||
const ess = [
|
||||
mackayEverydayEssentials,
|
||||
mackayPremiumEssentials,
|
||||
mackaySimpleEssentials,
|
||||
mackayMemorialEssentials,
|
||||
][idx];
|
||||
const allOptionals: Optional[][] = [
|
||||
[
|
||||
{ name: 'Online Notice', treatment: 'included' },
|
||||
{ name: 'Viewing Fee', treatment: 'included' },
|
||||
{ name: 'Flowers', treatment: 'included' },
|
||||
]),
|
||||
extrasForComparison([
|
||||
],
|
||||
[
|
||||
{ name: 'Digital Recording', treatment: 'included' },
|
||||
{ name: 'Online Notice', treatment: 'included' },
|
||||
{ name: 'Viewing Fee', treatment: 'included' },
|
||||
{ name: 'Flowers', treatment: 'included' },
|
||||
],
|
||||
[{ name: 'Online Notice', treatment: 'included' }],
|
||||
[
|
||||
{ name: 'Online Notice', treatment: 'included' },
|
||||
{ name: 'Viewing Fee', treatment: 'included' },
|
||||
],
|
||||
];
|
||||
const optionals = allOptionals[idx];
|
||||
const extras: Extra[] = [
|
||||
[
|
||||
{ name: 'Allowance for Celebrant', value: { allowance: 450 } },
|
||||
{ name: 'Catering', value: 'poa' },
|
||||
{ name: 'Catering', value: 'poa' as const },
|
||||
{ name: 'Saturday Service Fee', value: 750 },
|
||||
]),
|
||||
],
|
||||
}));
|
||||
],
|
||||
[
|
||||
{ name: 'Allowance for Celebrant', value: { allowance: 600 } },
|
||||
{ name: 'Catering', value: 1100 },
|
||||
{ name: 'Newspaper Notice', value: 320 },
|
||||
],
|
||||
[{ name: 'Allowance for Celebrant', value: { allowance: 350 } }],
|
||||
[
|
||||
{ name: 'Allowance for Celebrant', value: { allowance: 500 } },
|
||||
{ name: 'Catering', value: 'poa' as const },
|
||||
],
|
||||
][idx];
|
||||
return {
|
||||
id: pkg.id,
|
||||
name: pkg.name,
|
||||
price: pkg.price,
|
||||
provider: {
|
||||
name: 'Mackay Family Funeral Directors',
|
||||
location: 'Ourimbah, NSW',
|
||||
logoUrl: providersById['mackay'].logoUrl,
|
||||
rating: 4.6,
|
||||
reviewCount: 87,
|
||||
verified: true,
|
||||
},
|
||||
sections: [
|
||||
essentialsForComparison(ess),
|
||||
optionalsForComparison(optionals),
|
||||
extrasForComparison(extras),
|
||||
],
|
||||
};
|
||||
});
|
||||
|
||||
// ─── Mannings (verified, NSW) ────────────────────────────────────────────────
|
||||
|
||||
@@ -654,6 +923,39 @@ const manningsStandardEssentials: EssentialsPrices = {
|
||||
service: 2114.9,
|
||||
transport: 'included',
|
||||
};
|
||||
const manningsPremiumEssentials: EssentialsPrices = {
|
||||
coffin: 2100,
|
||||
cremationCert: 350,
|
||||
crematorium: 660,
|
||||
deathReg: 70,
|
||||
dressing: 'included',
|
||||
govLevy: 45.1,
|
||||
mortuary: 440,
|
||||
service: 3734.9,
|
||||
transport: 'included',
|
||||
};
|
||||
const manningsSimpleEssentials: EssentialsPrices = {
|
||||
coffin: 750,
|
||||
cremationCert: 350,
|
||||
crematorium: 660,
|
||||
deathReg: 70,
|
||||
dressing: 'included',
|
||||
govLevy: 45.1,
|
||||
mortuary: 440,
|
||||
service: 284.9,
|
||||
transport: 'included',
|
||||
};
|
||||
const manningsDirectEssentials: EssentialsPrices = {
|
||||
coffin: 600,
|
||||
cremationCert: 350,
|
||||
crematorium: 660,
|
||||
deathReg: 70,
|
||||
dressing: 'included',
|
||||
govLevy: 45.1,
|
||||
mortuary: 440,
|
||||
service: 34.9,
|
||||
transport: 'included',
|
||||
};
|
||||
|
||||
const manningsForStep: PackageData[] = [
|
||||
{
|
||||
@@ -666,7 +968,6 @@ const manningsForStep: PackageData[] = [
|
||||
optionalsForStep([
|
||||
{ name: 'Online Notice', treatment: 'included' },
|
||||
{ name: 'Viewing Fee', treatment: 'included' },
|
||||
{ name: 'Flowers', treatment: 'unknown' },
|
||||
]),
|
||||
],
|
||||
extras: extrasForStep([
|
||||
@@ -674,33 +975,101 @@ const manningsForStep: PackageData[] = [
|
||||
{ name: 'Catering', value: 'poa' },
|
||||
]),
|
||||
},
|
||||
{
|
||||
id: 'premium',
|
||||
name: 'Premium Funeral Service',
|
||||
price: sumEssentials(manningsPremiumEssentials),
|
||||
description: 'A more elaborate service with an upgraded coffin and broader inclusions.',
|
||||
sections: [
|
||||
essentialsForStep(manningsPremiumEssentials),
|
||||
optionalsForStep([
|
||||
{ name: 'Digital Recording', treatment: 'included' },
|
||||
{ name: 'Online Notice', treatment: 'included' },
|
||||
{ name: 'Viewing Fee', treatment: 'included' },
|
||||
{ name: 'Flowers', treatment: 'included' },
|
||||
]),
|
||||
],
|
||||
extras: extrasForStep([
|
||||
{ name: 'Allowance for Celebrant', value: { allowance: 600 } },
|
||||
{ name: 'Catering', value: 950 },
|
||||
{ name: 'Newspaper Notice', value: 280 },
|
||||
]),
|
||||
},
|
||||
{
|
||||
id: 'simple',
|
||||
name: 'Simple Cremation',
|
||||
price: sumEssentials(manningsSimpleEssentials),
|
||||
description: 'A straightforward cremation without a chapel service.',
|
||||
sections: [
|
||||
essentialsForStep(manningsSimpleEssentials),
|
||||
optionalsForStep([{ name: 'Online Notice', treatment: 'included' }]),
|
||||
],
|
||||
extras: extrasForStep([{ name: 'Allowance for Celebrant', value: { allowance: 350 } }]),
|
||||
},
|
||||
{
|
||||
id: 'direct-cremation',
|
||||
name: 'Direct Cremation',
|
||||
price: sumEssentials(manningsDirectEssentials),
|
||||
description: 'An unattended cremation with no service — the lowest-cost option.',
|
||||
sections: [essentialsForStep(manningsDirectEssentials), optionalsForStep([])],
|
||||
extras: extrasForStep([]),
|
||||
},
|
||||
];
|
||||
|
||||
const manningsForComparison: ComparisonPackage[] = manningsForStep.map((pkg) => ({
|
||||
id: pkg.id,
|
||||
name: pkg.name,
|
||||
price: pkg.price,
|
||||
provider: {
|
||||
name: 'Mannings Funerals',
|
||||
location: 'Bega, NSW',
|
||||
logoUrl: providersById['mannings'].logoUrl,
|
||||
rating: 4.7,
|
||||
reviewCount: 31,
|
||||
verified: true,
|
||||
},
|
||||
sections: [
|
||||
essentialsForComparison(manningsStandardEssentials),
|
||||
optionalsForComparison([
|
||||
const manningsForComparison: ComparisonPackage[] = manningsForStep.map((pkg, idx) => {
|
||||
const ess = [
|
||||
manningsStandardEssentials,
|
||||
manningsPremiumEssentials,
|
||||
manningsSimpleEssentials,
|
||||
manningsDirectEssentials,
|
||||
][idx];
|
||||
const allOptionals: Optional[][] = [
|
||||
[
|
||||
{ name: 'Online Notice', treatment: 'included' },
|
||||
{ name: 'Viewing Fee', treatment: 'included' },
|
||||
{ name: 'Flowers', treatment: 'unknown' },
|
||||
]),
|
||||
extrasForComparison([
|
||||
],
|
||||
[
|
||||
{ name: 'Digital Recording', treatment: 'included' },
|
||||
{ name: 'Online Notice', treatment: 'included' },
|
||||
{ name: 'Viewing Fee', treatment: 'included' },
|
||||
{ name: 'Flowers', treatment: 'included' },
|
||||
],
|
||||
[{ name: 'Online Notice', treatment: 'included' }],
|
||||
[],
|
||||
];
|
||||
const optionals = allOptionals[idx];
|
||||
const extras: Extra[] = [
|
||||
[
|
||||
{ name: 'Allowance for Celebrant', value: { allowance: 400 } },
|
||||
{ name: 'Catering', value: 'poa' },
|
||||
]),
|
||||
],
|
||||
}));
|
||||
{ name: 'Catering', value: 'poa' as const },
|
||||
],
|
||||
[
|
||||
{ name: 'Allowance for Celebrant', value: { allowance: 600 } },
|
||||
{ name: 'Catering', value: 950 },
|
||||
{ name: 'Newspaper Notice', value: 280 },
|
||||
],
|
||||
[{ name: 'Allowance for Celebrant', value: { allowance: 350 } }],
|
||||
[],
|
||||
][idx];
|
||||
return {
|
||||
id: pkg.id,
|
||||
name: pkg.name,
|
||||
price: pkg.price,
|
||||
provider: {
|
||||
name: 'Mannings Funerals',
|
||||
location: 'Bega, NSW',
|
||||
logoUrl: providersById['mannings'].logoUrl,
|
||||
rating: 4.7,
|
||||
reviewCount: 31,
|
||||
verified: true,
|
||||
},
|
||||
sections: [
|
||||
essentialsForComparison(ess),
|
||||
optionalsForComparison(optionals),
|
||||
extrasForComparison(extras),
|
||||
],
|
||||
};
|
||||
});
|
||||
|
||||
// ─── Wollongong City (tier 3 — itemised but unverified, mostly unknowns) ─────
|
||||
|
||||
@@ -832,13 +1201,13 @@ export const packagesByProvider: Record<string, PackageBundle> = {
|
||||
forComparison: killickForComparison,
|
||||
},
|
||||
mackay: {
|
||||
matching: mackayForStep,
|
||||
other: [],
|
||||
matching: mackayForStep.slice(0, 1),
|
||||
other: mackayForStep.slice(1),
|
||||
forComparison: mackayForComparison,
|
||||
},
|
||||
mannings: {
|
||||
matching: manningsForStep,
|
||||
other: [],
|
||||
matching: manningsForStep.slice(0, 1),
|
||||
other: manningsForStep.slice(1),
|
||||
forComparison: manningsForComparison,
|
||||
},
|
||||
'wollongong-city': {
|
||||
|
||||
Reference in New Issue
Block a user