Commit 3fbdb3a6 authored by Pavel Mishakov's avatar Pavel Mishakov

finished lesson 62

parent e9082886
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
"@testing-library/jest-dom": "^5.16.4", "@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.2.0", "@testing-library/react": "^13.2.0",
"@testing-library/user-event": "^13.5.0", "@testing-library/user-event": "^13.5.0",
"axios": "^1.2.1",
"react": "^18.1.0", "react": "^18.1.0",
"react-dom": "^18.1.0", "react-dom": "^18.1.0",
"react-router-dom": "^6.4.4", "react-router-dom": "^6.4.4",
...@@ -4544,6 +4545,29 @@ ...@@ -4544,6 +4545,29 @@
"node": ">=12" "node": ">=12"
} }
}, },
"node_modules/axios": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.2.1.tgz",
"integrity": "sha512-I88cFiGu9ryt/tfVEi4kX2SITsvDddTajXTOFmt2uK1ZVA8LytjtdeyefdQWEf5PU8w+4SSJDoYnggflB5tW4A==",
"dependencies": {
"follow-redirects": "^1.15.0",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
},
"node_modules/axios/node_modules/form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/axobject-query": { "node_modules/axobject-query": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz",
...@@ -13189,6 +13213,11 @@ ...@@ -13189,6 +13213,11 @@
"node": ">= 0.10" "node": ">= 0.10"
} }
}, },
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
},
"node_modules/psl": { "node_modules/psl": {
"version": "1.8.0", "version": "1.8.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
...@@ -19485,6 +19514,28 @@ ...@@ -19485,6 +19514,28 @@
"resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.4.2.tgz", "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.4.2.tgz",
"integrity": "sha512-LVAaGp/wkkgYJcjmHsoKx4juT1aQvJyPcW09MLCjVTh3V2cc6PnyempiLMNH5iMdfIX/zdbjUx2KDjMLCTdPeA==" "integrity": "sha512-LVAaGp/wkkgYJcjmHsoKx4juT1aQvJyPcW09MLCjVTh3V2cc6PnyempiLMNH5iMdfIX/zdbjUx2KDjMLCTdPeA=="
}, },
"axios": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.2.1.tgz",
"integrity": "sha512-I88cFiGu9ryt/tfVEi4kX2SITsvDddTajXTOFmt2uK1ZVA8LytjtdeyefdQWEf5PU8w+4SSJDoYnggflB5tW4A==",
"requires": {
"follow-redirects": "^1.15.0",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
},
"dependencies": {
"form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"requires": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
}
}
}
},
"axobject-query": { "axobject-query": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz",
...@@ -25613,6 +25664,11 @@ ...@@ -25613,6 +25664,11 @@
} }
} }
}, },
"proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
},
"psl": { "psl": {
"version": "1.8.0", "version": "1.8.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
"@testing-library/jest-dom": "^5.16.4", "@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.2.0", "@testing-library/react": "^13.2.0",
"@testing-library/user-event": "^13.5.0", "@testing-library/user-event": "^13.5.0",
"axios": "^1.2.1",
"react": "^18.1.0", "react": "^18.1.0",
"react-dom": "^18.1.0", "react-dom": "^18.1.0",
"react-router-dom": "^6.4.4", "react-router-dom": "^6.4.4",
......
import {burgerInstance} from "./instances";
class ApiBurger {
getOrders = async () => {
try {
const response = await burgerInstance.get('/orders.json')
return response.data
} catch(err) {
console.log(err)
}
}
createOrder = async (order) => {
try {
await burgerInstance.post('/orders.json', order)
} catch (err) {
console.log(err)
}
}
}
export const apiBurger = new ApiBurger()
\ No newline at end of file
export const burgerApiUrl = 'https://burger-project-f0b9d-default-rtdb.firebaseio.com/'
\ No newline at end of file
import axios from "axios";
import {burgerApiUrl} from "./apiUrl";
export const burgerInstance = axios.create({
baseURL: burgerApiUrl
})
\ No newline at end of file
.Spinner,
.Spinner:before,
.Spinner:after {
border-radius: 50%;
}
.Spinner {
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);
}
.Spinner:before,
.Spinner:after {
position: absolute;
content: '';
}
.Spinner: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.2em 5.1em;
transform-origin: 5.2em 5.1em;
-webkit-animation: load2 2s infinite ease 1.5s;
animation: load2 2s infinite ease 1.5s;
}
.Spinner:after {
width: 5.2em;
height: 10.2em;
background: #fff;
border-radius: 0 10.2em 10.2em 0;
top: -0.1em;
left: 5.1em;
-webkit-transform-origin: 0px 5.1em;
transform-origin: 0px 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);
}
}
import React from "react";
import './Spinner.css'
const Spinner = () => {
return (
<div className={'Spinner'}>Loading...</div>
)
}
export default Spinner
\ No newline at end of file
export const INGREDIENT_PRICES = {
salad: 50,
bacon: 300,
cheese: 200,
meat: 500
}
\ No newline at end of file
...@@ -5,6 +5,7 @@ import BuildControls from '../../components/BuildControls/BuildControls'; ...@@ -5,6 +5,7 @@ import BuildControls from '../../components/BuildControls/BuildControls';
import Burger from '../../components/Burger/Burger' import Burger from '../../components/Burger/Burger'
import OrderSummary from '../../components/Burger/OrderSummary/OrderSummary'; import OrderSummary from '../../components/Burger/OrderSummary/OrderSummary';
import Modal from '../../components/UI/Modal/Modal'; import Modal from '../../components/UI/Modal/Modal';
import {INGREDIENT_PRICES} from "../../constants/ingredients_prices";
const BurgerBuilder = () => { const BurgerBuilder = () => {
const navigate = useNavigate() const navigate = useNavigate()
...@@ -18,12 +19,7 @@ const BurgerBuilder = () => { ...@@ -18,12 +19,7 @@ const BurgerBuilder = () => {
const [purchasable, setPurchasable] = useState(false) const [purchasable, setPurchasable] = useState(false)
const [purchasing, setPurchasing] = useState(false) const [purchasing, setPurchasing] = useState(false)
const INGREDIENT_PRICES = {
salad: 50,
bacon: 300,
cheese: 200,
meat: 500
}
const addIngredientHandler = (type) => { const addIngredientHandler = (type) => {
const oldCount = ingredients[type] const oldCount = ingredients[type]
......
...@@ -3,6 +3,7 @@ import { useRef } from "react"; ...@@ -3,6 +3,7 @@ import { useRef } from "react";
import { NavLink, Outlet, useNavigate, useSearchParams } from "react-router-dom"; import { NavLink, Outlet, useNavigate, useSearchParams } from "react-router-dom";
import CheckoutSummary from "../../components/Order/CheckoutSummary/CheckoutSummary"; import CheckoutSummary from "../../components/Order/CheckoutSummary/CheckoutSummary";
import { parseSearch } from "../../helper/parseSearch"; import { parseSearch } from "../../helper/parseSearch";
import {INGREDIENT_PRICES} from "../../constants/ingredients_prices";
const Checkout = () => { const Checkout = () => {
...@@ -14,8 +15,15 @@ const Checkout = () => { ...@@ -14,8 +15,15 @@ const Checkout = () => {
const checkoutCancelledHandler = () => { const checkoutCancelledHandler = () => {
navigate(-1) navigate(-1)
} }
const getTotalPrice = (ingredients) => {
return Object.keys(ingredients).reduce((total, ingName) => {
total += INGREDIENT_PRICES[ingName] * ingredients[ingName]
return total
}, 0)
}
const checkoutContinuedHandler = () => { const checkoutContinuedHandler = () => {
navigate('contact-data', {state: {ingredients: ingredients.current}}) const price = getTotalPrice(ingredients.current)
navigate('contact-data', {state: {ingredients: ingredients.current, price}})
} }
return ( return (
......
...@@ -9,11 +9,18 @@ ...@@ -9,11 +9,18 @@
} }
.Input { .Input {
outline: none;
border: 1px solid #ccc;
background-color: white;
font: inherit;
padding: 6px 10px;
margin: 10px auto;
display: block; display: block;
width: 100%;
box-sizing: border-box;
} }
@media (min-width: 600px) { .Input:focus {
.ContactData { outline: none;
width: 500px; background-color: #ccc;
} }
}
\ No newline at end of file
import React from 'react'; import React, {useState} from 'react';
import './ContactData.css'; import './ContactData.css';
import Button from "../../../components/UI/Button/Button"; import Button from "../../../components/UI/Button/Button";
import {useLocation, useNavigate} from "react-router-dom";
import {apiBurger} from "../../../api/apiBurger";
import Spinner from "../../../components/UI/Spinner/Spinner";
const ContactData = () => { const ContactData = () => {
const navigate = useNavigate()
const location = useLocation()
const [loading, setLoading] = useState(false)
const [customer, setCustomer] = useState({
name: '',
email: '',
street: '',
postal: ''
})
const orderHandler = async (event) => {
event.preventDefault()
setLoading(true)
const {ingredients, price} = location.state
const order = {
ingredients: ingredients,
price: price,
customer: {...customer}
}
try {
await apiBurger.createOrder(order)
} finally {
setLoading(false)
navigate('/')
}
}
const customerDataChanged = (event) => {
const {name, value} = event.target
setCustomer(prevState => {
return {...prevState, [name]: value}
})
}
return ( return (
<div className="ContactData"> <div className="ContactData">
<h4>Enter your Contact Data</h4> <h4>Enter your Contact Data</h4>
<form> {loading
<input className="Input" type="text" name="name" placeholder="Your Name"/> ?
<input className="Input" type="email" name="email" placeholder="Your Mail"/> <Spinner />
<input className="Input" type="text" name="street" placeholder="Street"/> :
<input className="Input" type="text" name="postal" placeholder="Postal Code"/> <form onSubmit={(event) => {orderHandler(event)}}>
<Button btnType="Success">ORDER</Button> <input onChange={customerDataChanged} className="Input" type="text" name="name" placeholder="Your Name"/>
</form> <input onChange={customerDataChanged} className="Input" type="email" name="email" placeholder="Your Mail"/>
<input onChange={customerDataChanged} className="Input" type="text" name="street" placeholder="Street"/>
<input onChange={customerDataChanged} className="Input" type="text" name="postal" placeholder="Postal Code"/>
<Button btnType="Success">ORDER</Button>
</form>
}
</div> </div>
); );
}; };
......
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