Skip to content
Snippets Groups Projects
Commit e3f59ca3 authored by john's avatar john
Browse files

refactor booklist into dashboard and give delete book action its own modal

parent e4645f51
No related branches found
No related tags found
No related merge requests found
......@@ -20,7 +20,10 @@ export default class AddBook extends React.Component {
handleKeyOnInput (event) {
if (event.charCode !== 13) return
const { toggle } = this.props
this.onCreate()
toggle()
}
onCreate () {
......
import React from 'react'
import { Link } from 'react-router'
import RemoveBookModal from './RemoveBookModal'
import styles from './dashboard.local.scss'
class Book extends React.Component {
constructor (props) {
super(props)
this.removeBook = this.removeBook.bind(this)
this.toggleModal = this.toggleModal.bind(this)
this.state = {
showModal: false
}
}
toggleModal () {
this.setState({
showModal: !this.state.showModal
})
}
removeBook () {
const { book, remove } = this.props
remove(book)
}
renderTitle () {
const { book } = this.props
return (
<h2> { book.title } </h2>
)
}
renderEdit () {
const { book } = this.props
return (
<Link
className={styles.editBook}
to={`/books/${book.id}/book-builder`}
>
Edit
</Link>
)
}
renderRemove () {
return (
<a
className={styles.editBook}
href='#'
onClick={this.toggleModal}
>
Remove
</a>
)
}
renderButtons () {
const { book } = this.props
const edit = this.renderEdit(book)
const remove = this.renderRemove(book)
return (
<div className={styles.bookActions}>
{ edit }
{ remove }
</div>
)
}
renderRemoveModal () {
const { book, container } = this.props
const { showModal } = this.state
if (!showModal) return null
return (
<RemoveBookModal
book={book}
container={container}
remove={this.removeBook}
show={showModal}
toggle={this.toggleModal}
/>
)
}
render () {
const { book } = this.props
const title = this.renderTitle(book)
const buttons = this.renderButtons(book)
const removeModal = this.renderRemoveModal()
return (
<div className={styles.bookContainer}>
{ title }
{ buttons }
{ removeModal }
</div>
)
}
}
Book.propTypes = {
book: React.PropTypes.object.isRequired,
container: React.PropTypes.object.isRequired,
remove: React.PropTypes.func.isRequired
}
export default Book
import { map, reverse, sortBy } from 'lodash'
import React from 'react'
import Book from './Book'
class BookList extends React.Component {
renderBookList () {
const { books, container, remove } = this.props
if (!books) return 'Fetching...'
const items = reverse(sortBy(books, 'created'))
const bookComponents = map(items, book => {
return (
<Book
book={book}
container={container}
key={book.id}
remove={remove}
/>
)
})
return bookComponents
}
render () {
const bookList = this.renderBookList()
return (
<div className='col-lg-12'>
{ bookList }
</div>
)
}
}
BookList.propTypes = {
books: React.PropTypes.array.isRequired,
container: React.PropTypes.object.isRequired,
remove: React.PropTypes.func.isRequired
}
export default BookList
......@@ -2,15 +2,19 @@ import Actions from 'pubsweet-client/src/actions'
import React from 'react'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import { Link } from 'react-router'
// import { Link } from 'react-router'
import AddBook from './AddBook'
import styles from './styles/bookList.local.scss'
import BookList from './BookList'
import DashboardHeader from './DashboardHeader'
import styles from './dashboard.local.scss'
export class BookList extends React.Component {
export class Dashboard extends React.Component {
constructor (props) {
super(props)
this.createCollection = this.createCollection.bind(this)
this.removeCollection = this.removeCollection.bind(this)
this.toggleModal = this.toggleModal.bind(this)
this.state = {
......@@ -19,57 +23,44 @@ export class BookList extends React.Component {
}
toggleModal () {
this.setState({ showModal: !this.state.showModal })
this.setState({
showModal: !this.state.showModal
})
}
createCollection = newTitle => {
createCollection (newTitle) {
const { createCollection } = this.props.actions
const collection = { title: newTitle || 'Untitled' }
createCollection(collection)
this.toggleModal()
}
_removeCollection = (collection) => {
if (confirm('Remove this book?')) {
this.props.actions.deleteCollection(collection)
const collection = {
title: newTitle || 'Untitled'
}
createCollection(collection)
}
_sortNewestFirst = (a, b) => {
return (b.created < a.created) ? -1 : ((b.created > a.created) ? 1 : 0)
removeCollection (collection) {
const { deleteCollection } = this.props.actions
deleteCollection(collection)
}
render () {
const { books } = this.props
const { showModal } = this.state
const className = styles.bookList +
' bootstrap pubsweet-component pubsweet-component-scroll'
return (
<div className={styles.bookList + ' bootstrap pubsweet-component pubsweet-component-scroll'}>
<div className={className}>
<div className='container col-lg-offset-2 col-lg-8'>
<div className='col-lg-12'>
<h1 className={styles.bookTitle}>
Books
<div className={styles.addBookBtn} onClick={this.toggleModal}>
<a>add book</a>
</div>
</h1>
</div>
<div className='col-lg-12'>
{books ? books.sort(this._sortNewestFirst).map(book => (
<div key={book.id} className={styles.bookContainer}>
<h2>{book.title}</h2>
<div className={styles.bookActions}>
<Link to={`/books/${book.id}/book-builder`} className={styles.editBook}>Edit</Link>
<a href='#' onClick={() => this._removeCollection(book)} className={styles.editBook}>Remove</a>
</div>
</div>
)) : 'Fetching…' }
</div>
<DashboardHeader toggle={this.toggleModal} />
<BookList
books={books}
container={this}
remove={this.removeCollection}
/>
</div>
<AddBook
......@@ -83,7 +74,7 @@ export class BookList extends React.Component {
}
}
BookList.propTypes = {
Dashboard.propTypes = {
books: React.PropTypes.arrayOf(React.PropTypes.object),
actions: React.PropTypes.object.isRequired
}
......@@ -103,4 +94,4 @@ function mapDispatchToProps (dispatch) {
export default connect(
mapStateToProps,
mapDispatchToProps
)(BookList)
)(Dashboard)
import React from 'react'
import styles from './dashboard.local.scss'
class DashboardHeader extends React.Component {
render () {
const { toggle } = this.props
return (
<div className='col-lg-12'>
<h1 className={styles.bookTitle}>
Books
<div
className={styles.addBookBtn}
onClick={toggle}
>
<a>add book</a>
</div>
</h1>
</div>
)
}
}
DashboardHeader.propTypes = {
toggle: React.PropTypes.func.isRequired
}
export default DashboardHeader
import React from 'react'
import AbstractModal from '../common/AbstractModal'
class RemoveBookModal extends React.Component {
renderBody () {
const { book } = this.props
return (
<span>
Are you sure you want to permanently delete { book.title }?
</span>
)
}
render () {
const { container, remove, show, toggle } = this.props
const title = 'Delete Book'
const successText = 'Delete'
const body = this.renderBody()
return (
<AbstractModal
body={body}
container={container}
show={show}
successAction={remove}
successText={successText}
title={title}
toggle={toggle}
/>
)
}
}
RemoveBookModal.propTypes = {
book: React.PropTypes.object.isRequired,
container: React.PropTypes.object.isRequired,
remove: React.PropTypes.func.isRequired,
show: React.PropTypes.bool.isRequired,
toggle: React.PropTypes.func.isRequired
}
export default RemoveBookModal
......@@ -2,6 +2,18 @@ import React from 'react'
import { Modal } from 'react-bootstrap'
export class BookBuilderModal extends React.Component {
constructor (props) {
super(props)
this.performAction = this.performAction.bind(this)
}
performAction () {
const { successAction, toggle } = this.props
successAction()
toggle()
}
renderHeader () {
const { title } = this.props
......@@ -28,7 +40,7 @@ export class BookBuilderModal extends React.Component {
const { successAction, successText, toggle } = this.props
const success = successAction ? <a className='modal-button bb-modal-act'
onClick={successAction}>
onClick={this.performAction}>
{ successText }
</a> : null
......
......@@ -11,7 +11,7 @@ import Blog from 'pubsweet-component-blog/Blog'
// Editoria
import BookBuilder from './components/BookBuilder/BookBuilder'
import BookList from './components/BookBuilder/BookList'
import Dashboard from './components/Dashboard/Dashboard'
import SimpleEditorWrapper from './components/SimpleEditor/SimpleEditorWrapper'
// Authentication
......@@ -38,7 +38,7 @@ export default (
<Redirect from='/manage/posts' to='books' />
<Route path='/' component={AuthenticatedManage}>
<Route path='books' component={BookList} />
<Route path='books' component={Dashboard} />
<Route path='blog' component={Blog} />
<Route path='books/:id/book-builder' component={BookBuilder} />
<Route path='books/:bookId/fragments/:fragmentId' component={SimpleEditorWrapper} />
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment