import React from "react" import { draftToMarkdown, markdownToDraft } from "markdown-draft-js"; import { convertToRaw, convertFromRaw } from "draft-js" import { connect } from 'react-redux' import { Button } from '@material-ui/core' import isEmpty from 'underscore/modules/isEmpty' import EditorLayout from "../components/editor/layout" import CompetitionText from "../components/competition/competitionText" import Editor, { LeftPanel, RightPanel } from "../components/editor/editor" import StringInput from "../components/editor/input/stringInput" import MarkdownInput from "../components/editor/input/markdownInput" import DateInput from "../components/editor/input/dateInput" import InputWrapper from "../components/editor/input/inputWrapper" import Modal from "../components/modal" import { updateContest, fetchContest } from "../actions/contestActions" class ContestEditor extends React.Component { constructor(props) { super(props); this.state = {contest: {}}; this.handleChange = this._handleChange.bind(this); this.handleNumberChange = this._handleNumberChange.bind(this); this.handleMarkdownChange = this._handleMarkdownChange.bind(this); this.handleDateChange = this._handleDateChange.bind(this); this.handleSubmit = this._handleSubmit.bind(this); this.populateSavedData = this._populateSavedData.bind(this); } componentDidMount() { const prev_data = localStorage.getItem('unsaved_contest') //If we have a parameter we need to get the info for that contest if (this.props.match.params.id) { this.props.dispatch(fetchContest(this.props.match.params.id)) } else if (prev_data !== null && prev_data !== {}) { var contest = JSON.parse(prev_data); if (contest.endDate) { contest.endDate = new Date(contest.endDate); } var showModal = (isEmpty(contest)) ? false : true this.setState({...this.state, isLoaded: true, savedData: {...contest}, showModal: showModal}) } else { // Set to true automatically if we aren't requesting data this.setState({...this.state, isLoaded: true, contest: {}}) } } componentWillReceiveProps(nextProps) { var endDate if (nextProps.contest && nextProps.contest.endDate) { endDate = new Date(nextProps.contest.endDate); } this.setState({...this.state, contest: {...nextProps.contest, endDate}}) } componentDidUpdate() { localStorage.setItem('unsaved_contest', JSON.stringify(this.state.contest)) } _handleDateChange(date, name) { this.setState({ contest: { ...this.state.contest, [name]: date } }); } _handleMarkdownChange(editorState, name) { var raw = convertToRaw(editorState.getCurrentContent()); var markdown = draftToMarkdown(raw) this.setState({ contest: { ...this.state.contest, [name]: markdown } }); } _handleNumberChange(value, name) { this.setState({ contest: { ...this.state.contest, [name]: value.floatValue } }); } _handleChange(event) { const target = event.target; const value = target.value; const name = target.name; this.setState({ contest: { ...this.state.contest, [name]: value } }); } _handleSubmit() { const contestId = this.props.match.params.id this.props.dispatch(updateContest(contestId, this.state.contest, this.props.token)) } _populateSavedData(populateData) { if (populateData) { this.setState({...this.state, showModal: false, contest: this.state.savedData, savedData: null, }) } else { this.setState({...this.state, showModal: false, savedData: null }) } localStorage.removeItem('unsaved_contest') } render () { var modal = null if (this.state.savedData && this.state.showModal) { modal = <Modal show={this.state.showModal} header="Previous Data Found!" body="You have unsaved work, would you like to load it now?"> <Button color="primary" onClick={() => this.populateSavedData(true)}>Accept</Button> <Button color="secondary" onClick={() => this.populateSavedData(false)}>Decline</Button> </Modal> } const contest = this.state.contest var initialDescription = convertFromRaw(markdownToDraft(contest.description)) var initialRules = convertFromRaw(markdownToDraft(contest.rules)) var initialCriteria = convertFromRaw(markdownToDraft(contest.criteria)) return ( <EditorLayout onSubmit={this.handleSubmit}> {!this.props.isFetching ? <div className="row"> <div className="col"> {modal} <Editor> <LeftPanel> <div className="my-3 mx-5"> <InputWrapper title="Title" hint="test" > <StringInput className="editor-input col-12 form-control" placeholder="Title" onChange={event => this.handleChange(event)} name="title" value={contest.title} /> </InputWrapper> <InputWrapper title="End Date" hint="Competition end date" > <DateInput date={contest.endDate} onChange={(date) => this.handleDateChange(date, "endDate")} value={contest.endDate} /> </InputWrapper> <InputWrapper title="Description" hint="Contest description" > <MarkdownInput placeholder="Description" onChange={this.handleMarkdownChange} initialState={initialDescription} name="description" /> </InputWrapper> <InputWrapper title="Rules (Optional)" hint="Contest description" > <MarkdownInput placeholder="Rules" onChange={this.handleMarkdownChange} initialState={initialRules} name="rules" /> </InputWrapper> <InputWrapper title="Legislation Acceptance Criteria (Optional)" hint="Contest description" > <MarkdownInput placeholder="Juding Criteria" onChange={this.handleMarkdownChange} initialState={initialCriteria} name="criteria" /> </InputWrapper> </div> </LeftPanel> <RightPanel> <div className="mx-5 my-5"> <CompetitionText title={contest.title} prizes={contest.prize} endDate={(contest.endDate) ? contest.endDate.toISOString().split('T')[0]: null} description={contest.description} rules={contest.rules} criteria={contest.criteria} /> </div> </RightPanel> </Editor> </div> </div> : <div /> } </EditorLayout> ) } } function mapStateToProps(state) { var { contest, auth } = state const isFetching = contest.isFetching contest = contest.contest const { isAuthenticated } = auth return { isAuthenticated, isFetching, contest } } export default connect(mapStateToProps)(ContestEditor)