Last active
December 31, 2018 23:24
-
-
Save jeffeb3/b8eb060a564ca767679c6baff7351854 to your computer and use it in GitHub Desktop.
Trying out a wine scoring thing using react and boostrap but not using npm...
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
<!DOCTYPE html> | |
<html> | |
<head lang="en"> | |
<meta charset="UTF-8"> | |
<title>Flask React</title> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<!-- styles --> | |
<!-- Latest compiled and minified CSS --> | |
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> | |
</head> | |
<body> | |
<div class="container"> | |
<div id="root"></div> | |
</div> | |
<!-- scripts --> | |
<!-- Reactstrap Required dependencies --> | |
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/prop-types/15.6.1/prop-types.min.js"></script> | |
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/react/16.3.2/umd/react.production.min.js"></script> | |
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/react-dom/16.3.2/umd/react-dom.production.min.js"></script> | |
<!-- Reactstrap Optional dependencies --> | |
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/react-transition-group/2.2.1/react-transition-group.min.js"></script> | |
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script> | |
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/react-popper/0.10.4/umd/react-popper.min.js"></script> | |
<!-- Reactstrap --> | |
<script type="text/javascript" src="https://unpkg.com/[email protected]/dist/reactstrap.full.min.js"></script> | |
<!-- babel for converting the script --> | |
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> | |
<script type="text/babel" charset="utf-8"> | |
console.log("Hello, this is a log statement"); | |
// "Import" the components from Reactstrap | |
const { | |
Button, | |
ButtonToolbar, | |
Card, | |
CardBody, | |
CardHeader, | |
CardText, | |
Collapse, | |
Form, | |
FormGroup, | |
ListGroup, | |
ListGroupItem, | |
} = Reactstrap; | |
class WineHeader extends React.Component { | |
render() { | |
return ( | |
<div> | |
<h3>Hello {this.props.username}, You've tasted {this.props.tasted} wines and you have liked {this.props.liked} of them.</h3> | |
</div> | |
) | |
} | |
}; | |
class WineFooter extends React.Component { | |
render() { | |
return ( | |
<div> | |
<h3>When you're totally done, click this submit button</h3> | |
<Button color="primary">Submit Scores</Button> | |
</div> | |
) | |
} | |
}; | |
class ScoreButton extends React.Component { | |
render() { | |
return ( | |
<Button | |
color={this.props.chosenScore === this.props.value ? "primary" : "secondary"} | |
active={this.props.chosenScore === this.props.value} | |
onClick={() => this.props.doClick(this.props.value)} | |
> | |
{this.props.value} | |
</Button> | |
) | |
} | |
}; | |
class WineScore extends React.Component { | |
constructor (props) { | |
super(props); | |
this.state = { | |
expanded: false, | |
}; | |
this.onClick = this.onClick.bind(this); | |
} | |
onClick() { | |
this.setState({ expanded: !this.state.expanded }); | |
} | |
render() { | |
let scores = Array(8).fill().map((_, i) => { | |
return (<ScoreButton value={i+1} chosenScore={this.props.currentScore} doClick={(score) => this.props.doClick(this.props.wineNum, score)}/>); | |
}); | |
let activeClassName = ""; | |
if (this.state.expanded) { | |
activeClassName = "active"; | |
} | |
return ( | |
<ListGroupItem> | |
<ListGroup> | |
<ListGroupItem className={activeClassName} onClick={this.onClick}> | |
<h5>Wine {this.props.wineNum + 1}</h5> | |
</ListGroupItem> | |
<Collapse isOpen={this.state.expanded}> | |
<ListGroupItem> | |
<ButtonToolbar> | |
{scores} | |
</ButtonToolbar> | |
</ListGroupItem> | |
</Collapse> | |
</ListGroup> | |
</ListGroupItem> | |
) | |
}; | |
}; | |
class WineList extends React.Component { | |
render() { | |
let wineScores = Array(this.props.numWines).fill().map((_,i) => { | |
return <WineScore wineNum={i} currentScore={this.props.scores[i]} doClick={this.props.doClick}/> | |
}); | |
return ( | |
<ListGroup> | |
{wineScores} | |
</ListGroup> | |
) | |
} | |
}; | |
class UserPage extends React.Component { | |
constructor (props) { | |
super(props); | |
this.state = { | |
// This currentScore object is where the scores get filled at the beginning. This might | |
// be where you would populate it from the stored information in Python. | |
currentScore: Array(props.numWines).fill(0), | |
// These items are computed, so they may not belong in state, but it was an easy place | |
// to put them. | |
tasted: 0, | |
liked: 0, | |
}; | |
this.setScore = this.setScore.bind(this); | |
} | |
// setScore gets called way down on each button, and it gets called with the wine number and | |
// the score written on the button. This updates the state, which causes things to be | |
// redrawn, and make it look like it's been selected. It also is where you would attach any | |
// external calls to ajax, or a post call, or whatever. | |
setScore(wineNum, score) { | |
// Set the score for this press. | |
this.state.currentScore[wineNum] = score; | |
// Compute some "stats" | |
this.state.tasted = 0; | |
this.state.liked = 0; | |
this.state.currentScore.forEach((score) => { | |
if (score !== 0) { | |
this.state.tasted += 1; | |
} | |
if (score > 4) { | |
this.state.liked += 1; | |
} | |
}); | |
// Reset the "state", which will force a redraw. | |
this.setState({ | |
currentScore: [...this.state.currentScore], | |
tasted: this.state.tasted, | |
liked: this.state.liked, | |
}); | |
// Do whatever you want right here. The current scores just changed. | |
} | |
render() { | |
return ( | |
<div> | |
<WineHeader username="Jeff" tasted={this.state.tasted} liked={this.state.liked}/> | |
<WineList numWines={4} scores={this.state.currentScore} doClick={this.setScore}/> | |
<WineFooter/> | |
</div> | |
) | |
}; | |
}; | |
// Render a Reactstrap Button element onto root | |
ReactDOM.render( | |
React.createElement(UserPage, null), | |
document.getElementById('root') | |
); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment