97 lines
2.6 KiB
TypeScript
97 lines
2.6 KiB
TypeScript
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
|
import { CartItem, CatalogItem } from '../interfaces';
|
|
|
|
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,
|
|
};
|
|
|
|
const cartSlice = createSlice({
|
|
name: 'cart',
|
|
initialState,
|
|
reducers: {
|
|
addItem(state, action: PayloadAction<{ providerId: string; providerName: string; item: CatalogItem }>) {
|
|
const { providerId, providerName, item } = action.payload;
|
|
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,
|
|
});
|
|
}
|
|
},
|
|
removeItem(state, action: PayloadAction<string>) {
|
|
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;
|
|
}
|
|
},
|
|
clearCart(state) {
|
|
state.items = [];
|
|
state.couponCode = null;
|
|
state.discount = 0;
|
|
state.providerId = null;
|
|
state.providerName = null;
|
|
},
|
|
applyCoupon(state, action: PayloadAction<string>) {
|
|
state.couponCode = action.payload;
|
|
state.discount = 50;
|
|
},
|
|
removeCoupon(state) {
|
|
state.couponCode = null;
|
|
state.discount = 0;
|
|
},
|
|
},
|
|
});
|
|
|
|
export const { addItem, removeItem, clearCart, applyCoupon, removeCoupon } = cartSlice.actions;
|
|
|
|
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),
|
|
};
|
|
};
|
|
|
|
export default cartSlice.reducer;
|