import { createAsyncThunk, createSlice, type PayloadAction, createSelector } from '@reduxjs/toolkit' import type { RootState, ThunkApi } from '../store' import type { Product } from '../types' import type { ResponseData } from '../network' interface AddBasketAction { id: number count: number } interface ShopState { products: Product[] loading: boolean error?: string } const initialState: ShopState = { products: [], loading: false, error: undefined, } export const shopSlice = createSlice({ name: 'shop', initialState, reducers: { // TODO: дописать action.payload.id addToBasket: (state, action: PayloadAction) => { state.products[0].count -= action.payload.count state.products[0].reserved += action.payload.count }, }, extraReducers: builder => { builder .addCase(fetchProducts.pending, state => { state.loading = true state.error = undefined }) .addCase(fetchProducts.fulfilled, (state, action) => { state.products = action.payload.success as Product[] state.loading = false }) .addCase(fetchProducts.rejected, (state, action) => { state.loading = false if (action.payload) { state.error = (action.payload as ResponseData).error } else { state.error = action.error.message } }) }, }) export const { addToBasket } = shopSlice.actions export const selectShopLoading = (state: RootState) => state.shop.loading export const selectShopError = (state: RootState) => state.shop.error export const selectProducts = (state: RootState) => state.shop.products export const selectProduct = (productId: number) => createSelector([selectProducts], products => { return products.find(product => product.id === productId) }) export const shopReducer = shopSlice.reducer export const fetchProducts = createAsyncThunk( 'products/fetchProducts', async (_, { fulfillWithValue, rejectWithValue, extra: networkApi }) => { try { const data = await networkApi.request('/shop/') return fulfillWithValue(data) } catch (error) { return rejectWithValue(error) } } )