Filling out Redux structure to encompass the full app, with API calls to get currentChapter text

This commit is contained in:
Alex Hunt 2017-11-05 18:59:18 -05:00
parent 063a63ba72
commit 13bde03424
14 changed files with 175 additions and 54 deletions

View File

@ -5,24 +5,24 @@ from elasticsearch import Elasticsearch
#TODO: Extract to config
ELASTICSEARCH_HOST = '127.0.0.1:9200'
es = Elasticsearch(ELASTICSEARCH_HOST)
# if es.ping() == True?
print 'API initialized!'
api = Blueprint('api', __name__)
doc_type = 'chapter'
# Get all chapters
@api.route('/chapters/')
def get_chapters():
search = es.search(
index='joyce',
doc_type='chapters',
doc_type=doc_type,
_source_exclude=['text'],
body={
'query': {'match_all': {}},
'sort': [
{'id': {'order': 'asc'}}
]
}
}
)
res = []
for x in search['hits']['hits']:
@ -32,20 +32,24 @@ def get_chapters():
# Get specific chapter
@api.route('/chapters/<int:id>')
def get_chapter(id):
res = es.get_source(index='joyce', doc_type='chapters', id=id, _source=True)
res = es.get_source(index='joyce', doc_type=doc_type, id=id)
return jsonify(res)
# Create and update chapters
@api.route('/chapters/<int:id>', methods=['POST', 'PUT'])
def write_chapter(id):
def es_index(data):
return es.index(index='joyce', doc_type='chapter', id=id, body=data)
if request.method == 'POST':
if es.exists(index='joyce', doc_type='chapters', id=id):
res = es.exists(index='joyce', doc_type='chapters', id=id)
if es.exists(index='joyce', doc_type=doc_type, id=id):
res = 'That already exists.'
else:
res = es.index(index='joyce', doc_type='chapters', id=id, body=request.data)
res = es_index(request.data)
else:
if es.exists(index='joyce', doc_type='chapters', id=id):
res = es.index(index='joyce', doc_type='chapters', id=id, body=request.data)
if es.exists(index='joyce', doc_type=doc_type, id=id):
res = es_index(request.data)
else:
res = 'That doesn\'t exist.'
return jsonify(res)
@ -53,5 +57,5 @@ def write_chapter(id):
# Delete chapter
@api.route('/chapters/<int:id>', methods=['DELETE'])
def delete_chapter(id):
res = es.delete(index='joyce', doc_type='chapters', id=id)
res = es.delete(index='joyce', doc_type=doc_type, id=id)
return jsonify(res)

View File

@ -1,5 +1,9 @@
export const setCurrentChapter = id =>
const setCurrentChapter = id =>
({
type: 'SET_CURRENT_CHAPTER',
type: 'GET_TEXT_DATA',
id: id
})
})
export {
setCurrentChapter
}

View File

@ -0,0 +1,8 @@
import React from 'react'
const ChapterButton = ({chapter, onClick}) =>
<div className ='text-center'>
<a onClick={onClick} className='chapter_button btn btn-default btn-lg'>{chapter.name}</a>
</div>
export default ChapterButton

View File

@ -0,0 +1,11 @@
import React from 'react'
import ChapterButton from './ChapterButton'
const ChapterList = ({chapters, onChapterClick}) =>
<div>
{chapters.map(chapter =>
<ChapterButton key={chapter.id} chapter={chapter} onClick={()=>onChapterClick(chapter.id)}/>
)}
</div>
export default ChapterList

View File

@ -1,4 +1,5 @@
import React from 'react'
import ChapterListContainer from '../containers/ChapterListContainer'
// render() {
// return (
@ -10,19 +11,4 @@ import React from 'react'
// </div>
// );
// }
// }
const ChapterList = ({chapters, onChapterClick}) =>
<div>
{console.log(chapters)}
{chapters.map(chapter =>
<ChapterButton key={chapter.id} chapter={chapter} onClick={()=>onChapterClick(chapter.id)}/>
)}
</div>
const ChapterButton = ({chapter, onClick}) =>
<div className ='text-center'>
<a href={chapter.id} onClick={onClick} className='chapter_button btn btn-default btn-lg'>{chapter.name}</a>
</div>
export default ChapterList
// }

View File

@ -0,0 +1,9 @@
import React from 'react'
import ChapterListContainer from '../containers/ChapterListContainer'
const Sidebar = () =>
<div className="col-xs-4" id="sidebar">
<ChapterListContainer />
</div>
export default Sidebar

View File

