Skip to content

Instantly share code, notes, and snippets.

@vicneanschi
Last active August 24, 2017 23:50
Show Gist options
  • Save vicneanschi/d14b4d08ce202c5fcea73c6ec2ca87dc to your computer and use it in GitHub Desktop.
Save vicneanschi/d14b4d08ce202c5fcea73c6ec2ca87dc to your computer and use it in GitHub Desktop.
React samples
// use https://jscomplete.com/repl to test
var possibleCombinationSum = function(arr, n) {
if (arr.indexOf(n) >= 0) { return true; }
if (arr[0] > n) { return false; }
if (arr[arr.length - 1] > n) {
arr.pop();
return possibleCombinationSum(arr, n);
}
var listSize = arr.length, combinationsCount = (1 << listSize)
for (var i = 1; i < combinationsCount ; i++ ) {
var combinationSum = 0;
for (var j=0 ; j < listSize ; j++) {
if (i & (1 << j)) { combinationSum += arr[j]; }
}
if (n === combinationSum) { return true; }
}
return false;
};
const Stars = (props) => {
return (
<div className="col-5">
{_.range(props.numberOfStars).map(i => <i key={i} className="fa fa-star"></i>)}
</div>
)
}
const Button = (props) => {
let button;
switch(props.answerIsCorrect) {
case true:
button =
<button className="btn btn-success" onClick={props.acceptAnswer}>
<i className="fa fa-check"></i>
</button>;
break;
case false:
button =
<button className="btn btn-danger">
<i className="fa fa-times"></i>
</button>
break;
default:
button =
<button className="btn"
onClick={props.checkAnswer}
disabled={props.selectedNumbers.length === 0}>
=
</button>
break;
}
return (
<div className="col-2">
{button}
<button className="btn btn-warning btn-sm" onClick={props.redraw}
disabled={props.redraws === 0 || props.doneStatus}>
<i className="fa fa-refresh"></i> {props.redraws}
</button>
</div>
)
}
const Answer = (props) => {
return (
<div className="col-5">
{props.selectedNumbers.map((number, i) =>
<span key={i} onClick={() => props.unselectNumber(number)}>
{number}
</span>
)}
</div>
)
}
const Numbers = (props) => {
const numberClassName = (number) => {
if (props.usedNumbers.indexOf(number) >= 0) {
return 'used';
}
if (props.selectedNumbers.indexOf(number) >= 0) {
return 'selected';
}
}
return (
<div className="card text-center">
<div>
{Numbers.list.map((number, i) =>
<span key={i} className={numberClassName(number)}
onClick={() => props.selectNumber(number)}
>{number}</span>
)}
</div>
</div>
)
}
Numbers.list = _.range(1, 10);
const DoneFrame = (props) => {
return (
<div className="text-center">
<h2>{props.doneStatus}</h2>
<button className="btn btn-secondary" onClick={props.resetGame}>
Play again
</button>
</div>
);
}
const Timer = (props) => {
return (
<h3>
Remaining time: {props.remainingTime}
</h3>
);
}
class Game extends React.Component {
static randomNumber = () => 1 + Math.floor(Math.random()*9);
static initialState = () => ({
selectedNumbers: [],
randomNumberOfStars: Game.randomNumber(),
usedNumbers: [],
answerIsCorrect: null,
redraws: 7,
doneStatus: null,
remainingTime: 60
});
startTimer = () => {
return setInterval(() => {
this.setState(prevState => ({
remainingTime: prevState.remainingTime - 1
}), this.updateDoneStatus);
}, 1000)
};
state = Game.initialState();
gameTimer = this.startTimer();
resetGame = () => {
this.setState(Game.initialState());
this.gameTimer = this.startTimer();
};
selectNumber = (clickedNumber) => {
if (this.state.selectedNumbers.indexOf(clickedNumber) >= 0 || this.state.usedNumbers.indexOf(clickedNumber) >= 0) { return; }
this.setState(prevState => ({
answerIsCorrect: null,
selectedNumbers: prevState.selectedNumbers.concat(clickedNumber)
}))
}
unselectNumber = (clickedNumber) => {
this.setState(prevState => ({
answerIsCorrect: null,
selectedNumbers: prevState.selectedNumbers.filter(number => number !== clickedNumber)
}));
}
checkAnswer = () => {
this.setState(prevState => ({
answerIsCorrect: prevState.randomNumberOfStars ===
prevState.selectedNumbers.reduce((acc, n) => acc + n, 0)
}))
};
acceptAnswer = () => {
this.setState(prevState => ({
usedNumbers: prevState.usedNumbers.concat(prevState.selectedNumbers),
selectedNumbers: [],
answerIsCorrect: null,
randomNumberOfStars: Game.randomNumber(),
}), this.updateDoneStatus);
};
redraw = () => {
if (this.state.redraws === 0) { return; }
this.setState(prevState => ({
randomNumberOfStars: Game.randomNumber(),
answerIsCorrect: null,
selectedNumbers: [],
redraws: prevState.redraws -1,
}), this.updateDoneStatus)
};
possibleSolutions = ({randomNumberOfStars, usedNumbers}) => {
const possibleNumbers = _.range(1, 10).filter(number =>
usedNumbers.indexOf(number) === -1
);
return possibleCombinationSum(possibleNumbers, randomNumberOfStars);
};
updateDoneStatus = () => {
if (this.state.remainingTime <= 0) {
clearInterval(this.gameTimer);
}
this.setState(prevState => {
if (prevState.usedNumbers.length === 9) {
return { doneStatus: 'Done. Nice!' };
}
if (prevState.remainingTime <= 0 || prevState.redraws === 0 && !this.possibleSolutions(prevState)) {
return { doneStatus: 'Game Over!' };
}
});
};
render() {
const {
selectedNumbers,
randomNumberOfStars,
usedNumbers,
answerIsCorrect,
redraws,
doneStatus,
remainingTime,
} = this.state;
return (
<div>
<h3>Play Nine</h3>
<hr />
<div className="row">
<Stars numberOfStars={randomNumberOfStars} />
<Button selectedNumbers={selectedNumbers}
redraws={redraws}
checkAnswer={this.checkAnswer}
acceptAnswer={this.acceptAnswer}
redraw={this.redraw}
answerIsCorrect={answerIsCorrect}
doneStatus={doneStatus}/>
<Answer selectedNumbers={selectedNumbers}
unselectNumber={this.unselectNumber} />
</div>
<br />
{doneStatus ?
<DoneFrame resetGame={this.resetGame} doneStatus={doneStatus} /> :
<div>
<Numbers selectedNumbers={selectedNumbers}
selectNumber={this.selectNumber}
usedNumbers={usedNumbers} />
<Timer remainingTime={remainingTime}/>
</div>
}
<br />
</div>
)
}
}
class App extends React.Component {
render() {
return (
<div>
<Game />
</div>
)
}
}
ReactDOM.render(<App />, mountNode);
// use https://jscomplete.com/repl to test
const Card = (props) => {
return (
<div>
<img src={props.avatar_url} width='75' />
<div style={{display: 'inline-block', marginLeft: 10}}>
<div>{props.name}</div>
<div>{props.company}</div>
</div>
</div>
)
}
const CardList = (props) => {
return (
<div>
{props.cards.map(card => <Card key={card.id} {...card}
/>)}
</div>
);
}
class Form extends React.Component {
state = {userName: ''};
handleSubmit = (event) => {
event.preventDefault();
axios.get(`https://api.github.com/users/${this.state.userName}`)
.then(resp => {
this.props.onSubmit(resp.data);
this.setState({ userName: ''});
});
};
render() {
return (
<form onSubmit={this.handleSubmit}>
<input type="text"
value={this.state.userName}
onChange={(event) => this.setState({userName: event.target.value })}
placeholder="Github username" />
<button type="submit">Add card</button>
</form>
);
}
}
class App extends React.Component {
state = {
cards: []
};
addNewCard = (cardInfo) => {
this.setState(prevState => ({
cards: prevState.cards.concat(cardInfo)
}));
};
render() {
return (
<div>
<Form onSubmit={this.addNewCard}/>
<CardList cards={this.state.cards} />
</div>
)
}
}
ReactDOM.render(<App />, mountNode);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment