Skip to content

Commit 4782d79

Browse files
author
Joe Seifi
committed
radium solution round 1
1 parent 6064453 commit 4782d79

File tree

12 files changed

+382
-1
lines changed

12 files changed

+382
-1
lines changed

01-react-css3/solution/App.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React, { Component } from 'react'
22
import { FoodItem, BuyStrip } from './components/index'
33
import ReactCSSTransitionGroup from 'react-addons-css-transition-group'
44

5-
import { foodListData } from './api'
5+
import { foodListData } from '../../public/API'
66
import './app.css'
77

88
export default class App extends Component {

03-radium/solution/App.js

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import React, { Component } from 'react'
2+
import { FoodItem, BuyStrip } from './components/index'
3+
import ReactCSSTransitionGroup from 'react-addons-css-transition-group'
4+
5+
import { foodListData } from '../../public/API'
6+
import './app.css'
7+
8+
export default class App extends Component {
9+
10+
state = {
11+
totalPrice: 0,
12+
confirmed: false
13+
}
14+
15+
onBuy () {
16+
this.setState({
17+
confirmed: true
18+
})
19+
}
20+
21+
updateTotal (price, inCart) {
22+
this.setState({
23+
totalPrice: inCart ? this.state.totalPrice + price : this.state.totalPrice - price
24+
})
25+
}
26+
27+
render () {
28+
const { totalPrice, confirmed } = this.state
29+
30+
return (
31+
<div>
32+
<header className="header">
33+
<h1 className="logo"><span>Taco Shack</span></h1>
34+
</header>
35+
<section className="order">
36+
<main className="food">
37+
<figure className="food_header">
38+
<img className="food_header_image" src="../../workshop/img/taco.jpg" />
39+
</figure>
40+
<ReactCSSTransitionGroup
41+
transitionName="closefoods"
42+
transitionEnterTimeout={ 500 }
43+
transitionLeaveTimeout={ 600 }>
44+
{ !confirmed &&
45+
<div className="food_menu">
46+
<ul className="food_items">
47+
{
48+
foodListData.map( ({ id, name, price, photoPath }) => {
49+
return <FoodItem
50+
key={ id }
51+
name={ name }
52+
price={ price }
53+
photoPath={ photoPath }
54+
updateTotal= { this.updateTotal.bind(this) }
55+
/>
56+
})
57+
}
58+
</ul>
59+
</div>
60+
}
61+
</ReactCSSTransitionGroup>
62+
</main>
63+
<BuyStrip
64+
totalPrice={ totalPrice }
65+
confirmed={ confirmed }
66+
onBuy={ this.onBuy.bind(this) }
67+
/>
68+
</section>
69+
<footer className="footer">
70+
123 Narrow Road, San Francisco, CA
71+
</footer>
72+
</div>
73+
)
74+
}
75+
}

03-radium/solution/app.css

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
@import url("../../public/workshop/css/reset.css");
2+
@import url("../../public/workshop/css/app.css")
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import React, { Component, PropTypes } from 'react'
2+
import Radium from 'radium'
3+
4+
const buttonStyles = {
5+
btn: {
6+
display: 'inline-block',
7+
outline: 'none',
8+
textAlign: 'center',
9+
font: 'bold 15px helvetica',
10+
padding: '10px',
11+
border: '0',
12+
cursor: 'pointer',
13+
color: '#fff',
14+
backgroundColor: '#ec4800',
15+
userSelect: 'none',
16+
transition: 'all 120ms',
17+
':hover': {
18+
backgroundColor: '#f98d00'
19+
},
20+
depressed: {
21+
color: '#848484',
22+
backgroundColor: '#bebebe',
23+
':hover': {
24+
backgroundColor: '#bebebe'
25+
}
26+
},
27+
icon: {
28+
content: '',
29+
display: 'inline-block',
30+
width: '12px',
31+
height: '12px',
32+
marginLeft: '6px',
33+
backgroundSize: '12px',
34+
backgroundPosition: '50% 50%',
35+
backgroundRepeat: 'no-repeat',
36+
depressed: {
37+
display: 'none'
38+
}
39+
},
40+
'icon-add': {
41+
backgroundImage: 'url(/workshop/svg/add.svg)'
42+
}
43+
}
44+
}
45+
46+
const Button = ({
47+
icon,
48+
classNames,
49+
customStyles,
50+
depressed,
51+
disabled,
52+
onClick,
53+
children,
54+
...otherProps
55+
}) => {
56+
57+
return (
58+
<button
59+
style={ [
60+
buttonStyles.btn,
61+
depressed && buttonStyles.btn.depressed,
62+
customStyles.btn
63+
] }
64+
className={ classNames }
65+
onClick={ onClick }
66+
{ ...otherProps }
67+
>
68+
{ children }
69+
{
70+
<span style={ [
71+
icon && buttonStyles.btn.icon,
72+
icon && buttonStyles.btn['icon-'+icon],
73+
depressed && buttonStyles.btn.icon.depressed
74+
] }></span>
75+
}
76+
</button>
77+
)
78+
79+
}
80+
81+
const DecoratedButton = Radium(Button)
82+
export { DecoratedButton as Button }
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import React, { Component, PropTypes } from 'react'
2+
import { Button } from './index'
3+
import Radium from 'radium'
4+
5+
const customStyles = {
6+
btn: {
7+
minWidth: '110px'
8+
}
9+
}
10+
11+
export class ButtonAddToCart extends Component {
12+
13+
state = {
14+
depressed: false,
15+
buttonText: 'Add'
16+
}
17+
18+
static propTypes = {
19+
disabled: PropTypes.bool,
20+
onClick: PropTypes.func.isRequired
21+
}
22+
23+
onButtonClicked = () => {
24+
this.props.onClick(!this.state.depressed)
25+
this.setState({
26+
buttonText: this.state.depressed ? 'Add' : 'Remove',
27+
depressed: !this.state.depressed
28+
})
29+
}
30+
31+
render () {
32+
const { depressed, buttonText } = this.state
33+
const { disabled, onClick, ...otherProps } = this.props
34+
35+
return (
36+
<Button
37+
icon="add"
38+
customStyles={ customStyles }
39+
depressed={ depressed }
40+
disabled={ disabled }
41+
onClick={ this.onButtonClicked }
42+
{ ...otherProps }
43+
>
44+
{ buttonText }
45+
</Button>
46+
)
47+
48+
}
49+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import React, { Component, PropTypes } from 'react'
2+
import { Button } from './index'
3+
// import '../../../public/workshop/css/button-buy-now.css'
4+
import Radium from 'radium'
5+
6+
const customStyles = {
7+
btn: {
8+
backgroundColor: '#fff',
9+
color: '#000',
10+
boxShadow: '1px -1px 2px rgba(0, 0, 0, 0.2)',
11+
width: '110px',
12+
':hover': {
13+
backgroundColor: '#000',
14+
color: '#fff'
15+
},
16+
depressed: {
17+
boxShadow: '1px -1px 2px rgba(0, 0, 0, 0)'
18+
}
19+
}
20+
}
21+
22+
export class ButtonBuyNow extends Component {
23+
24+
state = {
25+
depressed: false,
26+
disabled: false,
27+
buttonText: 'Buy Now'
28+
}
29+
30+
static propTypes = {
31+
onClick: PropTypes.func.isRequired
32+
}
33+
34+
onButtonClicked = () => {
35+
this.props.onClick()
36+
this.setState({
37+
buttonText: 'Confirmed',
38+
depressed: true,
39+
disabled: true
40+
})
41+
}
42+
43+
render () {
44+
const { depressed, disabled, buttonText } = this.state
45+
const { onClick, ...otherProps } = this.props
46+
47+
return (
48+
<Button
49+
customStyles={ customStyles }
50+
depressed={ depressed }
51+
disabled={ disabled }
52+
onClick={ this.onButtonClicked }
53+
{ ...otherProps }
54+
>
55+
{ buttonText }
56+
</Button>
57+
)
58+
59+
}
60+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import React, { Component, PropTypes } from 'react'
2+
import { ButtonBuyNow } from './index'
3+
import numeral from 'numeral'
4+
import '../../../public/workshop/css/buy-strip.css'
5+
6+
export class BuyStrip extends Component {
7+
8+
static propTypes = {
9+
totalPrice: PropTypes.number.isRequired,
10+
confirmed: PropTypes.bool.isRequired,
11+
onBuy: PropTypes.func.isRequired
12+
}
13+
14+
render () {
15+
const { totalPrice, confirmed } = this.props
16+
const formattedPrice = numeral(totalPrice).format('$0.00')
17+
18+
return confirmed ?
19+
(
20+
<aside className="buy sold">
21+
<div className="buy_title"><p>Get Ready to eat!</p> Your order is confirmed. Your card was charged <span className="buy_total">{ formattedPrice }</span></div>
22+
</aside>
23+
) : (
24+
<aside className="buy">
25+
<div className="buy_title">Total:<span className="buy_total">{ formattedPrice }</span></div>
26+
<ButtonBuyNow
27+
onClick={ this.props.onBuy }
28+
disabled={ totalPrice === 0 }>
29+
Buy Now
30+
</ButtonBuyNow>
31+
</aside>
32+
)
33+
}
34+
35+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import React, { Component, PropTypes } from 'react'
2+
import { ButtonAddToCart } from './index'
3+
import numeral from 'numeral'
4+
import '../../../public/workshop/css/food-item.css'
5+
6+
export class FoodItem extends Component {
7+
8+
state = {
9+
inCart: false
10+
}
11+
12+
static propTypes = {
13+
id: PropTypes.number,
14+
name: PropTypes.string,
15+
price: PropTypes.number,
16+
photoPath: PropTypes.string,
17+
disabled: PropTypes.bool,
18+
updateTotal: PropTypes.func.isRequired
19+
}
20+
21+
addToCart (inCart) {
22+
this.props.updateTotal(this.props.price, inCart)
23+
}
24+
25+
render () {
26+
const { id, name, price, photoPath, disabled } = this.props
27+
28+
return (
29+
<li className="food_item">
30+
<figure className="food_item_figure"><img className="food_item_image" src={ photoPath } /></figure>
31+
<div className="food_item_name">{ name }<span className="food_item_price">{ numeral(price).format('$0.00') }</span></div>
32+
<ButtonAddToCart
33+
onClick={ this.addToCart.bind(this) }
34+
disabled={ disabled }
35+
/>
36+
</li>
37+
)
38+
}
39+
40+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export { Button } from './Button'
2+
3+
export { ButtonAddToCart } from './ButtonAddToCart'
4+
export { ButtonBuyNow } from './ButtonBuyNow'
5+
6+
export { FoodItem } from './FoodItem'
7+
export { BuyStrip } from './BuyStrip'

03-radium/solution/entry.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import React from 'react'
2+
import { render } from 'react-dom'
3+
import { AppContainer } from 'react-hot-loader'
4+
import App from './App'
5+
6+
render (
7+
<AppContainer>
8+
<App />
9+
</AppContainer>,
10+
document.getElementById('app')
11+
)
12+
13+
// Hot Module Replacement API
14+
if (module.hot) {
15+
module.hot.accept('./App', () => {
16+
const NextApp = require('./App').default
17+
render(
18+
<AppContainer>
19+
<NextApp/>
20+
</AppContainer>,
21+
document.getElementById('app')
22+
)
23+
})
24+
}

0 commit comments

Comments
 (0)