154 lines
5.0 KiB
JavaScript
154 lines
5.0 KiB
JavaScript
'use strict'
|
|
|
|
import React from 'react'
|
|
import ReactDOM from 'react-dom'
|
|
import { BrowserRouter as Router, Route, NavLink, Switch, Redirect } from 'react-router-dom'
|
|
import Progress from './components/Progress'
|
|
import UriListItem from './containers/UriListItem'
|
|
import reducer from './reducers'
|
|
import { fetchData, createNewUrl, setEditing, editUser } from './actions'
|
|
import UnderlineInput from './components/UnderlineInput'
|
|
import '../styles/index.scss'
|
|
|
|
class App extends React.Component {
|
|
constructor () {
|
|
super()
|
|
this.state = {
|
|
error: '',
|
|
user: {
|
|
id: '',
|
|
email: '',
|
|
password: '',
|
|
currentPassword: ''
|
|
},
|
|
urls: [],
|
|
editingUrl: null,
|
|
working: false
|
|
}
|
|
|
|
this.dispatch = this.dispatch.bind(this)
|
|
this.getRegisteredUris = this.getRegisteredUris.bind(this)
|
|
this.setUserValue = this.setUserValue.bind(this)
|
|
this.saveUser = this.saveUser.bind(this)
|
|
}
|
|
dispatch (action) {
|
|
if (!action) throw new Error('dispatch: missing action')
|
|
if (action instanceof Function) {
|
|
action(this.dispatch, () => this.state)
|
|
} else {
|
|
const changes = reducer(this.state, action)
|
|
if (!changes || !Object.keys(changes).length) return
|
|
this.setState({
|
|
...changes
|
|
})
|
|
}
|
|
}
|
|
componentDidMount () {
|
|
this.dispatch(fetchData())
|
|
}
|
|
getRegisteredUris () {
|
|
return this.state.urls.map((item, i) => {
|
|
return (<UriListItem
|
|
key={i}
|
|
dispatch={this.dispatch}
|
|
item={item}
|
|
editing={this.state.editingUrl === item.id} />)
|
|
})
|
|
}
|
|
setUserValue (which, e) {
|
|
this.setState({
|
|
user: {
|
|
...this.state.user,
|
|
[which]: e.target.value
|
|
}
|
|
})
|
|
}
|
|
saveUser () {
|
|
this.dispatch(editUser(this.state.user))
|
|
this.setState({
|
|
user: {
|
|
...this.state.user,
|
|
email: this.state.user.email,
|
|
password: '',
|
|
currentPassword: ''
|
|
}
|
|
})
|
|
}
|
|
render () {
|
|
return (
|
|
<Router>
|
|
<div className='root-container flex-container' onClick={() => this.dispatch(setEditing(null))}>
|
|
<aside className='nav nav-left'>
|
|
<header>
|
|
<h1>River of Ebooks</h1>
|
|
<h2 className='flex-container'>
|
|
<span className='flex'>{this.state.user.email}</span>
|
|
<a href='/logout'>Log out</a>
|
|
</h2>
|
|
</header>
|
|
<ul>
|
|
<li><NavLink to='/targets'>Push URIs</NavLink></li>
|
|
<li><NavLink to='/account'>My account</NavLink></li>
|
|
</ul>
|
|
</aside>
|
|
<section className={'content flex' + (this.state.working ? ' working' : '')}>
|
|
<Progress bound />
|
|
{this.state.error && <div className='error-box'>{this.state.error}</div>}
|
|
<Switch>
|
|
<Route path='/targets' exact children={props => (
|
|
<div>
|
|
<header className='flex-container'>
|
|
<div className='flex'>
|
|
<h1>Push URIs</h1>
|
|
<h2>Newly published books will be sent to these addresses.</h2>
|
|
</div>
|
|
<button className='btn' onClick={() => this.dispatch(createNewUrl())}>New address</button>
|
|
</header>
|
|
<ul className='list'>
|
|
{this.getRegisteredUris()}
|
|
</ul>
|
|
</div>
|
|
)} />
|
|
|
|
<Route path='/account' exact children={props => (
|
|
<div>
|
|
<header className='flex-container'>
|
|
<div className='flex'>
|
|
<h1>My account</h1>
|
|
<h2>User account settings</h2>
|
|
</div>
|
|
</header>
|
|
<section className='inputs'>
|
|
<UnderlineInput
|
|
placeholder='Email address'
|
|
value={this.state.user.email}
|
|
pattern={/^([a-zA-Z0-9_\-.]+)@([a-zA-Z0-9_\-.]+)\.([a-zA-Z]{2,5})$/}
|
|
onChange={(e) => this.setUserValue('email', e)} />
|
|
<UnderlineInput
|
|
placeholder='Password'
|
|
type='password'
|
|
value={this.state.user.password}
|
|
onChange={(e) => this.setUserValue('password', e)} />
|
|
<UnderlineInput
|
|
placeholder='Current password'
|
|
type='password'
|
|
value={this.state.user.currentPassword}
|
|
onChange={(e) => this.setUserValue('currentPassword', e)} />
|
|
<div className='buttons'>
|
|
<button className='btn' onClick={this.saveUser}>Save</button>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
)} />
|
|
|
|
<Route path='/' render={() => <Redirect to='/targets' />} />
|
|
</Switch>
|
|
</section>
|
|
</div>
|
|
</Router>
|
|
)
|
|
}
|
|
}
|
|
|
|
ReactDOM.render(<App />, document.getElementById('root'))
|