-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
bc7302f
commit d91d667
Showing
21 changed files
with
1,103 additions
and
140 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
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
This file was deleted.
Oops, something went wrong.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,28 +1,38 @@ | ||
import React, { Component } from 'react'; | ||
import logo from './logo.svg'; | ||
import './App.css'; | ||
import React, { Component } from 'react' | ||
import { HashRouter, Switch, Route, Redirect } from 'react-router-dom' | ||
import routeConfig from './routeConfig' | ||
import AppHeader from './Component/Common/AppHeader' | ||
import NoFoundPage from './Component/Page/NotFound' | ||
import 'bulma/css/bulma.min.css' | ||
|
||
class App extends Component { | ||
render() { | ||
render () { | ||
return ( | ||
<div className="App"> | ||
<header className="App-header"> | ||
<img src={logo} className="App-logo" alt="logo" /> | ||
<p> | ||
Edit <code>src/App.js</code> and save to reload. | ||
</p> | ||
<a | ||
className="App-link" | ||
href="https://reactjs.org" | ||
target="_blank" | ||
rel="noopener noreferrer" | ||
> | ||
Learn React | ||
</a> | ||
</header> | ||
</div> | ||
); | ||
<HashRouter> | ||
<div className='App'> | ||
<AppHeader | ||
name='Test App' | ||
link='https://sky172839465.github.io/test-app' | ||
/> | ||
<section className='section'> | ||
<div className='container is-fluid'> | ||
<Switch> | ||
<Route exact path='/' render={() => <Redirect to={routeConfig[0].path} />} /> | ||
{routeConfig.map(route => { | ||
return <Route | ||
path={route.path} | ||
component={route.component} | ||
key={route.page} | ||
/> | ||
})} | ||
<Route component={NoFoundPage} /> | ||
</Switch> | ||
</div> | ||
</section> | ||
</div> | ||
</HashRouter> | ||
) | ||
} | ||
} | ||
|
||
export default App; | ||
export default App |
This file was deleted.
Oops, something went wrong.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import React from 'react' | ||
|
||
const AppHeader = ({name, link}) => { | ||
return ( | ||
<nav className='navbar is-primary' role='navigation' aria-label='main navigation'> | ||
<div className='navbar-brand'> | ||
<a className='navbar-item' href={link}> | ||
{name} | ||
</a> | ||
</div> | ||
</nav> | ||
) | ||
} | ||
|
||
export default AppHeader |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import React from 'react' | ||
|
||
const AppLoading = (props) => { | ||
return ( | ||
<div>loading</div> | ||
) | ||
} | ||
|
||
export default AppLoading |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import React from 'react' | ||
import clx from 'classnames' | ||
|
||
const ResultNotFound = ({className = 'is-primary', onDelete, children}) => ( | ||
<div className={clx('notification', className)}> | ||
<button className='delete' onClick={onDelete} /> | ||
{children} | ||
</div> | ||
) | ||
|
||
export default ResultNotFound |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import React from 'react' | ||
|
||
const NotFound = ({message = 'Oops! Not found page.'}) => { | ||
return ( | ||
<div | ||
data-role='not-found' | ||
className='is-size-3 has-text-centered' | ||
> | ||
{message} | ||
</div> | ||
) | ||
} | ||
|
||
export default NotFound |
Empty file.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import React from 'react' | ||
|
||
const RepoCard = (props) => { | ||
const {repo = {}} = props | ||
const { | ||
name, | ||
description, | ||
html_url: link | ||
} = repo | ||
|
||
return ( | ||
<div className='card'> | ||
<div className='card-content'> | ||
<p className='subtitle'> | ||
{name} | ||
</p> | ||
</div> | ||
<div data-role='desc' className='card-content'> | ||
{description} | ||
</div> | ||
<footer className='card-footer'> | ||
<p className='card-footer-item'> | ||
<span> | ||
See in <a target='_block' href={link}>Github</a> | ||
</span> | ||
</p> | ||
</footer> | ||
</div> | ||
) | ||
} | ||
|
||
export default RepoCard |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import React from 'react' | ||
import clx from 'classnames' | ||
import styles from './index.module.scss' | ||
|
||
const SearchArea = (props) => { | ||
const { | ||
userName, | ||
isEmptyUserName, | ||
isLoading, | ||
onSubmitForm, | ||
onUserNameChange | ||
} = props | ||
|
||
return ( | ||
<form onSubmit={onSubmitForm}> | ||
<div className={clx('field is-grouped', styles.searchArea)}> | ||
<div className='control is-expanded'> | ||
<input | ||
type='text' | ||
name='userName' | ||
className={clx( | ||
'input is-fullwidth', | ||
{'is-primary': !isEmptyUserName}, | ||
{'is-danger': isEmptyUserName} | ||
)} | ||
placeholder='Find user' | ||
onChange={onUserNameChange} | ||
value={userName} | ||
readOnly={isLoading} | ||
/> | ||
{ | ||
isEmptyUserName && | ||
<p data-role='error-msg' className='help is-danger'> | ||
This field is required | ||
</p> | ||
} | ||
</div> | ||
<div className='control'> | ||
<button | ||
type='submit' | ||
className={clx( | ||
'button is-primary is-outlined', | ||
{'is-loading': isLoading} | ||
)} | ||
disabled={isEmptyUserName} | ||
> | ||
Search | ||
</button> | ||
</div> | ||
</div> | ||
</form> | ||
) | ||
} | ||
|
||
export default SearchArea |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
.searchArea { | ||
height: 3rem; | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
import React, {Component} from 'react' | ||
import {withRouter} from 'react-router-dom' | ||
import clx from 'classnames' | ||
import _ from 'lodash' | ||
import {API_END_POINT} from '../../../constant' | ||
import SearchArea from './SearchArea' | ||
import RepoCard from './RepoCard' | ||
import ResultNotFound from '../../Common/ResultNotFound' | ||
|
||
class Search extends Component { | ||
constructor () { | ||
super() | ||
this.state = { | ||
userName: '', | ||
isLoading: false, | ||
repoList: [] | ||
} | ||
} | ||
|
||
componentDidMount () { | ||
const {location} = this.props | ||
const params = new URLSearchParams(_.get(location, 'search', '')) | ||
const defaultUserName = params.get('userName') || '' | ||
this.setState( | ||
() => ({userName: defaultUserName}), | ||
() => !_.isEmpty(defaultUserName) && this.submitForm() | ||
) | ||
} | ||
|
||
submitForm = (event) => { | ||
const {history, location} = this.props | ||
const {userName} = this.state | ||
if (event) { | ||
event.preventDefault() | ||
history.push({ | ||
pathname: _.get(location, 'pathname', ''), | ||
search: `?${_.toString(new URLSearchParams({userName}))}` | ||
}) | ||
} | ||
this.setState({ | ||
isLoading: true, | ||
message: '', | ||
repoList: [] | ||
}) | ||
|
||
fetch(`${API_END_POINT}/users/${userName}/repos`) | ||
.then(resp => resp.json()) | ||
.then(data => { | ||
const message = _.get(data, 'message', _.isEmpty(data) ? 'Not Found' : '') | ||
const repoList = _.isEmpty(message) ? data : [] | ||
this.setState({ | ||
repoList, | ||
message, | ||
isLoading: false | ||
}) | ||
}) | ||
.catch(error => { | ||
this.setState({ | ||
isLoading: false, | ||
message: _.get(error, 'message', '') | ||
}) | ||
}) | ||
} | ||
|
||
onUserNameChange = e => this.setState({userName: e.target.value}) | ||
|
||
render () { | ||
const { | ||
userName, | ||
isLoading, | ||
repoList, | ||
message | ||
} = this.state | ||
const isEmptyUserName = _.isEmpty(userName) | ||
const searchAreaProps = { | ||
userName, | ||
isEmptyUserName, | ||
isLoading, | ||
onSubmitForm: this.submitForm, | ||
onUserNameChange: this.onUserNameChange | ||
} | ||
const repoCardProps = { | ||
} | ||
const resultNotFoundProps = { | ||
className: '', | ||
onDelete: () => this.setState({message: ''}) | ||
} | ||
return ( | ||
<React.Fragment> | ||
<SearchArea {...searchAreaProps} /> | ||
<div className='m-t-20'> | ||
{ | ||
_.isEmpty(message) | ||
? ( | ||
<div data-role='result-area' className='columns is-multiline'> | ||
{repoList.map((repo, index) => ( | ||
<div | ||
key={index} | ||
className={clx( | ||
'column', | ||
'is-full-mobile', | ||
'is-half-tablet', | ||
'is-one-third-desktop', | ||
'is-one-quarter-widescreen' | ||
)}> | ||
<RepoCard repo={repo} {...repoCardProps} /> | ||
</div> | ||
))} | ||
</div> | ||
) | ||
: <ResultNotFound {...resultNotFoundProps}>{message}</ResultNotFound> | ||
} | ||
</div> | ||
</React.Fragment> | ||
) | ||
} | ||
} | ||
|
||
export default withRouter(Search) |
Oops, something went wrong.