From c908aa5b633bc4a7f7151c938df8bc2dcb1ea16d Mon Sep 17 00:00:00 2001 From: fbruc03 <65135023+fbruc03@users.noreply.github.com> Date: Thu, 17 Feb 2022 18:33:31 +0100 Subject: [PATCH] file upload with multer --- package.json | 4 +- src/components/Tutorial/Builder/Builder.js | 2 + .../Tutorial/Builder/MarkdownEditor.js | 83 +++++++++++++++++++ src/components/Tutorial/Builder/Step.js | 79 +++++++++++------- 4 files changed, 139 insertions(+), 29 deletions(-) create mode 100644 src/components/Tutorial/Builder/MarkdownEditor.js diff --git a/package.json b/package.json index 6196f1a..1ba65e0 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "axios": "^0.22.0", "blockly": "^6.20210701.0", "file-saver": "^2.0.2", + "markdown-it": "^12.3.2", "mnemonic-id": "^3.2.7", "moment": "^2.28.0", "prismjs": "^1.25.0", @@ -28,6 +29,7 @@ "react-cookie-consent": "^7.0.0", "react-dom": "^17.0.2", "react-markdown": "^5.0.2", + "react-markdown-editor-lite": "^1.3.2", "react-mde": "^11.5.0", "react-redux": "^7.2.4", "react-router-dom": "^5.2.0", @@ -39,7 +41,7 @@ "uuid": "^8.3.1" }, "scripts": { - "start": "react-scripts start", + "start": "node_modules/react-scripts/bin/react-scripts.js start", "dev": "set \"REACT_APP_BLOCKLY_API=http://localhost:8080\" && npm start", "build": "react-scripts build", "test": "react-scripts test", diff --git a/src/components/Tutorial/Builder/Builder.js b/src/components/Tutorial/Builder/Builder.js index 12803c2..4bbad7f 100644 --- a/src/components/Tutorial/Builder/Builder.js +++ b/src/components/Tutorial/Builder/Builder.js @@ -41,6 +41,8 @@ import FormControl from "@material-ui/core/FormControl"; import Select from "@material-ui/core/Select"; import * as Blockly from "blockly"; +import MarkdownEditor from "./MarkdownEditor"; + const styles = (theme) => ({ backdrop: { zIndex: theme.zIndex.drawer + 1, diff --git a/src/components/Tutorial/Builder/MarkdownEditor.js b/src/components/Tutorial/Builder/MarkdownEditor.js new file mode 100644 index 0000000..6155c3b --- /dev/null +++ b/src/components/Tutorial/Builder/MarkdownEditor.js @@ -0,0 +1,83 @@ +import React, { Component, useRef } from "react"; +import PropTypes from "prop-types"; +import { connect } from "react-redux"; +import { + tutorialTitle, + jsonString, + changeContent, + setError, + deleteError, +} from "../../../actions/tutorialBuilderActions"; + +import FormControl from "@material-ui/core/FormControl"; +import Button from "@material-ui/core/Button"; +import MarkdownIt from "markdown-it"; +import Editor from "react-markdown-editor-lite"; +import "react-markdown-editor-lite/lib/index.css"; + +import axios from "axios"; + +const mdParser = new MarkdownIt(/* Markdown-it options */); + +const MarkdownEditor = (props) => { + const [value, setValue] = React.useState(props.value); + + const mdEditor = React.useRef(null); + + function handleChange({ html, text }) { + setValue(text); + var value = text; + console.log(text); + props.changeContent(value, props.index, props.property, props.property2); + if (value.replace(/\s/g, "") === "") { + props.setError(props.index, props.property); + } else { + props.deleteError(props.index, props.property); + } + } + + async function uploadImage(files) { + return new Promise((resolve, reject) => { + const formData = new FormData(); + formData.append("files", files); + axios({ + method: "post", + url: `${process.env.REACT_APP_BLOCKLY_API}/upload/uploadImage`, + data: formData, + headers: { "Content-Type": "multipart/form-data" }, + }) + .then((res) => { + console.log(res); + resolve(`${process.env.REACT_APP_BLOCKLY_API}/upload/`+res.data.filename); + }) + .catch((err) => { + reject(new Error("error")); + }) + }) + } + + return ( + + mdParser.render(text)} + onChange={handleChange} + value={value} + id={props.property} + label={props.label} + property={props.property} + onImageUpload={uploadImage} + plugins={[]} + /> + + ); +}; + +export default connect(null, { + tutorialTitle, + jsonString, + changeContent, + setError, + deleteError, +})(MarkdownEditor); \ No newline at end of file diff --git a/src/components/Tutorial/Builder/Step.js b/src/components/Tutorial/Builder/Step.js index ba0e18c..6cee443 100644 --- a/src/components/Tutorial/Builder/Step.js +++ b/src/components/Tutorial/Builder/Step.js @@ -20,6 +20,8 @@ import Tooltip from '@material-ui/core/Tooltip'; import { faPlus, faAngleDoubleUp, faAngleDoubleDown, faTrash } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import MarkdownEditor from "./MarkdownEditor"; + const styles = (theme) => ({ button: { backgroundColor: theme.palette.primary.main, @@ -47,67 +49,88 @@ class Step extends Component { var index = this.props.index; var steps = this.props.steps; return ( -
- Schritt {index+1} -
-
+
+ Schritt {index + 1} +
+
this.props.addStep(index+1)} + style={index === 0 ? {} : { marginBottom: '5px' }} + onClick={() => this.props.addStep(index + 1)} > - + {index !== 0 ?
- + this.props.changeStepIndex(index, index-1)} + style={{ marginBottom: '5px' }} + onClick={() => this.props.changeStepIndex(index, index - 1)} > - + - + this.props.changeStepIndex(index, index+1)} + style={{ marginBottom: '5px' }} + onClick={() => this.props.changeStepIndex(index, index + 1)} > - + - + this.props.removeStep(index)} > - +
- : null} + : null}
-
+
- - + + {index === 0 ?
- - + +
- : null} + : null} {this.props.step.type === 'instruction' ? - : null} - + : null} +
@@ -130,4 +153,4 @@ const mapStateToProps = state => ({ error: state.builder.error }); -export default connect(mapStateToProps, { addStep, removeStep, changeStepIndex })(withStyles(styles, {withTheme: true})(Step)); +export default connect(mapStateToProps, { addStep, removeStep, changeStepIndex })(withStyles(styles, { withTheme: true })(Step));