Enhance SelectionSummaryCard to improve pack selection feedback and error handling
This commit is contained in:
parent
e3c571ee4f
commit
93886751a3
@ -1,4 +1,5 @@
|
|||||||
import type { CoffeeItem } from '../hooks/getActiveCoffees';
|
import type { CoffeeItem } from '../hooks/getActiveCoffees';
|
||||||
|
import { MAX_ABO_PACKS, MIN_ABO_PACKS, packsToCapsules } from '../lib/orderRules';
|
||||||
|
|
||||||
type SelectedEntry = {
|
type SelectedEntry = {
|
||||||
coffee: CoffeeItem;
|
coffee: CoffeeItem;
|
||||||
@ -12,9 +13,9 @@ type Props = {
|
|||||||
selectedShippingFee: number;
|
selectedShippingFee: number;
|
||||||
totalNetWithShipping: number;
|
totalNetWithShipping: number;
|
||||||
totalCapsules: number;
|
totalCapsules: number;
|
||||||
packsSelected: number;
|
totalPacks: number;
|
||||||
selectedPlanCapsules: number;
|
orderPackError: string | null;
|
||||||
requiredPacks: number;
|
remainingMinPacks: number;
|
||||||
canProceed: boolean;
|
canProceed: boolean;
|
||||||
onProceed: () => void;
|
onProceed: () => void;
|
||||||
title: string;
|
title: string;
|
||||||
@ -29,9 +30,9 @@ export default function SelectionSummaryCard({
|
|||||||
selectedShippingFee,
|
selectedShippingFee,
|
||||||
totalNetWithShipping,
|
totalNetWithShipping,
|
||||||
totalCapsules,
|
totalCapsules,
|
||||||
packsSelected,
|
totalPacks,
|
||||||
selectedPlanCapsules,
|
orderPackError,
|
||||||
requiredPacks,
|
remainingMinPacks,
|
||||||
canProceed,
|
canProceed,
|
||||||
onProceed,
|
onProceed,
|
||||||
title,
|
title,
|
||||||
@ -49,10 +50,10 @@ export default function SelectionSummaryCard({
|
|||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<span className="font-medium text-slate-800">{entry.coffee.name}</span>
|
<span className="font-medium text-slate-800">{entry.coffee.name}</span>
|
||||||
<span className="text-xs text-slate-500">
|
<span className="text-xs text-slate-500">
|
||||||
{entry.quantity} pcs • <span className="inline-flex items-center font-semibold text-slate-900">EUR {entry.coffee.pricePer10}/10</span>
|
{entry.quantity} packs ({packsToCapsules(entry.quantity)} capsules) • <span className="inline-flex items-center font-semibold text-slate-900">EUR {entry.coffee.pricePer10.toFixed(2)}/pack</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-right font-semibold text-slate-800">EUR {((entry.quantity / 10) * entry.coffee.pricePer10).toFixed(2)}</div>
|
<div className="text-right font-semibold text-slate-800">EUR {(entry.quantity * entry.coffee.pricePer10).toFixed(2)}</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
@ -68,11 +69,21 @@ export default function SelectionSummaryCard({
|
|||||||
<span className="text-lg font-extrabold tracking-tight text-slate-900">EUR {totalNetWithShipping.toFixed(2)}</span>
|
<span className="text-lg font-extrabold tracking-tight text-slate-900">EUR {totalNetWithShipping.toFixed(2)}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="text-xs text-slate-700">
|
<div className="space-y-2 text-xs text-slate-700">
|
||||||
Selected: {totalCapsules} capsules ({packsSelected} packs of 10). Target: {selectedPlanCapsules} capsules ({requiredPacks} packs).
|
<div>
|
||||||
{packsSelected !== requiredPacks && (
|
<span className="font-semibold">{totalPacks.toLocaleString('en-US')}</span> packs selected.
|
||||||
<span className="ml-2 inline-flex items-center rounded-md bg-rose-50 text-rose-700 px-2 py-1 border border-rose-200">
|
<div className="text-slate-500">{totalCapsules.toLocaleString('en-US')} capsules total · minimum {MIN_ABO_PACKS} packs · maximum {MAX_ABO_PACKS.toLocaleString('en-US')} packs</div>
|
||||||
{packsSelected < requiredPacks ? `${requiredPacks - packsSelected} packs missing.` : `${packsSelected - requiredPacks} packs too many.`}
|
</div>
|
||||||
|
|
||||||
|
{orderPackError ? (
|
||||||
|
<span className="inline-flex items-center rounded-md bg-rose-50 text-rose-700 px-2 py-1 border border-rose-200">
|
||||||
|
{remainingMinPacks > 0
|
||||||
|
? `${remainingMinPacks} more pack${remainingMinPacks === 1 ? '' : 's'} needed to reach the minimum order.`
|
||||||
|
: orderPackError}
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
<span className="inline-flex items-center rounded-md bg-emerald-50 text-emerald-700 px-2 py-1 border border-emerald-200">
|
||||||
|
Selection is within the allowed order range.
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -101,7 +112,9 @@ export default function SelectionSummaryCard({
|
|||||||
|
|
||||||
{!canProceed && (
|
{!canProceed && (
|
||||||
<p className="text-xs text-slate-600">
|
<p className="text-xs text-slate-600">
|
||||||
You can continue once exactly {selectedPlanCapsules} capsules ({requiredPacks} packs) are selected.
|
{remainingMinPacks > 0
|
||||||
|
? `You can continue once at least ${MIN_ABO_PACKS} packs are selected.`
|
||||||
|
: `Please reduce the order to ${MAX_ABO_PACKS.toLocaleString('en-US')} packs or fewer.`}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user