Last active
July 21, 2020 14:41
-
-
Save VasVV/58a9671b67da3240edbb20962193a926 to your computer and use it in GitHub Desktop.
Menu - React
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const sampleBurger = {name: 'Cheeseburger', price: 1488, description: 'Burger with meat and cheese', image: 'https://www.mcdonalds.com/is/image/content/dam/usa/nfl/nutrition/items/hero/desktop/t-mcdonalds-Cheeseburger.jpg', status: true}; | |
const formatPrice = (cents) => { | |
return (cents / 100).toLocaleString("en-US", { | |
style: "currency", | |
currency: "EUR" | |
}); | |
} | |
const removeDuplicates = (arr) => { | |
let p = {}; | |
arr.forEach( (x) => { p[x] = (p[x] || 0) + 1; }); | |
return Object.keys(p).map( (x) => { return { id: x, count: p[x] }; }); | |
} | |
class App extends React.Component { | |
constructor() { | |
super(); | |
this.state = { | |
burgers: [], | |
order: [] | |
} | |
this.addBurger = this.addBurger.bind(this); | |
} | |
addBurger = (e) => { | |
this.setState({ burgers: [...this.state.burgers, e] }); | |
}; | |
loadSample = () => { | |
this.setState({ burgers: [...this.state.burgers, sampleBurger] }) | |
}; | |
addToOrder = (e) => { | |
console.log(this.state.order); | |
this.setState({ order: [...this.state.order, e.name] }); | |
} | |
updateBurger = (e, u) => { | |
const burger = this.state.burgers; | |
burger[e] = u; | |
this.setState({ burgers: [...this.state.burgers, burger] }); | |
this.setState({ burgers: [...this.state.burgers.filter(e => {return !Array.isArray(e)})] }); | |
} | |
deleteBurger = e => { | |
const burger = this.state.burgers; | |
burger.splice(e,1); | |
this.setState({ burgers: [...this.state.burgers, burger] }); | |
this.setState({ burgers: [...this.state.burgers.filter(e => {return !Array.isArray(e)})] }); | |
} | |
render() { | |
const burgerlist = this.state.burgers.map((e,i) => { | |
return <Burger key={e} index={e} details={this.state.burgers[i]} addToOrder = {this.addToOrder}/>}) | |
return ( | |
<div className='catch-of-the-day'> | |
<div className='menu'> | |
<Header /> | |
<ul> | |
{burgerlist} | |
</ul> | |
</div> | |
<Order {...this.state}/> | |
<Inventory addBurger={this.addBurger} loadSample={this.loadSample} burgers = {this.state.burgers} updateBurger={this.updateBurger} deleteBurger={this.deleteBurger}/> | |
</div> | |
) | |
} | |
}; | |
const Header = () => ( | |
<header className='top'> | |
<h1>Menu</h1> | |
</header> | |
) | |
class AddBurger extends React.Component { | |
constructor(props) { | |
super(props); | |
this.nameRef = React.createRef(); | |
this.priceRef = React.createRef(); | |
this.descriptionRef = React.createRef(); | |
this.imageRef = React.createRef(); | |
this.statusRef = React.createRef(); | |
} | |
addBurger = (e) => { | |
e.preventDefault(); | |
const burger = { | |
name: this.nameRef.current.value, | |
price: Number(this.priceRef.current.value), | |
description: this.descriptionRef.current.value, | |
image: this.imageRef.current.value, | |
status: this.statusRef.current.value === 'yes' ? true : false | |
}; | |
this.props.addBurger(burger); | |
e.currentTarget.reset(); | |
} | |
render() { | |
return ( | |
<form className='burger-edit' onSubmit={this.addBurger}> | |
<input name='name' type='text' ref={this.nameRef} placeholder='Name' /> | |
<input name='price' type='text' ref={this.priceRef} placeholder='Price' /> | |
<input name='description' type='text' ref={this.descriptionRef} placeholder='Description' /> | |
<input name='image' type='text' ref={this.imageRef} placeholder='Image' /> | |
<select name='status' ref={this.statusRef}> | |
<option value='yes'>Available</option> | |
<option value='no'>Unavailable</option> | |
</select> | |
<button type='submit'>Add Burger </button> | |
</form> | |
) | |
} | |
} | |
class EditBurger extends React.Component { | |
constructor(props) { | |
super(props); | |
} | |
handleChange=(e)=>{ | |
const editedBurger = {...this.props.burgers, | |
[e.currentTarget.name]: e.currentTarget.value} | |
this.props.updateBurger(this.props.index, editedBurger) | |
} | |
render() { | |
return (<div className='burger-edit'> | |
<input name='name' type='text' onChange={this.handleChange} value ={this.props.burgers.name} readonly="readonly"/> | |
<input name='price' type='text' value ={this.props.burgers.price} onChange={this.handleChange} /> | |
<input name='description' type='text' value ={this.props.burgers.description} onChange={this.handleChange} /> | |
<input name='image' type='text' value ={this.props.burgers.image} onChange={this.handleChange}/> | |
<select name='status' value ={this.props.burgers.status ? 'yes' : 'no'} onChange={this.handleChange}> | |
<option value='yes'>Available</option> | |
<option value='no'>Unavailable</option> | |
</select> | |
<button onClick={() => this.props.deleteBurger(this.props.index)}>DELETE BURGER</button> | |
</div>) | |
} | |
} | |
class Inventory extends React.Component { | |
constructor(props) { | |
super(props); | |
} | |
render() { | |
return ( | |
<div> <h2>Stock</h2> | |
{this.props.burgers.map((e,i) => { | |
return <EditBurger burgers={Object.values(this.props.burgers)[i]} updateBurger ={this.props.updateBurger} key={i} index={i} deleteBurger={this.props.deleteBurger}/> | |
})} | |
<AddBurger addBurger={this.props.addBurger} /> | |
<button onClick={this.props.loadSample} >LOAD SAMPLE BURGER</button> | |
</div> | |
) | |
} | |
} | |
class Order extends React.Component { | |
render() { | |
const orderIds = Object.values(this.props.order); | |
const burgerprice = Object.values(this.props.burgers); | |
let pricer = {}; | |
for (let a = 0; a<burgerprice.length; a++) { | |
let b = burgerprice[a].name; | |
for (let c = 0; c< orderIds.length; c++) { | |
if (orderIds[c] === b) { | |
pricer[b] = burgerprice[a].price; | |
break; | |
} | |
} | |
} | |
let temp = 0; | |
let total = removeDuplicates(orderIds).forEach(e => {temp+=pricer[e.id]*e.count}); | |
let x = removeDuplicates(orderIds).map(e => {return <ul><li class='prices'>{e.count} {e.id}{e.count>1 ? 's' : ''} { formatPrice(pricer[e.id]*e.count)} </li></ul>}); | |
return ( | |
<div className='order-wrap' id='orders'> | |
<h2>Your order</h2> | |
{x} | |
<div className={temp === 0 ? 'hidden' : ''} ><b>Total: </b>{formatPrice(temp)}</div> | |
</div> | |
) | |
} | |
} | |
class Burger extends React.Component { | |
render() { | |
const way = this.props.details; | |
const isAvailiable = way.status ? true : false; | |
return ( | |
<li className='menu-burger'> | |
<img src={way.image}/> | |
<h3 className='burger-name'>{way.name} | |
<span className='price'> | |
{formatPrice(way.price)} | |
</span> | |
</h3> | |
<p>{way.description}</p> | |
<button disabled={!isAvailiable} onClick ={() => {this.props.addToOrder(this.props.index)}}>{isAvailiable ? 'ADD TO CART' : 'SOLD OUT'}</button> | |
</li> | |
) | |
} | |
} | |
ReactDOM.render(<App />, document.getElementById('root')) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.0/umd/react.production.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.0/umd/react-dom.production.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-router/5.1.2/react-router.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-router-dom/5.1.2/react-router-dom.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/prop-types/15.7.2/prop-types.min.js"></script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.order-enter { | |
-webkit-transform: translateX(-120%); | |
transform: translateX(-120%); | |
-webkit-transition: 0.5s; | |
transition: 0.5s; | |
max-height: 0; | |
padding: 0 !important; | |
} | |
.order-enter.order-enter-active { | |
max-height: 60px; | |
-webkit-transform: translateX(0); | |
transform: translateX(0); | |
padding: 2rem 0 !important; | |
} | |
.order-exit { | |
-webkit-transition: 0.5s; | |
transition: 0.5s; | |
-webkit-transform: translateX(0); | |
transform: translateX(0); | |
} | |
.order-exit.order-exit-active { | |
-webkit-transform: translateX(120%); | |
transform: translateX(120%); | |
padding: 0; | |
} | |
.count-enter { | |
background: #f00; | |
-webkit-transition: 0.5s; | |
transition: 0.5s; | |
-webkit-transform: translateY(100%); | |
transform: translateY(100%); | |
} | |
.count-enter.count-enter-active { | |
background: #ff0; | |
-webkit-transform: translateY(0); | |
transform: translateY(0); | |
} | |
.count-exit { | |
background: #000; | |
-webkit-transform: translateY(0); | |
transform: translateY(0); | |
-webkit-transition: 0.5s; | |
transition: 0.5s; | |
position: absolute; | |
left: 0; | |
bottom: 0; | |
} | |
.count-exit.count-exit-active { | |
background: #008000; | |
-webkit-transform: translateY(-100%) scale(3); | |
transform: translateY(-100%) scale(3); | |
} | |
article, | |
aside, | |
details, | |
figcaption, | |
figure, | |
footer, | |
header, | |
hgroup, | |
nav, | |
section, | |
summary { | |
display: block; | |
} | |
audio, | |
canvas, | |
video { | |
display: inline-block; | |
} | |
audio:not([controls]) { | |
display: none; | |
height: 0; | |
} | |
[hidden] { | |
display: none; | |
} | |
html { | |
font-family: sans-serif; | |
-webkit-text-size-adjust: 100%; | |
-ms-text-size-adjust: 100%; | |
} | |
a:focus { | |
outline: thin dotted; | |
} | |
a:active, | |
a:hover { | |
outline: 0; | |
} | |
h1 { | |
font-size: 2em; | |
} | |
abbr[title] { | |
border-bottom: 1px dotted; | |
} | |
b, | |
strong { | |
font-weight: 700; | |
} | |
dfn { | |
font-style: italic; | |
} | |
mark { | |
background: #ff0; | |
color: #000; | |
} | |
code, | |
kbd, | |
pre, | |
samp { | |
font-family: monospace, serif; | |
font-size: 1em; | |
} | |
pre { | |
white-space: pre-wrap; | |
word-wrap: break-word; | |
} | |
q { | |
quotes: 2 1C 2 1D 2 18 2 19; | |
} | |
small { | |
font-size: 80%; | |
} | |
sub, | |
sup { | |
font-size: 75%; | |
line-height: 0; | |
position: relative; | |
vertical-align: baseline; | |
} | |
sup { | |
top: -0.5em; | |
} | |
sub { | |
bottom: -0.25em; | |
} | |
img { | |
border: 0; | |
} | |
svg:not(:root) { | |
overflow: hidden; | |
} | |
fieldset { | |
border: 1px solid #c0c0c0; | |
margin: 0 2px; | |
padding: 0.35em 0.625em 0.75em; | |
} | |
button, | |
input, | |
select, | |
textarea { | |
font-family: inherit; | |
font-size: 100%; | |
margin: 0; | |
} | |
button, | |
input { | |
line-height: normal; | |
} | |
button, | |
html input[type=button], | |
input[type=reset], | |
input[type=submit] { | |
-webkit-appearance: button; | |
cursor: pointer; | |
} | |
button[disabled], | |
input[disabled] { | |
cursor: default; | |
} | |
input[type=checkbox], | |
input[type=radio] { | |
box-sizing: border-box; | |
padding: 0; | |
} | |
input[type=search] { | |
-webkit-appearance: textfield; | |
box-sizing: content-box; | |
} | |
input[type=search]::-webkit-search-cancel-button, | |
input[type=search]::-webkit-search-decoration { | |
-webkit-appearance: none; | |
} | |
textarea { | |
overflow: auto; | |
vertical-align: top; | |
} | |
table { | |
border-collapse: collapse; | |
border-spacing: 0; | |
} | |
body, | |
figure { | |
margin: 0; | |
} | |
legend, | |
button::-moz-focus-inner, | |
input::-moz-focus-inner { | |
border: 0; | |
padding: 0; | |
} | |
.clearfix:after { | |
visibility: hidden; | |
display: block; | |
font-size: 0; | |
content: " "; | |
clear: both; | |
height: 0; | |
} | |
* { | |
box-sizing: border-box; | |
} | |
html { | |
font-size: 62.5%; | |
} | |
body { | |
background: #d4d4d4; | |
-webkit-font-smoothing: antialiased; | |
-moz-osx-font-smoothing: grayscale; | |
font-family: 'Open Sans', sans-serif; | |
font-size: 2rem; | |
} | |
h1 { | |
font-family: 'blanchcaps_inline', sans-serif; | |
text-align: center; | |
font-weight: normal; | |
margin: 0; | |
} | |
h2, | |
h3, | |
h4, | |
h5, | |
h6 { | |
font-weight: normal; | |
font-family: 'haymakerregular', sans-serif; | |
} | |
h2 { | |
text-align: center; | |
margin-top: 0; | |
margin-bottom: 2rem; | |
} | |
h3 { | |
font-size: 3rem; | |
} | |
header.top { | |
text-align: center; | |
} | |
header.top h1 { | |
font-size: 14.4rem; | |
line-height: 0.7; | |
display: -webkit-box; | |
display: flex; | |
-webkit-box-pack: center; | |
justify-content: center; | |
} | |
header.top h1 .ofThe { | |
display: -webkit-box; | |
display: flex; | |
font-size: 3rem; | |
color: #f5a623; | |
-webkit-box-pack: center; | |
justify-content: center; | |
-webkit-box-align: center; | |
align-items: center; | |
background: url("images/anchor.svg") center no-repeat; | |
background-size: cover; | |
padding: 0 1rem; | |
} | |
header.top h1 .ofThe .of { | |
padding-right: 2rem; | |
position: relative; | |
right: -0.5rem; | |
} | |
header.top h3 { | |
margin: 0; | |
font-size: 2rem; | |
color: #f5a623; | |
position: relative; | |
display: inline-block; | |
} | |
header.top h3 span { | |
background: #fff; | |
position: relative; | |
z-index: 2; | |
padding-left: 1rem; | |
padding-right: 1rem; | |
} | |
header.top h3:before, | |
header.top h3:after { | |
display: block; | |
z-index: 1; | |
background: #000; | |
position: absolute; | |
width: 130%; | |
height: 1px; | |
content: ''; | |
top: 5px; | |
margin-left: -15%; | |
} | |
header.top h3:after { | |
top: auto; | |
bottom: 7px; | |
} | |
.catch-of-the-day { | |
display: -webkit-box; | |
display: flex; | |
height: 90vh; | |
max-width: 1500px; | |
margin: 0 auto; | |
margin-top: 5vh; | |
-webkit-perspective: 1000px; | |
perspective: 1000px; | |
-webkit-transform-style: preserve-3d; | |
transform-style: preserve-3d; | |
} | |
.catch-of-the-day > * { | |
-webkit-box-flex: 1; | |
flex: 1 4 auto; | |
padding: 2rem; | |
border: 1rem double #1a1a1a; | |
position: relative; | |
background: #fff; | |
-webkit-transition: all 0.3s; | |
transition: all 0.3s; | |
box-shadow: 0 5px 5px rgba(0,0,0,0.1); | |
overflow: scroll; | |
} | |
.catch-of-the-day > *:first-child { | |
flex-shrink: 1; | |
flex-basis: 50%; | |
-webkit-transform: translateX(50%) rotateY(6deg) translateX(-50%); | |
transform: translateX(50%) rotateY(6deg) translateX(-50%); | |
} | |
.catch-of-the-day > *:nth-child(2) { | |
-webkit-transform: translateX(-50%) rotateY(-14deg) translateX(50%); | |
transform: translateX(-50%) rotateY(-14deg) translateX(50%); | |
border-left: 0; | |
border-right: 0; | |
min-width: 300px; | |
} | |
.catch-of-the-day > *:last-child { | |
flex-shrink: 1; | |
flex-basis: 50%; | |
-webkit-transform: translateX(-50%) rotateY(10deg) translateX(50%) scale(1.08) translateX(24px); | |
transform: translateX(-50%) rotateY(10deg) translateX(50%) scale(1.08) translateX(24px); | |
} | |
input#fold:not(:checked) ~ #main .catch-of-the-day > * { | |
-webkit-transform: none; | |
transform: none; | |
} | |
label[for="fold"] { | |
position: absolute; | |
top: 1rem; | |
left: 1rem; | |
text-transform: uppercase; | |
font-size: 1.3rem; | |
background: #000; | |
color: #fff; | |
border: 2px solid #000; | |
cursor: pointer; | |
padding: 0.5rem 1rem; | |
} | |
input#fold { | |
display: none; | |
} | |
input#fold:checked + label { | |
background: #fff; | |
color: #000; | |
} | |
ul { | |
list-style: none; | |
margin: 0; | |
padding: 0; | |
} | |
ul.order li { | |
border-bottom: 1px solid #000; | |
padding: 2rem 0; | |
display: -webkit-box; | |
display: flex; | |
font-size: 1.4rem; | |
-webkit-box-pack: justify; | |
justify-content: space-between; | |
-webkit-box-align: center; | |
align-items: center; | |
} | |
ul.order li:hover button { | |
display: inline; | |
} | |
ul.order li button { | |
border: 0; | |
display: none; | |
line-height: 1; | |
padding: 0; | |
} | |
ul.order li.unavailable { | |
text-decoration: line-through; | |
background: #f8d0d2; | |
} | |
ul.order li .price { | |
font-size: 1.2rem; | |
} | |
ul.order li span.count { | |
position: relative; | |
overflow: hidden; | |
float: left; | |
} | |
ul.order li span.count span { | |
display: inline-block; | |
} | |
.total { | |
padding: 2rem 0; | |
font-size: 1.4rem; | |
border-bottom: 3px solid #000; | |
border-top: 3px double #000; | |
} | |
.total strong { | |
float: right; | |
} | |
.order-title { | |
text-align: center; | |
} | |
.burger-edit { | |
margin-bottom: 20px; | |
border: 2px solid #000; | |
overflow: hidden; | |
display: -webkit-box; | |
display: flex; | |
flex-wrap: wrap; | |
} | |
.burger-edit, | |
.burger-edit textarea, | |
.burger-edit select { | |
padding: 10px; | |
line-height: 1; | |
font-size: 1.2rem; | |
border: 0; | |
border-bottom: 1px solid #000; | |
border-right: 1px solid #000; | |
-webkit-appearance: none; | |
-moz-appearance: none; | |
appearance: none; | |
border-radius: 0; | |
background: #fff; | |
} | |
.burger-edit input:focus, | |
.burger-edit textarea:focus, | |
.burger-edit select:focus { | |
outline: 0; | |
background: #fef2de; | |
} | |
.burger-edit textarea { | |
width: 100%; | |
} | |
.burger-edit input:last-of-type { | |
width: 100%; | |
} | |
.burger-edit button { | |
width: 100%; | |
border: 0; | |
} | |
.list-of-fish { | |
border-top: 2px solid #000; | |
border-bottom: 1px solid #000; | |
padding-top: 5px; | |
margin-top: 2rem; | |
-webkit-transform: translateZ(0); | |
transform: translateZ(0); | |
} | |
.menu-burger { | |
border-bottom: 2px solid #000; | |
border-top: 1px solid #000; | |
padding-bottom: 2rem; | |
padding-top: 2rem; | |
margin-bottom: 5px; | |
clear: both; | |
overflow: hidden; | |
} | |
.menu-burger p { | |
margin: 0; | |
font-size: 1.8rem; | |
} | |
.menu-burger .burger-name { | |
margin: 0; | |
display: -webkit-box; | |
display: flex; | |
-webkit-box-pack: justify; | |
justify-content: space-between; | |
-webkit-box-align: center; | |
align-items: center; | |
} | |
.menu-burger .price { | |
font-size: 1.4rem; | |
-webkit-box-pack: end; | |
justify-content: flex-end; | |
} | |
.menu-burger img { | |
float: left; | |
width: 150px; | |
margin-right: 1rem; | |
} | |
button, | |
input[type=submit] { | |
text-transform: uppercase; | |
background: none; | |
border: 1px solid #000; | |
font-weight: 600; | |
font-size: 1.5rem; | |
font-family: 'Open Sans'; | |
-webkit-transition: all 0.2s; | |
transition: all 0.2s; | |
position: relative; | |
z-index: 2; | |
} | |
button:disabled, | |
input[type=submit][disabled] { | |
color: #d12028; | |
background: #fff; | |
border-color: #d12028; | |
-webkit-transform: rotate(-10deg) scale(2) translateX(50%) translateY(-50%); | |
transform: rotate(-10deg) scale(2) translateX(50%) translateY(-50%); | |
} | |
button[disabled]:hover, | |
input[type=submit][disabled]:hover { | |
color: #d12028; | |
cursor: not-allowed; | |
} | |
button[disabled]:after, | |
input[type=submit][disabled]:after { | |
display: none; | |
} | |
button:after, | |
input[type=submit]:after { | |
content: ''; | |
z-index: -1; | |
display: block; | |
background: #000; | |
position: absolute; | |
width: 100%; | |
height: 0; | |
left: 0; | |
top: 0; | |
-webkit-transition: all 0.2s; | |
transition: all 0.2s; | |
} | |
button:hover, | |
input[type=submit]:hover, | |
button:focus, | |
input[type=submit]:focus { | |
color: #fff; | |
outline: 0; | |
} | |
button:hover:after, | |
input[type=submit]:hover:after, | |
button:focus:after, | |
input[type=submit]:focus:after { | |
height: 100%; | |
} | |
button.warning:after, | |
input[type=submit].warning:after { | |
background: #d12028; | |
} | |
button.success:after, | |
input[type=submit].success:after { | |
background: #2dc22d; | |
} | |
button.github, | |
input[type=submit].github, | |
button.facebook, | |
input[type=submit].facebook, | |
button.twitter, | |
input[type=submit].twitter { | |
border: 0; | |
display: block; | |
margin-bottom: 2rem; | |
width: 100%; | |
color: #fff; | |
padding: 2rem; | |
} | |
button.github, | |
input[type=submit].github { | |
background: #82d465; | |
} | |
button.github:after, | |
input[type=submit].github:after { | |
background: #5cc437; | |
} | |
button.facebook, | |
input[type=submit].facebook { | |
background: #3864a3; | |
} | |
button.facebook:after, | |
input[type=submit].facebook:after { | |
background: #2d5082; | |
} | |
button.twitter, | |
input[type=submit].twitter { | |
background: #5ea9dd; | |
} | |
button.twitter:after, | |
input[type=submit].twitter:after { | |
background: #2c8dd0; | |
} | |
.store-selector { | |
background: #fff; | |
max-width: 500px; | |
margin: 50px auto; | |
padding: 2rem; | |
border: 2px solid #000; | |
} | |
.store-selector input, | |
.store-selector button { | |
width: 100%; | |
} | |
.store-selector input[type="text"], | |
.store-selector button[type="text"] { | |
text-align: center; | |
font-size: 3rem; | |
} | |
.hidden { display:none; } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment