The commit that Kirk and I made during the Static Showdown.
src/components/Button/Button.js
import React, {Component, PropTypes} from 'react'
import classes from './Button.scss'
export default class Button extends Component {
static propTypes = {
children: PropTypes.element.isRequired,
button: PropTypes.string
}
render () {
return (
<button className={classes.btn + ' btn-success'}>{this.props.children}</button>
)
}
}
src/components/Button/Button.scss
.btn {
font-size: 40px;
width: 80%;
max-width: 50%;
width: 500px;
font-family: 'Quicksand';
font-weight: 500;
font-style: normal;
text-align: center;
}
src/index.html
<!doctype html>
<html lang="en">
<head>
<title>Voyage Vault</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity_no="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="./assets/stylesheets/main.css">
<link href='https://fonts.googleapis.com/css?family=Lato:400,700italic,400italic,700,900italic,900,300italic,300,100,100italic' rel='stylesheet' type='text/css'>
<link href='https://fonts.googleapis.com/css?family=Quicksand:400,300,700' rel='stylesheet' type='text/css'>
</head>
<body>
<div id="root" style="height: 100%"></div>
</body>
</html>
src/views/EditorView/EditorView.js
import React, { Component, PropTypes } from 'react'
import { connect } from 'react-redux'
import Button from 'components/Button/Button'
import Firebase from 'firebase'
import { FIREBASE_URL } from 'redux/constants/firebase'
import DrawingEditor from 'components/editors/DrawingEditor/DrawingEditor'
import TextEditor from 'components/editors/TextEditor/TextEditor'
import { submitContent, updateNode } from '../../redux/modules/nodes'
export class EditorView extends Component {
static propTypes = {
node: PropTypes.object,
submitContent: PropTypes.func,
updateNode: PropTypes.func,
nodeId: PropTypes.string
}
componentDidMount () {
this.setupFirebase()
}
componentWillUnmount () {
this.cleanUpFirebase()
}
cleanUpFirebase () {
if (this.ref) {
this.ref.off()
}
}
setupFirebase () {
const { updateNode, nodeId } = this.props
this.cleanUpFirebase()
this.ref = new Firebase(`${FIREBASE_URL}nodes/${nodeId}`)
this.ref.on('value', (snapShot) => {
updateNode(nodeId, snapShot.val())
})
}
submitImage (content) {
const { submitContent, node, nodeId } = this.props
submitContent(node.voyage, nodeId, content, 'image')
}
submitText (content) {
const { submitContent, node, nodeId } = this.props
submitContent(node.voyage, nodeId, content, 'text')
}
generateEditor () {
const { node: { type } } = this.props
let editor
switch (type) {
case 'text':
editor = <DrawingEditor submit={::this.submitImage}/>
break
case 'image':
editor = <TextEditor submit={::this.submitText}/>
break
}
return editor
}
render () {
const { node } = this.props
if (!node) {
return <p>Loading...</p>
}
return (
<div>
{this.generateEditor()}
<Button>SUBMIT</Button>
</div>
)
}
}
const mapStateToProps = (state, ownProps) => {
const nodeId = ownProps.params.nodeId
const node = state.nodes.get(nodeId)
return {
nodeId,
node: node ? node.toJS() : undefined
}
}
export default connect(mapStateToProps, {
submitContent,
updateNode
})(EditorView)
src/views/HomeView/HomeView.js
import React, { Component } from 'react'
import { connect } from 'react-redux'
import Button from 'components/Button/Button'
export class HomeView extends Component {
render () {
return (
<div className='container text-center'>
<p>HomeView</p>
<Button>NEW VOYAGE</Button><br /><br />
<Button>RANDOM VOYAGE</Button>
</div>
)
}
}
const mapStateToProps = (state) => ({
})
export default connect((mapStateToProps), {})(HomeView)
src/views/PromptView/PromptView.js
import React, { Component, PropTypes } from 'react'
import { connect } from 'react-redux'
import Button from 'components/Button/Button'
import Firebase from 'firebase'
import { FIREBASE_URL } from 'redux/constants/firebase'
import { updateNode } from 'redux/modules/nodes'
import { createVoyage } from 'redux/modules/voyages'
import { Link } from 'react-router'
import ContentViewer from 'components/viewers/ContentViewer/ContentViewer'
export class PromptView extends Component {
static propTypes = {
nodeId: PropTypes.string,
node: PropTypes.object,
updateNode: PropTypes.func,
createVoyage: PropTypes.func
}
componentDidMount () {
const { nodeId, createVoyage } = this.props
if (nodeId) {
this.setupFirebase()
} else {
createVoyage()
}
}
componentDidUpdate (prevProps, prevState) {
if (!prevProps.nodeId && this.props.nodeId) {
this.setupFirebase()
}
}
componentWillUnmount () {
this.cleanUpFirebase()
}
cleanUpFirebase () {
if (this.ref) {
this.ref.off()
}
}
setupFirebase () {
const { updateNode, nodeId } = this.props
this.cleanUpFirebase()
this.ref = new Firebase(`${FIREBASE_URL}nodes/${nodeId}`)
this.ref.on('value', (snapShot) => {
updateNode(nodeId, snapShot.val())
})
}
render () {
const { nodeId, node } = this.props
if (!node) {
return <p>Loading {nodeId}...</p>
}
return (
<div className='container text-center'>
<ContentViewer node={node}/>
<Link to={`/editor/${nodeId}`}>Start</Link><br /><br />
<Button>GO DRAW</Button><br /><br />
<Button>GO WRITE</Button>
</div>
)
}
}
const mapStateToProps = (state, ownProps) => {
const { params: { nodeId } } = ownProps
const node = state.nodes.get(nodeId)
return {
nodeId,
node: node ? node.toJS() : undefined
}
}
export default connect((mapStateToProps), {
updateNode,
createVoyage
})(PromptView)
src/views/TreeView/TreeView.js
import React, { Component } from 'react'
import { connect } from 'react-redux'
import Button from 'components/Button/Button'
export class TreeView extends Component {
render () {
return (
<div className='container text-center'>
<p>TreeView</p>
<Button>NEW VOYAGE</Button><br /><br />
<Button>RANDOM VOYAGE</Button>
</div>
)
}
}
const mapStateToProps = (state) => ({
// counter: state.counter
})
export default connect((mapStateToProps), {})(TreeView)