diff --git a/src/actions/tutorialBuilderActions.js b/src/actions/tutorialBuilderActions.js index f72e09a..b2d6c5c 100644 --- a/src/actions/tutorialBuilderActions.js +++ b/src/actions/tutorialBuilderActions.js @@ -180,7 +180,7 @@ export const setSubmitError = () => (dispatch, getState) => { // if(builder.id === undefined || builder.id === ''){ // dispatch(setError(undefined, 'id')); // } - if (builder.id === undefined || builder.title === '') { + if (builder.title === '') { dispatch(setError(undefined, 'title')); } var type = builder.steps.map((step, i) => { @@ -243,7 +243,7 @@ export const progress = (inProgress) => (dispatch) => { export const resetTutorial = () => (dispatch, getState) => { dispatch(jsonString('')); dispatch(tutorialTitle('')); - dispatch(tutorialId('')); + // dispatch(tutorialId('')); var steps = [ { id: 1, @@ -274,7 +274,7 @@ export const readJSON = (json) => (dispatch, getState) => { // accept only valid attributes var steps = json.steps.map((step, i) => { var object = { - id: step.id, + // id: step.id, type: step.type, headline: step.headline, text: step.text @@ -298,7 +298,7 @@ export const readJSON = (json) => (dispatch, getState) => { return object; }); dispatch(tutorialTitle(json.title)); - dispatch(tutorialId(json.id)); + // dispatch(tutorialId(json.id)); dispatch(tutorialSteps(steps)); dispatch(setSubmitError()); dispatch(progress(false)); diff --git a/src/components/Tutorial/Builder/Builder.js b/src/components/Tutorial/Builder/Builder.js index 788cde9..398c79f 100644 --- a/src/components/Tutorial/Builder/Builder.js +++ b/src/components/Tutorial/Builder/Builder.js @@ -1,7 +1,9 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; -import { checkError, readJSON, jsonString, progress, resetTutorial } from '../../../actions/tutorialBuilderActions'; +import { checkError, readJSON, jsonString, progress, tutorialId, resetTutorial as resetTutorialBuilder} from '../../../actions/tutorialBuilderActions'; +import { getTutorials, resetTutorial} from '../../../actions/tutorialActions'; +import { clearMessages } from '../../../actions/messageActions'; import axios from 'axios'; @@ -20,6 +22,13 @@ import Backdrop from '@material-ui/core/Backdrop'; import CircularProgress from '@material-ui/core/CircularProgress'; import Divider from '@material-ui/core/Divider'; import FormHelperText from '@material-ui/core/FormHelperText'; +import Radio from '@material-ui/core/Radio'; +import RadioGroup from '@material-ui/core/RadioGroup'; +import FormControlLabel from '@material-ui/core/FormControlLabel'; +import InputLabel from '@material-ui/core/InputLabel'; +import MenuItem from '@material-ui/core/MenuItem'; +import FormControl from '@material-ui/core/FormControl'; +import Select from '@material-ui/core/Select'; const styles = (theme) => ({ backdrop: { @@ -36,6 +45,7 @@ class Builder extends Component { constructor(props) { super(props); this.state = { + tutorial: 'new', open: false, title: '', content: '', @@ -47,65 +57,23 @@ class Builder extends Component { this.inputRef = React.createRef(); } + componentDidMount() { + this.props.getTutorials(); + } + + componentDidUpdate(props, state) { + if(this.props.message.id === 'GET_TUTORIALS_FAIL'){ + alert(this.props.message.msg); + this.props.clearMessages(); + } + } + componentWillUnmount() { - this.reset(); - } - - submit = () => { - var isError = this.props.checkError(); - if (isError) { - this.setState({ snackbar: true, key: Date.now(), message: `Die Angaben für das Tutorial sind nicht vollständig.`, type: 'error' }); - window.scrollTo(0, 0); - } - else { - // export steps without attribute 'url' - var steps = this.props.steps; - var newTutorial = new FormData(); - newTutorial.append('title', this.props.title); - steps.forEach((step, i) => { - newTutorial.append(`steps[${i}][type]`, step.type); - newTutorial.append(`steps[${i}][headline]`, step.headline); - newTutorial.append(`steps[${i}][text]`, step.text); - if(i === 0 && step.type === 'instruction'){ - if(step.requirements){ // optional - step.requirements.forEach((requirement, j) => { - newTutorial.append(`steps[${i}][requirements][${j}]`, requirement); - }); - } - step.hardware.forEach((hardware, j) => { - newTutorial.append(`steps[${i}][hardware][${j}]`, hardware); - }); - } - if(step.xml){ // optional - newTutorial.append(`steps[${i}][xml]`, step.xml); - } - if(step.media){ // optional - if(step.media.youtube){ - newTutorial.append(`steps[${i}][media][youtube]`, step.media.youtube); - } - if(step.media.picture){ - newTutorial.append(`steps[${i}][media][picture]`, step.media.picture); - } - } - }); - axios.post(`${process.env.REACT_APP_BLOCKLY_API}/tutorial/`, newTutorial) - .then(res => { - var tutorial = res.data.tutorial; - this.props.history.push(`/tutorial/${tutorial._id}`); - }) - .catch(err => { - this.setState({ snackbar: true, key: Date.now(), message: `Fehler beim Erstellen des Tutorials. Versuche es noch einmal.`, type: 'error' }); - window.scrollTo(0, 0); - }); - // var blob = new Blob([JSON.stringify(tutorial)], { type: 'text/json' }); - // saveAs(blob, `${detectWhitespacesAndReturnReadableResult(tutorial.title)}.json`); - } - } - - reset = () => { + this.resetFull(); this.props.resetTutorial(); - this.setState({ snackbar: true, key: Date.now(), message: `Das Tutorial wurde erfolgreich zurückgesetzt.`, type: 'success' }); - window.scrollTo(0, 0); + if(this.props.message.msg){ + this.props.clearMessages(); + } } uploadJsonFile = (jsonFile) => { @@ -153,6 +121,104 @@ class Builder extends Component { this.setState({ open: !this.state }); } + onChange = (value) => { + this.props.resetTutorialBuilder(); + this.props.tutorialId(''); + this.setState({tutorial: value}); + } + + onChangeId = (value) => { + this.props.tutorialId(value); + this.props.progress(true); + var tutorial = this.props.tutorials.filter(tutorial => tutorial._id === value)[0]; + this.props.readJSON(tutorial); + this.setState({ snackbar: true, key: Date.now(), message: `Das ausgewählte Tutorial "${tutorial.title}" wurde erfolgreich übernommen.`, type: 'success' }); + } + + resetFull = () => { + this.props.resetTutorialBuilder(); + this.setState({ snackbar: true, key: Date.now(), message: `Das Tutorial wurde erfolgreich zurückgesetzt.`, type: 'success' }); + window.scrollTo(0, 0); + } + + resetTutorial = () => { + var tutorial = this.props.tutorials.filter(tutorial => tutorial._id === this.props.id)[0]; + this.props.readJSON(tutorial); + this.setState({ snackbar: true, key: Date.now(), message: `Das Tutorial ${tutorial.title} wurde erfolgreich auf den ursprünglichen Stand zurückgesetzt.`, type: 'success' }); + window.scrollTo(0, 0); + } + + submit = () => { + var isError = this.props.checkError(); + if (isError) { + this.setState({ snackbar: true, key: Date.now(), message: `Die Angaben für das Tutorial sind nicht vollständig.`, type: 'error' }); + window.scrollTo(0, 0); + return false; + } + else { + // export steps without attribute 'url' + var steps = this.props.steps; + var newTutorial = new FormData(); + newTutorial.append('title', this.props.title); + steps.forEach((step, i) => { + newTutorial.append(`steps[${i}][type]`, step.type); + newTutorial.append(`steps[${i}][headline]`, step.headline); + newTutorial.append(`steps[${i}][text]`, step.text); + if(i === 0 && step.type === 'instruction'){ + if(step.requirements){ // optional + step.requirements.forEach((requirement, j) => { + newTutorial.append(`steps[${i}][requirements][${j}]`, requirement); + }); + } + step.hardware.forEach((hardware, j) => { + newTutorial.append(`steps[${i}][hardware][${j}]`, hardware); + }); + } + if(step.xml){ // optional + newTutorial.append(`steps[${i}][xml]`, step.xml); + } + if(step.media){ // optional + if(step.media.youtube){ + newTutorial.append(`steps[${i}][media][youtube]`, step.media.youtube); + } + if(step.media.picture){ + newTutorial.append(`steps[${i}][media][picture]`, step.media.picture); + } + } + }); + return newTutorial; + } + } + + submitNew = () => { + var newTutorial = this.submit(); + if(newTutorial){ + axios.post(`${process.env.REACT_APP_BLOCKLY_API}/tutorial/`, newTutorial) + .then(res => { + var tutorial = res.data.tutorial; + this.props.history.push(`/tutorial/${tutorial._id}`); + }) + .catch(err => { + this.setState({ snackbar: true, key: Date.now(), message: `Fehler beim Erstellen des Tutorials. Versuche es noch einmal.`, type: 'error' }); + window.scrollTo(0, 0); + }); + } + } + + submitUpdate = () => { + var updatedTutorial = this.submit(); + if(updatedTutorial){ + axios.put(`${process.env.REACT_APP_BLOCKLY_API}/tutorial/${this.props.id}`, updatedTutorial) + .then(res => { + var tutorial = res.data.tutorial; + this.props.history.push(`/tutorial/${tutorial._id}`); + }) + .catch(err => { + this.setState({ snackbar: true, key: Date.now(), message: `Fehler beim Ändern des Tutorials. Versuche es noch einmal.`, type: 'error' }); + window.scrollTo(0, 0); + }); + } + } render() { return ( @@ -161,41 +227,88 @@ class Builder extends Component {