Commit 124b653c authored by Denis Sedura's avatar Denis Sedura

[RNA-761] Fix after rebase

parent 16869631
......@@ -3,202 +3,239 @@ import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { denormalize } from 'normalizr'
import { createSelector } from 'reselect'
import { isEqual } from 'lodash'
import { debounce } from 'lodash'
import { Router } from 'tipsi-router'
import { updateStoreCartProductCount } from 'tipsi_api/actions'
import {
entitiesSelector,
paginationsSelector,
relationsSelector,
metaSelector,
createStoreSelector,
createStoreCartOrderSelector,
createInventorySelector,
userSelector,
createStoreCartSelector,
} from 'tipsi_api/selectors'
import { Schemas } from 'tipsi_api/middleware'
import {
loadStoreCart,
addInventoryToCart,
increaseInventoryCount,
decreaseInventoryCount,
} from '../../actions/storeCarts'
import { createCartStatusSelector } from '../../selectors'
import { loadStoreCart } from '../../actions'
export function enhanceAddToCartView(ComposedComponent) {
class Wrapper extends Component {
static propTypes = {
user: PropTypes.object,
inventoryType: PropTypes.string,
// props
storeId: PropTypes.number.isRequired,
inventoryId: PropTypes.number.isRequired,
store: PropTypes.object,
inventoryType: PropTypes.string, // eslint-disable-line react/no-unused-prop-types
// map state to props
store: PropTypes.object, // eslint-disable-line react/no-unused-prop-types
inventory: PropTypes.object,
user: PropTypes.object,
order: PropTypes.object,
isLoadingStoreCart: PropTypes.bool.isRequired,
orderProduct: PropTypes.object,
isUpdatingInventory: PropTypes.bool.isRequired,
// map dispatch to props
loadStoreCart: PropTypes.func.isRequired,
addInventoryToCart: PropTypes.func.isRequired,
increaseInventoryCount: PropTypes.func.isRequired,
decreaseInventoryCount: PropTypes.func.isRequired,
isLoadingCart: PropTypes.bool,
isAddingToCart: PropTypes.bool,
isIncreasingCount: PropTypes.bool,
isDecreasingCount: PropTypes.bool,
isRemovingFromCart: PropTypes.bool,
updateStoreCartProductCount: PropTypes.func.isRequired,
}
static defaultProps = {
user: undefined,
// props
inventoryType: 'other',
// map state to props
store: undefined,
inventory: undefined,
user: undefined,
order: undefined,
orderProduct: undefined,
isLoadingCart: false,
isAddingToCart: false,
isIncreasingCount: false,
isDecreasingCount: false,
isRemovingFromCart: false,
}
shouldComponentUpdate(nextProps) {
return !isEqual(this.props, nextProps)
}
state = this.getCurrentState()
loadStoreCart = () => {
const { storeId, inventoryId, isLoadingCart } = this.props
if (!isLoadingCart) {
this.props.loadStoreCart({ storeId, inventoryId })
}
}
shouldComponentUpdate(nextProps, nextState) {
const { orderProduct, user } = this.props
const userHasLoggedIn = !user && nextProps.user
const totalCountHasChanged = this.getTotalCount() !== this.getTotalCount(nextProps)
const orderProductHasBeenAdded = !orderProduct && nextProps.orderProduct
const orderProductHasBeenRemoved = orderProduct && !nextProps.orderProduct
const orderProductCountHasChanged = orderProduct && nextProps.orderProduct && (
this.getCount() !== this.getCount(nextProps)
)
addToCart = () => {
const { storeId, inventoryId, isAddingToCart, user } = this.props
const localOrderProductCountHasChanged = (
this.state.count !== nextState.count
)
if (!user) {
Router.showModal(null, Router.routes.login, {
config: { navigationBar: { visible: false } },
})
return
const shouldUpdate = (
userHasLoggedIn ||
totalCountHasChanged ||
orderProductHasBeenAdded ||
orderProductHasBeenRemoved ||
orderProductCountHasChanged ||
localOrderProductCountHasChanged ||
this.props.isUpdatingInventory !== nextProps.isUpdatingInventory
)
return !!shouldUpdate
}
if (!isAddingToCart) {
this.props.addInventoryToCart({ storeId, inventoryId })
getTotalCount(nextProps) {
const { order = {} } = nextProps || this.props
return order.total_count || 0
}
getCount(nextProps) {
const { orderProduct = {} } = nextProps || this.props
return orderProduct.count || 0
}
increaseCount = () => {
const { storeId, inventoryId, isIncreasingCount } = this.props
if (!isIncreasingCount) {
this.props.increaseInventoryCount({ storeId, inventoryId })
getCurrentState(nextProps) {
const props = nextProps || this.props
return {
totalCount: this.getTotalCount(props),
count: this.getCount(props),
}
}
decreaseCount = () => {
const { storeId, inventoryId, isDecreasingCount, isRemovingFromCart } = this.props
const loading = isDecreasingCount || isRemovingFromCart
if (!loading) {
this.props.decreaseInventoryCount({ storeId, inventoryId })
loadStoreCart = () => {
if (!this.props.isLoadingStoreCart && !this.props.order && this.props.user) {
this.props.loadStoreCart(this.props.storeId)
}
}
countForOrder = (order) => {
let count = 0
if (order && order.total_count) {
count = order.total_count
isLoading = (nextProps) => {
const props = nextProps || this.props
return (props.isLoadingStoreCart || props.isUpdatingInventory)
}
return count
updateStoreCartProduct = (totalCount, count) => {
this.setState({ totalCount, count })
if (this.props.orderProduct) {
return this.debounceUpdateStoreCartProduct(count)
}
countForOrderProduct = (orderProduct) => {
let count = 0
if (orderProduct && orderProduct.count) {
count = orderProduct.count
return this.props.updateStoreCartProductCount(
this.props.storeId,
[{ inventory_id: this.props.inventoryId, count }]
)
}
return count
debounceUpdateStoreCartProduct = debounce((count) => {
// No need send update if count does not change
if (count === this.getCount()) {
return
}
this.props.updateStoreCartProductCount(
this.props.storeId,
[{ inventory_id: this.props.inventoryId, count }]
)
}, 1000)
handleAddToCartButtonOnPress = () => {
const { isLoadingCart, isAddingToCart } = this.props
const loading = isLoadingCart || isAddingToCart
if (!loading) {
this.addToCart()
// Should not update inventory if is in loading state
if (this.isLoading()) {
return
}
// Should not update inventory for guest access
if (!this.props.user) {
Router.showModal(null, Router.routes.login, {
config: { navigationBar: { visible: false } },
})
return
}
this.updateStoreCartProduct(this.state.totalCount + 1, this.state.count + 1)
}
handleCartButtonOnPress = () => {
// const { order: { id: orderId }, navigation } = this.props
// const navigatorApp = navigation.getNavigator('app')
// navigatorApp.push('Cart', { orderId })
console.log('Show Cart')
// this.props.navigation.getNavigator('app').push('Cart', { storeId: this.props.storeId })
console.log('Go to Cart')
}
handleRemoveButtonOnPress = () => {
this.decreaseCount()
const { count } = this.state
// Should not update inventory if is in loading state
if (this.isLoading()) {
return
}
// Should not update inventory if current count is zero
if (count === 0) {
return
}
this.updateStoreCartProduct(this.state.totalCount - 1, count - 1)
}
handleAddButtonOnPress = () => {
this.increaseCount()
const { inventory = { in_stock: 0 } } = this.props
const { count } = this.state
// Should not update inventory if is in loading state
if (this.isLoading()) {
return
}
// Should not update inventory if is no more items available
if (count >= inventory.in_stock) {
throw new Error('Sorry, there are no more items in stock')
}
this.updateStoreCartProduct(this.state.totalCount + 1, count + 1)
}
render() {
return (
<ComposedComponent
{...this.props}
addToCart={this.addToCart}
{...this.state}
loadStoreCart={this.loadStoreCart}
countForOrder={this.countForOrder}
countForOrderProduct={this.countForOrderProduct}
isLoading={this.isLoading}
handleAddToCartButtonOnPress={this.handleAddToCartButtonOnPress}
handleCartButtonOnPress={this.handleCartButtonOnPress}
handleAddButtonOnPress={this.handleAddButtonOnPress}
handleRemoveButtonOnPress={this.handleRemoveButtonOnPress}
handleAddToCartButtonOnPress={this.handleAddToCartButtonOnPress}
handleAddButtonOnPress={this.handleAddButtonOnPress}
/>
)
}
}
const getStoreId = (state, props) => props.storeId
const inventoryIdSelector = (state, props) => props.inventoryId
const createStoreCartSelector = createSelector(
createStoreCartOrderSelector(getStoreId),
paginationsSelector,
const mapStateToProps = createSelector(
(state, props) => ({ props }),
createStoreSelector((state, props) => props.storeId),
createInventorySelector((state, props) => props.inventoryId),
userSelector,
createStoreCartSelector((state, props) => props.storeId),
entitiesSelector,
(order = {}, paginations, entities) => {
const { ids = [] } = paginations.orderProducts[order.id] || {}
const orderProducts = denormalize(ids, Schemas.ORDER_PRODUCT_ARRAY, entities)
return { order, orderProducts }
relationsSelector,
metaSelector,
({ props }, { store }, { inventory }, { user }, storeCart, entities, relations, meta) => {
const { inventoryId } = props
let orderProduct
const orderProductId = relations.storeCartItems.inventory[inventoryId]
if (orderProductId && storeCart.orderProductIds.includes(orderProductId)) {
orderProduct = denormalize(orderProductId, Schemas.ORDER_PRODUCT, entities)
}
)
const createStoreInventoryCartSelector = createSelector(
createStoreCartSelector,
createInventorySelector(inventoryIdSelector),
inventoryIdSelector,
({ order, orderProducts }, { inventory }, inventoryId) => ({
order,
inventory,
orderProduct: orderProducts.find(product => product.inventory.id === inventoryId),
})
)
const isUpdatingInventory = meta.storeCartInventory.fetchStatus[inventoryId] || false
const mapStateToProps = createSelector(
createStoreSelector(getStoreId),
createCartStatusSelector(getStoreId, inventoryIdSelector),
createStoreInventoryCartSelector,
userSelector,
({ store }, status, { order, inventory, orderProduct }, { user }) => ({
return {
store,
order,
orderProduct,
inventory,
user,
...status,
})
order: storeCart.order,
isLoadingStoreCart: storeCart.isLoading,
orderProduct,
isUpdatingInventory,
}
}
)
return connect(mapStateToProps, {
loadStoreCart,
addInventoryToCart,
increaseInventoryCount,
decreaseInventoryCount,
})(Wrapper)
return connect(mapStateToProps, { loadStoreCart, updateStoreCartProductCount })(Wrapper)
}
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { createSelector } from 'reselect'
import { Router } from 'tipsi-router'
import {
loginEmail,
loginTwitter,
loginFacebook,
loadUserProfile,
register,
linkSocialAccount,
} from 'tipsi_api/actions'
import { authSelector, userSelector } from 'tipsi_api/selectors'
function enhanceLogin(ComposedComponent) {
class Wrapper extends Component {
static propTypes = {
loginEmail: PropTypes.func.isRequired,
loginTwitter: PropTypes.func.isRequired,
loginFacebook: PropTypes.func.isRequired,
loadUserProfile: PropTypes.func.isRequired,
navigation: PropTypes.object.isRequired,
isLoading: PropTypes.bool.isRequired,
isTwitterLoading: PropTypes.bool.isRequired,
isFacebookLoading: PropTypes.bool.isRequired,
route: PropTypes.object.isRequired,
user: PropTypes.object,
}
static defaultProps = {
user: null,
}
state = {
username: '',
password: '',
}
componentWillReceiveProps(nextProps) {
const { route, user } = nextProps
if (!this.props.user && user && user.username) {
Router.dismissModal()
if (route.params.redirect) {
// navigation.getNavigator('app').push(route.params.redirect, { user })
console.log('Redirect to');
}
}
}
handleDismissLogin = () => {
export default function enhanceLogin(ComposedComponent) {
return class Wrapper extends Component {
dismissModal = () => (
Router.dismissModal()
}
handleChangeUsername = (username) => {
this.setState({ username })
}
handleChangePassword = (password) => {
this.setState({ password: password.replace(/\s+/g, '') })
}
)
render() {
return (
<ComposedComponent
{...this.props}
{...this.state}
handleDismissLogin={this.handleDismissLogin}
handleChangeUsername={this.handleChangeUsername}
handleChangePassword={this.handleChangePassword}
/>
<ComposedComponent {...this.props} dismissModal={this.dismissModal} />
)
}
}
const mapStateToProps = createSelector(
[authSelector, userSelector],
({ isLoading, isTwitterLoading, isFacebookLoading }, user) => ({
...user,
isLoading,
isTwitterLoading,
isFacebookLoading,
})
)
const mapDispatchToProps = {
loginEmail,
loginTwitter,
loginFacebook,
loadUserProfile,
register,
linkSocialAccount,
}
return connect(mapStateToProps, mapDispatchToProps)(Wrapper)
}
export default enhanceLogin
......@@ -27,6 +27,7 @@
"tipsi-stripe": "4.0.0"
},
"peerDependencies": {
"redux-form": "^7.1.2",
"normalizr": "^3.2.2",
"@expo/ex-navigation": "3.1.0",
"react-native-firebase-analytics": "3.0.2",
......
import { createStore, applyMiddleware, combineReducers, compose } from 'redux'
import { AsyncStorage, Platform } from 'react-native'
import { persistStore, autoRehydrate } from 'redux-persist'
import { reducer as form } from 'redux-form'
import createFilter from 'redux-persist-transform-filter'
import thunk from 'redux-thunk'
import uuidv4 from 'uuid/v4'
......@@ -27,7 +28,7 @@ const tipsiMiddleware = createApiMiddleware({
}),
})
const middleware = [tipsiMiddleware, thunk, analyticsMiddleware]//, logger]
const middleware = [tipsiMiddleware, thunk, analyticsMiddleware] // ,logger]
// if (__DEV__) {
// middleware.push(require('redux-logger')())
......@@ -47,6 +48,7 @@ const combinedReducers = combineReducers({
meta,
paginations,
navigation,
form,
...reducers,
})
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment