application/components/content/content-publish.js
import React from 'react';
import moment from 'moment';
import Dialog from 'material-ui/Dialog';
import {Step, Stepper, StepLabel} from 'material-ui/Stepper';
import RaisedButton from 'material-ui/RaisedButton';
import FlatButton from 'material-ui/FlatButton';
import FontIcon from 'material-ui/FontIcon';
import DatePicker from 'material-ui/DatePicker';
import TimePicker from 'material-ui/TimePicker';
import Subheader from 'material-ui/Subheader';
import {stateToHTML} from 'draft-js-export-html';
// import stateToHTML from './../../exportToHTML_modified';
import SimpleEditor from './../common/simple-editor';
import WordCounter from './../common/word-counter';
import {Row, Col} from './../flexbox';
import UrlHandler from './url-handler';
import striptags from '../../util/striptags';
import {language} from './../../lang/en/publish.js';
import {stateFromHTML} from 'draft-js-import-html';
import {convertToRaw} from 'draft-js';
class ContentPublish extends React.Component {
constructor(props) {
super(props);
this.totalSteps = 3;
const now = new moment();
this.state = {
isOpen: this.props.isOpen,
finished: false,
stepIndex: 0,
content: this.props.content,
abstract: this.props.abstract ? this.props.abstract.html : this.props.content.get('abstract'),
abstract_raw: this.props.abstract ? this.props.abstract.raw : this.props.content.get('abstract_raw'),
pubDate: now.add('1', 'days').startOf('day').local().toDate(),
pubTime: now.add('1', 'days').startOf('day').local().toDate(),
};
this.state.startValue = this.state.abstract;
this.handleDateChange = this.handleDateChange.bind(this);
this.handleTimeChange = this.handleTimeChange.bind(this);
this.handleFinish = this.handleFinish.bind(this);
this.stepOne = this.stepOne.bind(this);
this.stepTwo = this.stepTwo.bind(this);
this.stepThree = this.stepThree.bind(this);
}
componentWillMount() {
const now = new moment();
this.setState({
isOpen: this.props.isOpen,
finished: false,
stepIndex: 0,
didEditAbstract: false,
content: this.props.content,
pubDate: now.add('1', 'days').startOf('day').local().toDate(),
pubTime: now.add('1', 'days').startOf('day').local().toDate(),
});
}
handleDateChange(e, date) {
this.setState({pubDate: date});
}
handleTimeChange(e, time) {
this.setState({pubTime: time});
}
handleFinish() {
const pubDate = new moment(this.state.pubDate);
const pubTime = new moment(this.state.pubTime);
pubDate.set('hour', pubTime.hour());
pubDate.set('minute', pubTime.minute());
this.props.onPublish({
'published_at': pubDate.utc().format('Y-MM-DD HH:mm:ss'),
'abstract': this.state.didEditAbstract ? this.state.abstract : null,
'abstract_raw': this.state.didEditAbstract ? this.state.abstract_raw : null
});
setTimeout(() => {
this.handleClose();
}, 100);
}
doPublishNow() {
this.props.onPublish({
'published_at': new moment().utc().format('Y-MM-DD HH:mm:ss'),
'abstract': this.state.didEditAbstract ? this.state.abstract : null,
'abstract_raw': this.state.didEditAbstract ? this.state.abstract_raw : null
});
setTimeout(() => {
this.handleClose();
}, 100);
}
stepOne() {
if (!this.state.content.get('title_url')) {
return (
<div>
You must provide a URL slug before publishing.
</div>
);
}
return (
<div>
{language.stepOne()}
<h4>Title:</h4>
<p>{this.state.content.get('title') ? this.state.content.get('title') : 'No Title!'}</p>
<h4>URLs:</h4>
<p><UrlHandler disabled={true} displayOnly={true} content={this.state.content} /></p>
</div>
);
}
stepTwo() {
return (
<div>
{language.stepTwo()}
<SimpleEditor
name="abstract"
mentions={false}
value={this.state.startValue}
onChange={this.handleSimpleEditorChange.bind(this)}
toolbarRight={
<span className='simple-editor-styleButton' onClick={this.handleGenerateAbstract.bind(this)} title="Auto-generate Abstract">
<FontIcon style={{'fontSize': '1rem', 'cursor': 'pointer'}} className='mui-icons'>content_copy</FontIcon>
</span>
}
/>
{
this.state.abstract
? (
<small>
<WordCounter count={this.state.abstract} displayEmpty={true} />
</small>
)
: ''
}
</div>
);
}
stepThree() {
return (
<div>
{language.stepThree()}
<Row middle={['xs']} center={['xs']}>
<Col xs={5}>
<RaisedButton
primary={true}
label='Publish Now'
onClick={this.doPublishNow.bind(this)}
/>
</Col>
<Col xs={2}>
- OR -
</Col>
<Col xs={5}>
<DatePicker
value={this.state.pubDate}
onChange={this.handleDateChange}
autoOk={true}
floatingLabelText='Publication date'
firstDayOfWeek={0}
/>
<TimePicker
value={this.state.pubTime}
autoOk={true}
onChange={this.handleTimeChange}
floatingLabelText='Publication time'
/>
</Col>
</Row>
</div>
);
}
handleNext() {
const {stepIndex} = this.state;
this.setState({
stepIndex: stepIndex + 1,
finished: stepIndex >= this.totalSteps - 1
}, () => {
if (this.state.finished) {
this.handleFinish();
}
});
}
handlePrev() {
const {stepIndex} = this.state;
if (stepIndex > 0) {
this.setState({stepIndex: stepIndex - 1, finished: false})
} else {
this.handleClose();
}
}
handleCancel() {
const {stepIndex} = this.state;
if (stepIndex > 0) {
this.setState({stepIndex: 0, finished: false})
}
this.handleClose();
}
getStepContent(index) {
switch(index) {
case 0:
return this.stepOne();
case 1:
return this.stepTwo();
case 2:
return this.stepThree();
}
}
componentWillReceiveProps(nextProps) {
this.setState(nextProps);
}
handleGenerateAbstract() {
// strip tags and split it apart
let content = this.props.content.get('content');
content = striptags(content).split(/(\r|\n)/g);
// create one graf
const html = '<p>' + content[0] + '</p>';
// put them back together, but create a new editor state in the process
this.setState({
didEditAbstract: true,
abstract: html,
abstract_raw: convertToRaw(stateFromHTML(html)),
startValue: html
});
}
handleClose() {
this.setState({'isOpen': false});
if (this.props.onClose) {
this.props.onClose();
}
}
handleSimpleEditorChange(raw, editorState, name) {
this.setState({
didEditAbstract: true,
abstract_raw: raw,
abstract: stateToHTML(editorState.getCurrentContent())
});
}
render() {
const {finished, stepIndex} = this.state;
const actions = [
<FlatButton
label='Cancel'
secondary={true}
onClick={this.handleCancel.bind(this)}
/>,
<FlatButton
style={stepIndex === 0 ? {display:'none'} : {display:'inline-block'} }
label='Back'
labelPosition='after'
icon={<FontIcon className='mui-icons'>keyboard_arrow_left</FontIcon>}
onClick={this.handlePrev.bind(this)}
/>,
<FlatButton
disabled={this.state.content.get('title_url') ? false : true}
label={stepIndex === 2 ? 'Finish' : 'Next'}
labelPosition='before'
icon={stepIndex === 2 ? <FontIcon className='mui-icons'>check_circle</FontIcon> : <FontIcon className='mui-icons'>keyboard_arrow_right</FontIcon>}
onClick={this.handleNext.bind(this)}
/>
];
return (
<Dialog
actions={actions}
modal={true}
open={this.state.isOpen}
>
<Stepper activeStep={stepIndex}>
<Step>
<StepLabel>Title and URLs</StepLabel>
</Step>
<Step>
<StepLabel>Abstract</StepLabel>
</Step>
<Step>
<StepLabel>Publish</StepLabel>
</Step>
</Stepper>
<div>
{this.getStepContent(stepIndex)}
</div>
</Dialog>
);
}
}
export default ContentPublish;