Skip to content

Commit

Permalink
Add starter website
Browse files Browse the repository at this point in the history
  • Loading branch information
sky172839465 committed Feb 6, 2019
1 parent bc7302f commit d91d667
Show file tree
Hide file tree
Showing 21 changed files with 1,103 additions and 140 deletions.
736 changes: 723 additions & 13 deletions package-lock.json

Large diffs are not rendered by default.

16 changes: 12 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,14 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^16.8.0",
"react-dom": "^16.8.0",
"react-scripts": "2.1.3"
"bulma": "^0.7.2",
"classnames": "^2.2.6",
"lodash": "^4.17.11",
"react": "16.6.3",
"react-dom": "16.6.3",
"react-loadable": "^5.5.0",
"react-router-dom": "^4.3.1",
"react-scripts": "^2.1.3"
},
"scripts": {
"start": "react-scripts start",
Expand All @@ -21,5 +26,8 @@
"not dead",
"not ie <= 11",
"not op_mini all"
]
],
"devDependencies": {
"node-sass": "^4.11.0"
}
}
32 changes: 0 additions & 32 deletions src/App.css

This file was deleted.

54 changes: 32 additions & 22 deletions src/App.js
100755 → 100644
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
9 changes: 0 additions & 9 deletions src/App.test.js

This file was deleted.

15 changes: 15 additions & 0 deletions src/Component/Common/AppHeader/index.js
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
9 changes: 9 additions & 0 deletions src/Component/Common/AppLoading/index.js
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
11 changes: 11 additions & 0 deletions src/Component/Common/ResultNotFound/index.js
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
14 changes: 14 additions & 0 deletions src/Component/Page/NotFound/index.js
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.
32 changes: 32 additions & 0 deletions src/Component/Page/Search/RepoCard/index.js
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
55 changes: 55 additions & 0 deletions src/Component/Page/Search/SearchArea/index.js
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
3 changes: 3 additions & 0 deletions src/Component/Page/Search/SearchArea/index.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.searchArea {
height: 3rem;
}
119 changes: 119 additions & 0 deletions src/Component/Page/Search/index.js
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)
Loading

0 comments on commit d91d667

Please sign in to comment.