Skip to content

Instantly share code, notes, and snippets.

@jmmarco
Created April 13, 2018 02:13
Show Gist options
  • Save jmmarco/d8a33e52d3cba457f306e45356b6e3bd to your computer and use it in GitHub Desktop.
Save jmmarco/d8a33e52d3cba457f306e45356b6e3bd to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<title>Popular Repos</title>
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src='https://unpkg.com/babel-standalone@6/babel.min.js'></script>
<style>
body {
font-family: sans-serif;
}
h1, label{
margin-left: 20px;
}
h2 {
text-align: center;
}
.flex-container {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.list {
width: 200px;
border: 1px solid darkgrey;
margin: 5px;
-webkit-box-shadow: 5px 5px 5px 0 rgba(56,55,56,1);
box-shadow: 5px 5px 5px 0 rgba(56,55,56,1);
padding: 10px;
list-style: none;
border-radius: 5px;
}
.list li {
line-height: 1.5em;
}
.loader {
display: flex;
justify-content: center;
align-content: center;
font-size: 40px;
font-weight: bold;
letter-spacing: 5px;
}
.name-link {
text-decoration: none;
}
label {
font-size: 26px;
font-weight: bold;
}
select {
-webkit-border-radius: 0;
border-radius: 0;
}
</style>
</head>
<body>
<div id='app'></div>
<script>
window.API = {
fetchPopularRepos(language) {
// "language" can be "javascript", "ruby", "python", or "all"
const encodedURI = encodeURI(`https://api.github.com/search/repositories?q=stars:>1+language:${language}&sort=stars&order=desc&type=Repositories`)
return fetch(encodedURI)
.then((data) => data.json())
.then((repos) => repos.items)
.catch((error) => {
console.warn(error)
return null
});
}
}
</script>
<script type='text/babel'>
class Loading extends React.Component {
constructor(props) {
super(props);
this.state = {
text: 'Loading',
};
}
componentDidMount() {
const stopper = this.state.text + '...';
this.interval = window.setInterval(() => {
this.state.text === stopper
? this.setState(() => ({ text: 'Loading' }))
: this.setState((prevState) => ({ text: prevState.text + '.' }))
}, 300)
}
componentWillUnmount() {
window.clearInterval(this.interval);
}
render() {
return (
<p className="loader">
{this.state.text}
</p>
)
}
}
function Repo(props) {
const { owner, url, stargazers_count, html_url, name } = props.repo
return (
<ul className="list">
<li><a className="name-link" href={html_url} target="_blank">{name}</a></li>
<li>@{owner.login}</li>
<li>⭐{stargazers_count}</li>
</ul>
)
}
class LanguageSelect extends React.Component {
constructor(props) {
super(props)
// We're gonna lift the state..
// this.state = {
// value: 'all',
// }
this.handleChange = this.handleChange.bind(this)
}
handleChange(e) {
this.props.onRepoChange(e.target.value)
}
render() {
const language = this.props.language
return (
<div>
<label>Select a language:</label>
<select value={language} onChange={this.handleChange}>
<option defaultValue="all">all</option>
<option value="javascript">javascript</option>
<option value="ruby">ruby</option>
<option value="python">python</option>
</select>
</div>
)
}
}
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
repos: [],
language: 'all',
loading: true,
}
this.handleLanguageChange = this.handleLanguageChange.bind(this)
}
componentDidMount() {
API.fetchPopularRepos(this.state.language)
.then((repos) => {
this.setState({
repos,
loading: false
})
})
}
componentDidUpdate() {
// Did not use it
}
handleLanguageChange(language) {
API.fetchPopularRepos(language)
.then((repos) => {
this.setState({
repos,
language
})
})
}
render() {
const {repos} = this.state
return (
<div>
<h1>Popular GitHub Repos</h1>
{
this.state.loading === true ?
<Loading />
:
<div>
<LanguageSelect onRepoChange={this.handleLanguageChange} language={this.state.language}/>
<h2>{this.state.language}</h2>
<div className="flex-container">
{repos && repos.map((repo) => {
return (
<Repo key={repo.id} repo={repo} />
)
})}
</div>
</div>
}
</div>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('app')
)
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment