@@ -75,12 +84,12 @@ export default function CoffeeAbonnementDetailPage() {
- Price per 10
+ Price per pack
EUR {coffee.pricePer10.toFixed(2)}
- Price per capsule
- EUR {(coffee.pricePer10 / 10).toFixed(2)}
+ Capsules per pack
+ 10 capsules
Gallery images
@@ -92,7 +101,7 @@ export default function CoffeeAbonnementDetailPage() {
-
Ready to add this coffee to your plan? Go back to the selection page and choose quantity in 10-piece steps.
+
Ready to add this coffee to your plan? Go back to the selection page and choose how many packs you want.
+
+
+ );
+}
+
+function CoffeeAbonnementPageContent() {
const { t } = useTranslation();
const [selections, setSelections] = useState
>({});
- const [bump, setBump] = useState>({});
- const [selectedPlanCapsules, setSelectedPlanCapsules] = useState(60);
const router = useRouter();
// Fetch active coffees from the backend
@@ -24,32 +39,6 @@ export default function CoffeeAbonnementPage() {
// Shipping fees (threshold-based)
const { resolveShippingFee, loading: shippingLoading, error: shippingError } = useShippingFees();
- const selectedShippingFee = resolveShippingFee(selectedPlanCapsules);
- const isFreeShippingSelected = Number(selectedShippingFee) === 0;
-
- const changePlanSize = (delta: number) => {
- setSelectedPlanCapsules(prev => {
- const next = Math.max(60, prev + delta);
- // Trim selections that exceed the new plan size
- setSelections(sel => {
- const trimmed = { ...sel };
- let running = 0;
- for (const id of Object.keys(trimmed)) {
- if (running + trimmed[id] <= next) {
- running += trimmed[id];
- } else if (running < next) {
- const allowed = Math.floor((next - running) / 10) * 10;
- if (allowed >= 10) { trimmed[id] = allowed; running = next; }
- else delete trimmed[id];
- } else {
- delete trimmed[id];
- }
- }
- return trimmed;
- });
- return next;
- });
- };
const selectedEntries = useMemo(
() =>
@@ -64,61 +53,62 @@ export default function CoffeeAbonnementPage() {
const totalPrice = useMemo(
() =>
selectedEntries.reduce(
- (sum, entry) => sum + (entry.quantity / 10) * entry.coffee.pricePer10,
+ (sum, entry) => sum + entry.quantity * entry.coffee.pricePer10,
0
),
[selectedEntries]
);
+ const totalPacks = useMemo(
+ () => selectedEntries.reduce((sum, entry) => sum + entry.quantity, 0),
+ [selectedEntries]
+ );
+
+ const totalCapsules = useMemo(() => packsToCapsules(totalPacks), [totalPacks]);
+ const selectedShippingFee = resolveShippingFee(totalCapsules);
+ const isFreeShippingSelected = Number(selectedShippingFee) === 0;
+ const orderPackError = getOrderPackError(totalPacks);
+ const remainingMinPacks = getRemainingMinPacks(totalPacks);
+
const totalNetWithShipping = useMemo(
() => totalPrice + (Number.isFinite(selectedShippingFee) ? selectedShippingFee : 0),
[totalPrice, selectedShippingFee]
);
- // NEW: enforce selected plan size (60 or 120 capsules)
- const totalCapsules = useMemo(
- () => selectedEntries.reduce((sum, entry) => sum + entry.quantity, 0),
- [selectedEntries]
- );
- const packsSelected = totalCapsules / 10;
- const requiredPacks = selectedPlanCapsules / 10;
- const canProceed = packsSelected === requiredPacks;
+ const canProceed = selectedEntries.length > 0 && !orderPackError;
const proceedToSummary = () => {
if (!canProceed) return;
try {
- sessionStorage.setItem('coffeeSelections', JSON.stringify(selections));
- sessionStorage.setItem('coffeeAboSizeCapsules', String(selectedPlanCapsules));
+ sessionStorage.setItem(COFFEE_SELECTIONS_STORAGE_KEY, JSON.stringify(selections));
+ sessionStorage.setItem(COFFEE_SELECTIONS_UNIT_STORAGE_KEY, COFFEE_SELECTIONS_UNIT);
} catch {}
router.push('/coffee-abonnements/summary');
};
- const toggleCoffee = (id: string) => {
+ const setQuantity = (id: string, nextValue: number) => {
setSelections((prev) => {
- const copy = { ...prev };
- if (id in copy) {
- delete copy[id];
- } else {
- const total = Object.values(copy).reduce((sum, qty) => sum + qty, 0);
- if (total + 10 > selectedPlanCapsules) return prev;
- copy[id] = 10;
+ const normalized = Math.max(0, Math.floor(Number(nextValue) || 0));
+ const current = prev[id] || 0;
+ const otherTotal = Object.entries(prev).reduce((sum, [key, qty]) => key === id ? sum : sum + qty, 0);
+ const maxForCoffee = Math.max(0, MAX_ABO_PACKS - otherTotal);
+ const bounded = Math.min(normalized, maxForCoffee);
+
+ if (bounded <= 0) {
+ if (!(id in prev)) return prev;
+ const next = { ...prev };
+ delete next[id];
+ return next;
}
- return copy;
+
+ if (bounded === current) return prev;
+ return { ...prev, [id]: bounded };
});
};
- const changeQuantity = (id: string, delta: number) => {
- setSelections((prev) => {
- if (!(id in prev)) return prev;
- const otherTotal = Object.entries(prev).reduce((sum, [key, qty]) => key === id ? sum : sum + qty, 0);
- const maxForCoffee = selectedPlanCapsules - otherTotal;
- const next = prev[id] + delta;
- if (next < 10 || next > maxForCoffee) return prev;
- const updated = { ...prev, [id]: next };
- setBump((b) => ({ ...b, [id]: true }));
- setTimeout(() => setBump((b) => ({ ...b, [id]: false })), 250);
- return updated;
- });
+ const adjustQuantity = (id: string, delta: number) => {
+ const current = selections[id] || 0;
+ setQuantity(id, current + delta);
};
return (
@@ -132,28 +122,14 @@ export default function CoffeeAbonnementPage() {
- changePlanSize(-10)}
- onIncrease={() => changePlanSize(+10)}
- loadingText={t('autofix.k12a86c71')}
- freeShippingText={t('autofix.ke7f0a9e3')}
- />
-
@@ -164,9 +140,9 @@ export default function CoffeeAbonnementPage() {
selectedShippingFee={selectedShippingFee}
totalNetWithShipping={totalNetWithShipping}
totalCapsules={totalCapsules}
- packsSelected={packsSelected}
- selectedPlanCapsules={selectedPlanCapsules}
- requiredPacks={requiredPacks}
+ totalPacks={totalPacks}
+ orderPackError={orderPackError}
+ remainingMinPacks={remainingMinPacks}
canProceed={canProceed}
onProceed={proceedToSummary}
title={t('autofix.ke7b634f2')}