-
Notifications
You must be signed in to change notification settings - Fork 51
/
ProductQuantityStepper.js
113 lines (102 loc) · 2.69 KB
/
ProductQuantityStepper.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { NumericStepper, withToast } from 'vtex.styleguide'
import { debounce } from 'lodash'
import { injectIntl, intlShape } from 'react-intl'
import { compose, graphql } from 'react-apollo'
import gql from 'graphql-tag'
import { productShape } from '../utils/propTypes'
export const UPDATE_ITEMS_MUTATION = gql`
mutation updateItems($items: [MinicartItem]) {
updateItems(items: $items) @client
}
`
class ProductQuantityStepper extends Component {
static propTypes = {
product: productShape.isRequired,
onUpdateItemsState: PropTypes.func.isRequired,
showToast: PropTypes.func,
intl: intlShape,
minicartItems: PropTypes.array,
updateItems: PropTypes.func.isRequired,
}
state = {
quantity: this.props.product.quantity,
canIncrease: true,
}
componentDidUpdate = prevProps => {
const {
product: { quantity: prevQuantity },
} = prevProps
const {
product: { quantity },
showToast,
intl,
} = this.props
if (prevQuantity !== quantity) {
const canIncrease = quantity === this.state.quantity
this.setState({ quantity, canIncrease })
if (!canIncrease) {
showToast({
message: intl.formatMessage({
id: 'editor.productSummary.quantity-error',
}),
})
}
}
}
handleOnChange = e => {
e.stopPropagation()
e.preventDefault()
this.props.onUpdateItemsState(true)
this.setState({ quantity: e.value }, () =>
this.debouncedUpdate(this.state.quantity)
)
}
updateItemQuantity = async quantity => {
const { product, updateItems } = this.props
this.setState({ canIncrease: true })
const {
sku: { itemId: id },
seller = {},
cartIndex,
} = product
try {
await updateItems([
{
id,
quantity,
seller: seller.sellerId,
index: cartIndex,
},
])
} catch (err) {
// gone wrong, rollback to old quantity value
console.error(err)
}
this.props.onUpdateItemsState(false)
}
debouncedUpdate = debounce(this.updateItemQuantity, 1000)
render() {
return (
<NumericStepper
lean
size="small"
value={this.state.quantity}
minValue={1}
maxValue={this.state.canIncrease ? undefined : this.state.quantity}
onChange={this.handleOnChange}
/>
)
}
}
const withUpdateItemsMutation = graphql(UPDATE_ITEMS_MUTATION, {
props: ({ mutate }) => ({
updateItems: items => mutate({ variables: { items } }),
}),
})
export default compose(
injectIntl,
withToast,
withUpdateItemsMutation
)(ProductQuantityStepper)