10.06 Displaying Spinner While Sending Request
Grab the Spinner
projects.lukehaas.me: CSS LoadersNew Spinner.js
Spinner.js
import React from "react";
import classes from "./Spinner.module.css";
const spinner = () => <div className={classes.Loader}>Loading...</div>;
export default spinner;
New Spinner.module.css
caution
Change all .loader
s to .Loader
s. And don't forget to add the module
keyword to the filename.
Spinner.module.css
.Loader,
.Loader:before,
.Loader:after {
border-radius: 50%;
}
.Loader {
color: #521751;
font-size: 11px;
text-indent: -99999em;
margin: 55px auto;
position: relative;
width: 10em;
height: 10em;
box-shadow: inset 0 0 0 1em;
-webkit-transform: translateZ(0);
-ms-transform: translateZ(0);
transform: translateZ(0);
}
.Loader:before,
.Loader:after {
position: absolute;
content: "";
}
.Loader:before {
width: 5.2em;
height: 10.2em;
background: #fff;
border-radius: 10.2em 0 0 10.2em;
top: -0.1em;
left: -0.1em;
-webkit-transform-origin: 5.1em 5.1em;
transform-origin: 5.1em 5.1em;
-webkit-animation: load2 2s infinite ease 1.5s;
animation: load2 2s infinite ease 1.5s;
}
.Loader:after {
width: 5.2em;
height: 10.2em;
background: #fff;
border-radius: 0 10.2em 10.2em 0;
top: -0.1em;
left: 4.9em;
-webkit-transform-origin: 0.1em 5.1em;
transform-origin: 0.1em 5.1em;
-webkit-animation: load2 2s infinite ease;
animation: load2 2s infinite ease;
}
@-webkit-keyframes load2 {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@keyframes load2 {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
BurgerBuilder.js
BurgerBuilder.js
import React, { Component, Fragment } from "react";
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";
const INGREDIENT_PRICES = {
salad: 0.5,
cheese: 0.4,
meat: 1.3,
bacon: 0.7,
};
class BurgerBuilder extends Component {
// constructor(props) {
// super(props);
// this.state = {...}
// }
state = {
ingredients: {
salad: 0,
bacon: 0,
cheese: 0,
meat: 0,
},
totalPrice: 4,
purchasable: false,
purchasing: false,
loading: false,
};
updatePurchaseState(ingredients) {
const sum = Object.keys(ingredients)
.map((igKey) => {
return ingredients[igKey];
})
.reduce((sum, el) => {
return sum + el;
}, 0);
this.setState({ purchasable: sum > 0 });
}
addIngredientHandler = (type) => {
const oldCount = this.state.ingredients[type];
const updateCount = oldCount + 1;
const updatedIngredients = {
...this.state.ingredients,
};
updatedIngredients[type] = updateCount;
const priceAddition = INGREDIENT_PRICES[type];
const oldPrice = this.state.totalPrice;
const newPrice = oldPrice + priceAddition;
this.setState({ totalPrice: newPrice, ingredients: updatedIngredients });
this.updatePurchaseState(updatedIngredients);
};
removeIngredientHandler = (type) => {
const oldCount = this.state.ingredients[type];
if (oldCount <= 0) {
return;
}
const updateCount = oldCount - 1;
const updatedIngredients = {
...this.state.ingredients,
};
updatedIngredients[type] = updateCount;
const priceDeduction = INGREDIENT_PRICES[type];
const oldPrice = this.state.totalPrice;
const newPrice = oldPrice - priceDeduction;
this.setState({ totalPrice: newPrice, ingredients: updatedIngredients });
this.updatePurchaseState(updatedIngredients);
};
purchaseHandler = () => {
this.setState({ purchasing: true });
};
purchaseCancelHandler = () => {
this.setState({ purchasing: false });
};
purchaseContinueHandler = () => {
// alert("You continue!");
this.setState({ loading: true });
const order = {
ingredients: this.state.ingredients,
price: this.state.totalPrice,
customer: {
name: "Pash Pa",
address: {
street: "Teststreet 1",
zipCode: "34234",
country: "Russia",
},
email: "test@test.com",
},
deliveryMethod: "fastest",
};
axios
.post("/orders.json", order)
.then((response) => {
this.setState({ loading: false, purchasing: false });
})
.catch((error) => {
this.setState({ loading: false, purchasing: false });
});
};
render() {
const disabledInfo = {
...this.state.ingredients,
};
for (let key in disabledInfo) {
disabledInfo[key] = disabledInfo[key] <= 0;
}
let orderSummary = (
<OrderSummary
ingredients={this.state.ingredients}
purchaseCancelled={this.purchaseCancelHandler}
purchaseContinued={this.purchaseContinueHandler}
price={this.state.totalPrice}
/>
);
if (this.state.loading) {
orderSummary = <Spinner />;
}
return (
<Fragment>
<Modal
show={this.state.purchasing}
modalClosed={this.purchaseCancelHandler}
>
{orderSummary}
</Modal>
<Burger ingredients={this.state.ingredients} />
<BuildControls
ingredientAdded={this.addIngredientHandler}
ingredientRemoved={this.removeIngredientHandler}
disabled={disabledInfo}
purchasable={this.state.purchasable}
ordered={this.purchaseHandler}
price={this.state.totalPrice}
/>
</Fragment>
);
}
}
export default BurgerBuilder;
Modal.js
Modal.js
import React, { Component, Fragment } from "react";
import Backdrop from "../Backdrop/Backdrop";
import classes from "./Modal.module.css";
class Modal extends Component {
shouldComponentUpdate(nextProps, nextState) {
return (
nextProps.show !== this.props.show ||
nextProps.children !== this.props.children
);
}
componentWillUpdate() {
console.log("[Modal] WillUpdate");
}
render() {
return (
<Fragment>
<Backdrop show={this.props.show} clicked={this.props.modalClosed} />
<div
className={classes.Modal}
style={{
transform: this.props.show ? "translateY(0)" : "translateY(-100vh)",
opacity: this.props.show ? "1" : "0",
}}
>
{this.props.children}
</div>
</Fragment>
);
}
}
export default Modal;