Enhance SelectionSummaryCard to improve pack selection feedback and error handling

This commit is contained in:
seaznCode 2026-05-05 22:08:30 +02:00
parent e3c571ee4f
commit 93886751a3

View File

@ -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>