Обновлена логика добавления товаров в корзину во всех компонентах. Теперь добавление происходит асинхронно с обработкой успешных и ошибочных результатов. Добавлена информация о наличии товара при добавлении в корзину. Улучшены уведомления о добавлении товара с учетом статуса операции.
This commit is contained in:
@ -25,6 +25,8 @@ const initialState: CartState = {
|
||||
// Типы действий
|
||||
type CartAction =
|
||||
| { type: 'ADD_ITEM'; payload: Omit<CartItem, 'id' | 'selected' | 'favorite'> }
|
||||
| { type: 'ADD_ITEM_SUCCESS'; payload: { items: CartItem[]; summary: any } }
|
||||
| { type: 'ADD_ITEM_ERROR'; payload: string }
|
||||
| { type: 'REMOVE_ITEM'; payload: string }
|
||||
| { type: 'UPDATE_QUANTITY'; payload: { id: string; quantity: number } }
|
||||
| { type: 'TOGGLE_SELECT'; payload: string }
|
||||
@ -44,6 +46,16 @@ type CartAction =
|
||||
// Функция для генерации ID
|
||||
const generateId = () => Math.random().toString(36).substr(2, 9)
|
||||
|
||||
// Утилитарная функция для парсинга количества в наличии
|
||||
const parseStock = (stockStr: string | number | undefined): number => {
|
||||
if (typeof stockStr === 'number') return stockStr;
|
||||
if (typeof stockStr === 'string') {
|
||||
const match = stockStr.match(/\d+/);
|
||||
return match ? parseInt(match[0]) : 0;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
// Функция для расчета итогов
|
||||
const calculateSummary = (items: CartItem[], deliveryPrice: number) => {
|
||||
const selectedItems = items.filter(item => item.selected)
|
||||
@ -78,9 +90,12 @@ const cartReducer = (state: CartState, action: CartAction): CartState => {
|
||||
|
||||
if (existingItemIndex >= 0) {
|
||||
// Увеличиваем количество существующего товара
|
||||
const existingItem = state.items[existingItemIndex];
|
||||
const totalQuantity = existingItem.quantity + action.payload.quantity;
|
||||
|
||||
newItems = state.items.map((item, index) =>
|
||||
index === existingItemIndex
|
||||
? { ...item, quantity: item.quantity + action.payload.quantity }
|
||||
? { ...item, quantity: totalQuantity }
|
||||
: item
|
||||
)
|
||||
} else {
|
||||
@ -335,8 +350,31 @@ export const CartProvider: React.FC<{ children: React.ReactNode }> = ({ children
|
||||
}, [state.items, state.delivery, state.orderComment, isInitialized])
|
||||
|
||||
// Функции для работы с корзиной
|
||||
const addItem = (item: Omit<CartItem, 'id' | 'selected' | 'favorite'>) => {
|
||||
const addItem = async (item: Omit<CartItem, 'id' | 'selected' | 'favorite'>) => {
|
||||
// Проверяем наличие товара на складе перед добавлением
|
||||
const existingItemIndex = state.items.findIndex(
|
||||
existingItem =>
|
||||
(existingItem.productId && existingItem.productId === item.productId) ||
|
||||
(existingItem.offerKey && existingItem.offerKey === item.offerKey)
|
||||
)
|
||||
|
||||
let totalQuantity = item.quantity;
|
||||
if (existingItemIndex >= 0) {
|
||||
const existingItem = state.items[existingItemIndex];
|
||||
totalQuantity = existingItem.quantity + item.quantity;
|
||||
}
|
||||
|
||||
// Проверяем наличие товара на складе
|
||||
const availableStock = parseStock(item.stock);
|
||||
if (availableStock > 0 && totalQuantity > availableStock) {
|
||||
const errorMessage = `Недостаточно товара в наличии. Доступно: ${availableStock} шт., запрошено: ${totalQuantity} шт.`;
|
||||
dispatch({ type: 'SET_ERROR', payload: errorMessage });
|
||||
return { success: false, error: errorMessage };
|
||||
}
|
||||
|
||||
// Если проверка прошла успешно, добавляем товар
|
||||
dispatch({ type: 'ADD_ITEM', payload: item })
|
||||
return { success: true }
|
||||
}
|
||||
|
||||
const removeItem = (id: string) => {
|
||||
@ -344,6 +382,17 @@ export const CartProvider: React.FC<{ children: React.ReactNode }> = ({ children
|
||||
}
|
||||
|
||||
const updateQuantity = (id: string, quantity: number) => {
|
||||
// Найдем товар для проверки наличия
|
||||
const item = state.items.find(item => item.id === id);
|
||||
if (item) {
|
||||
const availableStock = parseStock(item.stock);
|
||||
if (availableStock > 0 && quantity > availableStock) {
|
||||
// Показываем ошибку, но не изменяем количество
|
||||
dispatch({ type: 'SET_ERROR', payload: `Недостаточно товара в наличии. Доступно: ${availableStock} шт.` });
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
dispatch({ type: 'UPDATE_QUANTITY', payload: { id, quantity } })
|
||||
}
|
||||
|
||||
@ -388,6 +437,10 @@ export const CartProvider: React.FC<{ children: React.ReactNode }> = ({ children
|
||||
}
|
||||
}
|
||||
|
||||
const clearError = () => {
|
||||
dispatch({ type: 'SET_ERROR', payload: '' })
|
||||
}
|
||||
|
||||
const contextValue: CartContextType = {
|
||||
state,
|
||||
addItem,
|
||||
@ -401,7 +454,8 @@ export const CartProvider: React.FC<{ children: React.ReactNode }> = ({ children
|
||||
removeAll,
|
||||
removeSelected,
|
||||
updateDelivery,
|
||||
clearCart
|
||||
clearCart,
|
||||
clearError
|
||||
}
|
||||
|
||||
return (
|
||||
|
Reference in New Issue
Block a user