diff --git a/src/entities/ProductEntity/ui/ProductEntity/ProductEntity.tsx b/src/entities/ProductEntity/ui/ProductEntity/ProductEntity.tsx index 59cdbb8d..321033e9 100644 --- a/src/entities/ProductEntity/ui/ProductEntity/ProductEntity.tsx +++ b/src/entities/ProductEntity/ui/ProductEntity/ProductEntity.tsx @@ -18,9 +18,9 @@ export const ProductEntity: FC = product => { return (
- {product.images.length > 0 && ( + {(product.images.length > 0 && ( {'product'} - )} + )) || <>}
{product.id} diff --git a/src/features/CartEdit/model/services/putRenewProductAmount.ts b/src/features/CartEdit/model/services/putRenewProductAmount.ts new file mode 100644 index 00000000..89bf6645 --- /dev/null +++ b/src/features/CartEdit/model/services/putRenewProductAmount.ts @@ -0,0 +1,30 @@ +import { createAsyncThunk } from '@reduxjs/toolkit' + +import { ThunkConfig } from '@/app/providers/StoreProvider/config/StateSchema' +import { apiErrorIdentify } from '@/shared/api/apiErrorIdentify' +import { ApiError, ApiErrorTypes, ApiRoutes } from '@/shared/api/types' +import { IProductCartList } from '@/shared/model/types/ProductCartListModel' + +import { IRenewProductAmountRequest } from '../types' + +export const putRenewProductAmount = createAsyncThunk< + IProductCartList, + IRenewProductAmountRequest, + ThunkConfig +>('cart-renew-product-amount', async (request, thunkAPI) => { + const { rejectWithValue, extra } = thunkAPI + try { + const { data } = await extra.api.put( + `api/${ApiRoutes.RENEW_PRODUCT_AMOUNT}${request.cart}/`, + { + product: request.product, + cart: request.cart, + amount: (request.amount === 0 && 1) || request.amount + }, + { withCredentials: true } + ) + return data + } catch (error) { + return rejectWithValue(apiErrorIdentify(error, ApiErrorTypes.DATA_EMPTY_ERROR)) + } +}) diff --git a/src/features/CartEdit/model/slice/productAmountSlice.ts b/src/features/CartEdit/model/slice/productAmountSlice.ts index 62ff426b..898fac85 100644 --- a/src/features/CartEdit/model/slice/productAmountSlice.ts +++ b/src/features/CartEdit/model/slice/productAmountSlice.ts @@ -4,6 +4,7 @@ import { rejectedPayloadHandle } from '@/shared/api/rejectedPayloadHandle' import { putDecreaseProductAmount } from '../services/putDecreaseProductAmount' import { putIncreaseProductAmount } from '../services/putIncreaseProductAmount' +import { putRenewProductAmount } from '../services/putRenewProductAmount' import { IProductAmountStateSchema } from '../types' const initialState: IProductAmountStateSchema = { @@ -25,7 +26,8 @@ const initialState: IProductAmountStateSchema = { full_price: 0, full_weight: 0 }, - isDecreaseSuccessful: false + isDecreaseSuccessful: false, + isRenewProductAmountSuccessful: false } export const productAmountSlice = createSlice({ @@ -40,7 +42,6 @@ export const productAmountSlice = createSlice({ builder .addCase(putIncreaseProductAmount.pending, state => { state.isIncreaseSuccessful = false - state.isDecreaseSuccessful = false }) .addCase(putIncreaseProductAmount.fulfilled, (state, { payload }) => { state.isIncreaseSuccessful = true @@ -62,6 +63,21 @@ export const productAmountSlice = createSlice({ state.isDecreaseSuccessful = false state.error = rejectedPayloadHandle(payload) }) + + .addCase(putRenewProductAmount.pending, state => { + state.isRenewProductAmountSuccessful = false + }) + .addCase(putRenewProductAmount.fulfilled, (state, { payload }) => { + state.isRenewProductAmountSuccessful = true + state.productList = { + ...state.productList, + amount: payload.amount + } + }) + .addCase(putRenewProductAmount.rejected, (state, { payload }) => { + state.isRenewProductAmountSuccessful = false + state.error = rejectedPayloadHandle(payload) + }) } }) diff --git a/src/features/CartEdit/model/types.ts b/src/features/CartEdit/model/types.ts index 55789200..0ae61009 100644 --- a/src/features/CartEdit/model/types.ts +++ b/src/features/CartEdit/model/types.ts @@ -3,6 +3,13 @@ import { IProductCartList } from '@/shared/model/types/ProductCartListModel' export interface IProductAmountStateSchema { isIncreaseSuccessful: boolean isDecreaseSuccessful: boolean + isRenewProductAmountSuccessful: boolean productList: IProductCartList error?: string | string[] } + +export interface IRenewProductAmountRequest { + product: number + cart: number + amount: number +} diff --git a/src/features/CartEdit/ui/CartEdit/CartEdit.tsx b/src/features/CartEdit/ui/CartEdit/CartEdit.tsx index df0f7263..c278bd74 100644 --- a/src/features/CartEdit/ui/CartEdit/CartEdit.tsx +++ b/src/features/CartEdit/ui/CartEdit/CartEdit.tsx @@ -13,6 +13,7 @@ import Subheading from '@/shared/ui/Subheading/Subheading' import { getProductListSelector } from '../../model/selectors' import { putDecreaseProductAmount } from '../../model/services/putDecreaseProductAmount' import { putIncreaseProductAmount } from '../../model/services/putIncreaseProductAmount' +import { putRenewProductAmount } from '../../model/services/putRenewProductAmount' import { productAmountActions } from '../../model/slice/productAmountSlice' import styles from './CartEdit.module.scss' @@ -32,10 +33,13 @@ export type TCartEditProps = { // eslint-disable-next-line @typescript-eslint/no-unused-vars export const CartEdit: React.FC = ({ cartId, productList }: TCartEditProps) => { const [needToOpenContextMenuButtonDots, setNeedToOpen] = useState(false) + const EMPTY = '' const dispatch = useAppDispatch() const productListState: IProductCartList = useSelector(getProductListSelector) + const [value, setValue] = useState(EMPTY) + function deleteProductHandler() { setNeedToOpen(false) // removeProduct(product.id) переделать на вызов action https://github.com/Studio-Yandex-Practicum/maxboom_frontend/issues/319 @@ -50,17 +54,36 @@ export const CartEdit: React.FC = ({ cartId, productList }: TCar function decreaseAmountHandler() { dispatch(putDecreaseProductAmount(productListState.product.id)) - // tbd https://github.com/Studio-Yandex-Practicum/maxboom_frontend/issues/318 } - function setAmountHandler() { - //tbd https://github.com/Studio-Yandex-Practicum/maxboom_frontend/issues/316 + function setAmountHandler(e: React.ChangeEvent) { + const newValue = Number(e.target.value) + + if (Number.isInteger(newValue) && newValue > 0) { + dispatch( + putRenewProductAmount({ + product: productList.product.id, + cart: cartId, + amount: newValue + }) + ) + } else { + setValue(EMPTY) + } } useEffect(() => { dispatch(productAmountActions.setProductList(productList)) }, [productList]) + useEffect(() => { + if (productListState.amount === 0) { + setValue(EMPTY) + } else { + setValue(String(productListState.amount)) + } + }, [productListState.amount]) + return ( <>
@@ -88,7 +111,7 @@ export const CartEdit: React.FC = ({ cartId, productList }: TCar