17.15 Handling Purchases And Updating UI
BurgerBuilder.js
src\containers\BurgerBuilder\BurgerBuilder.js
import React, { Component, Fragment } from "react";
import { connect } from "react-redux";
import axios from "../../axios-orders";
import BuildControls from "../../components/Burger/BuildControls/BuildControls";
import Burger from "../../components/Burger/Burger";
import OrderSummary from "../../components/Burger/OrderSummary/OrderSummary";
import Modal from "../../components/UI/Modal/Modal";
import Spinner from "../../components/UI/Spinner/Spinner";
import withErrorHandler from "../../hoc/withErrorHandler/withErrorHandler";
import * as actions from "../../store/actions/index";
class BurgerBuilder extends Component {
// constructor(props) {
// super(props);
// this.state = {...}
// }
state = {
purchasing: false,
};
componentDidMount() {
console.log(this.props);
this.props.onInitIngredients();
}
updatePurchaseState(ingredients) {
const sum = Object.keys(ingredients)
.map((igKey) => {
return ingredients[igKey];
})
.reduce((sum, el) => {
return sum + el;
}, 0);
return sum > 0;
}
purchaseHandler = () => {
this.setState({ purchasing: true });
};
purchaseCancelHandler = () => {
this.setState({ purchasing: false });
};
purchaseContinueHandler = () => {
this.props.onInitPurchase();
this.props.history.push("/checkout");
};
render() {
const disabledInfo = {
...this.props.ings,
};
for (let key in disabledInfo) {
disabledInfo[key] = disabledInfo[key] <= 0;
}
let orderSummary = null;
let burger = this.props.error ? (
<p>Ingredients can't be loaded!</p>
) : (
<Spinner />
);
if (this.props.ings) {
burger = (
<Fragment>
<Burger ingredients={this.props.ings} />
<BuildControls
ingredientAdded={this.props.onIgredientAdded}
ingredientRemoved={this.props.onIgredientRemoved}
disabled={disabledInfo}
purchasable={this.updatePurchaseState(this.props.ings)}
ordered={this.purchaseHandler}
price={this.props.price}
/>
</Fragment>
);
orderSummary = (
<OrderSummary
ingredients={this.props.ings}
purchaseCancelled={this.purchaseCancelHandler}
purchaseContinued={this.purchaseContinueHandler}
price={this.props.price}
/>
);
}
return (
<Fragment>
<Modal
show={this.state.purchasing}
modalClosed={this.purchaseCancelHandler}
>
{orderSummary}
</Modal>
{burger}
</Fragment>
);
}
}
const mapStateToProps = (state) => {
return {
ings: state.burgerBuilder.ingredients,
price: state.burgerBuilder.totalPrice,
error: state.burgerBuilder.error,
};
};
const mapDispatchToProps = (dispatch) => {
return {
onIgredientAdded: (ingName) => dispatch(actions.addIngredient(ingName)),
onIgredientRemoved: (ingName) =>
dispatch(actions.removeIngredient(ingName)),
onInitIngredients: () => dispatch(actions.initIngredients()),
onInitPurchase: () => dispatch(actions.purchaseInit()),
};
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(withErrorHandler(BurgerBuilder, axios));
Checkout.js
src\containers\Checkout\Checkout.js
import React, { Component } from "react";
import { connect } from "react-redux";
import { Redirect, Route } from "react-router-dom";
import CheckoutSummary from "../../components/Order/CheckoutSummary/CheckoutSummary";
import ContactData from "./ContactData/ContactData";
class Checkout extends Component {
checkoutCancelledHandler = () => {
this.props.history.goBack();
};
checkoutContinuedHandler = () => {
this.props.history.replace("/checkout/contact-data");
};
render() {
let summary = <Redirect to="/" />;
if (this.props.ings) {
const purchasedRedirect = this.props.purchased ? (
<Redirect to="/" />
) : null;
summary = (
<div>
{purchasedRedirect}
<CheckoutSummary
ingredients={this.props.ings}
checkoutCancelled={this.checkoutCancelledHandler}
checkoutContinued={this.checkoutContinuedHandler}
/>
<Route
path={this.props.match.path + "/contact-data"}
component={ContactData}
/>
</div>
);
}
return summary;
actionTypes.js
src\store\actions\actionTypes.js
export const ADD_INGREDIENT = "ADD_INGREDIENT";
export const REMOVE_INGREDIENT = "REMOVE_INGREDIENT";
export const SET_INGREDIENTS = "SET_INGREDIENTS";
export const FETCH_INGREDIENTS_FAILED = "FETCH_INGREDIENTS_FAILED";
export const PURCHASE_BURGER_START = "PURCHASE_BURGER_START";
export const PURCHASE_BURGER_SUCCESS = "PURCHASE_BURGER_SUCCESS";
export const PURCHASE_BURGER_FAIL = "PURCHASE_BURGER_FAIL";
export const PURCHASE_INIT = "PURCHASE_INIT";
actions/index.js
src\store\actions\index.js
export {
addIngredient,
initIngredients,
removeIngredient,
} from "./burgerBuilder";
export { purchaseBurger, purchaseInit } from "./order";
actions/order.js
src\store\actions\order.js
import axios from "../../axios-orders";
import * as actionTypes from "./actionTypes";
export const purchaseBurgerSuccess = (id, orderData) => {
return {
type: actionTypes.PURCHASE_BURGER_SUCCESS,
orderId: id,
orderData: orderData,
};
};
export const purchaseBurgerFail = (error) => {
return {
type: actionTypes.PURCHASE_BURGER_FAIL,
error: error,
};
};
export const purchaseBurgerStart = () => {
return {
type: actionTypes.PURCHASE_BURGER_START,
};
};
export const purchaseBurger = (orderData) => {
return (dispatch) => {
dispatch(purchaseBurgerStart());
axios
.post("/orders.json", orderData)
.then((response) => {
console.log(response.data);
dispatch(purchaseBurgerSuccess(response.data.name, orderData));
})
.catch((error) => {
dispatch(purchaseBurgerFail(error));
});
};
};
export const purchaseInit = () => {
return {
type: actionTypes.PURCHASE_INIT,
};
};