112 lines
3.8 KiB
TypeScript

import { createReducer } from '@reduxjs/toolkit';
import { CartItem, MerchantCartGroup } from '@interfaces/cart';
import { addToCartThunk, getCartThunk, updateCartItemThunk } from './thunk';
// ─── State ───────────────────────────────────────────────────────────────────
export interface CartState {
id: string | null;
customerId: string | null;
items: CartItem[];
groupedByMerchant: MerchantCartGroup[];
subtotal: number;
totalItems: number;
isLoading: boolean;
error: string | null;
}
const initialState: CartState = {
id: null,
customerId: null,
items: [],
groupedByMerchant: [],
subtotal: 0,
totalItems: 0,
isLoading: false,
error: null,
};
// ─── Selector ────────────────────────────────────────────────────────────────
export const selectCartTotal = (state: { cart: CartState }) => {
const subtotal = state.cart.subtotal || 0;
const deliveryFee = 40; // Flat fee for now
const platformFee = 10; // Flat fee for now
const discount = 0; // Removing discount logic for now as requested
return {
subtotal,
deliveryFee,
platformFee,
discount,
total: Math.max(0, subtotal + deliveryFee + platformFee - discount),
itemCount: state.cart.totalItems || 0,
};
};
// ─── Reducer ─────────────────────────────────────────────────────────────────
const cartReducer = createReducer(initialState, builder => {
builder
// getCartThunk
.addCase(getCartThunk.pending, state => {
state.isLoading = true;
state.error = null;
})
.addCase(getCartThunk.fulfilled, (state, action) => {
state.isLoading = false;
const cart = action.payload;
state.id = cart.id;
state.customerId = cart.customerId;
state.items = cart.items || [];
state.groupedByMerchant = cart.groupedByMerchant || [];
state.subtotal = cart.subtotal || 0;
state.totalItems = cart.totalItems || 0;
})
.addCase(getCartThunk.rejected, (state, action) => {
state.isLoading = false;
state.error = (action.payload as string) || 'Failed to get cart';
})
// addToCartThunk
.addCase(addToCartThunk.pending, state => {
state.isLoading = true;
state.error = null;
})
.addCase(addToCartThunk.fulfilled, (state, action) => {
state.isLoading = false;
const cart = action.payload;
state.id = cart.id;
state.customerId = cart.customerId;
state.items = cart.items || [];
state.groupedByMerchant = cart.groupedByMerchant || [];
state.subtotal = cart.subtotal || 0;
state.totalItems = cart.totalItems || 0;
})
.addCase(addToCartThunk.rejected, (state, action) => {
state.isLoading = false;
state.error = (action.payload as string) || 'Failed to add to cart';
})
// updateCartItemThunk
.addCase(updateCartItemThunk.pending, state => {
state.isLoading = true;
state.error = null;
})
.addCase(updateCartItemThunk.fulfilled, (state, action) => {
state.isLoading = false;
const cart = action.payload;
state.id = cart.id;
state.customerId = cart.customerId;
state.items = cart.items || [];
state.groupedByMerchant = cart.groupedByMerchant || [];
state.subtotal = cart.subtotal || 0;
state.totalItems = cart.totalItems || 0;
})
.addCase(updateCartItemThunk.rejected, (state, action) => {
state.isLoading = false;
state.error = (action.payload as string) || 'Failed to update cart item';
});
});
export default cartReducer;