import { createAction, createReducer } from '@reduxjs/toolkit'; import { CartItem, CatalogItem } from '../../../interfaces'; // ─── State ─────────────────────────────────────────────────────────────────── export interface CartState { items: CartItem[]; couponCode: string | null; discount: number; providerId: string | null; providerName: string | null; } const initialState: CartState = { items: [], couponCode: null, discount: 0, providerId: null, providerName: null, }; // ─── Actions ───────────────────────────────────────────────────────────────── export const addItem = createAction<{ providerId: string; providerName: string; item: CatalogItem; }>('cart/addItem'); export const removeItem = createAction('cart/removeItem'); export const clearCart = createAction('cart/clearCart'); export const applyCoupon = createAction('cart/applyCoupon'); export const removeCoupon = createAction('cart/removeCoupon'); // ─── Selector ──────────────────────────────────────────────────────────────── export const selectCartTotal = (state: { cart: CartState }) => { const subtotal = state.cart.items.reduce( (sum, item) => sum + item.item.price * item.quantity, 0, ); const deliveryFee = 40; const platformFee = 10; const discount = state.cart.discount; return { subtotal, deliveryFee, platformFee, discount, total: Math.max(0, subtotal + deliveryFee + platformFee - discount), itemCount: state.cart.items.reduce((sum, item) => sum + item.quantity, 0), }; }; // ─── Reducer ───────────────────────────────────────────────────────────────── const cartReducer = createReducer(initialState, builder => { builder .addCase(addItem, (state, action) => { const { providerId, providerName, item } = action.payload; // Clear cart if switching providers if (state.providerId && state.providerId !== providerId) { state.items = []; } state.providerId = providerId; state.providerName = providerName; const existing = state.items.find(i => i.item.id === item.id); if (existing) { existing.quantity += 1; } else { state.items.push({ id: `${providerId}-${item.id}`, providerId, providerName, item, quantity: 1, }); } }) .addCase(removeItem, (state, action) => { const existing = state.items.find(i => i.item.id === action.payload); if (existing) { if (existing.quantity > 1) { existing.quantity -= 1; } else { state.items = state.items.filter(i => i.item.id !== action.payload); } } if (state.items.length === 0) { state.providerId = null; state.providerName = null; } }) .addCase(clearCart, state => { state.items = []; state.couponCode = null; state.discount = 0; state.providerId = null; state.providerName = null; }) .addCase(applyCoupon, (state, action) => { state.couponCode = action.payload; state.discount = 50; }) .addCase(removeCoupon, state => { state.couponCode = null; state.discount = 0; }); }); export default cartReducer;