Last active
August 24, 2017 23:50
-
-
Save vicneanschi/d14b4d08ce202c5fcea73c6ec2ca87dc to your computer and use it in GitHub Desktop.
React samples
This file contains hidden or 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
// 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); |
This file contains hidden or 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
// 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