Skip to content

Commit aacb900

Browse files
committed
Delete product actions
1 parent 6af29eb commit aacb900

File tree

13 files changed

+112
-36
lines changed

13 files changed

+112
-36
lines changed

server/db/db.json

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,6 @@
3838
"image_url": "/images/iphone-11-pro-max.jpg",
3939
"brand": "APPLE"
4040
},
41-
{
42-
"id": "iphone-11-pro",
43-
"name": "Iphone 11 Pro",
44-
"image_url": "/images/iphone-11-pro.jpg",
45-
"brand": "APPLE"
46-
},
4741
{
4842
"id": "iphone-11",
4943
"name": "Iphone 11",
@@ -86,12 +80,6 @@
8680
"image_url": "https://images.frandroid.com/wp-content/uploads/2020/10/iphone-12-max-frandroid-2020.png",
8781
"id": "5695c3c0-10b3-40d7-b39b-f8f807323dc4"
8882
},
89-
{
90-
"name": "Iphone 12 Pro Max",
91-
"brand": "APPLE",
92-
"image_url": "https://www.apple.com/newsroom/images/product/iphone/standard/Apple_announce-iphone12pro_10132020.jpg.landing-big_2x.jpg",
93-
"id": "4a36b6d8-e8e4-4f13-a19a-ca3c155e479a"
94-
},
9583
{
9684
"name": "Iphone 12 Pro Max",
9785
"brand": "APPLE",

src/@types/product.d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,6 @@ interface ProductForm {
1414
image_url: string;
1515
brand: string;
1616
}
17+
interface ProductUrlParams {
18+
id: string;
19+
}

src/components/Products/Product.actions.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,17 @@ export const createProductSuccess = (payload: Product) => ({
1515
payload,
1616
});
1717

18+
export const editProductSuccess = (payload: Product) => ({
19+
type: types.EDIT_PRODUCT,
20+
payload,
21+
});
22+
1823
export const updateProductSuccess = (payload: Product) => ({
1924
type: types.UPDATE_PRODUCT,
2025
payload,
2126
});
2227

23-
export const deleteProductSuccess = (payload: string) => ({
28+
export const deleteProductSuccess = () => ({
2429
type: types.DELETE_PRODUCT,
2530
});
2631

src/components/Products/Product.constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export const GET_PRODUCTS = 'views/Product/GET_PRODUCTS';
22
export const GET_PRODUCT = 'views/Product/GET_PRODUCT';
33
export const PRODUCT_ERROR = 'views/Product/PRODUCT_ERROR';
44
export const CREATE_PRODUCT = 'views/Product/CREATE_PRODUCT';
5+
export const EDIT_PRODUCT = 'views/Product/EDIT_PRODUCT';
56
export const UPDATE_PRODUCT = 'views/Product/UPDATE_PRODUCT';
67
export const DELETE_PRODUCT = 'views/Product/DELETE_PRODUCT';
78
export const CLEAR_PRODUCT = 'views/Product/CLEAR_PRODUCT';

src/components/Products/Product.reducers.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,14 @@ export const productReducer = (state = initialState, action) =>
2626
draft.products = [payload, ...state.products];
2727
draft.loading = false;
2828
break;
29-
case types.UPDATE_PRODUCT:
29+
case types.EDIT_PRODUCT:
30+
draft.loading = false;
3031
draft.product = payload;
32+
break;
33+
case types.UPDATE_PRODUCT:
34+
draft.products = state.products.map(x =>
35+
x.id === payload.id ? { ...payload } : x,
36+
);
3137
draft.loading = false;
3238
break;
3339
case types.DELETE_PRODUCT:

src/components/Products/Product.thunks.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,35 @@ export const createProduct = (formData: ProductForm) => async dispatch => {
5757
export const deleteProduct = (id: string) => async dispatch => {
5858
try {
5959
await axios.delete(`${URL.baseAPIUrl}/api/products/${id}`);
60-
dispatch(actions.deleteProductSuccess(id));
60+
dispatch(actions.deleteProductSuccess());
61+
dispatch(getProducts());
62+
} catch (error) {
63+
const payload = {
64+
msg: error.response?.statusText,
65+
status: error.response?.status,
66+
};
67+
dispatch(actions.productError(payload));
68+
}
69+
};
70+
71+
export const editProduct = (id: string) => async dispatch => {
72+
try {
73+
const res = await axios.get(`${URL.baseAPIUrl}/api/products/${id}`);
74+
const product = res.data as Product;
75+
dispatch(actions.editProductSuccess(product));
76+
} catch (error) {
77+
const payload = {
78+
msg: error.response?.statusText,
79+
status: error.response?.status,
80+
};
81+
dispatch(actions.productError(payload));
82+
}
83+
};
84+
85+
export const updateProduct = (product: Product) => async dispatch => {
86+
try {
87+
await axios.put(`${URL.baseAPIUrl}/api/products/${product.id}`, product);
88+
dispatch(actions.updateProductSuccess(product));
6189
} catch (error) {
6290
const payload = {
6391
msg: error.response?.statusText,

src/components/Products/ProductForm.tsx

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,63 @@
1-
import React from 'react';
1+
import React, { useEffect } from 'react';
22
import { connect, ConnectedProps } from 'react-redux';
33
import { Form, Input, Button, Select } from 'antd';
44
import { PhoneBrand } from 'src/constants/products';
5-
import { useHistory } from 'react-router-dom';
5+
import { useHistory, useParams } from 'react-router-dom';
66

7-
import { createProduct } from './Product.thunks';
7+
import { createProduct, editProduct, updateProduct } from './Product.thunks';
88
import { PATH } from 'src/constants/paths';
99
const { Option } = Select;
1010

1111
const mapStateToProps = (state: AppState) => ({
1212
products: state.products.products,
13+
product: state.products.product,
1314
});
14-
const mapDispatchToProps = { createProduct };
15+
const mapDispatchToProps = { createProduct, editProduct, updateProduct };
1516
const connector = connect(mapStateToProps, mapDispatchToProps);
16-
interface Props extends ConnectedProps<typeof connector> {}
17-
17+
interface Props extends ConnectedProps<typeof connector> {
18+
edit: boolean;
19+
}
1820
export const _ProductForm = (props: Props) => {
19-
const { createProduct } = props;
21+
const { createProduct, edit, product, updateProduct, editProduct } = props;
2022
const history = useHistory();
23+
const params: ProductUrlParams = useParams();
2124
const layout = {
2225
labelCol: { span: 4 },
2326
wrapperCol: { span: 16 },
2427
};
2528

2629
const onFinish = values => {
27-
createProduct(values);
30+
if (!edit) {
31+
createProduct(values);
32+
}
33+
2834
history.push(PATH.HOME);
2935
};
3036

3137
const allBrands = Object.values(PhoneBrand).filter(
3238
x => typeof x !== 'number',
3339
);
40+
const initialValues = { ...product };
41+
42+
useEffect(() => {
43+
if (edit) {
44+
const { id } = params;
45+
editProduct(id);
46+
}
47+
}, [edit, editProduct, params]);
3448

3549
return (
3650
<div className="main-body-section">
3751
<div id="main-contact" className="block">
3852
<div className="container">
3953
<div className="block-title">
40-
<h2>Create product</h2>
54+
<h2>{edit ? 'Create product' : 'Update product'}</h2>
4155
</div>
4256
<Form
4357
{...layout}
4458
name="product_form"
4559
className="product-form"
46-
initialValues={{ remember: true }}
60+
initialValues={{ ...initialValues, remember: true }}
4761
onFinish={onFinish}
4862
>
4963
<Form.Item

src/components/Products/ProductItem.tsx

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React, { useEffect } from 'react';
22
import { connect, ConnectedProps } from 'react-redux';
3-
import { getProduct } from './Product.thunks';
3+
import { getProduct, deleteProduct } from './Product.thunks';
44
import { useParams } from 'react-router-dom';
55
import { Row, Col, Image, Button } from 'antd';
66
import { NotFound } from 'src/components/Error/404';
@@ -10,26 +10,33 @@ import {
1010
DeleteOutlined,
1111
EditOutlined,
1212
} from '@ant-design/icons';
13+
import { PATH } from 'src/constants/paths';
1314

1415
const mapStateToProps = (state: AppState) => ({
1516
product: state.products.product,
1617
});
1718
const mapDispatchToProps = {
1819
getProduct,
20+
deleteProduct,
1921
};
20-
interface Params {
21-
id: string;
22-
}
22+
2323
const connector = connect(mapStateToProps, mapDispatchToProps);
2424
interface Props extends ConnectedProps<typeof connector> {}
2525

2626
export const _ProductItem = (props: Props) => {
27-
const { product, getProduct } = props;
27+
const { product, getProduct, deleteProduct } = props;
2828

2929
const history = useHistory();
3030
const goBack = () => {
3131
history.goBack();
3232
};
33+
const goEdit = () => {
34+
history.push(PATH.PRODUCT_EDIT);
35+
};
36+
const onDelete = () => {
37+
deleteProduct(product.id);
38+
history.push(PATH.HOME);
39+
};
3340

3441
let productComponent = item => {
3542
if (item) {
@@ -57,10 +64,10 @@ export const _ProductItem = (props: Props) => {
5764
</Button>
5865
</Col>
5966
<Col span={6} offset={0}>
60-
<Button type="primary">
67+
<Button type="primary" onClick={goEdit}>
6168
<EditOutlined /> Edit
6269
</Button>{' '}
63-
<Button danger>
70+
<Button danger onClick={onDelete}>
6471
<DeleteOutlined /> Delete
6572
</Button>
6673
</Col>
@@ -73,7 +80,7 @@ export const _ProductItem = (props: Props) => {
7380
}
7481
};
7582

76-
const params: Params = useParams();
83+
const params: ProductUrlParams = useParams();
7784
useEffect(() => {
7885
const { id } = params;
7986
getProduct(id);

src/components/Products/ProductList.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ export const _ProductList = (props: Props) => {
7777
useEffect(() => {
7878
getProducts();
7979
}, [getProducts]);
80+
8081
products.map((product: Product, index: number) => {
8182
if (index === 0) {
8283
data = [

src/constants/paths.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,7 @@ export const PATH = {
1010
FEATURE2: '/feature2',
1111
PROFILE: '/profile',
1212
PRODUCTS: '/products',
13+
PRODUCT_SHOW: '/products/:id',
1314
PRODUCT_NEW: '/products/new',
15+
PRODUCT_EDIT: '/products/:id/edit',
1416
};

0 commit comments

Comments
 (0)