@ -0,0 +1,25 @@
import React from 'react'
import { connect } from 'react-redux'
import { setCurrentChapter } from '../actions/actions'
import ChapterList from '../components/chapterList'
const mapStateToProps = state => {
return {
chapters: state.chapters,
currentChapter: state.currentChapter
}
}
const mapDispatchToProps = dispatch => {
return {
onChapterClick: id => {
dispatch(setCurrentChapter(id))
}
}
}
const ChapterListContainer = connect(mapStateToProps, mapDispatchToProps)(ChapterList)
export default ChapterListContainer

View File

@ -1,9 +1,10 @@
import { connect } from 'react-redux'
import ChapterList from '../components'
import { setCurrentChapter } from '../actions/actions'
const mapStateToProps = state => {
// console.log('State is:')
// console.log(state)
console.log('State is:')
console.log(state)
return {
chapters: state.chapters,
currentChapter: state.currentChapter
@ -18,6 +19,4 @@ const mapDispatchToProps = dispatch => {
}
}
const ChapterListContainer = connect(mapStateToProps, mapDispatchToProps)(ChapterList)
export default ChapterListContainer
export const ChapterListContainer = connect(mapStateToProps, mapDispatchToProps)(ChapterList)

View File

@ -0,0 +1,34 @@
import React from 'react'
import { connect } from 'react-redux'
import ChapterList from '../components'
import { setCurrentChapter } from '../actions/actions'
class Page extends React.Component {
render() {
{console.log(this.props.currentChapter)}
return (
<div className="col-xs-8" id="reader">
{this.props.currentChapter.text}
</div>
)
}
}
const mapStateToProps = state => {
return {
chapters: state.chapters,
currentChapter: state.currentChapter
}
}
const mapDispatchToProps = dispatch => {
return {
onChapterClick: id => {
dispatch(setCurrentChapter(id))
}
}
}
const PageContainer = connect(mapStateToProps, mapDispatchToProps)(Page)
export default PageContainer

View File

@ -0,0 +1,35 @@
import React from 'react'
import { connect } from 'react-redux'
import { setCurrentChapter } from '../actions/actions'
import Sidebar from '../components/sidebar'
import PageContainer from '../containers/pageContainer'
class Reader extends React.Component {
render() {
return (
<div className="row">
<Sidebar />
<PageContainer />
</div>
)
}
}
const mapStateToProps = state => {
return {
chapters: state.chapters,
currentChapter: state.currentChapter
}
}
const mapDispatchToProps = dispatch => {
return {
onChapterClick: id => {
dispatch(setCurrentChapter(id))
}
}
}
export const ReaderContainer = connect(mapStateToProps, mapDispatchToProps)(Reader)

View File

@ -1,10 +1,12 @@
import axios from 'axios'
let apiRoute = 'api/chapters/'
const joyceAPIService = state => next => action => {
next(action)
switch(action.type) {
case 'GET_CHAPTER_DATA':
axios.get('/api/chapters').then(res => {
axios.get(apiRoute).then(res => {
const data = res.data
return next({
type: 'GET_CHAPTER_DATA_RECEIVED',
@ -16,7 +18,21 @@ const joyceAPIService = state => next => action => {
error
})
})
break
break
case 'GET_TEXT_DATA':
axios.get(apiRoute + action.id).then(res=> {
const data = res.data
return next({
type: 'GET_TEXT_DATA_RECEIVED',
data
})
}).catch(error => {
return next({
type: 'GET_TEXT_DATA_ERROR',
error
})
})
break
defaut:
break
}

View File

@ -2,17 +2,18 @@ import React from 'react'
import ReactDOM from 'react-dom'
import { createStore, applyMiddleware } from 'redux'
import { Provider } from 'react-redux'
import readerApp from './reducers'
import ChapterListContainer from './containers'
import joyceAPIService from './middleware'
import { ReaderContainer } from './containers/readerContainer'
let store = createStore(readerApp, applyMiddleware(joyceAPIService))
ReactDOM.render(
<Provider store={store}>
<ChapterListContainer />
<ReaderContainer />
</Provider>,
document.getElementById('sidebar')
document.getElementById('joyce_reader')
)
store.dispatch({type: 'GET_CHAPTER_DATA'})

View File

@ -12,11 +12,8 @@ const chapters = (state=[], action) => {
const currentChapter = (state={}, action) => {
switch(action.type) {
case 'SET_CURRENT_CHAPTER':
return objectAssign(
{}, state,
{currentChapter: {id: action.id, name: chapter.name}}
)
case 'GET_TEXT_DATA_RECEIVED':
return action.data
default:
return state
}

View File

@ -11,14 +11,6 @@
<body>
<!-- Reader Layout -->
<div id="joyce_reader" class="container-fluid">
<div class="row">
<div class="col-xs-4" id="sidebar">
</div>
<div class="col-xs-8" id="reader">
</div>
</div>
</div>
<!-- Scripts -->