Compare commits

...

8 Commits

9 changed files with 212 additions and 33 deletions

44
package-lock.json generated
View File

@ -368,6 +368,14 @@
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz",
"integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA=="
},
"axios": {
"version": "0.21.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz",
"integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==",
"requires": {
"follow-redirects": "^1.10.0"
}
},
"axobject-query": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-0.1.0.tgz",
@ -3276,9 +3284,9 @@
}
},
"esprima": {
"version": "2.7.3",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
"integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE="
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
},
"esquery": {
"version": "1.3.1",
@ -4400,9 +4408,9 @@
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"ini": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
},
"inquirer": {
"version": "3.3.0",
@ -5201,12 +5209,12 @@
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
},
"js-yaml": {
"version": "3.7.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.7.0.tgz",
"integrity": "sha1-XJZ93YN6m/3KXy3oQlOr6KHAO4A=",
"version": "3.14.1",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
"integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
"requires": {
"argparse": "^1.0.7",
"esprima": "^2.6.0"
"esprima": "^4.0.0"
}
},
"jsbn": {
@ -9025,6 +9033,22 @@
"mkdirp": "~0.5.1",
"sax": "~1.2.1",
"whet.extend": "~0.9.9"
},
"dependencies": {
"esprima": {
"version": "2.7.3",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
"integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE="
},
"js-yaml": {
"version": "3.7.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.7.0.tgz",
"integrity": "sha1-XJZ93YN6m/3KXy3oQlOr6KHAO4A=",
"requires": {
"argparse": "^1.0.7",
"esprima": "^2.6.0"
}
}
}
},
"sw-precache": {

View File

@ -4,6 +4,7 @@
"private": true,
"dependencies": {
"autoprefixer": "7.1.6",
"axios": "^0.21.1",
"babel-core": "6.26.0",
"babel-eslint": "7.2.3",
"babel-jest": "20.0.3",

View File

@ -8,7 +8,7 @@ class App extends Component {
return (
<div>
<Layout>
<BurgerBuilder />
<BurgerBuilder />
</Layout>
</div>
);

7
src/axios-orders.js Normal file
View File

@ -0,0 +1,7 @@
import axios from 'axios';
const instance = axios.create({
baseURL: 'https://react-my-burger-e4645.firebaseio.com/'
});
export default instance;

View File

@ -7,7 +7,7 @@ import classes from './Modal.css';
class Modal extends Component {
shouldComponentUpdate(nextProps, nextState){
return nextProps.show !== this.props.show;
return nextProps.show !== this.props.show || nextProps.children !== this.props.children;
}
render() {

View File

@ -0,0 +1,41 @@
.Loader,
.Loader:after {
border-radius: 50%;
width: 10em;
height: 10em;
}
.Loader {
margin: 60px auto;
font-size: 10px;
position: relative;
text-indent: -9999em;
border-top: 1.1em solid rgba(195,8,247, 0.2);
border-right: 1.1em solid rgba(195,8,247, 0.2);
border-bottom: 1.1em solid rgba(195,8,247, 0.2);
border-left: 1.1em solid #c308f7;
-webkit-transform: translateZ(0);
-ms-transform: translateZ(0);
transform: translateZ(0);
-webkit-animation: load8 1.1s infinite linear;
animation: load8 1.1s infinite linear;
}
@-webkit-keyframes load8 {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@keyframes load8 {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}

View File

@ -0,0 +1,9 @@
import React from 'react';
import classes from './Spinner.css';
const spinner = () => (
<div className={classes.Loader}>Loading...</div>
);
export default spinner;

View File

@ -5,6 +5,9 @@ import Burger from '../../components/Burger/Burger';
import BuildControls from '../../components/Burger/BuildControls/BuildControls';
import Modal from '../../components/UI/Modal/Modal';
import OrderSummary from '../../components/Burger/OrderSummary/OrderSummary';
import Spinner from '../../components/UI/Spinner/Spinner';
import withErrorHandler from '../../hoc/withErrorHandler/withErrorHandler';
import axios from '../../axios-orders';
const INGREDIENT_PRICE = {
salad: 0.4,
@ -16,15 +19,22 @@ const INGREDIENT_PRICE = {
class BurgerBuilder extends Component {
state = {
ingredients: {
meat: 0,
cheese: 0,
salad: 0,
bacon: 0,
},
ingredients: null,
totalPrice: 0,
purchasable: false,
purchasing: false,
loading: false,
error: false,
}
componentDidMount() {
axios.get('https://react-my-burger-e4645.firebaseio.com/ingredients.json') // remove .json to throw error
.then(res => {
this.setState({ ingredients: res.data });
})
.catch(error => {
this.setState({ error: true});
})
}
updatePurchaseState(ingredients) {
@ -87,7 +97,30 @@ class BurgerBuilder extends Component {
}
purchaseContinueHandler = () => {
alert("You continue");
this.setState({
loading: true,
});
const order = {
ingredients: this.state.ingredients,
price: this.state.totalPrice,
customer: {
address: {
country: "NEW ZEALAND",
street: "test street 1",
zipCode: "8042",
},
email: "test@test.com",
name: "oscar",
}
};
axios.post('/order.json', order) // remove .json to throw error
.then(response => {
this.setState({ loading: false, purchasing: false }); // set purchasing: false can close Order Summary dialog
})
.catch(error => {
this.setState({ loading: false });
});
}
render() {
@ -99,28 +132,45 @@ class BurgerBuilder extends Component {
disabledInfo[key] = disabledInfo[key] <= 0;
}
let orderSummary = null;
let burger = this.state.error ? <p>Ingredients can't be loaded!</p> : <Spinner />;
if (this.state.ingredients) {
orderSummary = <OrderSummary
ingredients={this.state.ingredients}
price={this.state.totalPrice}
purchaseCancalled={this.purchaseCancelHandler}
purchaseContinued={this.purchaseContinueHandler}></OrderSummary>;
burger = (
<Aux>
<Burger ingredients={this.state.ingredients} />
<BuildControls
ingredientAdded={this.addIngredientHandler}
ingredientRemoved={this.removeIngredientHandler}
ordered={this.purchaseHandler}
disabled={disabledInfo}
purchasable={this.state.purchasable}
price={this.state.totalPrice} />
</Aux>
);
}
if (this.state.loading) {
orderSummary = <Spinner />
}
return (
<Aux>
<Modal
show={this.state.purchasing}
modalClosed={this.purchaseCancelHandler}>
<OrderSummary
ingredients={this.state.ingredients}
price={this.state.totalPrice}
purchaseCancalled={this.purchaseCancelHandler}
purchaseContinued={this.purchaseContinueHandler}></OrderSummary>
{orderSummary}
</Modal>
<Burger ingredients={this.state.ingredients} />
<BuildControls
ingredientAdded={this.addIngredientHandler}
ingredientRemoved={this.removeIngredientHandler}
ordered={this.purchaseHandler}
disabled={disabledInfo}
purchasable={this.state.purchasable}
price={this.state.totalPrice} />
{burger}
</Aux>
);
};
};
export default BurgerBuilder;
export default withErrorHandler(BurgerBuilder, axios);

View File

@ -0,0 +1,47 @@
import React, { Component } from 'react';
import Aux from '../Auxiliary/Auxiliary';
import Modal from '../../components/UI/Modal/Modal';
const withErrorHandler = (WrappedComponent, axios) => {
return class extends Component {
state = {
error: null,
}
componentWillMount() { // This will happen before child component rendering
this.reqInterceptor = axios.interceptors.request.use(req => {
this.setState({ error: null });
return req;
});
this.resInterceptor = axios.interceptors.response.use(res => res, error => {
this.setState({ error: error });
});
}
componentWillUnmount() {
axios.interceptors.request.eject(this.reqInterceptor);
axios.interceptors.response.eject(this.resInterceptor);
}
errorConfirmedHandler = () => {
this.setState({ error: null });
}
render() {
return (
<Aux>
<Modal
show={this.state.error}
modalClosed={this.errorConfirmedHandler}>
{this.state.error ? this.state.error.message : null}
</Modal>
<WrappedComponent {...this.props} />
</Aux>
);
}
}
}
export default withErrorHandler;